18ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh/* 28ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * Copyright (C) 2013 The Android Open Source Project 38ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * 48ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * Licensed under the Apache License, Version 2.0 (the "License"); 58ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * you may not use this file except in compliance with the License. 68ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * You may obtain a copy of the License at 78ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * 88ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * http://www.apache.org/licenses/LICENSE-2.0 98ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * 108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * Unless required by applicable law or agreed to in writing, software 118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * distributed under the License is distributed on an "AS IS" BASIS, 128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * See the License for the specific language governing permissions and 148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * limitations under the License. 158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshpackage com.android.server.location; 178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.content.ComponentName; 198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.content.Intent; 208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.content.ServiceConnection; 218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.hardware.location.GeofenceHardwareService; 228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.hardware.location.IGeofenceHardware; 238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.location.IGeofenceProvider; 248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.location.IGpsGeofenceHardware; 258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.content.Context; 268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.Handler; 278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.IBinder; 288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.Message; 298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.RemoteException; 308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.UserHandle; 318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.util.Log; 328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport com.android.server.ServiceWatcher; 338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport java.util.List; 358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh/** 378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * @hide 388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshpublic final class GeofenceProxy { 408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final String TAG = "GeofenceProxy"; 418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final String SERVICE_ACTION = 428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh "com.android.location.service.GeofenceProvider"; 438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private ServiceWatcher mServiceWatcher; 448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private Context mContext; 458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private IGeofenceHardware mGeofenceHardware; 468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private IGpsGeofenceHardware mGpsGeofenceHardware; 478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GEOFENCE_PROVIDER_CONNECTED = 1; 498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GEOFENCE_HARDWARE_CONNECTED = 2; 508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GEOFENCE_HARDWARE_DISCONNECTED = 3; 518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GEOFENCE_GPS_HARDWARE_CONNECTED = 4; 528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GEOFENCE_GPS_HARDWARE_DISCONNECTED = 5; 538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private Runnable mRunnable = new Runnable() { 558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh @Override 568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void run() { 578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mHandler.sendEmptyMessage(GEOFENCE_PROVIDER_CONNECTED); 588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh }; 608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public static GeofenceProxy createAndBind(Context context, 62c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun int overlaySwitchResId, int defaultServicePackageNameResId, 63c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence) { 64c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun GeofenceProxy proxy = new GeofenceProxy(context, overlaySwitchResId, 65c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun defaultServicePackageNameResId, initialPackageNamesResId, handler, gpsGeofence); 668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (proxy.bindGeofenceProvider()) { 678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return proxy; 688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else { 698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return null; 708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 73c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun private GeofenceProxy(Context context, 74c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun int overlaySwitchResId, int defaultServicePackageNameResId, 75c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun int initialPackageNamesResId, Handler handler, IGpsGeofenceHardware gpsGeofence) { 768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mContext = context; 77c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun mServiceWatcher = new ServiceWatcher(context, TAG, SERVICE_ACTION, overlaySwitchResId, 78c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun defaultServicePackageNameResId, initialPackageNamesResId, mRunnable, handler); 798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGpsGeofenceHardware = gpsGeofence; 808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh bindHardwareGeofence(); 818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private boolean bindGeofenceProvider() { 848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return mServiceWatcher.start(); 858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private IGeofenceProvider getGeofenceProviderService() { 888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return IGeofenceProvider.Stub.asInterface(mServiceWatcher.getBinder()); 898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private void bindHardwareGeofence() { 928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mContext.bindServiceAsUser(new Intent(mContext, GeofenceHardwareService.class), 938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mServiceConnection, Context.BIND_AUTO_CREATE, UserHandle.OWNER); 948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private ServiceConnection mServiceConnection = new ServiceConnection() { 978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh @Override 988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void onServiceConnected(ComponentName name, IBinder service) { 998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceHardware = IGeofenceHardware.Stub.asInterface(service); 1008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_CONNECTED); 1018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh @Override 1048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void onServiceDisconnected(ComponentName name) { 1058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceHardware = null; 1068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mHandler.sendEmptyMessage(GEOFENCE_HARDWARE_DISCONNECTED); 1078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh }; 1098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private void setGeofenceHardwareInProvider() { 1118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 1128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh getGeofenceProviderService().setGeofenceHardware(mGeofenceHardware); 1138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 1148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "Remote Exception: setGeofenceHardwareInProvider: " + e); 1158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private void setGpsGeofence() { 1198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 1208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceHardware.setGpsGeofenceHardware(mGpsGeofenceHardware); 1218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 1228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "Error while connecting to GeofenceHardwareService"); 1238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // This needs to be reworked, when more services get added, 1288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // Might need a state machine or add a framework utility class, 1298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private Handler mHandler = new Handler() { 1308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private boolean mGeofenceHardwareConnected = false; 1318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private boolean mGeofenceProviderConnected = false; 1328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh @Override 1358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void handleMessage(Message msg) { 1368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (msg.what) { 1378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GEOFENCE_PROVIDER_CONNECTED: 1388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceProviderConnected = true; 1398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGeofenceHardwareConnected) { 1408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh setGeofenceHardwareInProvider(); 1418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 1438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GEOFENCE_HARDWARE_CONNECTED: 1448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh setGpsGeofence(); 1458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceHardwareConnected = true; 1468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGeofenceProviderConnected) { 1478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh setGeofenceHardwareInProvider(); 1488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 1508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GEOFENCE_HARDWARE_DISCONNECTED: 1518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceHardwareConnected = false; 1528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh setGeofenceHardwareInProvider(); 1538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 1548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh }; 1578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh} 158