Merge "Update PowerManager to make ambient display suppression apply to dreams." into tm-qpr-dev
This commit is contained in:
@@ -2479,6 +2479,8 @@
|
|||||||
<integer name="config_attentionMaximumExtension">900000</integer> <!-- 15 minutes. -->
|
<integer name="config_attentionMaximumExtension">900000</integer> <!-- 15 minutes. -->
|
||||||
<!-- Is the system user the only user allowed to dream. -->
|
<!-- Is the system user the only user allowed to dream. -->
|
||||||
<bool name="config_dreamsOnlyEnabledForSystemUser">false</bool>
|
<bool name="config_dreamsOnlyEnabledForSystemUser">false</bool>
|
||||||
|
<!-- Whether dreams are disabled when ambient mode is suppressed. -->
|
||||||
|
<bool name="config_dreamsDisabledByAmbientModeSuppressionConfig">false</bool>
|
||||||
|
|
||||||
<!-- Whether to dismiss the active dream when an activity is started. Doesn't apply to
|
<!-- Whether to dismiss the active dream when an activity is started. Doesn't apply to
|
||||||
assistant activities (ACTIVITY_TYPE_ASSISTANT) -->
|
assistant activities (ACTIVITY_TYPE_ASSISTANT) -->
|
||||||
|
|||||||
@@ -2235,6 +2235,7 @@
|
|||||||
<java-symbol type="integer" name="config_dreamsBatteryLevelMinimumWhenNotPowered" />
|
<java-symbol type="integer" name="config_dreamsBatteryLevelMinimumWhenNotPowered" />
|
||||||
<java-symbol type="integer" name="config_dreamsBatteryLevelDrainCutoff" />
|
<java-symbol type="integer" name="config_dreamsBatteryLevelDrainCutoff" />
|
||||||
<java-symbol type="string" name="config_dreamsDefaultComponent" />
|
<java-symbol type="string" name="config_dreamsDefaultComponent" />
|
||||||
|
<java-symbol type="bool" name="config_dreamsDisabledByAmbientModeSuppressionConfig" />
|
||||||
<java-symbol type="bool" name="config_dreamsOnlyEnabledForSystemUser" />
|
<java-symbol type="bool" name="config_dreamsOnlyEnabledForSystemUser" />
|
||||||
<java-symbol type="array" name="config_supportedDreamComplications" />
|
<java-symbol type="array" name="config_supportedDreamComplications" />
|
||||||
<java-symbol type="array" name="config_disabledDreamComponents" />
|
<java-symbol type="array" name="config_disabledDreamComponents" />
|
||||||
|
|||||||
@@ -40,13 +40,24 @@ import java.util.Set;
|
|||||||
public class AmbientDisplaySuppressionController {
|
public class AmbientDisplaySuppressionController {
|
||||||
private static final String TAG = "AmbientDisplaySuppressionController";
|
private static final String TAG = "AmbientDisplaySuppressionController";
|
||||||
|
|
||||||
private final Context mContext;
|
|
||||||
private final Set<Pair<String, Integer>> mSuppressionTokens;
|
private final Set<Pair<String, Integer>> mSuppressionTokens;
|
||||||
|
private final AmbientDisplaySuppressionChangedCallback mCallback;
|
||||||
private IStatusBarService mStatusBarService;
|
private IStatusBarService mStatusBarService;
|
||||||
|
|
||||||
AmbientDisplaySuppressionController(Context context) {
|
/** Interface to get a list of available logical devices. */
|
||||||
mContext = requireNonNull(context);
|
interface AmbientDisplaySuppressionChangedCallback {
|
||||||
|
/**
|
||||||
|
* Called when the suppression state changes.
|
||||||
|
*
|
||||||
|
* @param isSuppressed Whether ambient is suppressed.
|
||||||
|
*/
|
||||||
|
void onSuppressionChanged(boolean isSuppressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
AmbientDisplaySuppressionController(
|
||||||
|
@NonNull AmbientDisplaySuppressionChangedCallback callback) {
|
||||||
mSuppressionTokens = Collections.synchronizedSet(new ArraySet<>());
|
mSuppressionTokens = Collections.synchronizedSet(new ArraySet<>());
|
||||||
|
mCallback = requireNonNull(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,6 +69,7 @@ public class AmbientDisplaySuppressionController {
|
|||||||
*/
|
*/
|
||||||
public void suppress(@NonNull String token, int callingUid, boolean suppress) {
|
public void suppress(@NonNull String token, int callingUid, boolean suppress) {
|
||||||
Pair<String, Integer> suppressionToken = Pair.create(requireNonNull(token), callingUid);
|
Pair<String, Integer> suppressionToken = Pair.create(requireNonNull(token), callingUid);
|
||||||
|
final boolean wasSuppressed = isSuppressed();
|
||||||
|
|
||||||
if (suppress) {
|
if (suppress) {
|
||||||
mSuppressionTokens.add(suppressionToken);
|
mSuppressionTokens.add(suppressionToken);
|
||||||
@@ -65,9 +77,14 @@ public class AmbientDisplaySuppressionController {
|
|||||||
mSuppressionTokens.remove(suppressionToken);
|
mSuppressionTokens.remove(suppressionToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean isSuppressed = isSuppressed();
|
||||||
|
if (isSuppressed != wasSuppressed) {
|
||||||
|
mCallback.onSuppressionChanged(isSuppressed);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
synchronized (mSuppressionTokens) {
|
synchronized (mSuppressionTokens) {
|
||||||
getStatusBar().suppressAmbientDisplay(isSuppressed());
|
getStatusBar().suppressAmbientDisplay(isSuppressed);
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.e(TAG, "Failed to suppress ambient display", e);
|
Slog.e(TAG, "Failed to suppress ambient display", e);
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ import com.android.server.am.BatteryStatsService;
|
|||||||
import com.android.server.lights.LightsManager;
|
import com.android.server.lights.LightsManager;
|
||||||
import com.android.server.lights.LogicalLight;
|
import com.android.server.lights.LogicalLight;
|
||||||
import com.android.server.policy.WindowManagerPolicy;
|
import com.android.server.policy.WindowManagerPolicy;
|
||||||
|
import com.android.server.power.AmbientDisplaySuppressionController.AmbientDisplaySuppressionChangedCallback;
|
||||||
import com.android.server.power.batterysaver.BatterySaverController;
|
import com.android.server.power.batterysaver.BatterySaverController;
|
||||||
import com.android.server.power.batterysaver.BatterySaverPolicy;
|
import com.android.server.power.batterysaver.BatterySaverPolicy;
|
||||||
import com.android.server.power.batterysaver.BatterySaverStateMachine;
|
import com.android.server.power.batterysaver.BatterySaverStateMachine;
|
||||||
@@ -507,6 +508,9 @@ public final class PowerManagerService extends SystemService
|
|||||||
// effectively and terminate the dream. Use -1 to disable this safety feature.
|
// effectively and terminate the dream. Use -1 to disable this safety feature.
|
||||||
private int mDreamsBatteryLevelDrainCutoffConfig;
|
private int mDreamsBatteryLevelDrainCutoffConfig;
|
||||||
|
|
||||||
|
// Whether dreams should be disabled when ambient mode is suppressed.
|
||||||
|
private boolean mDreamsDisabledByAmbientModeSuppressionConfig;
|
||||||
|
|
||||||
// True if dreams are enabled by the user.
|
// True if dreams are enabled by the user.
|
||||||
private boolean mDreamsEnabledSetting;
|
private boolean mDreamsEnabledSetting;
|
||||||
|
|
||||||
@@ -964,8 +968,8 @@ public final class PowerManagerService extends SystemService
|
|||||||
}
|
}
|
||||||
|
|
||||||
AmbientDisplaySuppressionController createAmbientDisplaySuppressionController(
|
AmbientDisplaySuppressionController createAmbientDisplaySuppressionController(
|
||||||
Context context) {
|
@NonNull AmbientDisplaySuppressionChangedCallback callback) {
|
||||||
return new AmbientDisplaySuppressionController(context);
|
return new AmbientDisplaySuppressionController(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
InattentiveSleepWarningController createInattentiveSleepWarningController() {
|
InattentiveSleepWarningController createInattentiveSleepWarningController() {
|
||||||
@@ -1044,7 +1048,8 @@ public final class PowerManagerService extends SystemService
|
|||||||
mConstants = new Constants(mHandler);
|
mConstants = new Constants(mHandler);
|
||||||
mAmbientDisplayConfiguration = mInjector.createAmbientDisplayConfiguration(context);
|
mAmbientDisplayConfiguration = mInjector.createAmbientDisplayConfiguration(context);
|
||||||
mAmbientDisplaySuppressionController =
|
mAmbientDisplaySuppressionController =
|
||||||
mInjector.createAmbientDisplaySuppressionController(context);
|
mInjector.createAmbientDisplaySuppressionController(
|
||||||
|
mAmbientSuppressionChangedCallback);
|
||||||
mAttentionDetector = new AttentionDetector(this::onUserAttention, mLock);
|
mAttentionDetector = new AttentionDetector(this::onUserAttention, mLock);
|
||||||
mFaceDownDetector = new FaceDownDetector(this::onFlip);
|
mFaceDownDetector = new FaceDownDetector(this::onFlip);
|
||||||
mScreenUndimDetector = new ScreenUndimDetector();
|
mScreenUndimDetector = new ScreenUndimDetector();
|
||||||
@@ -1403,6 +1408,8 @@ public final class PowerManagerService extends SystemService
|
|||||||
com.android.internal.R.integer.config_dreamsBatteryLevelMinimumWhenNotPowered);
|
com.android.internal.R.integer.config_dreamsBatteryLevelMinimumWhenNotPowered);
|
||||||
mDreamsBatteryLevelDrainCutoffConfig = resources.getInteger(
|
mDreamsBatteryLevelDrainCutoffConfig = resources.getInteger(
|
||||||
com.android.internal.R.integer.config_dreamsBatteryLevelDrainCutoff);
|
com.android.internal.R.integer.config_dreamsBatteryLevelDrainCutoff);
|
||||||
|
mDreamsDisabledByAmbientModeSuppressionConfig = resources.getBoolean(
|
||||||
|
com.android.internal.R.bool.config_dreamsDisabledByAmbientModeSuppressionConfig);
|
||||||
mDozeAfterScreenOff = resources.getBoolean(
|
mDozeAfterScreenOff = resources.getBoolean(
|
||||||
com.android.internal.R.bool.config_dozeAfterScreenOffByDefault);
|
com.android.internal.R.bool.config_dozeAfterScreenOffByDefault);
|
||||||
mMinimumScreenOffTimeoutConfig = resources.getInteger(
|
mMinimumScreenOffTimeoutConfig = resources.getInteger(
|
||||||
@@ -3340,12 +3347,32 @@ public final class PowerManagerService extends SystemService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GuardedBy("mLock")
|
||||||
|
private void onDreamSuppressionChangedLocked(final boolean isSuppressed) {
|
||||||
|
if (!mDreamsDisabledByAmbientModeSuppressionConfig) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isSuppressed && mIsPowered && mDreamsSupportedConfig && mDreamsEnabledSetting
|
||||||
|
&& shouldNapAtBedTimeLocked() && isItBedTimeYetLocked(
|
||||||
|
mPowerGroups.get(Display.DEFAULT_DISPLAY_GROUP))) {
|
||||||
|
napInternal(SystemClock.uptimeMillis(), Process.SYSTEM_UID, /* allowWake= */ true);
|
||||||
|
} else if (isSuppressed) {
|
||||||
|
mDirty |= DIRTY_SETTINGS;
|
||||||
|
updatePowerStateLocked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the {@code groupId} is allowed to dream in its current state.
|
* Returns true if the {@code groupId} is allowed to dream in its current state.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
private boolean canDreamLocked(final PowerGroup powerGroup) {
|
private boolean canDreamLocked(final PowerGroup powerGroup) {
|
||||||
|
final boolean dreamsSuppressed = mDreamsDisabledByAmbientModeSuppressionConfig
|
||||||
|
&& mAmbientDisplaySuppressionController.isSuppressed();
|
||||||
|
|
||||||
if (!mBootCompleted
|
if (!mBootCompleted
|
||||||
|
|| dreamsSuppressed
|
||||||
|| getGlobalWakefulnessLocked() != WAKEFULNESS_DREAMING
|
|| getGlobalWakefulnessLocked() != WAKEFULNESS_DREAMING
|
||||||
|| !mDreamsSupportedConfig
|
|| !mDreamsSupportedConfig
|
||||||
|| !mDreamsEnabledSetting
|
|| !mDreamsEnabledSetting
|
||||||
@@ -5037,6 +5064,16 @@ public final class PowerManagerService extends SystemService
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final AmbientDisplaySuppressionChangedCallback mAmbientSuppressionChangedCallback =
|
||||||
|
new AmbientDisplaySuppressionChangedCallback() {
|
||||||
|
@Override
|
||||||
|
public void onSuppressionChanged(boolean isSuppressed) {
|
||||||
|
synchronized (mLock) {
|
||||||
|
onDreamSuppressionChangedLocked(isSuppressed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for asynchronous operations performed by the power manager.
|
* Callback for asynchronous operations performed by the power manager.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -393,6 +393,12 @@ public class PowerManagerServiceTest {
|
|||||||
.thenReturn(minimumScreenOffTimeoutConfigMillis);
|
.thenReturn(minimumScreenOffTimeoutConfigMillis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setDreamsDisabledByAmbientModeSuppressionConfig(boolean disable) {
|
||||||
|
when(mResourcesSpy.getBoolean(
|
||||||
|
com.android.internal.R.bool.config_dreamsDisabledByAmbientModeSuppressionConfig))
|
||||||
|
.thenReturn(disable);
|
||||||
|
}
|
||||||
|
|
||||||
private void advanceTime(long timeMs) {
|
private void advanceTime(long timeMs) {
|
||||||
mClock.fastForward(timeMs);
|
mClock.fastForward(timeMs);
|
||||||
mTestLooper.dispatchAll();
|
mTestLooper.dispatchAll();
|
||||||
@@ -790,6 +796,91 @@ public class PowerManagerServiceTest {
|
|||||||
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
|
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("GuardedBy")
|
||||||
|
@Test
|
||||||
|
public void testAmbientSuppression_disablesDreamingAndWakesDevice() {
|
||||||
|
Settings.Secure.putInt(mContextSpy.getContentResolver(),
|
||||||
|
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
|
||||||
|
Settings.Secure.putInt(mContextSpy.getContentResolver(),
|
||||||
|
Settings.Secure.SCREENSAVER_ENABLED, 1);
|
||||||
|
|
||||||
|
setDreamsDisabledByAmbientModeSuppressionConfig(true);
|
||||||
|
setMinimumScreenOffTimeoutConfig(10000);
|
||||||
|
createService();
|
||||||
|
startSystem();
|
||||||
|
|
||||||
|
doAnswer(inv -> {
|
||||||
|
when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
|
||||||
|
return null;
|
||||||
|
}).when(mDreamManagerInternalMock).startDream(anyBoolean(), anyString());
|
||||||
|
|
||||||
|
setPluggedIn(true);
|
||||||
|
// Allow asynchronous sandman calls to execute.
|
||||||
|
advanceTime(10000);
|
||||||
|
|
||||||
|
forceDream();
|
||||||
|
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
|
||||||
|
mService.getBinderServiceInstance().suppressAmbientDisplay("test", true);
|
||||||
|
advanceTime(50);
|
||||||
|
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("GuardedBy")
|
||||||
|
@Test
|
||||||
|
public void testAmbientSuppressionDisabled_shouldNotWakeDevice() {
|
||||||
|
Settings.Secure.putInt(mContextSpy.getContentResolver(),
|
||||||
|
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
|
||||||
|
Settings.Secure.putInt(mContextSpy.getContentResolver(),
|
||||||
|
Settings.Secure.SCREENSAVER_ENABLED, 1);
|
||||||
|
|
||||||
|
setDreamsDisabledByAmbientModeSuppressionConfig(false);
|
||||||
|
setMinimumScreenOffTimeoutConfig(10000);
|
||||||
|
createService();
|
||||||
|
startSystem();
|
||||||
|
|
||||||
|
doAnswer(inv -> {
|
||||||
|
when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
|
||||||
|
return null;
|
||||||
|
}).when(mDreamManagerInternalMock).startDream(anyBoolean(), anyString());
|
||||||
|
|
||||||
|
setPluggedIn(true);
|
||||||
|
// Allow asynchronous sandman calls to execute.
|
||||||
|
advanceTime(10000);
|
||||||
|
|
||||||
|
forceDream();
|
||||||
|
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
|
||||||
|
mService.getBinderServiceInstance().suppressAmbientDisplay("test", true);
|
||||||
|
advanceTime(50);
|
||||||
|
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAmbientSuppression_doesNotAffectDreamForcing() {
|
||||||
|
Settings.Secure.putInt(mContextSpy.getContentResolver(),
|
||||||
|
Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
|
||||||
|
Settings.Secure.putInt(mContextSpy.getContentResolver(),
|
||||||
|
Settings.Secure.SCREENSAVER_ENABLED, 1);
|
||||||
|
|
||||||
|
setDreamsDisabledByAmbientModeSuppressionConfig(true);
|
||||||
|
setMinimumScreenOffTimeoutConfig(10000);
|
||||||
|
createService();
|
||||||
|
startSystem();
|
||||||
|
|
||||||
|
doAnswer(inv -> {
|
||||||
|
when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
|
||||||
|
return null;
|
||||||
|
}).when(mDreamManagerInternalMock).startDream(anyBoolean(), anyString());
|
||||||
|
|
||||||
|
mService.getBinderServiceInstance().suppressAmbientDisplay("test", true);
|
||||||
|
setPluggedIn(true);
|
||||||
|
// Allow asynchronous sandman calls to execute.
|
||||||
|
advanceTime(10000);
|
||||||
|
|
||||||
|
// Verify that forcing dream still works even though ambient display is suppressed
|
||||||
|
forceDream();
|
||||||
|
assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetDozeOverrideFromDreamManager_triggersSuspendBlocker() {
|
public void testSetDozeOverrideFromDreamManager_triggersSuspendBlocker() {
|
||||||
final String suspendBlockerName = "PowerManagerService.Display";
|
final String suspendBlockerName = "PowerManagerService.Display";
|
||||||
|
|||||||
Reference in New Issue
Block a user