Snap for 9392049 from 0a33f42345 to tm-qpr2-release

Change-Id: Ifccaf79c15062d48fd92ef68be378507ec501246
This commit is contained in:
Android Build Coastguard Worker
2022-12-11 02:20:28 +00:00
11 changed files with 554 additions and 12 deletions

View File

@@ -458,8 +458,7 @@ public class Dialog implements DialogInterface, Window.Callback,
&& WindowOnBackInvokedDispatcher.isOnBackInvokedCallbackEnabled(mContext)) {
// Add onBackPressed as default back behavior.
mDefaultBackCallback = this::onBackPressed;
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT, mDefaultBackCallback);
getOnBackInvokedDispatcher().registerSystemOnBackInvokedCallback(mDefaultBackCallback);
mDefaultBackCallback = null;
}
}

View File

@@ -5514,13 +5514,17 @@ public class SettingsProvider extends ContentProvider {
}
if (currentVersion == 210) {
final SettingsState secureSettings = getSecureSettingsLocked(userId);
final int defaultValueVibrateIconEnabled = getContext().getResources()
.getInteger(R.integer.def_statusBarVibrateIconEnabled);
secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.STATUS_BAR_SHOW_VIBRATE_ICON,
String.valueOf(defaultValueVibrateIconEnabled),
null /* tag */, true /* makeDefault */,
SettingsState.SYSTEM_PACKAGE_NAME);
final Setting currentSetting = secureSettings.getSettingLocked(
Secure.STATUS_BAR_SHOW_VIBRATE_ICON);
if (currentSetting.isNull()) {
final int defaultValueVibrateIconEnabled = getContext().getResources()
.getInteger(R.integer.def_statusBarVibrateIconEnabled);
secureSettings.insertSettingOverrideableByRestoreLocked(
Secure.STATUS_BAR_SHOW_VIBRATE_ICON,
String.valueOf(defaultValueVibrateIconEnabled),
null /* tag */, true /* makeDefault */,
SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 211;
}
// vXXX: Add new settings above this point.

View File

@@ -55,6 +55,7 @@ import android.view.WindowInsetsController.Appearance;
import android.view.WindowInsetsController.Behavior;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import com.android.internal.statusbar.LetterboxDetails;
import com.android.internal.view.AppearanceRegion;
@@ -125,7 +126,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
private final DisplayManager mDisplayManager;
private Context mWindowContext;
private ScreenPinningNotify mScreenPinningNotify;
private int mNavigationMode;
private int mNavigationMode = -1;
private final Consumer<Rect> mPipListener;
/**
@@ -217,8 +218,7 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
parseCurrentSysuiState();
mCommandQueue.addCallback(this);
mOverviewProxyService.addCallback(this);
mEdgeBackGestureHandler.onNavigationModeChanged(
mNavigationModeController.addListener(this));
onNavigationModeChanged(mNavigationModeController.addListener(this));
mNavBarHelper.registerNavTaskStateUpdater(mNavbarTaskbarStateUpdater);
mNavBarHelper.init();
mEdgeBackGestureHandler.onNavBarAttached();
@@ -492,6 +492,11 @@ public class TaskbarDelegate implements CommandQueue.Callbacks,
!QuickStepContract.isGesturalMode(mNavigationMode));
}
@VisibleForTesting
int getNavigationMode() {
return mNavigationMode;
}
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("TaskbarDelegate (displayId=" + mDisplayId + "):");

View File

@@ -119,6 +119,9 @@ constructor(
// Don't apply the filter to (non-promoted) group summaries
// - summary will be pruned if necessary, depending on if children are filtered
entry.parent?.summary == entry -> false
// Check that the entry satisfies certain characteristics that would bypass the
// filter
shouldIgnoreUnseenCheck(entry) -> false
else -> true
}.also { hasFiltered -> hasFilteredAnyNotifs = hasFilteredAnyNotifs || hasFiltered }
@@ -134,6 +137,13 @@ constructor(
keyguardNotificationVisibilityProvider.shouldHideNotification(entry)
}
private fun shouldIgnoreUnseenCheck(entry: NotificationEntry): Boolean =
when {
entry.isMediaNotification -> true
entry.sbn.isOngoing -> true
else -> false
}
// TODO(b/206118999): merge this class with SensitiveContentCoordinator which also depends on
// these same updates
private fun setupInvalidateNotifListCallbacks() {}

View File

@@ -0,0 +1,16 @@
package com.android.systemui.statusbar.notification.fsi
class FsiDebug {
companion object {
private const val debugTag = "FsiDebug"
private const val debug = true
fun log(s: Any) {
if (!debug) {
return
}
android.util.Log.d(debugTag, "$s")
}
}
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright (C) 2022 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.stylus
import android.hardware.input.InputManager
import android.os.Handler
import android.util.ArrayMap
import android.view.InputDevice
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import java.util.concurrent.CopyOnWriteArrayList
import javax.inject.Inject
/**
* A class which keeps track of InputDevice events related to stylus devices, and notifies
* registered callbacks of stylus events.
*/
@SysUISingleton
class StylusManager
@Inject
constructor(
private val inputManager: InputManager,
@Background private val handler: Handler,
) : InputManager.InputDeviceListener {
private val stylusCallbacks: CopyOnWriteArrayList<StylusCallback> = CopyOnWriteArrayList()
// This map should only be accessed on the handler
private val inputDeviceAddressMap: MutableMap<Int, String?> = ArrayMap()
/**
* Starts listening to InputManager InputDevice events. Will also load the InputManager snapshot
* at time of starting.
*/
fun startListener() {
addExistingStylusToMap()
inputManager.registerInputDeviceListener(this, handler)
}
/** Registers a StylusCallback to listen to stylus events. */
fun registerCallback(callback: StylusCallback) {
stylusCallbacks.add(callback)
}
/** Unregisters a StylusCallback. If StylusCallback is not registered, is a no-op. */
fun unregisterCallback(callback: StylusCallback) {
stylusCallbacks.remove(callback)
}
override fun onInputDeviceAdded(deviceId: Int) {
val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
// TODO(b/257936830): get address once input api available
val btAddress: String? = null
inputDeviceAddressMap[deviceId] = btAddress
executeStylusCallbacks { cb -> cb.onStylusAdded(deviceId) }
if (btAddress != null) {
executeStylusCallbacks { cb -> cb.onStylusBluetoothConnected(deviceId, btAddress) }
}
}
override fun onInputDeviceChanged(deviceId: Int) {
val device: InputDevice = inputManager.getInputDevice(deviceId) ?: return
if (!device.supportsSource(InputDevice.SOURCE_STYLUS)) return
// TODO(b/257936830): get address once input api available
val currAddress: String? = null
val prevAddress: String? = inputDeviceAddressMap[deviceId]
inputDeviceAddressMap[deviceId] = currAddress
if (prevAddress == null && currAddress != null) {
executeStylusCallbacks { cb -> cb.onStylusBluetoothConnected(deviceId, currAddress) }
}
if (prevAddress != null && currAddress == null) {
executeStylusCallbacks { cb -> cb.onStylusBluetoothDisconnected(deviceId, prevAddress) }
}
}
override fun onInputDeviceRemoved(deviceId: Int) {
if (!inputDeviceAddressMap.contains(deviceId)) return
val btAddress: String? = inputDeviceAddressMap[deviceId]
inputDeviceAddressMap.remove(deviceId)
if (btAddress != null) {
executeStylusCallbacks { cb -> cb.onStylusBluetoothDisconnected(deviceId, btAddress) }
}
executeStylusCallbacks { cb -> cb.onStylusRemoved(deviceId) }
}
private fun executeStylusCallbacks(run: (cb: StylusCallback) -> Unit) {
stylusCallbacks.forEach(run)
}
private fun addExistingStylusToMap() {
for (deviceId: Int in inputManager.inputDeviceIds) {
val device: InputDevice = inputManager.getInputDevice(deviceId) ?: continue
if (device.supportsSource(InputDevice.SOURCE_STYLUS)) {
// TODO(b/257936830): get address once input api available
inputDeviceAddressMap[deviceId] = null
}
}
}
/** Callback interface to receive events from the StylusManager. */
interface StylusCallback {
fun onStylusAdded(deviceId: Int) {}
fun onStylusRemoved(deviceId: Int) {}
fun onStylusBluetoothConnected(deviceId: Int, btAddress: String) {}
fun onStylusBluetoothDisconnected(deviceId: Int, btAddress: String) {}
}
companion object {
private val TAG = StylusManager::class.simpleName.orEmpty()
}
}

View File

@@ -0,0 +1,93 @@
package com.android.systemui.navigationbar
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.dump.DumpManager
import com.android.systemui.model.SysUiState
import com.android.systemui.navigationbar.gestural.EdgeBackGestureHandler
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.phone.AutoHideController
import com.android.systemui.statusbar.phone.LightBarController
import com.android.systemui.statusbar.phone.LightBarTransitionsController
import com.android.wm.shell.back.BackAnimation
import com.android.wm.shell.pip.Pip
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.any
import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.anyInt
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import java.util.Optional
@SmallTest
class TaskbarDelegateTest : SysuiTestCase() {
val DISPLAY_ID = 0;
val MODE_GESTURE = 0;
val MODE_THREE_BUTTON = 1;
private lateinit var mTaskbarDelegate: TaskbarDelegate
@Mock
lateinit var mEdgeBackGestureHandlerFactory : EdgeBackGestureHandler.Factory
@Mock
lateinit var mEdgeBackGestureHandler : EdgeBackGestureHandler
@Mock
lateinit var mLightBarControllerFactory : LightBarTransitionsController.Factory
@Mock
lateinit var mLightBarTransitionController: LightBarTransitionsController
@Mock
lateinit var mCommandQueue: CommandQueue
@Mock
lateinit var mOverviewProxyService: OverviewProxyService
@Mock
lateinit var mNavBarHelper: NavBarHelper
@Mock
lateinit var mNavigationModeController: NavigationModeController
@Mock
lateinit var mSysUiState: SysUiState
@Mock
lateinit var mDumpManager: DumpManager
@Mock
lateinit var mAutoHideController: AutoHideController
@Mock
lateinit var mLightBarController: LightBarController
@Mock
lateinit var mOptionalPip: Optional<Pip>
@Mock
lateinit var mBackAnimation: BackAnimation
@Mock
lateinit var mCurrentSysUiState: NavBarHelper.CurrentSysuiState
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
`when`(mEdgeBackGestureHandlerFactory.create(context)).thenReturn(mEdgeBackGestureHandler)
`when`(mLightBarControllerFactory.create(any())).thenReturn(mLightBarTransitionController)
`when`(mNavBarHelper.currentSysuiState).thenReturn(mCurrentSysUiState)
`when`(mSysUiState.setFlag(anyInt(), anyBoolean())).thenReturn(mSysUiState)
mTaskbarDelegate = TaskbarDelegate(context, mEdgeBackGestureHandlerFactory,
mLightBarControllerFactory)
mTaskbarDelegate.setDependencies(mCommandQueue, mOverviewProxyService, mNavBarHelper,
mNavigationModeController, mSysUiState, mDumpManager, mAutoHideController,
mLightBarController, mOptionalPip, mBackAnimation)
}
@Test
fun navigationModeInitialized() {
`when`(mNavigationModeController.addListener(any())).thenReturn(MODE_THREE_BUTTON)
assert(mTaskbarDelegate.navigationMode == -1)
mTaskbarDelegate.init(DISPLAY_ID)
assert(mTaskbarDelegate.navigationMode == MODE_THREE_BUTTON)
}
@Test
fun navigationModeInitialized_notifyEdgeBackHandler() {
`when`(mNavigationModeController.addListener(any())).thenReturn(MODE_GESTURE)
mTaskbarDelegate.init(DISPLAY_ID)
verify(mEdgeBackGestureHandler, times(1)).onNavigationModeChanged(MODE_GESTURE)
}
}

View File

@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.collection.coordinator
import android.app.Notification
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
@@ -33,6 +34,7 @@ import com.android.systemui.statusbar.notification.collection.provider.SectionHe
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProvider
import com.android.systemui.statusbar.notification.collection.provider.SeenNotificationsProviderImpl
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.withArgCaptor
@@ -104,6 +106,50 @@ class KeyguardCoordinatorTest : SysuiTestCase() {
}
}
@Test
fun unseenFilterDoesNotSuppressSeenOngoingNotifWhileKeyguardShowing() {
whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
// GIVEN: Keyguard is not showing, and an ongoing notification is present
keyguardRepository.setKeyguardShowing(false)
runKeyguardCoordinatorTest {
val fakeEntry = NotificationEntryBuilder()
.setNotification(Notification.Builder(mContext).setOngoing(true).build())
.build()
collectionListener.onEntryAdded(fakeEntry)
// WHEN: The keyguard is now showing
keyguardRepository.setKeyguardShowing(true)
testScheduler.runCurrent()
// THEN: The notification is recognized as "ongoing" and is not filtered out.
assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isFalse()
}
}
@Test
fun unseenFilterDoesNotSuppressSeenMediaNotifWhileKeyguardShowing() {
whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)
// GIVEN: Keyguard is not showing, and a media notification is present
keyguardRepository.setKeyguardShowing(false)
runKeyguardCoordinatorTest {
val fakeEntry = NotificationEntryBuilder().build().apply {
row = mock<ExpandableNotificationRow>().apply {
whenever(isMediaRow).thenReturn(true)
}
}
collectionListener.onEntryAdded(fakeEntry)
// WHEN: The keyguard is now showing
keyguardRepository.setKeyguardShowing(true)
testScheduler.runCurrent()
// THEN: The notification is recognized as "media" and is not filtered out.
assertThat(unseenFilter.shouldFilterOut(fakeEntry, 0L)).isFalse()
}
}
@Test
fun unseenFilterUpdatesSeenProviderWhenSuppressing() {
whenever(notifPipelineFlags.shouldFilterUnseenNotifsOnKeyguard).thenReturn(true)

View File

@@ -0,0 +1,221 @@
/*
* Copyright (C) 2022 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.stylus
import android.hardware.input.InputManager
import android.os.Handler
import android.testing.AndroidTestingRunner
import android.view.InputDevice
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.whenever
import org.junit.Before
import org.junit.Ignore
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@SmallTest
@Ignore("b/257936830 until bt APIs")
class StylusManagerTest : SysuiTestCase() {
@Mock lateinit var inputManager: InputManager
@Mock lateinit var stylusDevice: InputDevice
@Mock lateinit var btStylusDevice: InputDevice
@Mock lateinit var otherDevice: InputDevice
@Mock lateinit var handler: Handler
@Mock lateinit var stylusCallback: StylusManager.StylusCallback
@Mock lateinit var otherStylusCallback: StylusManager.StylusCallback
private lateinit var stylusManager: StylusManager
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
whenever(handler.post(any())).thenAnswer {
(it.arguments[0] as Runnable).run()
true
}
stylusManager = StylusManager(inputManager, handler)
stylusManager.registerCallback(stylusCallback)
whenever(otherDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(false)
whenever(stylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
whenever(btStylusDevice.supportsSource(InputDevice.SOURCE_STYLUS)).thenReturn(true)
// whenever(stylusDevice.bluetoothAddress).thenReturn(null)
// whenever(btStylusDevice.bluetoothAddress).thenReturn(STYLUS_BT_ADDRESS)
whenever(inputManager.getInputDevice(OTHER_DEVICE_ID)).thenReturn(otherDevice)
whenever(inputManager.getInputDevice(STYLUS_DEVICE_ID)).thenReturn(stylusDevice)
whenever(inputManager.getInputDevice(BT_STYLUS_DEVICE_ID)).thenReturn(btStylusDevice)
whenever(inputManager.inputDeviceIds).thenReturn(intArrayOf(STYLUS_DEVICE_ID))
}
@Test
fun startListener_registersInputDeviceListener() {
stylusManager.startListener()
verify(inputManager, times(1)).registerInputDeviceListener(stylusManager, handler)
}
@Test
fun onInputDeviceAdded_multipleRegisteredCallbacks_callsAll() {
stylusManager.registerCallback(otherStylusCallback)
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
verify(stylusCallback, times(1)).onStylusAdded(STYLUS_DEVICE_ID)
verifyNoMoreInteractions(stylusCallback)
verify(otherStylusCallback, times(1)).onStylusAdded(STYLUS_DEVICE_ID)
verifyNoMoreInteractions(otherStylusCallback)
}
@Test
fun onInputDeviceAdded_stylus_callsCallbacksOnStylusAdded() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
verify(stylusCallback, times(1)).onStylusAdded(STYLUS_DEVICE_ID)
verifyNoMoreInteractions(stylusCallback)
}
@Test
fun onInputDeviceAdded_btStylus_callsCallbacksWithAddress() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
inOrder(stylusCallback).let {
it.verify(stylusCallback, times(1)).onStylusAdded(BT_STYLUS_DEVICE_ID)
it.verify(stylusCallback, times(1))
.onStylusBluetoothConnected(BT_STYLUS_DEVICE_ID, STYLUS_BT_ADDRESS)
}
}
@Test
fun onInputDeviceAdded_notStylus_doesNotCallCallbacks() {
stylusManager.onInputDeviceAdded(OTHER_DEVICE_ID)
verifyNoMoreInteractions(stylusCallback)
}
@Test
fun onInputDeviceChanged_multipleRegisteredCallbacks_callsAll() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
// whenever(stylusDevice.bluetoothAddress).thenReturn(STYLUS_BT_ADDRESS)
stylusManager.registerCallback(otherStylusCallback)
stylusManager.onInputDeviceChanged(STYLUS_DEVICE_ID)
verify(stylusCallback, times(1))
.onStylusBluetoothConnected(STYLUS_DEVICE_ID, STYLUS_BT_ADDRESS)
verify(otherStylusCallback, times(1))
.onStylusBluetoothConnected(STYLUS_DEVICE_ID, STYLUS_BT_ADDRESS)
}
@Test
fun onInputDeviceChanged_stylusNewBtConnection_callsCallbacks() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
// whenever(stylusDevice.bluetoothAddress).thenReturn(STYLUS_BT_ADDRESS)
stylusManager.onInputDeviceChanged(STYLUS_DEVICE_ID)
verify(stylusCallback, times(1))
.onStylusBluetoothConnected(STYLUS_DEVICE_ID, STYLUS_BT_ADDRESS)
}
@Test
fun onInputDeviceChanged_stylusLostBtConnection_callsCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
// whenever(btStylusDevice.bluetoothAddress).thenReturn(null)
stylusManager.onInputDeviceChanged(BT_STYLUS_DEVICE_ID)
verify(stylusCallback, times(1))
.onStylusBluetoothDisconnected(BT_STYLUS_DEVICE_ID, STYLUS_BT_ADDRESS)
}
@Test
fun onInputDeviceChanged_btConnection_stylusAlreadyBtConnected_onlyCallsListenersOnce() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
stylusManager.onInputDeviceChanged(BT_STYLUS_DEVICE_ID)
verify(stylusCallback, times(1))
.onStylusBluetoothConnected(BT_STYLUS_DEVICE_ID, STYLUS_BT_ADDRESS)
}
@Test
fun onInputDeviceChanged_noBtConnection_stylusNeverBtConnected_doesNotCallCallbacks() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
stylusManager.onInputDeviceChanged(STYLUS_DEVICE_ID)
verify(stylusCallback, never()).onStylusBluetoothDisconnected(any(), any())
}
@Test
fun onInputDeviceRemoved_multipleRegisteredCallbacks_callsAll() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
stylusManager.registerCallback(otherStylusCallback)
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
verify(stylusCallback, times(1)).onStylusRemoved(STYLUS_DEVICE_ID)
verify(otherStylusCallback, times(1)).onStylusRemoved(STYLUS_DEVICE_ID)
}
@Test
fun onInputDeviceRemoved_stylus_callsCallbacks() {
stylusManager.onInputDeviceAdded(STYLUS_DEVICE_ID)
stylusManager.onInputDeviceRemoved(STYLUS_DEVICE_ID)
verify(stylusCallback, times(1)).onStylusRemoved(STYLUS_DEVICE_ID)
verify(stylusCallback, never()).onStylusBluetoothDisconnected(any(), any())
}
@Test
fun onInputDeviceRemoved_btStylus_callsCallbacks() {
stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
stylusManager.onInputDeviceRemoved(BT_STYLUS_DEVICE_ID)
inOrder(stylusCallback).let {
it.verify(stylusCallback, times(1))
.onStylusBluetoothDisconnected(BT_STYLUS_DEVICE_ID, STYLUS_BT_ADDRESS)
it.verify(stylusCallback, times(1)).onStylusRemoved(BT_STYLUS_DEVICE_ID)
}
}
companion object {
private const val OTHER_DEVICE_ID = 0
private const val STYLUS_DEVICE_ID = 1
private const val BT_STYLUS_DEVICE_ID = 2
private const val STYLUS_BT_ADDRESS = "SOME:ADDRESS"
}
}

View File

@@ -379,6 +379,10 @@ public final class DreamManagerService extends SystemService {
return false;
}
if (!dreamsEnabledForUser(ActivityManager.getCurrentUser())) {
return false;
}
if ((mWhenToDream & DREAM_ON_CHARGE) == DREAM_ON_CHARGE) {
return mIsCharging;
}

View File

@@ -1049,6 +1049,19 @@ public class PhoneWindowManager implements WindowManagerPolicy {
return;
}
// Make sure the device locks. Unfortunately, this has the side-effect of briefly revealing
// the lock screen before the dream appears. Note that this locking behavior needs to
// happen regardless of whether we end up dreaming (below) or not.
// TODO(b/261662912): Find a better way to lock the device that doesn't result in jank.
lockNow(null);
// Don't dream if the user isn't user zero.
// TODO(b/261907079): Move this check to DreamManagerService#canStartDreamingInternal().
if (ActivityManager.getCurrentUser() != UserHandle.USER_SYSTEM) {
noDreamAction.run();
return;
}
final DreamManagerInternal dreamManagerInternal = getDreamManagerInternal();
if (dreamManagerInternal == null || !dreamManagerInternal.canStartDreaming(isScreenOn)) {
noDreamAction.run();