blob: b886eef4311dcff270b274e9e248045b2f708305 [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
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070035/**
36 * @hide
37 */
38public final class GeofenceProxy {
39 private static final String TAG = "GeofenceProxy";
40 private static final String SERVICE_ACTION =
41 "com.android.location.service.GeofenceProvider";
Zhentao Sund535ead2013-08-29 14:43:35 -070042 private final ServiceWatcher mServiceWatcher;
43 private final Context mContext;
44 private final IGpsGeofenceHardware mGpsGeofenceHardware;
45 private final IFusedGeofenceHardware mFusedGeofenceHardware;
46
47 private final Object mLock = new Object();
48
49 // Access to mGeofenceHardware needs to be synchronized by mLock.
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070050 private IGeofenceHardware mGeofenceHardware;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070051
52 private static final int GEOFENCE_PROVIDER_CONNECTED = 1;
53 private static final int GEOFENCE_HARDWARE_CONNECTED = 2;
54 private static final int GEOFENCE_HARDWARE_DISCONNECTED = 3;
55 private static final int GEOFENCE_GPS_HARDWARE_CONNECTED = 4;
56 private static final int GEOFENCE_GPS_HARDWARE_DISCONNECTED = 5;
57
58 private Runnable mRunnable = new Runnable() {
59 @Override
60 public void run() {
61 mHandler.sendEmptyMessage(GEOFENCE_PROVIDER_CONNECTED);
62 }
63 };
64
65 public static GeofenceProxy createAndBind(Context context,
Zhentao Sunc5fc9982013-04-17 17:47:53 -070066 int overlaySwitchResId, int defaultServicePackageNameResId,
destradaa0682809a2013-08-12 18:50:30 -070067 int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence,
68 IFusedGeofenceHardware fusedGeofenceHardware) {
Zhentao Sunc5fc9982013-04-17 17:47:53 -070069 GeofenceProxy proxy = new GeofenceProxy(context, overlaySwitchResId,
destradaa0682809a2013-08-12 18:50:30 -070070 defaultServicePackageNameResId, initialPackageNamesResId, handler, gpsGeofence,
71 fusedGeofenceHardware);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070072 if (proxy.bindGeofenceProvider()) {
73 return proxy;
74 } else {
75 return null;
76 }
77 }
78
Zhentao Sunc5fc9982013-04-17 17:47:53 -070079 private GeofenceProxy(Context context,
80 int overlaySwitchResId, int defaultServicePackageNameResId,
destradaa0682809a2013-08-12 18:50:30 -070081 int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence,
82 IFusedGeofenceHardware fusedGeofenceHardware) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070083 mContext = context;
Zhentao Sunc5fc9982013-04-17 17:47:53 -070084 mServiceWatcher = new ServiceWatcher(context, TAG, SERVICE_ACTION, overlaySwitchResId,
85 defaultServicePackageNameResId, initialPackageNamesResId, mRunnable, handler);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070086 mGpsGeofenceHardware = gpsGeofence;
destradaa0682809a2013-08-12 18:50:30 -070087 mFusedGeofenceHardware = fusedGeofenceHardware;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070088 bindHardwareGeofence();
89 }
90
91 private boolean bindGeofenceProvider() {
92 return mServiceWatcher.start();
93 }
94
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070095 private void bindHardwareGeofence() {
96 mContext.bindServiceAsUser(new Intent(mContext, GeofenceHardwareService.class),
97 mServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.OWNER);
98 }
99
100 private ServiceConnection mServiceConnection = new ServiceConnection() {
101 @Override
102 public void onServiceConnected(ComponentName name, IBinder service) {
Zhentao Sund535ead2013-08-29 14:43:35 -0700103 synchronized (mLock) {
104 mGeofenceHardware = IGeofenceHardware.Stub.asInterface(service);
105 mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_CONNECTED);
106 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700107 }
108
109 @Override
110 public void onServiceDisconnected(ComponentName name) {
Zhentao Sund535ead2013-08-29 14:43:35 -0700111 synchronized (mLock) {
112 mGeofenceHardware = null;
113 mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_DISCONNECTED);
114 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700115 }
116 };
117
Zhentao Sund535ead2013-08-29 14:43:35 -0700118 private void setGeofenceHardwareInProviderLocked() {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700119 try {
Zhentao Sund535ead2013-08-29 14:43:35 -0700120 IGeofenceProvider provider = IGeofenceProvider.Stub.asInterface(
121 mServiceWatcher.getBinder());
122 if (provider != null) {
123 provider.setGeofenceHardware(mGeofenceHardware);
124 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700125 } catch (RemoteException e) {
Zhentao Sund535ead2013-08-29 14:43:35 -0700126 Log.e(TAG, "Remote Exception: setGeofenceHardwareInProviderLocked: " + e);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700127 }
128 }
129
Zhentao Sund535ead2013-08-29 14:43:35 -0700130 private void setGpsGeofenceLocked() {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700131 try {
132 mGeofenceHardware.setGpsGeofenceHardware(mGpsGeofenceHardware);
133 } catch (RemoteException e) {
134 Log.e(TAG, "Error while connecting to GeofenceHardwareService");
135 }
136 }
137
Zhentao Sund535ead2013-08-29 14:43:35 -0700138 private void setFusedGeofenceLocked() {
destradaa0682809a2013-08-12 18:50:30 -0700139 try {
140 mGeofenceHardware.setFusedGeofenceHardware(mFusedGeofenceHardware);
141 } catch(RemoteException e) {
142 Log.e(TAG, "Error while connecting to GeofenceHardwareService");
143 }
144 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700145
146 // This needs to be reworked, when more services get added,
147 // Might need a state machine or add a framework utility class,
148 private Handler mHandler = new Handler() {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700149
150 @Override
151 public void handleMessage(Message msg) {
152 switch (msg.what) {
153 case GEOFENCE_PROVIDER_CONNECTED:
Zhentao Sund535ead2013-08-29 14:43:35 -0700154 synchronized (mLock) {
155 if (mGeofenceHardware != null) {
156 setGeofenceHardwareInProviderLocked();
157 }
158 // else: the geofence provider will be notified when the connection to
159 // GeofenceHardwareService is established.
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700160 }
161 break;
162 case GEOFENCE_HARDWARE_CONNECTED:
Zhentao Sund535ead2013-08-29 14:43:35 -0700163 synchronized (mLock) {
164 // Theoretically this won't happen because once the GeofenceHardwareService
165 // is connected to, we won't lose connection to it because it's a system
166 // service. But this check does make the code more robust.
167 if (mGeofenceHardware != null) {
168 setGpsGeofenceLocked();
169 setFusedGeofenceLocked();
170 setGeofenceHardwareInProviderLocked();
171 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700172 }
173 break;
174 case GEOFENCE_HARDWARE_DISCONNECTED:
Zhentao Sund535ead2013-08-29 14:43:35 -0700175 synchronized (mLock) {
176 if (mGeofenceHardware == null) {
177 setGeofenceHardwareInProviderLocked();
178 }
179 }
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700180 break;
181 }
182 }
183 };
184}