1 /* 2 * Copyright (C) 2008 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; 18 19 import android.content.Context; 20 import android.hardware.ISensorService; 21 import android.os.Binder; 22 import android.os.Bundle; 23 import android.os.RemoteException; 24 import android.os.IBinder; 25 import android.util.Config; 26 import android.util.Log; 27 28 import java.util.ArrayList; 29 30 import com.android.internal.app.IBatteryStats; 31 import com.android.server.am.BatteryStatsService; 32 33 34 /** 35 * Class that manages the device's sensors. It register clients and activate 36 * the needed sensors. The sensor events themselves are not broadcasted from 37 * this service, instead, a file descriptor is provided to each client they 38 * can read events from. 39 */ 40 41 class SensorService extends ISensorService.Stub { 42 static final String TAG = SensorService.class.getSimpleName(); 43 private static final boolean DEBUG = false; 44 private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; 45 private static final int SENSOR_DISABLE = -1; 46 47 /** 48 * Battery statistics to be updated when sensors are enabled and disabled. 49 */ 50 final IBatteryStats mBatteryStats = BatteryStatsService.getService(); 51 52 private final class Listener implements IBinder.DeathRecipient { 53 final IBinder mToken; 54 55 int mSensors = 0; 56 int mDelay = 0x7FFFFFFF; 57 Listener(IBinder token)58 Listener(IBinder token) { 59 mToken = token; 60 } 61 addSensor(int sensor, int delay)62 void addSensor(int sensor, int delay) { 63 mSensors |= (1<<sensor); 64 if (mDelay > delay) 65 mDelay = delay; 66 } 67 removeSensor(int sensor)68 void removeSensor(int sensor) { 69 mSensors &= ~(1<<sensor); 70 } 71 hasSensor(int sensor)72 boolean hasSensor(int sensor) { 73 return ((mSensors & (1<<sensor)) != 0); 74 } 75 binderDied()76 public void binderDied() { 77 if (localLOGV) Log.d(TAG, "sensor listener died"); 78 synchronized(mListeners) { 79 mListeners.remove(this); 80 mToken.unlinkToDeath(this, 0); 81 // go through the lists of sensors used by the listener that 82 // died and deactivate them. 83 for (int sensor=0 ; sensor<32 && mSensors!=0 ; sensor++) { 84 if (hasSensor(sensor)) { 85 removeSensor(sensor); 86 try { 87 deactivateIfUnusedLocked(sensor); 88 } catch (RemoteException e) { 89 Log.w(TAG, "RemoteException in binderDied"); 90 } 91 } 92 } 93 if (mListeners.size() == 0) { 94 _sensors_control_wake(); 95 _sensors_control_close(); 96 } 97 mListeners.notify(); 98 } 99 } 100 } 101 102 @SuppressWarnings("unused") SensorService(Context context)103 public SensorService(Context context) { 104 if (localLOGV) Log.d(TAG, "SensorService startup"); 105 _sensors_control_init(); 106 } 107 getDataChannel()108 public Bundle getDataChannel() throws RemoteException { 109 // synchronize so we do not require sensor HAL to be thread-safe. 110 synchronized(mListeners) { 111 return _sensors_control_open(); 112 } 113 } 114 enableSensor(IBinder binder, String name, int sensor, int enable)115 public boolean enableSensor(IBinder binder, String name, int sensor, int enable) 116 throws RemoteException { 117 if (localLOGV) Log.d(TAG, "enableSensor " + name + "(#" + sensor + ") " + enable); 118 119 // Inform battery statistics service of status change 120 int uid = Binder.getCallingUid(); 121 long identity = Binder.clearCallingIdentity(); 122 if (enable == SENSOR_DISABLE) { 123 mBatteryStats.noteStopSensor(uid, sensor); 124 } else { 125 mBatteryStats.noteStartSensor(uid, sensor); 126 } 127 Binder.restoreCallingIdentity(identity); 128 129 if (binder == null) { 130 Log.w(TAG, "listener is null (sensor=" + name + ", id=" + sensor + ")"); 131 return false; 132 } 133 134 synchronized(mListeners) { 135 if (enable!=SENSOR_DISABLE && !_sensors_control_activate(sensor, true)) { 136 Log.w(TAG, "could not enable sensor " + sensor); 137 return false; 138 } 139 140 Listener l = null; 141 int minDelay = enable; 142 for (Listener listener : mListeners) { 143 if (binder == listener.mToken) { 144 l = listener; 145 } 146 if (minDelay > listener.mDelay) 147 minDelay = listener.mDelay; 148 } 149 150 if (l == null && enable!=SENSOR_DISABLE) { 151 l = new Listener(binder); 152 binder.linkToDeath(l, 0); 153 mListeners.add(l); 154 mListeners.notify(); 155 } 156 157 if (l == null) { 158 // by construction, this means we're disabling a listener we 159 // don't know about... 160 Log.w(TAG, "listener with binder " + binder + 161 ", doesn't exist (sensor=" + name + ", id=" + sensor + ")"); 162 return false; 163 } 164 165 if (minDelay >= 0) { 166 _sensors_control_set_delay(minDelay); 167 } 168 169 if (enable != SENSOR_DISABLE) { 170 l.addSensor(sensor, enable); 171 } else { 172 l.removeSensor(sensor); 173 deactivateIfUnusedLocked(sensor); 174 if (l.mSensors == 0) { 175 mListeners.remove(l); 176 binder.unlinkToDeath(l, 0); 177 mListeners.notify(); 178 } 179 } 180 181 if (mListeners.size() == 0) { 182 _sensors_control_wake(); 183 _sensors_control_close(); 184 } 185 } 186 return true; 187 } 188 deactivateIfUnusedLocked(int sensor)189 private void deactivateIfUnusedLocked(int sensor) throws RemoteException { 190 int size = mListeners.size(); 191 for (int i=0 ; i<size ; i++) { 192 if (mListeners.get(i).hasSensor(sensor)) 193 return; 194 } 195 _sensors_control_activate(sensor, false); 196 } 197 198 private ArrayList<Listener> mListeners = new ArrayList<Listener>(); 199 _sensors_control_init()200 private static native int _sensors_control_init(); _sensors_control_open()201 private static native Bundle _sensors_control_open(); _sensors_control_close()202 private static native int _sensors_control_close(); _sensors_control_activate(int sensor, boolean activate)203 private static native boolean _sensors_control_activate(int sensor, boolean activate); _sensors_control_set_delay(int ms)204 private static native int _sensors_control_set_delay(int ms); _sensors_control_wake()205 private static native int _sensors_control_wake(); 206 } 207