blob: bbc1f472387f6038f442977297e5b49261f54217 [file] [log] [blame]
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.server.location;
17
18import android.content.ComponentName;
19import android.content.Intent;
20import android.content.ServiceConnection;
21import android.hardware.location.GeofenceHardwareService;
22import android.hardware.location.IGeofenceHardware;
23import android.location.IGeofenceProvider;
24import android.location.IGpsGeofenceHardware;
destradaa0682809a2013-08-12 18:50:30 -070025import android.location.IFusedGeofenceHardware;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070026import android.content.Context;
27import android.os.Handler;
28import android.os.IBinder;
29import android.os.Message;
30import android.os.RemoteException;
31import android.os.UserHandle;
32import android.util.Log;
33import com.android.server.ServiceWatcher;
34
35import java.util.List;
36
37/**
38 * @hide
39 */
40public final class GeofenceProxy {
41 private static final String TAG = "GeofenceProxy";
42 private static final String SERVICE_ACTION =
43 "com.android.location.service.GeofenceProvider";
Zhentao Sund535ead2013-08-29 14:43:35 -070044 private final ServiceWatcher mServiceWatcher;
45 private final Context mContext;
46 private final IGpsGeofenceHardware mGpsGeofenceHardware;
47 private final IFusedGeofenceHardware mFusedGeofenceHardware;
48
49 private final Object mLock = new Object();
50
51 // Access to mGeofenceHardware needs to be synchronized by mLock.
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070052 private IGeofenceHardware mGeofenceHardware;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070053
54 private static final int GEOFENCE_PROVIDER_CONNECTED = 1;
55 private static final int GEOFENCE_HARDWARE_CONNECTED = 2;
56 private static final int GEOFENCE_HARDWARE_DISCONNECTED = 3;
57 private static final int GEOFENCE_GPS_HARDWARE_CONNECTED = 4;
58 private static final int GEOFENCE_GPS_HARDWARE_DISCONNECTED = 5;
59
60 private Runnable mRunnable = new Runnable() {
61 @Override
62 public void run() {
63 mHandler.sendEmptyMessage(GEOFENCE_PROVIDER_CONNECTED);
64 }
65 };
66
67 public static GeofenceProxy createAndBind(Context context,
Zhentao Sunc5fc9982013-04-17 17:47:53 -070068 int overlaySwitchResId, int defaultServicePackageNameResId,
destradaa0682809a2013-08-12 18:50:30 -070069 int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence,
70 IFusedGeofenceHardware fusedGeofenceHardware) {
Zhentao Sunc5fc9982013-04-17 17:47:53 -070071 GeofenceProxy proxy = new GeofenceProxy(context, overlaySwitchResId,
destradaa0682809a2013-08-12 18:50:30 -070072 defaultServicePackageNameResId, initialPackageNamesResId, handler, gpsGeofence,
73 fusedGeofenceHardware);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070074 if (proxy.bindGeofenceProvider()) {
75 return proxy;
76 } else {
77 return null;
78 }
79 }
80
Zhentao Sunc5fc9982013-04-17 17:47:53 -070081 private GeofenceProxy(Context context,
82 int overlaySwitchResId, int defaultServicePackageNameResId,
destradaa0682809a2013-08-12 18:50:30 -070083 int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence,
84 IFusedGeofenceHardware fusedGeofenceHardware) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070085 mContext = context;
Zhentao Sunc5fc9982013-04-17 17:47:53 -070086 mServiceWatcher = new ServiceWatcher(context, TAG, SERVICE_ACTION, overlaySwitchResId,
87 defaultServicePackageNameResId, initialPackageNamesResId, mRunnable, handler);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070088 mGpsGeofenceHardware = gpsGeofence;
destradaa0682809a2013-08-12 18:50:30 -070089 mFusedGeofenceHardware = fusedGeofenceHardware;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070090 bindHardwareGeofence();
91 }
92
93 private boolean bindGeofenceProvider() {
94 return mServiceWatcher.start();
95 }
96
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070097 private void bindHardwareGeofence() {
98 mContext.bindServiceAsUser(new Intent(mContext, GeofenceHardwareService.class),
99 mServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.OWNER);
100 }
101
102 private ServiceConnection mServiceConnection = new ServiceConnection() {
103 @Override
104 public void onServiceConnected(ComponentName name, IBinder service) {
Zhentao Sund535ead2013-08-29 14:43:35 -0700105 synchronized (mLock) {
106 mGeofenceHardware = IGeofenceHardware.Stub.asInterface(service);
107 mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_CONNECTED);
108 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700109 }
110
111 @Override
112 public void onServiceDisconnected(ComponentName name) {
Zhentao Sund535ead2013-08-29 14:43:35 -0700113 synchronized (mLock) {
114 mGeofenceHardware = null;
115 mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_DISCONNECTED);
116 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700117 }
118 };
119
Zhentao Sund535ead2013-08-29 14:43:35 -0700120 private void setGeofenceHardwareInProviderLocked() {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700121 try {
Zhentao Sund535ead2013-08-29 14:43:35 -0700122 IGeofenceProvider provider = IGeofenceProvider.Stub.asInterface(
123 mServiceWatcher.getBinder());
124 if (provider != null) {
125 provider.setGeofenceHardware(mGeofenceHardware);
126 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700127 } catch (RemoteException e) {
Zhentao Sund535ead2013-08-29 14:43:35 -0700128 Log.e(TAG, "Remote Exception: setGeofenceHardwareInProviderLocked: " + e);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700129 }
130 }
131
Zhentao Sund535ead2013-08-29 14:43:35 -0700132 private void setGpsGeofenceLocked() {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700133 try {
134 mGeofenceHardware.setGpsGeofenceHardware(mGpsGeofenceHardware);
135 } catch (RemoteException e) {
136 Log.e(TAG, "Error while connecting to GeofenceHardwareService");
137 }
138 }
139
Zhentao Sund535ead2013-08-29 14:43:35 -0700140 private void setFusedGeofenceLocked() {
destradaa0682809a2013-08-12 18:50:30 -0700141 try {
142 mGeofenceHardware.setFusedGeofenceHardware(mFusedGeofenceHardware);
143 } catch(RemoteException e) {
144 Log.e(TAG, "Error while connecting to GeofenceHardwareService");
145 }
146 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700147
148 // This needs to be reworked, when more services get added,
149 // Might need a state machine or add a framework utility class,
150 private Handler mHandler = new Handler() {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700151
152 @Override
153 public void handleMessage(Message msg) {
154 switch (msg.what) {
155 case GEOFENCE_PROVIDER_CONNECTED:
Zhentao Sund535ead2013-08-29 14:43:35 -0700156 synchronized (mLock) {
157 if (mGeofenceHardware != null) {
158 setGeofenceHardwareInProviderLocked();
159 }
160 // else: the geofence provider will be notified when the connection to
161 // GeofenceHardwareService is established.
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700162 }
163 break;
164 case GEOFENCE_HARDWARE_CONNECTED:
Zhentao Sund535ead2013-08-29 14:43:35 -0700165 synchronized (mLock) {
166 // Theoretically this won't happen because once the GeofenceHardwareService
167 // is connected to, we won't lose connection to it because it's a system
168 // service. But this check does make the code more robust.
169 if (mGeofenceHardware != null) {
170 setGpsGeofenceLocked();
171 setFusedGeofenceLocked();
172 setGeofenceHardwareInProviderLocked();
173 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700174 }
175 break;
176 case GEOFENCE_HARDWARE_DISCONNECTED:
Zhentao Sund535ead2013-08-29 14:43:35 -0700177 synchronized (mLock) {
178 if (mGeofenceHardware == null) {
179 setGeofenceHardwareInProviderLocked();
180 }
181 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700182 break;
183 }
184 }
185 };
186}