Register for light sensor events if non-hardware based auto-brightnees is enabled

Change-Id: I9521cf8b315306bdafa70c1500f2e4af83d94ec3
Signed-off-by: Mike Lockwood <lockwood@android.com>
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index a1220b6..99e008c 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -65,7 +65,7 @@
 import java.util.Observer;
 
 class PowerManagerService extends IPowerManager.Stub
-        implements LocalPowerManager, Watchdog.Monitor, SensorEventListener {
+        implements LocalPowerManager, Watchdog.Monitor {
 
     private static final String TAG = "PowerManagerService";
     static final String PARTIAL_NAME = "PowerManagerService";
@@ -190,6 +190,9 @@
     private BatteryService mBatteryService;
     private SensorManager mSensorManager;
     private Sensor mProximitySensor;
+    private Sensor mLightSensor;
+    private boolean mLightSensorEnabled;
+    private float mLightSensorValue = -1;
     private boolean mDimScreen = true;
     private long mNextTimeout;
     private volatile int mPokey = 0;
@@ -210,6 +213,7 @@
 
     // could be either static or controllable at runtime
     private static final boolean mSpew = false;
+    private static final boolean mDebugLightSensor = false;
 
     /*
     static PrintStream mLog;
@@ -1171,7 +1175,7 @@
 
                 // Finally, set the flag that prevents the screen from turning on.
                 // (Below, in setPowerState(), we'll check mPreventScreenOn and
-                // we *won't* call Power.setScreenState(true) if it's set.)
+                // we *won't* call setScreenStateLocked(true) if it's set.)
                 mPreventScreenOn = true;
             } else {
                 // (Re)enable the screen.
@@ -1189,9 +1193,9 @@
                         Log.d(TAG,
                               "preventScreenOn: turning on after a prior preventScreenOn(true)!");
                     }
-                    int err = Power.setScreenState(true);
+                    int err = setScreenStateLocked(true);
                     if (err != 0) {
-                        Log.w(TAG, "preventScreenOn: error from Power.setScreenState(): " + err);
+                        Log.w(TAG, "preventScreenOn: error from setScreenStateLocked(): " + err);
                     }
                 }
 
@@ -1246,6 +1250,14 @@
             }
         };
 
+    private int setScreenStateLocked(boolean on) {
+        int err = Power.setScreenState(on);
+        if (err == 0) {
+            enableLightSensor(on && mAutoBrightessEnabled);
+        }
+        return err;
+    }
+
     private void setPowerState(int state)
     {
         setPowerState(state, false, false);
@@ -1334,7 +1346,7 @@
                         reallyTurnScreenOn = false;
                     }
                     if (reallyTurnScreenOn) {
-                        err = Power.setScreenState(true);
+                        err = setScreenStateLocked(true);
                         long identity = Binder.clearCallingIdentity();
                         try {
                             mBatteryStats.noteScreenBrightness(
@@ -1346,7 +1358,7 @@
                             Binder.restoreCallingIdentity(identity);
                         }
                     } else {
-                        Power.setScreenState(false);
+                        setScreenStateLocked(false);
                         // But continue as if we really did turn the screen on...
                         err = 0;
                     }
@@ -1391,7 +1403,7 @@
         EventLog.writeEvent(LOG_POWER_SCREEN_STATE, 0, becauseOfUser ? 1 : 0,
                 mTotalTouchDownTime, mTouchCycles);
         mLastTouchDown = 0;
-        int err = Power.setScreenState(false);
+        int err = setScreenStateLocked(false);
         if (mScreenOnStartTime != 0) {
             mScreenOnTime += SystemClock.elapsedRealtime() - mScreenOnStartTime;
             mScreenOnStartTime = 0;
@@ -1809,6 +1821,14 @@
         }
     }
 
+    private void lightSensorChangedLocked(float value) {
+        if (mDebugLightSensor) {
+            Log.d(TAG, "lightSensorChangedLocked " + value);
+        }
+        mLightSensorValue = value;
+        // more to do here
+    }
+
     /**
      * The user requested that we go to sleep (probably with the power button).
      * This overrides all wake locks that are held.
@@ -1900,7 +1920,7 @@
             mHardware.setAutoBrightness_UNCHECKED(mAutoBrightessEnabled);
             setBacklightBrightness((int)mScreenBrightness.curValue);
         } else {
-            // not yet implemented
+            enableLightSensor(screenIsOn() && mAutoBrightessEnabled);
         }
     }
 
@@ -2050,6 +2070,14 @@
     }
     
     void systemReady() {
+        mSensorManager = new SensorManager(mHandlerThread.getLooper());
+        mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
+        // don't bother with the light sensor if auto brightness is handled in hardware
+        if (!mHasHardwareAutoBrightness) {
+            mLightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+            enableLightSensor(mAutoBrightessEnabled);
+        }
+
         synchronized (mLocks) {
             Log.d(TAG, "system ready!");
             mDoneBooting = true;
@@ -2077,8 +2105,6 @@
                    | PowerManager.FULL_WAKE_LOCK
                    | PowerManager.SCREEN_DIM_WAKE_LOCK;
 
-        // call getSensorManager() to make sure mProximitySensor is initialized
-        getSensorManager();
         if (mProximitySensor != null) {
             result |= PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK;
         }
@@ -2117,26 +2143,19 @@
         }
     }
 
-    private SensorManager getSensorManager() {
-        if (mSensorManager == null) {
-            mSensorManager = new SensorManager(mHandlerThread.getLooper());
-            mProximitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
-        }
-        return mSensorManager;
-    }
-
     private void enableProximityLockLocked() {
         if (mSpew) {
             Log.d(TAG, "enableProximityLockLocked");
         }
-        mSensorManager.registerListener(this, mProximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
+        mSensorManager.registerListener(mProximityListener, mProximitySensor,
+                SensorManager.SENSOR_DELAY_NORMAL);
     }
 
     private void disableProximityLockLocked() {
         if (mSpew) {
             Log.d(TAG, "disableProximityLockLocked");
         }
-        mSensorManager.unregisterListener(this);
+        mSensorManager.unregisterListener(mProximityListener);
         synchronized (mLocks) {
             if (mProximitySensorActive) {
                 mProximitySensorActive = false;
@@ -2145,32 +2164,65 @@
         }
     }
 
-    public void onSensorChanged(SensorEvent event) {
-        long milliseconds = event.timestamp / 1000000;
-        synchronized (mLocks) {
-            float distance = event.values[0];
-            // compare against getMaximumRange to support sensors that only return 0 or 1
-            if (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
-                    distance < mProximitySensor.getMaximumRange()) {
-                if (mSpew) {
-                    Log.d(TAG, "onSensorChanged: proximity active, distance: " + distance);
-                }
-                goToSleepLocked(milliseconds);
-                mProximitySensorActive = true;
+    private void enableLightSensor(boolean enable) {
+        if (mDebugLightSensor) {
+            Log.d(TAG, "enableLightSensor " + enable);
+        }
+        if (mSensorManager != null && mLightSensorEnabled != enable) {
+            mLightSensorEnabled = enable;
+            if (enable) {
+                mSensorManager.registerListener(mLightListener, mLightSensor,
+                        SensorManager.SENSOR_DELAY_NORMAL);
             } else {
-                // proximity sensor negative events trigger as user activity.
-                // temporarily set mUserActivityAllowed to true so this will work
-                // even when the keyguard is on.
-                if (mSpew) {
-                    Log.d(TAG, "onSensorChanged: proximity inactive, distance: " + distance);
-                }
-                mProximitySensorActive = false;
-                forceUserActivityLocked();
+                mSensorManager.unregisterListener(mLightListener);
             }
         }
     }
 
-    public void onAccuracyChanged(Sensor sensor, int accuracy) {
-        // ignore
-    }
+    SensorEventListener mProximityListener = new SensorEventListener() {
+        public void onSensorChanged(SensorEvent event) {
+            long milliseconds = event.timestamp / 1000000;
+            synchronized (mLocks) {
+                float distance = event.values[0];
+                // compare against getMaximumRange to support sensors that only return 0 or 1
+                if (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&
+                        distance < mProximitySensor.getMaximumRange()) {
+                    if (mSpew) {
+                        Log.d(TAG, "onSensorChanged: proximity active, distance: " + distance);
+                    }
+                    goToSleepLocked(milliseconds);
+                    mProximitySensorActive = true;
+                } else {
+                    // proximity sensor negative events trigger as user activity.
+                    // temporarily set mUserActivityAllowed to true so this will work
+                    // even when the keyguard is on.
+                    if (mSpew) {
+                        Log.d(TAG, "onSensorChanged: proximity inactive, distance: " + distance);
+                    }
+                    mProximitySensorActive = false;
+                    forceUserActivityLocked();
+                }
+            }
+        }
+
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+            // ignore
+        }
+    };
+
+    SensorEventListener mLightListener = new SensorEventListener() {
+        public void onSensorChanged(SensorEvent event) {
+            synchronized (mLocks) {
+                int value = (int)event.values[0];
+                if (mDebugLightSensor) {
+                    Log.d(TAG, "onSensorChanged: light value: " + value);
+                }
+                lightSensorChangedLocked(value);
+            }
+        }
+
+        public void onAccuracyChanged(Sensor sensor, int accuracy) {
+            // ignore
+        }
+    };
 }