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
This commit is contained in:
@@ -128,6 +128,8 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
|
||||
mPrivacyIconsController.setChipVisibilityListener(this);
|
||||
mIconContainer.addIgnoredSlot(
|
||||
getResources().getString(com.android.internal.R.string.status_bar_managed_profile));
|
||||
mIconContainer.addIgnoredSlot(
|
||||
getResources().getString(com.android.internal.R.string.status_bar_alarm_clock));
|
||||
mIconContainer.setShouldRestrictIcons(false);
|
||||
mStatusBarIconController.addIconGroup(mIconManager);
|
||||
|
||||
|
||||
@@ -270,6 +270,14 @@ class LargeScreenShadeHeaderController @Inject constructor(
|
||||
qsCarrierGroupController = qsCarrierGroupControllerBuilder
|
||||
.setQSCarrierGroup(qsCarrierGroup)
|
||||
.build()
|
||||
|
||||
if (!combinedHeaders) {
|
||||
// In the new header, we display alarm icon but we ignore it when not using the new
|
||||
// headers.
|
||||
iconContainer.addIgnoredSlot(
|
||||
context.getString(com.android.internal.R.string.status_bar_alarm_clock)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewAttached() {
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
@@ -127,7 +128,7 @@ public class PhoneStatusBarPolicy
|
||||
private final DateFormatUtil mDateFormatUtil;
|
||||
private final TelecomManager mTelecomManager;
|
||||
|
||||
private final Handler mHandler = new Handler();
|
||||
private final Handler mHandler;
|
||||
private final CastController mCast;
|
||||
private final HotspotController mHotspot;
|
||||
private final NextAlarmController mNextAlarmController;
|
||||
@@ -166,7 +167,7 @@ public class PhoneStatusBarPolicy
|
||||
@Inject
|
||||
public PhoneStatusBarPolicy(StatusBarIconController iconController,
|
||||
CommandQueue commandQueue, BroadcastDispatcher broadcastDispatcher,
|
||||
@UiBackground Executor uiBgExecutor, @Main Resources resources,
|
||||
@UiBackground Executor uiBgExecutor, @Main Looper looper, @Main Resources resources,
|
||||
CastController castController, HotspotController hotspotController,
|
||||
BluetoothController bluetoothController, NextAlarmController nextAlarmController,
|
||||
UserInfoController userInfoController, RotationLockController rotationLockController,
|
||||
@@ -185,6 +186,7 @@ public class PhoneStatusBarPolicy
|
||||
mIconController = iconController;
|
||||
mCommandQueue = commandQueue;
|
||||
mBroadcastDispatcher = broadcastDispatcher;
|
||||
mHandler = new Handler(looper);
|
||||
mResources = resources;
|
||||
mCast = castController;
|
||||
mHotspot = hotspotController;
|
||||
@@ -332,6 +334,7 @@ public class PhoneStatusBarPolicy
|
||||
mRotationLockController.addCallback(this);
|
||||
mBluetooth.addCallback(this);
|
||||
mProvisionedController.addCallback(this);
|
||||
mCurrentUserSetup = mProvisionedController.isCurrentUserSetup();
|
||||
mZenController.addCallback(this);
|
||||
mCast.addCallback(mCastCallback);
|
||||
mHotspot.addCallback(mHotspotCallback);
|
||||
@@ -562,6 +565,7 @@ public class PhoneStatusBarPolicy
|
||||
mHandler.post(() -> {
|
||||
updateAlarm();
|
||||
updateManagedProfile();
|
||||
onUserSetupChanged();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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<View>(anyInt())).thenReturn(mockView)
|
||||
`when`(view.findViewById<QSCarrierGroup>(R.id.carrier_group)).thenReturn(qsCarrierGroup)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<NextAlarmController.NextAlarmChangeCallback>
|
||||
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user