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 if (!mServiceWatcher.runOnBinder(new ServiceWatcher.BinderRunner() { 107 @Override 108 public void run(IBinder binder) { 109 String descriptor; 110 try { 111 descriptor = binder.getInterfaceDescriptor(); 112 } catch (RemoteException e) { 113 Log.e(TAG, "Unable to get interface descriptor.", e); 114 return; 115 } 116 117 if (IActivityRecognitionHardwareWatcher.class.getCanonicalName() 118 .equals(descriptor)) { 119 IActivityRecognitionHardwareWatcher watcher = 120 IActivityRecognitionHardwareWatcher.Stub.asInterface(binder); 121 if (watcher == null) { 122 Log.e(TAG, "No watcher found on connection."); 123 return; 124 } 125 if (mInstance == null) { 126 // to keep backwards compatibility do not update the watcher when there is 127 // no instance available, or it will cause an NPE 128 Log.d(TAG, "AR HW instance not available, binding will be a no-op."); 129 return; 130 } 131 try { 132 watcher.onInstanceChanged(mInstance); 133 } catch (RemoteException e) { 134 Log.e(TAG, "Error delivering hardware interface to watcher.", e); 135 } 136 } else if (IActivityRecognitionHardwareClient.class.getCanonicalName() 137 .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 Log.e(TAG, "Null binder found on connection."); 155 } 156 } 157 } 158