Merge "Store ambient display suppression state in memory." into rvc-dev am: 1399825fe7 am: f411b28870
Change-Id: Ib47cb66bd3cf2e38e5dffbd18c84098400041ba6
This commit is contained in:
@@ -220,4 +220,10 @@ oneway interface IStatusBar
|
||||
* Notifies SystemUI to stop tracing.
|
||||
*/
|
||||
void stopTracing();
|
||||
|
||||
/**
|
||||
* If true, suppresses the ambient display from showing. If false, re-enables the ambient
|
||||
* display.
|
||||
*/
|
||||
void suppressAmbientDisplay(boolean suppress);
|
||||
}
|
||||
|
||||
@@ -139,4 +139,10 @@ interface IStatusBarService
|
||||
* Returns whether SystemUI tracing is enabled.
|
||||
*/
|
||||
boolean isTracing();
|
||||
|
||||
/**
|
||||
* If true, suppresses the ambient display from showing. If false, re-enables the ambient
|
||||
* display.
|
||||
*/
|
||||
void suppressAmbientDisplay(boolean suppress);
|
||||
}
|
||||
|
||||
@@ -102,7 +102,8 @@ public class DozeFactory {
|
||||
wrappedService, mDozeParameters);
|
||||
|
||||
DozeMachine machine = new DozeMachine(wrappedService, config, wakeLock,
|
||||
mWakefulnessLifecycle, mBatteryController, mDozeLog, mDockManager);
|
||||
mWakefulnessLifecycle, mBatteryController, mDozeLog, mDockManager,
|
||||
mDozeServiceHost);
|
||||
machine.setParts(new DozeMachine.Part[]{
|
||||
new DozePauser(mHandler, machine, mAlarmManager, mDozeParameters.getPolicy()),
|
||||
new DozeFalsingManagerAdapter(mFalsingManager),
|
||||
@@ -118,7 +119,6 @@ public class DozeFactory {
|
||||
new DozeWallpaperState(mWallpaperManager, mBiometricUnlockController,
|
||||
mDozeParameters),
|
||||
new DozeDockHandler(config, machine, mDockManager),
|
||||
new DozeSuppressedHandler(dozeService, config, machine),
|
||||
new DozeAuthRemover(dozeService)
|
||||
});
|
||||
|
||||
|
||||
@@ -81,6 +81,9 @@ public interface DozeHost {
|
||||
*/
|
||||
void stopPulsing();
|
||||
|
||||
/** Returns whether doze is suppressed. */
|
||||
boolean isDozeSuppressed();
|
||||
|
||||
interface Callback {
|
||||
/**
|
||||
* Called when a high priority notification is added.
|
||||
@@ -94,6 +97,9 @@ public interface DozeHost {
|
||||
* @param active whether power save is active or not
|
||||
*/
|
||||
default void onPowerSaveChanged(boolean active) {}
|
||||
|
||||
/** Called when the doze suppression state changes. */
|
||||
default void onDozeSuppressedChanged(boolean suppressed) {}
|
||||
}
|
||||
|
||||
interface PulseCallback {
|
||||
|
||||
@@ -134,6 +134,7 @@ public class DozeMachine {
|
||||
private final AmbientDisplayConfiguration mConfig;
|
||||
private final WakefulnessLifecycle mWakefulnessLifecycle;
|
||||
private final BatteryController mBatteryController;
|
||||
private final DozeHost mDozeHost;
|
||||
private Part[] mParts;
|
||||
|
||||
private final ArrayList<State> mQueuedRequests = new ArrayList<>();
|
||||
@@ -144,7 +145,7 @@ public class DozeMachine {
|
||||
|
||||
public DozeMachine(Service service, AmbientDisplayConfiguration config, WakeLock wakeLock,
|
||||
WakefulnessLifecycle wakefulnessLifecycle, BatteryController batteryController,
|
||||
DozeLog dozeLog, DockManager dockManager) {
|
||||
DozeLog dozeLog, DockManager dockManager, DozeHost dozeHost) {
|
||||
mDozeService = service;
|
||||
mConfig = config;
|
||||
mWakefulnessLifecycle = wakefulnessLifecycle;
|
||||
@@ -152,6 +153,7 @@ public class DozeMachine {
|
||||
mBatteryController = batteryController;
|
||||
mDozeLog = dozeLog;
|
||||
mDockManager = dockManager;
|
||||
mDozeHost = dozeHost;
|
||||
}
|
||||
|
||||
/** Initializes the set of {@link Part}s. Must be called exactly once after construction. */
|
||||
@@ -328,7 +330,7 @@ public class DozeMachine {
|
||||
if (mState == State.FINISH) {
|
||||
return State.FINISH;
|
||||
}
|
||||
if (mConfig.dozeSuppressed(UserHandle.USER_CURRENT) && requestedState.isAlwaysOn()) {
|
||||
if (mDozeHost.isDozeSuppressed() && requestedState.isAlwaysOn()) {
|
||||
Log.i(TAG, "Doze is suppressed. Suppressing state: " + requestedState);
|
||||
mDozeLog.traceDozeSuppressed(requestedState);
|
||||
return State.DOZE;
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.systemui.doze;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.hardware.display.AmbientDisplayConfiguration;
|
||||
import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
/** Handles updating the doze state when doze is suppressed. */
|
||||
public final class DozeSuppressedHandler implements DozeMachine.Part {
|
||||
|
||||
private static final String TAG = DozeSuppressedHandler.class.getSimpleName();
|
||||
private static final boolean DEBUG = DozeService.DEBUG;
|
||||
|
||||
private final ContentResolver mResolver;
|
||||
private final AmbientDisplayConfiguration mConfig;
|
||||
private final DozeMachine mMachine;
|
||||
private final DozeSuppressedSettingObserver mSettingObserver;
|
||||
private final Handler mHandler = new Handler();
|
||||
|
||||
public DozeSuppressedHandler(Context context, AmbientDisplayConfiguration config,
|
||||
DozeMachine machine) {
|
||||
this(context, config, machine, null);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
DozeSuppressedHandler(Context context, AmbientDisplayConfiguration config, DozeMachine machine,
|
||||
DozeSuppressedSettingObserver observer) {
|
||||
mResolver = context.getContentResolver();
|
||||
mConfig = requireNonNull(config);
|
||||
mMachine = requireNonNull(machine);
|
||||
if (observer == null) {
|
||||
mSettingObserver = new DozeSuppressedSettingObserver(mHandler);
|
||||
} else {
|
||||
mSettingObserver = observer;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
|
||||
switch (newState) {
|
||||
case INITIALIZED:
|
||||
mSettingObserver.register();
|
||||
break;
|
||||
case FINISH:
|
||||
mSettingObserver.unregister();
|
||||
break;
|
||||
default:
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to changes to the DOZE_SUPPRESSED secure setting and updates the doze state
|
||||
* accordingly.
|
||||
*/
|
||||
final class DozeSuppressedSettingObserver extends ContentObserver {
|
||||
private boolean mRegistered;
|
||||
|
||||
private DozeSuppressedSettingObserver(Handler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri, int userId) {
|
||||
if (userId != ActivityManager.getCurrentUser()) {
|
||||
return;
|
||||
}
|
||||
final DozeMachine.State nextState;
|
||||
if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)
|
||||
&& !mConfig.dozeSuppressed(UserHandle.USER_CURRENT)) {
|
||||
nextState = DozeMachine.State.DOZE_AOD;
|
||||
} else {
|
||||
nextState = DozeMachine.State.DOZE;
|
||||
}
|
||||
mMachine.requestState(nextState);
|
||||
}
|
||||
|
||||
void register() {
|
||||
if (mRegistered) {
|
||||
return;
|
||||
}
|
||||
mResolver.registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.SUPPRESS_DOZE),
|
||||
false, this, UserHandle.USER_CURRENT);
|
||||
Log.d(TAG, "Register");
|
||||
mRegistered = true;
|
||||
}
|
||||
|
||||
void unregister() {
|
||||
if (!mRegistered) {
|
||||
return;
|
||||
}
|
||||
mResolver.unregisterContentObserver(this);
|
||||
Log.d(TAG, "Unregister");
|
||||
mRegistered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,7 +127,7 @@ public class DozeTriggers implements DozeMachine.Part {
|
||||
mDozeLog.tracePulseDropped("pulseOnNotificationsDisabled");
|
||||
return;
|
||||
}
|
||||
if (mConfig.dozeSuppressed(UserHandle.USER_CURRENT)) {
|
||||
if (mDozeHost.isDozeSuppressed()) {
|
||||
runIfNotNull(onPulseSuppressedListener);
|
||||
mDozeLog.tracePulseDropped("dozeSuppressed");
|
||||
return;
|
||||
@@ -492,5 +492,16 @@ public class DozeTriggers implements DozeMachine.Part {
|
||||
mMachine.requestState(DozeMachine.State.DOZE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDozeSuppressedChanged(boolean suppressed) {
|
||||
final DozeMachine.State nextState;
|
||||
if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) && !suppressed) {
|
||||
nextState = DozeMachine.State.DOZE_AOD;
|
||||
} else {
|
||||
nextState = DozeMachine.State.DOZE;
|
||||
}
|
||||
mMachine.requestState(nextState);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -125,6 +125,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
|
||||
private static final int MSG_SHOW_TOAST = 53 << MSG_SHIFT;
|
||||
private static final int MSG_HIDE_TOAST = 54 << MSG_SHIFT;
|
||||
private static final int MSG_TRACING_STATE_CHANGED = 55 << MSG_SHIFT;
|
||||
private static final int MSG_SUPPRESS_AMBIENT_DISPLAY = 56 << MSG_SHIFT;
|
||||
|
||||
public static final int FLAG_EXCLUDE_NONE = 0;
|
||||
public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
|
||||
@@ -316,6 +317,9 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
|
||||
*/
|
||||
default void dismissInattentiveSleepWarning(boolean animated) { }
|
||||
|
||||
/** Called to suppress ambient display. */
|
||||
default void suppressAmbientDisplay(boolean suppress) { }
|
||||
|
||||
/**
|
||||
* @see IStatusBar#showToast(String, IBinder, CharSequence, IBinder, int,
|
||||
* ITransientNotificationCallback)
|
||||
@@ -950,6 +954,13 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suppressAmbientDisplay(boolean suppress) {
|
||||
synchronized (mLock) {
|
||||
mHandler.obtainMessage(MSG_SUPPRESS_AMBIENT_DISPLAY, suppress).sendToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
private final class H extends Handler {
|
||||
private H(Looper l) {
|
||||
super(l);
|
||||
@@ -1282,6 +1293,11 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
|
||||
mCallbacks.get(i).onTracingStateChanged((Boolean) msg.obj);
|
||||
}
|
||||
break;
|
||||
case MSG_SUPPRESS_AMBIENT_DISPLAY:
|
||||
for (Callbacks callbacks: mCallbacks) {
|
||||
callbacks.suppressAmbientDisplay((boolean) msg.obj);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@ public final class DozeServiceHost implements DozeHost {
|
||||
private NotificationPanelViewController mNotificationPanel;
|
||||
private View mAmbientIndicationContainer;
|
||||
private StatusBar mStatusBar;
|
||||
private boolean mSuppressed;
|
||||
|
||||
@Inject
|
||||
public DozeServiceHost(DozeLog dozeLog, PowerManager powerManager,
|
||||
@@ -449,4 +450,18 @@ public final class DozeServiceHost implements DozeHost {
|
||||
boolean getIgnoreTouchWhilePulsing() {
|
||||
return mIgnoreTouchWhilePulsing;
|
||||
}
|
||||
|
||||
void setDozeSuppressed(boolean suppressed) {
|
||||
if (suppressed == mSuppressed) {
|
||||
return;
|
||||
}
|
||||
mSuppressed = suppressed;
|
||||
for (Callback callback : mCallbacks) {
|
||||
callback.onDozeSuppressedChanged(suppressed);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDozeSuppressed() {
|
||||
return mSuppressed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4287,4 +4287,8 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
return mTransientShown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suppressAmbientDisplay(boolean suppressed) {
|
||||
mDozeServiceHost.setDozeSuppressed(suppressed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,8 @@ public class DozeMachineTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private DozeLog mDozeLog;
|
||||
@Mock private DockManager mDockManager;
|
||||
@Mock
|
||||
private DozeHost mHost;
|
||||
private DozeServiceFake mServiceFake;
|
||||
private WakeLockFake mWakeLockFake;
|
||||
private AmbientDisplayConfiguration mConfigMock;
|
||||
@@ -85,7 +87,8 @@ public class DozeMachineTest extends SysuiTestCase {
|
||||
when(mDockManager.isHidden()).thenReturn(false);
|
||||
|
||||
mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake,
|
||||
mWakefulnessLifecycle, mock(BatteryController.class), mDozeLog, mDockManager);
|
||||
mWakefulnessLifecycle, mock(BatteryController.class), mDozeLog, mDockManager,
|
||||
mHost);
|
||||
mMachine.setParts(new DozeMachine.Part[]{mPartMock});
|
||||
}
|
||||
|
||||
@@ -140,7 +143,7 @@ public class DozeMachineTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testInitialize_dozeSuppressed_alwaysOnDisabled_goesToDoze() {
|
||||
when(mConfigMock.dozeSuppressed(anyInt())).thenReturn(true);
|
||||
when(mHost.isDozeSuppressed()).thenReturn(true);
|
||||
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
|
||||
|
||||
mMachine.requestState(INITIALIZED);
|
||||
@@ -151,7 +154,7 @@ public class DozeMachineTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testInitialize_dozeSuppressed_alwaysOnEnabled_goesToDoze() {
|
||||
when(mConfigMock.dozeSuppressed(anyInt())).thenReturn(true);
|
||||
when(mHost.isDozeSuppressed()).thenReturn(true);
|
||||
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
|
||||
|
||||
mMachine.requestState(INITIALIZED);
|
||||
@@ -162,7 +165,7 @@ public class DozeMachineTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testInitialize_dozeSuppressed_afterDocked_goesToDoze() {
|
||||
when(mConfigMock.dozeSuppressed(anyInt())).thenReturn(true);
|
||||
when(mHost.isDozeSuppressed()).thenReturn(true);
|
||||
when(mDockManager.isDocked()).thenReturn(true);
|
||||
|
||||
mMachine.requestState(INITIALIZED);
|
||||
@@ -173,7 +176,7 @@ public class DozeMachineTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testInitialize_dozeSuppressed_alwaysOnDisabled_afterDockPaused_goesToDoze() {
|
||||
when(mConfigMock.dozeSuppressed(anyInt())).thenReturn(true);
|
||||
when(mHost.isDozeSuppressed()).thenReturn(true);
|
||||
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
|
||||
when(mDockManager.isDocked()).thenReturn(true);
|
||||
when(mDockManager.isHidden()).thenReturn(true);
|
||||
@@ -186,7 +189,7 @@ public class DozeMachineTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testInitialize_dozeSuppressed_alwaysOnEnabled_afterDockPaused_goesToDoze() {
|
||||
when(mConfigMock.dozeSuppressed(anyInt())).thenReturn(true);
|
||||
when(mHost.isDozeSuppressed()).thenReturn(true);
|
||||
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
|
||||
when(mDockManager.isDocked()).thenReturn(true);
|
||||
when(mDockManager.isHidden()).thenReturn(true);
|
||||
@@ -225,7 +228,7 @@ public class DozeMachineTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testPulseDone_dozeSuppressed_goesToSuppressed() {
|
||||
when(mConfigMock.dozeSuppressed(anyInt())).thenReturn(true);
|
||||
when(mHost.isDozeSuppressed()).thenReturn(true);
|
||||
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
|
||||
mMachine.requestState(INITIALIZED);
|
||||
mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
|
||||
@@ -252,7 +255,7 @@ public class DozeMachineTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testPulseDone_dozeSuppressed_afterDocked_goesToDoze() {
|
||||
when(mConfigMock.dozeSuppressed(anyInt())).thenReturn(true);
|
||||
when(mHost.isDozeSuppressed()).thenReturn(true);
|
||||
when(mDockManager.isDocked()).thenReturn(true);
|
||||
mMachine.requestState(INITIALIZED);
|
||||
mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
|
||||
@@ -281,7 +284,7 @@ public class DozeMachineTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testPulseDone_dozeSuppressed_afterDockPaused_goesToDoze() {
|
||||
when(mConfigMock.dozeSuppressed(anyInt())).thenReturn(true);
|
||||
when(mHost.isDozeSuppressed()).thenReturn(true);
|
||||
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
|
||||
when(mDockManager.isDocked()).thenReturn(true);
|
||||
when(mDockManager.isHidden()).thenReturn(true);
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.systemui.doze;
|
||||
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.hardware.display.AmbientDisplayConfiguration;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.doze.DozeSuppressedHandler.DozeSuppressedSettingObserver;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@RunWithLooper
|
||||
public class DozeSuppressedHandlerTest extends SysuiTestCase {
|
||||
@Mock private DozeMachine mMachine;
|
||||
@Mock private DozeSuppressedSettingObserver mObserver;
|
||||
private AmbientDisplayConfiguration mConfig;
|
||||
private DozeSuppressedHandler mSuppressedHandler;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mConfig = DozeConfigurationUtil.createMockConfig();
|
||||
mSuppressedHandler = new DozeSuppressedHandler(mContext, mConfig, mMachine, mObserver);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transitionTo_initialized_registersObserver() throws Exception {
|
||||
mSuppressedHandler.transitionTo(DozeMachine.State.UNINITIALIZED,
|
||||
DozeMachine.State.INITIALIZED);
|
||||
|
||||
verify(mObserver).register();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transitionTo_finish_unregistersObserver() throws Exception {
|
||||
mSuppressedHandler.transitionTo(DozeMachine.State.INITIALIZED,
|
||||
DozeMachine.State.FINISH);
|
||||
|
||||
verify(mObserver).unregister();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transitionTo_doze_doesNothing() throws Exception {
|
||||
mSuppressedHandler.transitionTo(DozeMachine.State.INITIALIZED,
|
||||
DozeMachine.State.DOZE);
|
||||
|
||||
verify(mObserver, never()).register();
|
||||
verify(mObserver, never()).unregister();
|
||||
}
|
||||
}
|
||||
@@ -447,4 +447,11 @@ public class CommandQueueTest extends SysuiTestCase {
|
||||
waitForIdleSync();
|
||||
verify(mCallbacks).hideAuthenticationDialog();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuppressAmbientDisplay() {
|
||||
mCommandQueue.suppressAmbientDisplay(true);
|
||||
waitForIdleSync();
|
||||
verify(mCallbacks).suppressAmbientDisplay(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -858,6 +858,18 @@ public class StatusBarTest extends SysuiTestCase {
|
||||
any(UserHandle.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuppressAmbientDisplay_suppress() {
|
||||
mStatusBar.suppressAmbientDisplay(true);
|
||||
verify(mDozeServiceHost).setDozeSuppressed(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuppressAmbientDisplay_unsuppress() {
|
||||
mStatusBar.suppressAmbientDisplay(false);
|
||||
verify(mDozeServiceHost).setDozeSuppressed(false);
|
||||
}
|
||||
|
||||
public static class TestableNotificationInterruptionStateProvider extends
|
||||
NotificationInterruptionStateProvider {
|
||||
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* Copyright (C) 2020 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 static java.util.Objects.requireNonNull;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Communicates with System UI to suppress the ambient display.
|
||||
*/
|
||||
public class AmbientDisplaySuppressionController {
|
||||
private static final String TAG = "AmbientDisplaySuppressionController";
|
||||
|
||||
private final Context mContext;
|
||||
private final Set<Pair<String, Integer>> mSuppressionTokens;
|
||||
private IStatusBarService mStatusBarService;
|
||||
|
||||
AmbientDisplaySuppressionController(Context context) {
|
||||
mContext = requireNonNull(context);
|
||||
mSuppressionTokens = Collections.synchronizedSet(new ArraySet<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppresses ambient display.
|
||||
*
|
||||
* @param token A persistible identifier for the ambient display suppression.
|
||||
* @param callingUid The uid of the calling application.
|
||||
* @param suppress If true, suppresses the ambient display. Otherwise, unsuppresses it.
|
||||
*/
|
||||
public void suppress(@NonNull String token, int callingUid, boolean suppress) {
|
||||
Pair<String, Integer> suppressionToken = Pair.create(requireNonNull(token), callingUid);
|
||||
|
||||
if (suppress) {
|
||||
mSuppressionTokens.add(suppressionToken);
|
||||
} else {
|
||||
mSuppressionTokens.remove(suppressionToken);
|
||||
}
|
||||
|
||||
try {
|
||||
synchronized (mSuppressionTokens) {
|
||||
getStatusBar().suppressAmbientDisplay(isSuppressed());
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Failed to suppress ambient display", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether ambient display is suppressed for the given token.
|
||||
*
|
||||
* @param token A persistible identifier for the ambient display suppression.
|
||||
* @param callingUid The uid of the calling application.
|
||||
*/
|
||||
public boolean isSuppressed(@NonNull String token, int callingUid) {
|
||||
return mSuppressionTokens.contains(Pair.create(requireNonNull(token), callingUid));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether ambient display is suppressed.
|
||||
*/
|
||||
public boolean isSuppressed() {
|
||||
return !mSuppressionTokens.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the state of ambient display suppression and the list of suppression tokens into
|
||||
* {@code pw}.
|
||||
*/
|
||||
public void dump(PrintWriter pw) {
|
||||
pw.println("AmbientDisplaySuppressionController:");
|
||||
pw.println(" ambientDisplaySuppressed=" + isSuppressed());
|
||||
pw.println(" mSuppressionTokens=" + mSuppressionTokens);
|
||||
}
|
||||
|
||||
private synchronized IStatusBarService getStatusBar() {
|
||||
if (mStatusBarService == null) {
|
||||
mStatusBarService = IStatusBarService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
|
||||
}
|
||||
return mStatusBarService;
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,6 @@ import android.provider.Settings.SettingNotFoundException;
|
||||
import android.service.dreams.DreamManagerInternal;
|
||||
import android.service.vr.IVrManager;
|
||||
import android.service.vr.IVrStateCallbacks;
|
||||
import android.util.ArraySet;
|
||||
import android.util.KeyValueListParser;
|
||||
import android.util.PrintWriterPrinter;
|
||||
import android.util.Slog;
|
||||
@@ -115,7 +114,6 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The power manager service is responsible for coordinating power management
|
||||
@@ -266,6 +264,7 @@ public final class PowerManagerService extends SystemService
|
||||
private LogicalLight mAttentionLight;
|
||||
|
||||
private InattentiveSleepWarningController mInattentiveSleepWarningOverlayController;
|
||||
private final AmbientDisplaySuppressionController mAmbientDisplaySuppressionController;
|
||||
|
||||
private final Object mLock = LockGuard.installNewLock(LockGuard.INDEX_POWER);
|
||||
|
||||
@@ -585,9 +584,6 @@ public final class PowerManagerService extends SystemService
|
||||
// but the DreamService has not yet been told to start (it's an async process).
|
||||
private boolean mDozeStartInProgress;
|
||||
|
||||
// Set of all tokens suppressing ambient display.
|
||||
private final Set<String> mAmbientDisplaySuppressionTokens = new ArraySet<>();
|
||||
|
||||
private final class ForegroundProfileObserver extends SynchronousUserSwitchObserver {
|
||||
@Override
|
||||
public void onUserSwitching(@UserIdInt int newUserId) throws RemoteException {
|
||||
@@ -785,6 +781,11 @@ public final class PowerManagerService extends SystemService
|
||||
return new AmbientDisplayConfiguration(context);
|
||||
}
|
||||
|
||||
AmbientDisplaySuppressionController createAmbientDisplaySuppressionController(
|
||||
Context context) {
|
||||
return new AmbientDisplaySuppressionController(context);
|
||||
}
|
||||
|
||||
InattentiveSleepWarningController createInattentiveSleepWarningController() {
|
||||
return new InattentiveSleepWarningController();
|
||||
}
|
||||
@@ -840,6 +841,8 @@ public final class PowerManagerService extends SystemService
|
||||
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
|
||||
mConstants = new Constants(mHandler);
|
||||
mAmbientDisplayConfiguration = mInjector.createAmbientDisplayConfiguration(context);
|
||||
mAmbientDisplaySuppressionController =
|
||||
mInjector.createAmbientDisplaySuppressionController(context);
|
||||
mAttentionDetector = new AttentionDetector(this::onUserAttention, mLock);
|
||||
|
||||
mBatterySavingStats = new BatterySavingStats(mLock);
|
||||
@@ -3488,26 +3491,6 @@ public final class PowerManagerService extends SystemService
|
||||
}
|
||||
}
|
||||
|
||||
private void suppressAmbientDisplayInternal(String token, boolean suppress) {
|
||||
if (DEBUG_SPEW) {
|
||||
Slog.d(TAG, "Suppress ambient display for token " + token + ": " + suppress);
|
||||
}
|
||||
|
||||
if (suppress) {
|
||||
mAmbientDisplaySuppressionTokens.add(token);
|
||||
} else {
|
||||
mAmbientDisplaySuppressionTokens.remove(token);
|
||||
}
|
||||
|
||||
Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.SUPPRESS_DOZE,
|
||||
Math.min(mAmbientDisplaySuppressionTokens.size(), 1));
|
||||
}
|
||||
|
||||
private String createAmbientDisplayToken(String token, int callingUid) {
|
||||
return callingUid + "_" + token;
|
||||
}
|
||||
|
||||
private void boostScreenBrightnessInternal(long eventTime, int uid) {
|
||||
synchronized (mLock) {
|
||||
if (!mSystemReady || getWakefulnessLocked() == WAKEFULNESS_ASLEEP
|
||||
@@ -3943,6 +3926,8 @@ public final class PowerManagerService extends SystemService
|
||||
if (mNotifier != null) {
|
||||
mNotifier.dump(pw);
|
||||
}
|
||||
|
||||
mAmbientDisplaySuppressionController.dump(pw);
|
||||
}
|
||||
|
||||
private void dumpProto(FileDescriptor fd) {
|
||||
@@ -5211,7 +5196,7 @@ public final class PowerManagerService extends SystemService
|
||||
final int uid = Binder.getCallingUid();
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
suppressAmbientDisplayInternal(createAmbientDisplayToken(token, uid), suppress);
|
||||
mAmbientDisplaySuppressionController.suppress(token, uid, suppress);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
@@ -5225,8 +5210,7 @@ public final class PowerManagerService extends SystemService
|
||||
final int uid = Binder.getCallingUid();
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return mAmbientDisplaySuppressionTokens.contains(
|
||||
createAmbientDisplayToken(token, uid));
|
||||
return mAmbientDisplaySuppressionController.isSuppressed(token, uid);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
@@ -5239,7 +5223,7 @@ public final class PowerManagerService extends SystemService
|
||||
|
||||
final long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
return mAmbientDisplaySuppressionTokens.size() > 0;
|
||||
return mAmbientDisplaySuppressionController.isSuppressed();
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ import com.android.server.LocalServices;
|
||||
import com.android.server.notification.NotificationDelegate;
|
||||
import com.android.server.policy.GlobalActionsProvider;
|
||||
import com.android.server.power.ShutdownThread;
|
||||
import com.android.server.wm.WindowManagerService;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -1453,6 +1452,17 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suppressAmbientDisplay(boolean suppress) {
|
||||
enforceStatusBarService();
|
||||
if (mBar != null) {
|
||||
try {
|
||||
mBar.suppressAmbientDisplay(suppress);
|
||||
} catch (RemoteException ex) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getStatusBarIcons() {
|
||||
return mContext.getResources().getStringArray(R.array.config_statusBarIcons);
|
||||
}
|
||||
|
||||
@@ -841,66 +841,6 @@ public class PowerManagerServiceTest {
|
||||
assertThat(mService.getBinderServiceInstance().isAmbientDisplayAvailable()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuppressAmbientDisplay_suppressed() throws Exception {
|
||||
createService();
|
||||
mService.getBinderServiceInstance().suppressAmbientDisplay("test", true);
|
||||
|
||||
assertThat(Settings.Secure.getInt(mContextSpy.getContentResolver(),
|
||||
Settings.Secure.SUPPRESS_DOZE)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuppressAmbientDisplay_multipleCallers_suppressed() throws Exception {
|
||||
createService();
|
||||
mService.getBinderServiceInstance().suppressAmbientDisplay("test1", true);
|
||||
mService.getBinderServiceInstance().suppressAmbientDisplay("test2", false);
|
||||
|
||||
assertThat(Settings.Secure.getInt(mContextSpy.getContentResolver(),
|
||||
Settings.Secure.SUPPRESS_DOZE)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuppressAmbientDisplay_suppressTwice_suppressed() throws Exception {
|
||||
createService();
|
||||
mService.getBinderServiceInstance().suppressAmbientDisplay("test", true);
|
||||
mService.getBinderServiceInstance().suppressAmbientDisplay("test", true);
|
||||
|
||||
assertThat(Settings.Secure.getInt(mContextSpy.getContentResolver(),
|
||||
Settings.Secure.SUPPRESS_DOZE)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuppressAmbientDisplay_suppressTwiceThenUnsuppress_notSuppressed()
|
||||
throws Exception {
|
||||
createService();
|
||||
mService.getBinderServiceInstance().suppressAmbientDisplay("test", true);
|
||||
mService.getBinderServiceInstance().suppressAmbientDisplay("test", true);
|
||||
mService.getBinderServiceInstance().suppressAmbientDisplay("test", false);
|
||||
|
||||
assertThat(Settings.Secure.getInt(mContextSpy.getContentResolver(),
|
||||
Settings.Secure.SUPPRESS_DOZE)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuppressAmbientDisplay_notSuppressed() throws Exception {
|
||||
createService();
|
||||
mService.getBinderServiceInstance().suppressAmbientDisplay("test", false);
|
||||
|
||||
assertThat(Settings.Secure.getInt(mContextSpy.getContentResolver(),
|
||||
Settings.Secure.SUPPRESS_DOZE)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuppressAmbientDisplay_unsuppressTwice_notSuppressed() throws Exception {
|
||||
createService();
|
||||
mService.getBinderServiceInstance().suppressAmbientDisplay("test", false);
|
||||
mService.getBinderServiceInstance().suppressAmbientDisplay("test", false);
|
||||
|
||||
assertThat(Settings.Secure.getInt(mContextSpy.getContentResolver(),
|
||||
Settings.Secure.SUPPRESS_DOZE)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsAmbientDisplaySuppressed_default_notSuppressed() throws Exception {
|
||||
createService();
|
||||
|
||||
Reference in New Issue
Block a user