Switch preffered display mode on lock screen

To save power, now it's possible to specify a preferred refresh rate for
the lock screen. It's -1 by default, and should be configured on a
device overlay whenever required.

Test: manual
Test: atest StatusBarWindowControllerTest
Fixes: 138303350
Change-Id: I4d1ca210b50d32d937b0fea2fcb9e28a7c50c0b3
This commit is contained in:
Lucas Dupin
2019-07-29 13:51:35 -07:00
parent 82aec2e913
commit e25c487141
5 changed files with 85 additions and 10 deletions

View File

@@ -482,4 +482,7 @@
-->
<string name="config_rounded_mask" translatable="false">"M8,0C3.6,0,0,3.6,0,8"</string>
<!-- Preferred refresh rate at keyguard, if supported by the display -->
<integer name="config_keyguardRefreshRate">-1</integer>
</resources>

View File

@@ -90,6 +90,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.util.InjectionInflationController;
import java.io.FileDescriptor;
@@ -204,6 +205,8 @@ public class KeyguardViewMediator extends SystemUI {
private AlarmManager mAlarmManager;
private AudioManager mAudioManager;
private StatusBarManager mStatusBarManager;
private final StatusBarWindowController mStatusBarWindowController =
Dependency.get(StatusBarWindowController.class);
private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
private boolean mSystemReady;
@@ -1779,6 +1782,7 @@ public class KeyguardViewMediator extends SystemUI {
adjustStatusBarLocked();
userActivity();
mUpdateMonitor.setKeyguardGoingAway(false /* away */);
mStatusBarWindowController.setKeyguardGoingAway(false /* goingAway */);
mShowKeyguardWakeLock.release();
}
mKeyguardDisplayManager.show();
@@ -1811,6 +1815,7 @@ public class KeyguardViewMediator extends SystemUI {
}
mUpdateMonitor.setKeyguardGoingAway(true /* goingAway */);
mStatusBarWindowController.setKeyguardGoingAway(true /* goingAway */);
// Don't actually hide the Keyguard at the moment, wait for window
// manager until it tells us it's safe to do so with

View File

@@ -29,7 +29,9 @@ import android.graphics.PixelFormat;
import android.os.Binder;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.Trace;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
@@ -57,6 +59,7 @@ import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -76,6 +79,8 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
private final WindowManager.LayoutParams mLpChanged;
private final boolean mKeyguardScreenRotation;
private final long mLockScreenDisplayTimeout;
private final Display.Mode mKeyguardDisplayMode;
private final KeyguardBypassController mKeyguardBypassController;
private ViewGroup mStatusBarView;
private WindowManager.LayoutParams mLp;
private boolean mHasTopUi;
@@ -91,14 +96,21 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class);
@Inject
public StatusBarWindowController(Context context) {
public StatusBarWindowController(Context context,
StatusBarStateController statusBarStateController,
ConfigurationController configurationController,
KeyguardBypassController keyguardBypassController) {
this(context, context.getSystemService(WindowManager.class), ActivityManager.getService(),
DozeParameters.getInstance(context));
DozeParameters.getInstance(context), statusBarStateController,
configurationController, keyguardBypassController);
}
@VisibleForTesting
public StatusBarWindowController(Context context, WindowManager windowManager,
IActivityManager activityManager, DozeParameters dozeParameters) {
IActivityManager activityManager, DozeParameters dozeParameters,
StatusBarStateController statusBarStateController,
ConfigurationController configurationController,
KeyguardBypassController keyguardBypassController) {
mContext = context;
mWindowManager = windowManager;
mActivityManager = activityManager;
@@ -106,12 +118,27 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
mDozeParameters = dozeParameters;
mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
mLpChanged = new WindowManager.LayoutParams();
mKeyguardBypassController = keyguardBypassController;
mLockScreenDisplayTimeout = context.getResources()
.getInteger(R.integer.config_lockScreenDisplayTimeout);
((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class))
((SysuiStatusBarStateController) statusBarStateController)
.addCallback(mStateListener,
SysuiStatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER);
Dependency.get(ConfigurationController.class).addCallback(this);
configurationController.addCallback(this);
Display.Mode[] supportedModes = context.getDisplay().getSupportedModes();
Display.Mode currentMode = context.getDisplay().getMode();
// Running on the highest frame rate available can be expensive.
// Let's specify a preferred refresh rate, and allow higher FPS only when we
// know that we're not falsing (because we unlocked.)
int keyguardRefreshRate = context.getResources()
.getInteger(R.integer.config_keyguardRefreshRate);
// Find supported display mode with the same resolution and requested refresh rate.
mKeyguardDisplayMode = Arrays.stream(supportedModes).filter(mode ->
(int) mode.getRefreshRate() == keyguardRefreshRate
&& mode.getPhysicalWidth() == currentMode.getPhysicalWidth()
&& mode.getPhysicalHeight() == currentMode.getPhysicalHeight())
.findFirst().orElse(null);
}
/**
@@ -209,6 +236,18 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
} else {
mLpChanged.privateFlags &= ~LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
}
if (mKeyguardDisplayMode != null) {
boolean bypassOnKeyguard = mKeyguardBypassController.getBypassEnabled()
&& state.statusBarState == StatusBarState.KEYGUARD && !state.keyguardFadingAway
&& !state.keyguardGoingAway;
if (state.dozing || bypassOnKeyguard) {
mLpChanged.preferredDisplayModeId = mKeyguardDisplayMode.getModeId();
} else {
mLpChanged.preferredDisplayModeId = 0;
}
Trace.setCounter("display_mode_id", mLpChanged.preferredDisplayModeId);
}
}
private void adjustScreenOrientation(State state) {
@@ -575,7 +614,8 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("StatusBarWindowController state:");
pw.println("StatusBarWindowController:");
pw.println(" mKeyguardDisplayMode=" + mKeyguardDisplayMode);
pw.println(mCurrentState);
}
@@ -594,6 +634,14 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
setKeyguardDark(useDarkText);
}
/**
* When keyguard will be dismissed but didn't start animation yet.
*/
public void setKeyguardGoingAway(boolean goingAway) {
mCurrentState.keyguardGoingAway = goingAway;
apply(mCurrentState);
}
private static class State {
boolean keyguardShowing;
boolean keyguardOccluded;
@@ -603,6 +651,7 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
boolean statusBarFocusable;
boolean bouncerShowing;
boolean keyguardFadingAway;
boolean keyguardGoingAway;
boolean qsExpanded;
boolean headsUpShowing;
boolean forceStatusBarVisible;

View File

@@ -60,6 +60,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoveInterceptor;
import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
@@ -67,6 +68,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -105,6 +107,10 @@ public class BubbleControllerTest extends SysuiTestCase {
private ZenModeController mZenModeController;
@Mock
private ZenModeConfig mZenModeConfig;
@Mock
private SysuiStatusBarStateController mStatusBarStateController;
@Mock
private KeyguardBypassController mKeyguardBypassController;
private FrameLayout mStatusBarView;
@Captor
@@ -143,7 +149,8 @@ public class BubbleControllerTest extends SysuiTestCase {
// Bubbles get added to status bar window view
mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager,
mActivityManager, mDozeParameters);
mActivityManager, mDozeParameters, mStatusBarStateController,
mConfigurationController, mKeyguardBypassController);
mStatusBarWindowController.add(mStatusBarView, 120 /* height */);
// Need notifications for bubbles

View File

@@ -33,6 +33,8 @@ import android.view.WindowManager;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import org.junit.Before;
import org.junit.Test;
@@ -54,6 +56,12 @@ public class StatusBarWindowControllerTest extends SysuiTestCase {
private ViewGroup mStatusBarView;
@Mock
private IActivityManager mActivityManager;
@Mock
private SysuiStatusBarStateController mStatusBarStateController;
@Mock
private ConfigurationController mConfigurationController;
@Mock
private KeyguardBypassController mKeyguardBypassController;
private StatusBarWindowController mStatusBarWindowController;
@@ -63,7 +71,8 @@ public class StatusBarWindowControllerTest extends SysuiTestCase {
when(mDozeParameters.getAlwaysOn()).thenReturn(true);
mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager,
mActivityManager, mDozeParameters);
mActivityManager, mDozeParameters, mStatusBarStateController,
mConfigurationController, mKeyguardBypassController);
mStatusBarWindowController.add(mStatusBarView, 100 /* height */);
}
@@ -88,7 +97,8 @@ public class StatusBarWindowControllerTest extends SysuiTestCase {
@Test
public void testOnThemeChanged_doesntCrash() {
mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager,
mActivityManager, mDozeParameters);
mActivityManager, mDozeParameters, mStatusBarStateController,
mConfigurationController, mKeyguardBypassController);
mStatusBarWindowController.onThemeChanged();
}
@@ -100,7 +110,8 @@ public class StatusBarWindowControllerTest extends SysuiTestCase {
@Test
public void testSetForcePluginOpen_beforeStatusBarInitialization() {
mStatusBarWindowController = new StatusBarWindowController(mContext, mWindowManager,
mActivityManager, mDozeParameters);
mActivityManager, mDozeParameters, mStatusBarStateController,
mConfigurationController, mKeyguardBypassController);
mStatusBarWindowController.setForcePluginOpen(true);
}
}