1 /* 2 * Copyright (C) 2014 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 */ 16 17 package com.android.server.location; 18 19 import com.android.server.ServiceWatcher; 20 21 import android.content.Context; 22 import android.hardware.location.ActivityRecognitionHardware; 23 import android.hardware.location.IActivityRecognitionHardwareClient; 24 import android.hardware.location.IActivityRecognitionHardwareWatcher; 25 import android.os.Handler; 26 import android.os.IBinder; 27 import android.os.RemoteException; 28 import android.util.Log; 29 30 /** 31 * Proxy class to bind GmsCore to the ActivityRecognitionHardware. 32 * 33 * @hide 34 */ 35 public class ActivityRecognitionProxy { 36 private static final String TAG = "ActivityRecognitionProxy"; 37 38 private final ServiceWatcher mServiceWatcher; 39 private final boolean mIsSupported; 40 private final ActivityRecognitionHardware mInstance; 41 42 private ActivityRecognitionProxy( 43 Context context, 44 Handler handler, 45 boolean activityRecognitionHardwareIsSupported, 46 ActivityRecognitionHardware activityRecognitionHardware, 47 int overlaySwitchResId, 48 int defaultServicePackageNameResId, 49 int initialPackageNameResId) { 50 mIsSupported = activityRecognitionHardwareIsSupported; 51 mInstance = activityRecognitionHardware; 52 53 Runnable newServiceWork = new Runnable() { 54 @Override 55 public void run() { 56 bindProvider(); 57 } 58 }; 59 60 // prepare the connection to the provider 61 mServiceWatcher = new ServiceWatcher( 62 context, 63 TAG, 64 "com.android.location.service.ActivityRecognitionProvider", 65 overlaySwitchResId, 66 defaultServicePackageNameResId, 67 initialPackageNameResId, 68 newServiceWork, 69 handler); 70 } 71 72 /** 73 * Creates an instance of the proxy and binds it to the appropriate FusedProvider. 74 * 75 * @return An instance of the proxy if it could be bound, null otherwise. 76 */ 77 public static ActivityRecognitionProxy createAndBind( 78 Context context, 79 Handler handler, 80 boolean activityRecognitionHardwareIsSupported, 81 ActivityRecognitionHardware activityRecognitionHardware, 82 int overlaySwitchResId, 83 int defaultServicePackageNameResId, 84 int initialPackageNameResId) { 85 ActivityRecognitionProxy activityRecognitionProxy = new ActivityRecognitionProxy( 86 context, 87 handler, 88 activityRecognitionHardwareIsSupported, 89 activityRecognitionHardware, 90 overlaySwitchResId, 91 defaultServicePackageNameResId, 92 initialPackageNameResId); 93 94 // try to bind the provider 95 if (!activityRecognitionProxy.mServiceWatcher.start()) { 96 Log.e(TAG, "ServiceWatcher could not start."); 97 return null; 98 } 99 return activityRecognitionProxy; 100 } 101 102 /** 103 * Helper function to bind the FusedLocationHardware to the appropriate FusedProvider instance. 104 */ 105 private void bindProvider() { 106 IBinder binder = mServiceWatcher.getBinder(); 107 if (binder == null) { 108 Log.e(TAG, "Null binder found on connection."); 109 return; 110 } 111 String descriptor; 112 try { 113 descriptor = binder.getInterfaceDescriptor(); 114 } catch (RemoteException e) { 115 Log.e(TAG, "Unable to get interface descriptor.", e); 116 return; 117 } 118 119 if (IActivityRecognitionHardwareWatcher.class.getCanonicalName().equals(descriptor)) { 120 IActivityRecognitionHardwareWatcher watcher = 121 IActivityRecognitionHardwareWatcher.Stub.asInterface(binder); 122 if (watcher == null) { 123 Log.e(TAG, "No watcher found on connection."); 124 return; 125 } 126 if (mInstance == null) { 127 // to keep backwards compatibility do not update the watcher when there is no 128 // instance available, or it will cause an NPE 129 Log.d(TAG, "AR HW instance not available, binding will be a no-op."); 130 return; 131 } 132 try { 133 watcher.onInstanceChanged(mInstance); 134 } catch (RemoteException e) { 135 Log.e(TAG, "Error delivering hardware interface to watcher.", e); 136 } 137 } else if (IActivityRecognitionHardwareClient.class.getCanonicalName().equals(descriptor)) { 138 IActivityRecognitionHardwareClient client = 139 IActivityRecognitionHardwareClient.Stub.asInterface(binder); 140 if (client == null) { 141 Log.e(TAG, "No client found on connection."); 142 return; 143 } 144 try { 145 client.onAvailabilityChanged(mIsSupported, mInstance); 146 } catch (RemoteException e) { 147 Log.e(TAG, "Error delivering hardware interface to client.", e); 148 } 149 } else { 150 Log.e(TAG, "Invalid descriptor found on connection: " + descriptor); 151 } 152 } 153 } 154