From 92681e8cfbbae58b00a80bb1e60f5444cf53fbdd Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Tue, 28 Feb 2017 11:26:28 -0800 Subject: [PATCH] Hook up screen brightness knob to DisplayPowerController. This knob is designed to effectively tune the battery saver. Bug: 34693888 Test: FrameworksServicesTests Change-Id: I9fd7896f59fabd9baf649cdb12f01b1baaf4c34b --- .../hardware/display/DisplayManagerInternal.java | 9 +++ .../server/display/DisplayPowerController.java | 7 ++- .../android/server/power/PowerManagerService.java | 29 +++++++++- .../server/power/PowerManagerServiceTest.java | 66 ++++++++++++++++++++++ 4 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index 98a57490d4c6..b27600800cc6 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -213,6 +213,10 @@ public abstract class DisplayManagerInternal { // If true, scales the brightness to half of desired. public boolean lowPowerMode; + // The factor to adjust the screen brightness in low power mode in the range + // 0 (screen off) to 1 (no change) + public float screenLowPowerBrightnessFactor; + // If true, applies a brightness boost. public boolean boostScreenBrightness; @@ -235,6 +239,7 @@ public abstract class DisplayManagerInternal { useProximitySensor = false; screenBrightness = PowerManager.BRIGHTNESS_ON; screenAutoBrightnessAdjustment = 0.0f; + screenLowPowerBrightnessFactor = 0.5f; useAutoBrightness = false; blockScreenOn = false; dozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT; @@ -258,6 +263,7 @@ public abstract class DisplayManagerInternal { useProximitySensor = other.useProximitySensor; screenBrightness = other.screenBrightness; screenAutoBrightnessAdjustment = other.screenAutoBrightnessAdjustment; + screenLowPowerBrightnessFactor = other.screenLowPowerBrightnessFactor; brightnessSetByUser = other.brightnessSetByUser; useAutoBrightness = other.useAutoBrightness; blockScreenOn = other.blockScreenOn; @@ -279,6 +285,8 @@ public abstract class DisplayManagerInternal { && useProximitySensor == other.useProximitySensor && screenBrightness == other.screenBrightness && screenAutoBrightnessAdjustment == other.screenAutoBrightnessAdjustment + && screenLowPowerBrightnessFactor + == other.screenLowPowerBrightnessFactor && brightnessSetByUser == other.brightnessSetByUser && useAutoBrightness == other.useAutoBrightness && blockScreenOn == other.blockScreenOn @@ -299,6 +307,7 @@ public abstract class DisplayManagerInternal { + ", useProximitySensor=" + useProximitySensor + ", screenBrightness=" + screenBrightness + ", screenAutoBrightnessAdjustment=" + screenAutoBrightnessAdjustment + + ", screenLowPowerBrightnessFactor=" + screenLowPowerBrightnessFactor + ", brightnessSetByUser=" + brightnessSetByUser + ", useAutoBrightness=" + useAutoBrightness + ", blockScreenOn=" + blockScreenOn diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index bed269cf6c4f..0ef0561fe14f 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -705,11 +705,14 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mAppliedDimming = false; } - // If low power mode is enabled, cut the brightness level by half + // If low power mode is enabled, scale brightness by screenLowPowerBrightnessFactor // as long as it is above the minimum threshold. if (mPowerRequest.lowPowerMode) { if (brightness > mScreenBrightnessRangeMinimum) { - brightness = Math.max(brightness / 2, mScreenBrightnessRangeMinimum); + final float brightnessFactor = + Math.min(mPowerRequest.screenLowPowerBrightnessFactor, 1); + final int lowPowerBrightness = (int) (brightness * brightnessFactor); + brightness = Math.max(lowPowerBrightness, mScreenBrightnessRangeMinimum); } if (!mAppliedLowPower) { slowChange = false; diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index cd63527b05ff..c58b527b7dab 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -35,7 +35,6 @@ import android.hardware.power.V1_0.PowerHint; import android.net.Uri; import android.os.BatteryManager; import android.os.BatteryManagerInternal; -import android.os.PowerSaveState; import android.os.Binder; import android.os.Handler; import android.os.IBinder; @@ -44,6 +43,7 @@ import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.PowerManagerInternal; +import android.os.PowerSaveState; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; @@ -69,6 +69,7 @@ import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; import android.view.Display; import android.view.WindowManagerPolicy; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IAppOpsService; import com.android.internal.app.IBatteryStats; import com.android.internal.os.BackgroundThread; @@ -628,6 +629,21 @@ public final class PowerManagerService extends SystemService } } + @VisibleForTesting + PowerManagerService(Context context, BatterySaverPolicy batterySaverPolicy) { + super(context); + + mBatterySaverPolicy = batterySaverPolicy; + mContext = context; + mHandlerThread = new ServiceThread(TAG, + Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/); + mHandlerThread.start(); + mHandler = new PowerManagerHandler(mHandlerThread.getLooper()); + mConstants = new Constants(mHandler); + mDisplaySuspendBlocker = null; + mWakeLockSuspendBlocker = null; + } + @Override public void onStart() { publishBinderService(Context.POWER_SERVICE, new BinderService()); @@ -2260,9 +2276,10 @@ public final class PowerManagerService extends SystemService mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser; mDisplayPowerRequest.useAutoBrightness = autoBrightness; mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked(); - mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled; mDisplayPowerRequest.boostScreenBrightness = shouldBoostScreenBrightness(); + updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest); + if (mDisplayPowerRequest.policy == DisplayPowerRequest.POLICY_DOZE) { mDisplayPowerRequest.dozeScreenState = mDozeScreenStateOverrideFromDreamManager; if (mDisplayPowerRequest.dozeScreenState == Display.STATE_DOZE_SUSPEND @@ -2679,6 +2696,14 @@ public final class PowerManagerService extends SystemService } } + @VisibleForTesting + void updatePowerRequestFromBatterySaverPolicy(DisplayPowerRequest displayPowerRequest) { + PowerSaveState state = mBatterySaverPolicy. + getBatterySaverPolicy(ServiceType.SCREEN_BRIGHTNESS, mLowPowerModeEnabled); + displayPowerRequest.lowPowerMode = state.batterySaverEnabled; + displayPowerRequest.screenLowPowerBrightnessFactor = state.brightnessFactor; + } + void setStayOnSettingInternal(int val) { Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.STAY_ON_WHILE_PLUGGED_IN, val); diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java new file mode 100644 index 000000000000..967b0a44e086 --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.power; + +import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest; +import android.os.PowerSaveState; +import android.test.AndroidTestCase; +import android.test.suitebuilder.annotation.SmallTest; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; + +/** + * Tests for {@link com.android.server.power.PowerManagerService} + */ +public class PowerManagerServiceTest extends AndroidTestCase { + private static final float PRECISION = 0.001f; + private static final float BRIGHTNESS_FACTOR = 0.7f; + private static final boolean BATTERY_SAVER_ENABLED = true; + + private @Mock BatterySaverPolicy mBatterySaverPolicy; + private PowerManagerService mService; + private PowerSaveState mPowerSaveState; + private DisplayPowerRequest mDisplayPowerRequest; + + public void setUp() throws Exception { + super.setUp(); + MockitoAnnotations.initMocks(this); + + mPowerSaveState = new PowerSaveState.Builder() + .setBatterySaverEnabled(BATTERY_SAVER_ENABLED) + .setBrightnessFactor(BRIGHTNESS_FACTOR) + .build(); + when(mBatterySaverPolicy.getBatterySaverPolicy( + eq(BatterySaverPolicy.ServiceType.SCREEN_BRIGHTNESS), anyBoolean())) + .thenReturn(mPowerSaveState); + mDisplayPowerRequest = new DisplayPowerRequest(); + mService = new PowerManagerService(getContext(), mBatterySaverPolicy); + } + + @SmallTest + public void testUpdatePowerScreenPolicy_UpdateDisplayPowerRequest() { + mService.updatePowerRequestFromBatterySaverPolicy(mDisplayPowerRequest); + assertThat(mDisplayPowerRequest.lowPowerMode).isEqualTo(BATTERY_SAVER_ENABLED); + assertThat(mDisplayPowerRequest.screenLowPowerBrightnessFactor) + .isWithin(PRECISION).of(BRIGHTNESS_FACTOR); + } +} -- 2.11.0