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        public void setGpsGeofenceHardware(IGpsGeofenceHardware service) {
69            mGeofenceHardwareImpl.setGpsHardwareGeofence(service);
70        }
71
72        public void setFusedGeofenceHardware(IFusedGeofenceHardware service) {
73            mGeofenceHardwareImpl.setFusedGeofenceHardware(service);
74        }
75
76        public int[] getMonitoringTypes() {
77            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
78                    "Location Hardware permission not granted to access hardware geofence");
79
80            return mGeofenceHardwareImpl.getMonitoringTypes();
81        }
82
83        public int getStatusOfMonitoringType(int monitoringType) {
84            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
85                    "Location Hardware permission not granted to access hardware geofence");
86
87            return mGeofenceHardwareImpl.getStatusOfMonitoringType(monitoringType);
88        }
89        public boolean addCircularFence(
90                int monitoringType,
91                GeofenceHardwareRequestParcelable request,
92                IGeofenceHardwareCallback callback) {
93            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
94                    "Location Hardware permission not granted to access hardware geofence");
95            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
96            return mGeofenceHardwareImpl.addCircularFence(monitoringType, request, callback);
97        }
98
99        public boolean removeGeofence(int id, int monitoringType) {
100            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
101                    "Location Hardware permission not granted to access hardware geofence");
102
103            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
104            return mGeofenceHardwareImpl.removeGeofence(id, monitoringType);
105        }
106
107        public boolean pauseGeofence(int id, int monitoringType) {
108            mContext.enforceCallingPermission(Manifest.permission.LOCATION_HARDWARE,
109                    "Location Hardware permission not granted to access hardware geofence");
110
111            checkPermission(Binder.getCallingPid(), Binder.getCallingUid(), monitoringType);
112            return mGeofenceHardwareImpl.pauseGeofence(id, monitoringType);
113        }
114
115        public boolean resumeGeofence(int id, int monitoringType, int monitorTransitions) {
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.resumeGeofence(id, monitoringType, monitorTransitions);
121        }
122
123        public boolean registerForMonitorStateChangeCallback(int monitoringType,
124                IGeofenceHardwareMonitorCallback callback) {
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.registerForMonitorStateChangeCallback(monitoringType,
130                    callback);
131        }
132
133        public boolean unregisterForMonitorStateChangeCallback(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.unregisterForMonitorStateChangeCallback(monitoringType,
140                    callback);
141        }
142    };
143}
144