• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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  */
16 package com.android.server.location;
17 
18 import android.annotation.Nullable;
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.ServiceConnection;
23 import android.hardware.location.GeofenceHardwareService;
24 import android.hardware.location.IGeofenceHardware;
25 import android.location.IGeofenceProvider;
26 import android.location.IGpsGeofenceHardware;
27 import android.os.IBinder;
28 import android.os.RemoteException;
29 import android.os.UserHandle;
30 import android.util.Log;
31 
32 import com.android.server.FgThread;
33 import com.android.server.ServiceWatcher;
34 
35 import java.util.Objects;
36 
37 /**
38  * @hide
39  */
40 public final class GeofenceProxy {
41 
42     private static final String TAG = "GeofenceProxy";
43     private static final String SERVICE_ACTION = "com.android.location.service.GeofenceProvider";
44 
45     @Nullable
createAndBind(Context context, IGpsGeofenceHardware gpsGeofence)46     public static GeofenceProxy createAndBind(Context context, IGpsGeofenceHardware gpsGeofence) {
47         GeofenceProxy proxy = new GeofenceProxy(context, gpsGeofence);
48         if (proxy.register(context)) {
49             return proxy;
50         } else {
51             return null;
52         }
53     }
54 
55     private final IGpsGeofenceHardware mGpsGeofenceHardware;
56     private final ServiceWatcher mServiceWatcher;
57 
58     private volatile IGeofenceHardware mGeofenceHardware;
59 
GeofenceProxy(Context context, IGpsGeofenceHardware gpsGeofence)60     private GeofenceProxy(Context context, IGpsGeofenceHardware gpsGeofence) {
61         mGpsGeofenceHardware = Objects.requireNonNull(gpsGeofence);
62         mServiceWatcher = new ServiceWatcher(context, FgThread.getHandler(), SERVICE_ACTION,
63                 this::updateGeofenceHardware, null,
64                 com.android.internal.R.bool.config_enableGeofenceOverlay,
65                 com.android.internal.R.string.config_geofenceProviderPackageName);
66 
67         mGeofenceHardware = null;
68     }
69 
updateGeofenceHardware(IBinder binder)70     private void updateGeofenceHardware(IBinder binder) throws RemoteException {
71         IGeofenceProvider.Stub.asInterface(binder).setGeofenceHardware(mGeofenceHardware);
72     }
73 
register(Context context)74     private boolean register(Context context) {
75         if (mServiceWatcher.register()) {
76             context.bindServiceAsUser(
77                     new Intent(context, GeofenceHardwareService.class),
78                     new GeofenceProxyServiceConnection(),
79                     Context.BIND_AUTO_CREATE,
80                     UserHandle.SYSTEM);
81             return true;
82         }
83 
84         return false;
85     }
86 
87     private class GeofenceProxyServiceConnection implements ServiceConnection {
88 
89         @Override
onServiceConnected(ComponentName name, IBinder service)90         public void onServiceConnected(ComponentName name, IBinder service) {
91             IGeofenceHardware geofenceHardware = IGeofenceHardware.Stub.asInterface(service);
92 
93             try {
94                 geofenceHardware.setGpsGeofenceHardware(mGpsGeofenceHardware);
95                 mGeofenceHardware = geofenceHardware;
96                 mServiceWatcher.runOnBinder(GeofenceProxy.this::updateGeofenceHardware);
97             } catch (RemoteException e) {
98                 Log.w(TAG, "unable to initialize geofence hardware", e);
99             }
100         }
101 
102         @Override
onServiceDisconnected(ComponentName name)103         public void onServiceDisconnected(ComponentName name) {
104             mGeofenceHardware = null;
105             mServiceWatcher.runOnBinder(GeofenceProxy.this::updateGeofenceHardware);
106         }
107     }
108 }
109