SensorService: call close_data_source when we have no more sensor clients.

Change-Id: I94accda4571c3f2cf6f8a5b6801e37c30c027fe1
Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/services/java/com/android/server/SensorService.java b/services/java/com/android/server/SensorService.java
index ceef39f..4dfeb9d 100644
--- a/services/java/com/android/server/SensorService.java
+++ b/services/java/com/android/server/SensorService.java
@@ -84,12 +84,16 @@
                     if (hasSensor(sensor)) {
                         removeSensor(sensor);
                         try {
-                            deactivateIfUnused(sensor);
+                            deactivateIfUnusedLocked(sensor);
                         } catch (RemoteException e) {
                             Log.w(TAG, "RemoteException in binderDied");
                         }
                     }
                 }
+                if (mListeners.size() == 0) {
+                    _sensors_control_wake();
+                    _sensors_control_close();
+                }
                 mListeners.notify();
             }
         }
@@ -102,9 +106,12 @@
     }
     
     public Bundle getDataChannel() throws RemoteException {
-        return _sensors_control_open();
+        // synchronize so we do not require sensor HAL to be thread-safe.
+        synchronized(mListeners) {
+            return _sensors_control_open();
+        }
     }
-    
+
     public boolean enableSensor(IBinder binder, String name, int sensor, int enable)
              throws RemoteException {
         if (localLOGV) Log.d(TAG, "enableSensor " + name + "(#" + sensor + ") " + enable);
@@ -163,7 +170,7 @@
                 l.addSensor(sensor, enable);
             } else {
                 l.removeSensor(sensor);
-                deactivateIfUnused(sensor);
+                deactivateIfUnusedLocked(sensor);
                 if (l.mSensors == 0) {
                     mListeners.remove(l);
                     binder.unlinkToDeath(l, 0);
@@ -173,12 +180,13 @@
             
             if (mListeners.size() == 0) {
                 _sensors_control_wake();
+                _sensors_control_close();
             }
         }        
         return true;
     }
 
-    void deactivateIfUnused(int sensor) throws RemoteException {
+    private void deactivateIfUnusedLocked(int sensor) throws RemoteException {
         int size = mListeners.size();
         for (int i=0 ; i<size ; i++) {
             if (mListeners.get(i).hasSensor(sensor))
@@ -187,10 +195,11 @@
         _sensors_control_activate(sensor, false);
     }
 
-    ArrayList<Listener> mListeners = new ArrayList<Listener>();
+    private ArrayList<Listener> mListeners = new ArrayList<Listener>();
 
     private static native int _sensors_control_init();
     private static native Bundle _sensors_control_open();
+    private static native int _sensors_control_close();
     private static native boolean _sensors_control_activate(int sensor, boolean activate);
     private static native int _sensors_control_set_delay(int ms);
     private static native int _sensors_control_wake();
diff --git a/services/jni/com_android_server_SensorService.cpp b/services/jni/com_android_server_SensorService.cpp
index 7390786..3911d1f 100644
--- a/services/jni/com_android_server_SensorService.cpp
+++ b/services/jni/com_android_server_SensorService.cpp
@@ -111,6 +111,15 @@
     return bundle;
 }
 
+static jint
+android_close(JNIEnv *env, jclass clazz)
+{
+    if (sSensorDevice->close_data_source)
+        return sSensorDevice->close_data_source(sSensorDevice);
+    else
+        return 0;
+}
+
 static jboolean
 android_activate(JNIEnv *env, jclass clazz, jint sensor, jboolean activate)
 {
@@ -135,6 +144,7 @@
 static JNINativeMethod gMethods[] = {
     {"_sensors_control_init",     "()I",   (void*) android_init },
     {"_sensors_control_open",     "()Landroid/os/Bundle;",  (void*) android_open },
+    {"_sensors_control_close",     "()I",  (void*) android_close },
     {"_sensors_control_activate", "(IZ)Z", (void*) android_activate },
     {"_sensors_control_wake",     "()I", (void*) android_data_wake },
     {"_sensors_control_set_delay","(I)I", (void*) android_set_delay },