From 87231445933d8acad197c70ad6a2f4e54caa74a4 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Thu, 25 Aug 2022 11:03:36 -0400 Subject: Fix DeviceProvisioned on PhoneStatusBarPolicy With the new DeviceProvisionedController, adding the callback does not immediately call it back. Instead, we need to retrieve the value on subscription. This was causing the alarm icon not to show in QS headers (it's blocked in other surfaces using a blocklist). Keep it disabled (using ignore) for regular headers, but do not ignore it in the combined headers. Test: atest PhoneStatusBarPolicyTest QuickStatusBarHeaderControllerTest Test: atest com.android.systemui.shade Fixes: 204159738 Change-Id: I2eabfa6c61ed9eea66c9127449250919618a47fd --- .../qs/QuickStatusBarHeaderController.java | 2 + .../shade/LargeScreenShadeHeaderController.kt | 8 + .../statusbar/phone/PhoneStatusBarPolicy.java | 8 +- .../qs/QuickStatusBarHeaderControllerTest.kt | 8 + ...LargeScreenShadeHeaderControllerCombinedTest.kt | 7 + .../shade/LargeScreenShadeHeaderControllerTest.kt | 7 + .../statusbar/phone/PhoneStatusBarPolicyTest.kt | 230 +++++++++++++++++++++ 7 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java index 2a6cf66995ea..b5859616f392 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java @@ -128,6 +128,8 @@ class QuickStatusBarHeaderController extends ViewController { updateAlarm(); updateManagedProfile(); + onUserSetupChanged(); }); } }; diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt index cb4f08e6c552..eb907bd92471 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt @@ -192,6 +192,14 @@ class QuickStatusBarHeaderControllerTest : SysuiTestCase() { verify(view).setIsSingleCarrier(false) } + @Test + fun testAlarmIconIgnored() { + controller.init() + + verify(iconContainer).addIgnoredSlot( + mContext.getString(com.android.internal.R.string.status_bar_alarm_clock)) + } + private fun stubViews() { `when`(view.findViewById(anyInt())).thenReturn(mockView) `when`(view.findViewById(R.id.carrier_group)).thenReturn(qsCarrierGroup) diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt index 20c6d9adc300..e85ffb68de54 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt @@ -607,6 +607,13 @@ class LargeScreenShadeHeaderControllerCombinedTest : SysuiTestCase() { verify(mockConstraintsChanges.largeScreenConstraintsChanges)!!.invoke(any()) } + @Test + fun alarmIconNotIgnored() { + verify(statusIcons, never()).addIgnoredSlot( + context.getString(com.android.internal.R.string.status_bar_alarm_clock) + ) + } + private fun createWindowInsets( topCutout: Rect? = Rect() ): WindowInsets { diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt index eeb61bc8a0f8..8511443705e4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt @@ -191,4 +191,11 @@ class LargeScreenShadeHeaderControllerTest : SysuiTestCase() { verify(date).setTextAppearance(R.style.TextAppearance_QS_Status) verify(carrierGroup).updateTextAppearance(R.style.TextAppearance_QS_Status_Carriers) } + + @Test + fun alarmIconIgnored() { + verify(statusIcons).addIgnoredSlot( + context.getString(com.android.internal.R.string.status_bar_alarm_clock) + ) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt new file mode 100644 index 000000000000..64dee956fcc1 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicyTest.kt @@ -0,0 +1,230 @@ +/* + * 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.statusbar.phone + +import android.app.AlarmManager +import android.app.IActivityManager +import android.app.admin.DevicePolicyManager +import android.content.SharedPreferences +import android.os.UserManager +import android.telecom.TelecomManager +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.testing.TestableLooper.RunWithLooper +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.broadcast.BroadcastDispatcher +import com.android.systemui.privacy.PrivacyItemController +import com.android.systemui.privacy.logging.PrivacyLogger +import com.android.systemui.screenrecord.RecordingController +import com.android.systemui.statusbar.CommandQueue +import com.android.systemui.statusbar.policy.BluetoothController +import com.android.systemui.statusbar.policy.CastController +import com.android.systemui.statusbar.policy.DataSaverController +import com.android.systemui.statusbar.policy.DeviceProvisionedController +import com.android.systemui.statusbar.policy.HotspotController +import com.android.systemui.statusbar.policy.KeyguardStateController +import com.android.systemui.statusbar.policy.LocationController +import com.android.systemui.statusbar.policy.NextAlarmController +import com.android.systemui.statusbar.policy.RotationLockController +import com.android.systemui.statusbar.policy.SensorPrivacyController +import com.android.systemui.statusbar.policy.UserInfoController +import com.android.systemui.statusbar.policy.ZenModeController +import com.android.systemui.util.RingerModeTracker +import com.android.systemui.util.concurrency.FakeExecutor +import com.android.systemui.util.mockito.capture +import com.android.systemui.util.time.DateFormatUtil +import com.android.systemui.util.time.FakeSystemClock +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Answers +import org.mockito.ArgumentCaptor +import org.mockito.Captor +import org.mockito.Mock +import org.mockito.Mockito.anyInt +import org.mockito.Mockito.never +import org.mockito.Mockito.verify +import org.mockito.Mockito.`when` as whenever +import org.mockito.MockitoAnnotations + +@RunWith(AndroidTestingRunner::class) +@RunWithLooper +@SmallTest +class PhoneStatusBarPolicyTest : SysuiTestCase() { + + companion object { + private const val ALARM_SLOT = "alarm" + } + + @Mock + private lateinit var iconController: StatusBarIconController + @Mock + private lateinit var commandQueue: CommandQueue + @Mock + private lateinit var broadcastDispatcher: BroadcastDispatcher + @Mock + private lateinit var castController: CastController + @Mock + private lateinit var hotspotController: HotspotController + @Mock + private lateinit var bluetoothController: BluetoothController + @Mock + private lateinit var nextAlarmController: NextAlarmController + @Mock + private lateinit var userInfoController: UserInfoController + @Mock + private lateinit var rotationLockController: RotationLockController + @Mock + private lateinit var dataSaverController: DataSaverController + @Mock + private lateinit var zenModeController: ZenModeController + @Mock + private lateinit var deviceProvisionedController: DeviceProvisionedController + @Mock + private lateinit var keyguardStateController: KeyguardStateController + @Mock + private lateinit var locationController: LocationController + @Mock + private lateinit var sensorPrivacyController: SensorPrivacyController + @Mock + private lateinit var iActivityManager: IActivityManager + @Mock + private lateinit var alarmManager: AlarmManager + @Mock + private lateinit var userManager: UserManager + @Mock + private lateinit var devicePolicyManager: DevicePolicyManager + @Mock + private lateinit var recordingController: RecordingController + @Mock + private lateinit var telecomManager: TelecomManager + @Mock + private lateinit var sharedPreferences: SharedPreferences + @Mock + private lateinit var dateFormatUtil: DateFormatUtil + @Mock(answer = Answers.RETURNS_DEEP_STUBS) + private lateinit var ringerModeTracker: RingerModeTracker + @Mock + private lateinit var privacyItemController: PrivacyItemController + @Mock + private lateinit var privacyLogger: PrivacyLogger + @Captor + private lateinit var alarmCallbackCaptor: + ArgumentCaptor + + private lateinit var executor: FakeExecutor + private lateinit var statusBarPolicy: PhoneStatusBarPolicy + private lateinit var testableLooper: TestableLooper + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + executor = FakeExecutor(FakeSystemClock()) + testableLooper = TestableLooper.get(this) + context.orCreateTestableResources.addOverride( + com.android.internal.R.string.status_bar_alarm_clock, + ALARM_SLOT + ) + statusBarPolicy = createStatusBarPolicy() + } + + @Test + fun testDeviceNotProvisioned_alarmIconNotShown() { + val alarmInfo = createAlarmInfo() + + whenever(deviceProvisionedController.isCurrentUserSetup).thenReturn(false) + statusBarPolicy.init() + verify(nextAlarmController).addCallback(capture(alarmCallbackCaptor)) + + whenever(alarmManager.getNextAlarmClock(anyInt())).thenReturn(alarmInfo) + + alarmCallbackCaptor.value.onNextAlarmChanged(alarmInfo) + verify(iconController, never()).setIconVisibility(ALARM_SLOT, true) + } + + @Test + fun testDeviceProvisioned_alarmIconShown() { + val alarmInfo = createAlarmInfo() + + whenever(deviceProvisionedController.isCurrentUserSetup).thenReturn(true) + statusBarPolicy.init() + + verify(nextAlarmController).addCallback(capture(alarmCallbackCaptor)) + whenever(alarmManager.getNextAlarmClock(anyInt())).thenReturn(alarmInfo) + + alarmCallbackCaptor.value.onNextAlarmChanged(alarmInfo) + verify(iconController).setIconVisibility(ALARM_SLOT, true) + } + + @Test + fun testDeviceProvisionedChanged_alarmIconShownAfterCurrentUserSetup() { + val alarmInfo = createAlarmInfo() + + whenever(deviceProvisionedController.isCurrentUserSetup).thenReturn(false) + statusBarPolicy.init() + + verify(nextAlarmController).addCallback(capture(alarmCallbackCaptor)) + whenever(alarmManager.getNextAlarmClock(anyInt())).thenReturn(alarmInfo) + + alarmCallbackCaptor.value.onNextAlarmChanged(alarmInfo) + verify(iconController, never()).setIconVisibility(ALARM_SLOT, true) + + whenever(deviceProvisionedController.isCurrentUserSetup).thenReturn(true) + statusBarPolicy.onUserSetupChanged() + verify(iconController).setIconVisibility(ALARM_SLOT, true) + } + + private fun createAlarmInfo(): AlarmManager.AlarmClockInfo { + return AlarmManager.AlarmClockInfo(10L, null) + } + + private fun createStatusBarPolicy(): PhoneStatusBarPolicy { + return PhoneStatusBarPolicy( + iconController, + commandQueue, + broadcastDispatcher, + executor, + testableLooper.looper, + context.resources, + castController, + hotspotController, + bluetoothController, + nextAlarmController, + userInfoController, + rotationLockController, + dataSaverController, + zenModeController, + deviceProvisionedController, + keyguardStateController, + locationController, + sensorPrivacyController, + iActivityManager, + alarmManager, + userManager, + devicePolicyManager, + recordingController, + telecomManager, + /* displayId = */ 0, + sharedPreferences, + dateFormatUtil, + ringerModeTracker, + privacyItemController, + privacyLogger + ) + } +} -- cgit v1.2.3-59-g8ed1b