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
17package android.hardware.location;
18
19import android.Manifest;
20import android.app.Service;
21import android.content.Context;
22import android.content.Intent;
23import android.location.IFusedGeofenceHardware;
24import android.location.IGpsGeofenceHardware;
25import android.os.Binder;
26import android.os.IBinder;
27
28/**
29 * Service that handles hardware geofencing.
30 *
31 * @hide
32 */
33public class GeofenceHardwareService extends Service {
34    private GeofenceHardwareImpl mGeofenceHardwareImpl;
35    private Context mContext;
36
37    @Override
38    public void onCreate() {
39        mContext = this;
40        mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
41    }
42
43    @Override
44    public IBinder onBind(Intent intent) {
45        return mBinder;
46    }
47
48    @Override
49    public boolean onUnbind(Intent intent) {
50        return false;
51    }
52
53    @Override
54    public void onDestroy() {
55        mGeofenceHardwareImpl = null;
56    }
57
58
59    private void checkPermission(int pid, int uid, int monitoringType) {
60        if (mGeofenceHardwareImpl.getAllowedResolutionLevel(pid, uid) <
61                mGeofenceHardwareImpl.getMonitoringResolutionLevel(monitoringType)) {
62            throw new SecurityException("Insufficient permissions to access hardware geofence for"
63                    + " type: " + monitoringType);
64        }
65    }
66
67    private IBinder mBinder = new IGeofenceHardware.Stub() {
68        @Override
69        public void setGpsGeofenceHardware(IGpsGeofenceHardware service) {
70            mGeofenceHardwareImpl.setGpsHardwareGeofence(service);
71        }
72
73        @Override
74        public void setFusedGeofenceHardware(IFusedGeofenceHardware service) {
75            mGeofenceHardwareImpl.setFusedGeofenceHardware(service);
76        }
77
78        @Override
79        public int[] getMonitoringTypes() {
80            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
81                    "Location Hardware permission not granted to access hardware geofence");
82
83            return mGeofenceHardwareImpl.getMonitoringTypes();
84        }
85
86        @Override
87        public int getStatusOfMonitoringType(int monitoringType) {
88            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
89                    "Location Hardware permission not granted to access hardware geofence");
90
91            return mGeofenceHardwareImpl.getStatusOfMonitoringType(monitoringType);
92        }
93
94        @Override
95        public boolean addCircularFence(
96                int monitoringType,
97                GeofenceHardwareRequestParcelable request,
98                IGeofenceHardwareCallback callback) {
99            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
100                    "Location Hardware permission not granted to access hardware geofence");
101            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
102            return mGeofenceHardwareImpl.addCircularFence(monitoringType, request, callback);
103        }
104
105        @Override
106        public boolean removeGeofence(int id, int monitoringType) {
107            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
108                    "Location Hardware permission not granted to access hardware geofence");
109
110            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
111            return mGeofenceHardwareImpl.removeGeofence(id, monitoringType);
112        }
113
114        @Override
115        public boolean pauseGeofence(int id, int monitoringType) {
116            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
117                    "Location Hardware permission not granted to access hardware geofence");
118
119            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
120            return mGeofenceHardwareImpl.pauseGeofence(id, monitoringType);
121        }
122
123        @Override
124        public boolean resumeGeofence(int id, int monitoringType, int monitorTransitions) {
125            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
126                    "Location Hardware permission not granted to access hardware geofence");
127
128            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
129            return mGeofenceHardwareImpl.resumeGeofence(id, monitoringType, monitorTransitions);
130        }
131
132        @Override
133        public boolean registerForMonitorStateChangeCallback(int monitoringType,
134                IGeofenceHardwareMonitorCallback callback) {
135            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
136                    "Location Hardware permission not granted to access hardware geofence");
137
138            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
139            return mGeofenceHardwareImpl.registerForMonitorStateChangeCallback(monitoringType,
140                    callback);
141        }
142
143        @Override
144        public boolean unregisterForMonitorStateChangeCallback(int monitoringType,
145                IGeofenceHardwareMonitorCallback callback) {
146            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
147                    "Location Hardware permission not granted to access hardware geofence");
148
149            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
150            return mGeofenceHardwareImpl.unregisterForMonitorStateChangeCallback(monitoringType,
151                    callback);
152        }
153    };
154}
155