From 3d7172c9d436d90cb4d859c7888b69b066728289 Mon Sep 17 00:00:00 2001 From: Kenny Guy Date: Mon, 19 Mar 2018 14:18:23 +0000 Subject: [PATCH] Unregister lux sensor when not in adaptive mode. Unregister the lux sensor used to track user slider events and ambient brightness stats when user is in manual mode. Test: atest BrightnessTrackerTest Bug: 73231445 Change-Id: Ie389956bd85794ac9428e7904c501773a968102c --- .../server/display/BrightnessTracker.java | 89 +++++++++++++-- .../server/display/BrightnessTrackerTest.java | 101 +++++++++++++++--- 2 files changed, 163 insertions(+), 27 deletions(-) diff --git a/services/core/java/com/android/server/display/BrightnessTracker.java b/services/core/java/com/android/server/display/BrightnessTracker.java index 171f40ed37cda..88df195e8051c 100644 --- a/services/core/java/com/android/server/display/BrightnessTracker.java +++ b/services/core/java/com/android/server/display/BrightnessTracker.java @@ -25,12 +25,14 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ParceledListSlice; +import android.database.ContentObserver; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.display.AmbientBrightnessDayStats; import android.hardware.display.BrightnessChangeEvent; +import android.net.Uri; import android.os.BatteryManager; import android.os.Environment; import android.os.Handler; @@ -110,6 +112,8 @@ public class BrightnessTracker { private static final int MSG_BACKGROUND_START = 0; private static final int MSG_BRIGHTNESS_CHANGED = 1; + private static final int MSG_STOP_SENSOR_LISTENER = 2; + private static final int MSG_START_SENSOR_LISTENER = 3; // Lock held while accessing mEvents, is held while writing events to flash. private final Object mEventsLock = new Object(); @@ -127,9 +131,14 @@ public class BrightnessTracker { private final Context mContext; private final ContentResolver mContentResolver; private Handler mBgHandler; - // mBroadcastReceiver and mSensorListener should only be used on the mBgHandler thread. + + // mBroadcastReceiver, mSensorListener, mSettingsObserver and mSensorRegistered + // should only be used on the mBgHandler thread. private BroadcastReceiver mBroadcastReceiver; private SensorListener mSensorListener; + private SettingsObserver mSettingsObserver; + private boolean mSensorRegistered; + private @UserIdInt int mCurrentUserId = UserHandle.USER_NULL; // Lock held while collecting data related to brightness changes. @@ -178,10 +187,9 @@ public class BrightnessTracker { mSensorListener = new SensorListener(); - - if (mInjector.isInteractive(mContext)) { - mInjector.registerSensorListener(mContext, mSensorListener, mBgHandler); - } + mSettingsObserver = new SettingsObserver(mBgHandler); + mInjector.registerBrightnessModeObserver(mContentResolver, mSettingsObserver); + startSensorListener(); final IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_SHUTDOWN); @@ -205,10 +213,11 @@ public class BrightnessTracker { Slog.d(TAG, "Stop"); } mBgHandler.removeMessages(MSG_BACKGROUND_START); + stopSensorListener(); mInjector.unregisterSensorListener(mContext, mSensorListener); + mInjector.unregisterBrightnessModeObserver(mContext, mSettingsObserver); mInjector.unregisterReceiver(mContext, mBroadcastReceiver); mInjector.cancelIdleJob(mContext); - mAmbientBrightnessStatsTracker.stop(); synchronized (mDataCollectionLock) { mStarted = false; @@ -366,6 +375,25 @@ public class BrightnessTracker { } } + private void startSensorListener() { + if (!mSensorRegistered + && mInjector.isInteractive(mContext) + && mInjector.isBrightnessModeAutomatic(mContentResolver)) { + mAmbientBrightnessStatsTracker.start(); + mSensorRegistered = true; + mInjector.registerSensorListener(mContext, mSensorListener, + mInjector.getBackgroundHandler()); + } + } + + private void stopSensorListener() { + if (mSensorRegistered) { + mAmbientBrightnessStatsTracker.stop(); + mInjector.unregisterSensorListener(mContext, mSensorListener); + mSensorRegistered = false; + } + } + private void scheduleWriteBrightnessTrackerState() { if (!mWriteBrightnessTrackerStateScheduled) { mBgHandler.post(() -> { @@ -724,6 +752,24 @@ public class BrightnessTracker { } } + private final class SettingsObserver extends ContentObserver { + public SettingsObserver(Handler handler) { + super(handler); + } + + @Override + public void onChange(boolean selfChange, Uri uri) { + if (DEBUG) { + Slog.v(TAG, "settings change " + uri); + } + if (mInjector.isBrightnessModeAutomatic(mContentResolver)) { + mBgHandler.obtainMessage(MSG_START_SENSOR_LISTENER).sendToTarget(); + } else { + mBgHandler.obtainMessage(MSG_STOP_SENSOR_LISTENER).sendToTarget(); + } + } + } + private final class Receiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { @@ -741,12 +787,9 @@ public class BrightnessTracker { batteryLevelChanged(level, scale); } } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { - mAmbientBrightnessStatsTracker.stop(); - mInjector.unregisterSensorListener(mContext, mSensorListener); + mBgHandler.obtainMessage(MSG_STOP_SENSOR_LISTENER).sendToTarget(); } else if (Intent.ACTION_SCREEN_ON.equals(action)) { - mAmbientBrightnessStatsTracker.start(); - mInjector.registerSensorListener(mContext, mSensorListener, - mInjector.getBackgroundHandler()); + mBgHandler.obtainMessage(MSG_START_SENSOR_LISTENER).sendToTarget(); } } } @@ -767,6 +810,12 @@ public class BrightnessTracker { values.powerBrightnessFactor, values.isUserSetBrightness, values.isDefaultBrightnessConfig); break; + case MSG_START_SENSOR_LISTENER: + startSensorListener(); + break; + case MSG_STOP_SENSOR_LISTENER: + stopSensorListener(); + break; } } } @@ -801,6 +850,18 @@ public class BrightnessTracker { sensorManager.unregisterListener(sensorListener); } + public void registerBrightnessModeObserver(ContentResolver resolver, + ContentObserver settingsObserver) { + resolver.registerContentObserver(Settings.System.getUriFor( + Settings.System.SCREEN_BRIGHTNESS_MODE), + false, settingsObserver, UserHandle.USER_ALL); + } + + public void unregisterBrightnessModeObserver(Context context, + ContentObserver settingsObserver) { + context.getContentResolver().unregisterContentObserver(settingsObserver); + } + public void registerReceiver(Context context, BroadcastReceiver receiver, IntentFilter filter) { context.registerReceiver(receiver, filter); @@ -815,6 +876,12 @@ public class BrightnessTracker { return BackgroundThread.getHandler(); } + public boolean isBrightnessModeAutomatic(ContentResolver resolver) { + return Settings.System.getIntForUser(resolver, Settings.System.SCREEN_BRIGHTNESS_MODE, + Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL, UserHandle.USER_CURRENT) + == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; + } + public int getSecureIntForUser(ContentResolver resolver, String setting, int defaultValue, int userId) { return Settings.Secure.getIntForUser(resolver, setting, defaultValue, userId); diff --git a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java index b4f84742301d7..92cc537ada6dd 100644 --- a/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java +++ b/services/tests/servicestests/src/com/android/server/display/BrightnessTrackerTest.java @@ -30,6 +30,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.database.ContentObserver; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.display.BrightnessChangeEvent; @@ -101,20 +102,24 @@ public class BrightnessTrackerTest { assertNull(mInjector.mSensorListener); assertNotNull(mInjector.mBroadcastReceiver); assertTrue(mInjector.mIdleScheduled); - Intent onIntent = new Intent(); - onIntent.setAction(Intent.ACTION_SCREEN_ON); - mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(), - onIntent); + mInjector.sendScreenChange(/*screen on */ true); assertNotNull(mInjector.mSensorListener); - Intent offIntent = new Intent(); - offIntent.setAction(Intent.ACTION_SCREEN_OFF); - mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(), - offIntent); + mInjector.sendScreenChange(/*screen on */ false); assertNull(mInjector.mSensorListener); - mInjector.mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(), - onIntent); + // Turn screen on while brightness mode is manual + mInjector.setBrightnessMode(/* isBrightnessModeAutomatic */ false); + mInjector.sendScreenChange(/*screen on */ true); + assertNull(mInjector.mSensorListener); + + // Set brightness mode to automatic while screen is off. + mInjector.sendScreenChange(/*screen on */ false); + mInjector.setBrightnessMode(/* isBrightnessModeAutomatic */ true); + assertNull(mInjector.mSensorListener); + + // Turn on screen while brightness mode is automatic. + mInjector.sendScreenChange(/*screen on */ true); assertNotNull(mInjector.mSensorListener); mTracker.stop(); @@ -123,6 +128,37 @@ public class BrightnessTrackerTest { assertFalse(mInjector.mIdleScheduled); } + @Test + public void testAdaptiveOnOff() { + mInjector.mInteractive = true; + mInjector.mIsBrightnessModeAutomatic = false; + startTracker(mTracker); + assertNull(mInjector.mSensorListener); + assertNotNull(mInjector.mBroadcastReceiver); + assertNotNull(mInjector.mContentObserver); + assertTrue(mInjector.mIdleScheduled); + + mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ true); + assertNotNull(mInjector.mSensorListener); + + SensorEventListener listener = mInjector.mSensorListener; + mInjector.mSensorListener = null; + // Duplicate notification + mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ true); + // Sensor shouldn't have been registered as it was already registered. + assertNull(mInjector.mSensorListener); + mInjector.mSensorListener = listener; + + mInjector.setBrightnessMode(/*isBrightnessModeAutomatic*/ false); + assertNull(mInjector.mSensorListener); + + mTracker.stop(); + assertNull(mInjector.mSensorListener); + assertNull(mInjector.mBroadcastReceiver); + assertNull(mInjector.mContentObserver); + assertFalse(mInjector.mIdleScheduled); + } + @Test public void testBrightnessEvent() { final int brightness = 20; @@ -618,16 +654,39 @@ public class BrightnessTrackerTest { boolean mIdleScheduled; boolean mInteractive = true; int[] mProfiles; + ContentObserver mContentObserver; + boolean mIsBrightnessModeAutomatic = true; public TestInjector(Handler handler) { mHandler = handler; } - public void incrementTime(long timeMillis) { + void incrementTime(long timeMillis) { mCurrentTimeMillis += timeMillis; mElapsedRealtimeNanos += TimeUnit.MILLISECONDS.toNanos(timeMillis); } + void setBrightnessMode(boolean isBrightnessModeAutomatic) { + mIsBrightnessModeAutomatic = isBrightnessModeAutomatic; + mContentObserver.dispatchChange(false, null); + waitForHandler(); + } + + void sendScreenChange(boolean screenOn) { + mInteractive = screenOn; + Intent intent = new Intent(); + intent.setAction(screenOn ? Intent.ACTION_SCREEN_ON : Intent.ACTION_SCREEN_OFF); + mBroadcastReceiver.onReceive(InstrumentationRegistry.getContext(), intent); + waitForHandler(); + } + + void waitForHandler() { + Idle idle = new Idle(); + mHandler.getLooper().getQueue().addIdleHandler(idle); + mHandler.post(() -> {}); + idle.waitForIdle(); + } + @Override public void registerSensorListener(Context context, SensorEventListener sensorListener, Handler handler) { @@ -640,6 +699,18 @@ public class BrightnessTrackerTest { mSensorListener = null; } + @Override + public void registerBrightnessModeObserver(ContentResolver resolver, + ContentObserver settingsObserver) { + mContentObserver = settingsObserver; + } + + @Override + public void unregisterBrightnessModeObserver(Context context, + ContentObserver settingsObserver) { + mContentObserver = null; + } + @Override public void registerReceiver(Context context, BroadcastReceiver shutdownReceiver, IntentFilter shutdownFilter) { @@ -658,11 +729,9 @@ public class BrightnessTrackerTest { return mHandler; } - public void waitForHandler() { - Idle idle = new Idle(); - mHandler.getLooper().getQueue().addIdleHandler(idle); - mHandler.post(() -> {}); - idle.waitForIdle(); + @Override + public boolean isBrightnessModeAutomatic(ContentResolver resolver) { + return mIsBrightnessModeAutomatic; } @Override