Home | History | Annotate | Download | only in location
      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