Controls Visibility
Start to move controls visibility logic into the ControlsComponent, allowing multiple locations to ask about the state of controls. Bug: 179782498 Test: atest GlobalActionsDialog ControlsComponentTest DeviceControlsTileTest Change-Id: I09ce096c05e8b8826bd7baa479872cc7a2feaad6
This commit is contained in:
@@ -16,10 +16,19 @@
|
||||
|
||||
package com.android.systemui.controls.dagger
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
import android.database.ContentObserver
|
||||
import android.provider.Settings
|
||||
import com.android.systemui.controls.controller.ControlsController
|
||||
import com.android.systemui.controls.management.ControlsListingController
|
||||
import com.android.systemui.controls.ui.ControlsUiController
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.settings.SecureSettings
|
||||
import com.android.internal.widget.LockPatternUtils
|
||||
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
|
||||
import dagger.Lazy
|
||||
import java.util.Optional
|
||||
import javax.inject.Inject
|
||||
@@ -28,15 +37,43 @@ import javax.inject.Inject
|
||||
* Pseudo-component to inject into classes outside `com.android.systemui.controls`.
|
||||
*
|
||||
* If `featureEnabled` is false, all the optionals should be empty. The controllers will only be
|
||||
* instantiated if `featureEnabled` is true.
|
||||
* instantiated if `featureEnabled` is true. Can also be queried for the availability of controls.
|
||||
*/
|
||||
@SysUISingleton
|
||||
class ControlsComponent @Inject constructor(
|
||||
@ControlsFeatureEnabled private val featureEnabled: Boolean,
|
||||
private val context: Context,
|
||||
private val lazyControlsController: Lazy<ControlsController>,
|
||||
private val lazyControlsUiController: Lazy<ControlsUiController>,
|
||||
private val lazyControlsListingController: Lazy<ControlsListingController>
|
||||
private val lazyControlsListingController: Lazy<ControlsListingController>,
|
||||
private val lockPatternUtils: LockPatternUtils,
|
||||
private val keyguardStateController: KeyguardStateController,
|
||||
private val userTracker: UserTracker,
|
||||
private val secureSettings: SecureSettings
|
||||
) {
|
||||
|
||||
private val contentResolver: ContentResolver
|
||||
get() = context.contentResolver
|
||||
|
||||
private var canShowWhileLockedSetting = false
|
||||
|
||||
val showWhileLockedObserver = object : ContentObserver(null) {
|
||||
override fun onChange(selfChange: Boolean) {
|
||||
updateShowWhileLocked()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
if (featureEnabled) {
|
||||
secureSettings.registerContentObserver(
|
||||
Settings.Secure.getUriFor(Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT),
|
||||
false, /* notifyForDescendants */
|
||||
showWhileLockedObserver
|
||||
)
|
||||
updateShowWhileLocked()
|
||||
}
|
||||
}
|
||||
|
||||
fun getControlsController(): Optional<ControlsController> {
|
||||
return if (featureEnabled) Optional.of(lazyControlsController.get()) else Optional.empty()
|
||||
}
|
||||
@@ -52,4 +89,37 @@ class ControlsComponent @Inject constructor(
|
||||
Optional.empty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if controls are feature-enabled and have available services to serve controls
|
||||
*/
|
||||
fun isEnabled() = featureEnabled && lazyControlsController.get().available
|
||||
|
||||
/**
|
||||
* Returns one of 3 states:
|
||||
* * AVAILABLE - Controls can be made visible
|
||||
* * AVAILABLE_AFTER_UNLOCK - Controls can be made visible only after device unlock
|
||||
* * UNAVAILABLE - Controls are not enabled
|
||||
*/
|
||||
fun getVisibility(): Visibility {
|
||||
if (!isEnabled()) return Visibility.UNAVAILABLE
|
||||
if (lockPatternUtils.getStrongAuthForUser(userTracker.userHandle.identifier)
|
||||
== STRONG_AUTH_REQUIRED_AFTER_BOOT) {
|
||||
return Visibility.AVAILABLE_AFTER_UNLOCK
|
||||
}
|
||||
if (!canShowWhileLockedSetting && !keyguardStateController.isUnlocked()) {
|
||||
return Visibility.AVAILABLE_AFTER_UNLOCK
|
||||
}
|
||||
|
||||
return Visibility.AVAILABLE
|
||||
}
|
||||
|
||||
private fun updateShowWhileLocked() {
|
||||
canShowWhileLockedSetting = secureSettings.getInt(
|
||||
Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT, 0) != 0
|
||||
}
|
||||
|
||||
enum class Visibility {
|
||||
AVAILABLE, AVAILABLE_AFTER_UNLOCK, UNAVAILABLE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOM
|
||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
|
||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
|
||||
import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE;
|
||||
import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_GLOBAL_ACTIONS_SHOWING;
|
||||
|
||||
import android.animation.Animator;
|
||||
@@ -250,6 +252,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
private final IWindowManager mIWindowManager;
|
||||
private final Executor mBackgroundExecutor;
|
||||
private List<ControlsServiceInfo> mControlsServiceInfos = new ArrayList<>();
|
||||
private ControlsComponent mControlsComponent;
|
||||
private Optional<ControlsController> mControlsControllerOptional;
|
||||
private final RingerModeTracker mRingerModeTracker;
|
||||
private int mDialogPressDelay = DIALOG_PRESS_DELAY; // ms
|
||||
@@ -338,6 +341,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
mSysuiColorExtractor = colorExtractor;
|
||||
mStatusBarService = statusBarService;
|
||||
mNotificationShadeWindowController = notificationShadeWindowController;
|
||||
mControlsComponent = controlsComponent;
|
||||
mControlsUiControllerOptional = controlsComponent.getControlsUiController();
|
||||
mIWindowManager = iWindowManager;
|
||||
mBackgroundExecutor = backgroundExecutor;
|
||||
@@ -387,7 +391,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
if (mDialog.mWalletViewController != null) {
|
||||
mDialog.mWalletViewController.onDeviceLockStateChanged(!unlocked);
|
||||
}
|
||||
if (!mDialog.isShowingControls() && shouldShowControls()) {
|
||||
if (!mDialog.isShowingControls()
|
||||
&& mControlsComponent.getVisibility() == AVAILABLE) {
|
||||
mDialog.showControls(mControlsUiControllerOptional.get());
|
||||
}
|
||||
if (unlocked) {
|
||||
@@ -397,14 +402,15 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
});
|
||||
|
||||
if (controlsComponent.getControlsListingController().isPresent()) {
|
||||
controlsComponent.getControlsListingController().get()
|
||||
if (mControlsComponent.getControlsListingController().isPresent()) {
|
||||
mControlsComponent.getControlsListingController().get()
|
||||
.addCallback(list -> {
|
||||
mControlsServiceInfos = list;
|
||||
// This callback may occur after the dialog has been shown. If so, add
|
||||
// controls into the already visible space or show the lock msg if needed.
|
||||
if (mDialog != null) {
|
||||
if (!mDialog.isShowingControls() && shouldShowControls()) {
|
||||
if (!mDialog.isShowingControls()
|
||||
&& mControlsComponent.getVisibility() == AVAILABLE) {
|
||||
mDialog.showControls(mControlsUiControllerOptional.get());
|
||||
} else if (shouldShowLockMessage(mDialog)) {
|
||||
mDialog.showLockMessage();
|
||||
@@ -704,7 +710,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
|
||||
mDepthController.setShowingHomeControls(true);
|
||||
ControlsUiController uiController = null;
|
||||
if (mControlsUiControllerOptional.isPresent() && shouldShowControls()) {
|
||||
if (mControlsComponent.getVisibility() == AVAILABLE) {
|
||||
uiController = mControlsUiControllerOptional.get();
|
||||
}
|
||||
ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, mOverflowAdapter,
|
||||
@@ -2687,26 +2693,24 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
return isPanelDebugModeEnabled(context);
|
||||
}
|
||||
|
||||
private boolean shouldShowControls() {
|
||||
boolean showOnLockScreen = mShowLockScreenCardsAndControls && mLockPatternUtils
|
||||
.getStrongAuthForUser(getCurrentUser().id) != STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
||||
return controlsAvailable()
|
||||
&& (mKeyguardStateController.isUnlocked() || showOnLockScreen);
|
||||
}
|
||||
|
||||
private boolean controlsAvailable() {
|
||||
return mDeviceProvisioned
|
||||
&& mControlsUiControllerOptional.isPresent()
|
||||
&& mControlsUiControllerOptional.get().getAvailable()
|
||||
&& mControlsComponent.isEnabled()
|
||||
&& !mControlsServiceInfos.isEmpty();
|
||||
}
|
||||
|
||||
private boolean shouldShowLockMessage(ActionsDialog dialog) {
|
||||
return mControlsComponent.getVisibility() == AVAILABLE_AFTER_UNLOCK
|
||||
|| isWalletAvailableAfterUnlock(dialog);
|
||||
}
|
||||
|
||||
// Temporary while we move items out of the power menu
|
||||
private boolean isWalletAvailableAfterUnlock(ActionsDialog dialog) {
|
||||
boolean isLockedAfterBoot = mLockPatternUtils.getStrongAuthForUser(getCurrentUser().id)
|
||||
== STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
||||
return !mKeyguardStateController.isUnlocked()
|
||||
&& (!mShowLockScreenCardsAndControls || isLockedAfterBoot)
|
||||
&& (controlsAvailable() || dialog.isWalletViewAvailable());
|
||||
&& dialog.isWalletViewAvailable();
|
||||
}
|
||||
|
||||
private void onPowerMenuLockScreenSettingsChanged() {
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.android.internal.logging.MetricsLogger
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.controls.ControlsServiceInfo
|
||||
import com.android.systemui.controls.dagger.ControlsComponent
|
||||
import com.android.systemui.controls.dagger.ControlsComponent.Visibility.UNAVAILABLE
|
||||
import com.android.systemui.controls.management.ControlsListingController
|
||||
import com.android.systemui.controls.ui.ControlsDialog
|
||||
import com.android.systemui.dagger.qualifiers.Background
|
||||
@@ -91,7 +92,7 @@ class DeviceControlsTile @Inject constructor(
|
||||
override fun isAvailable(): Boolean {
|
||||
return featureFlags.isKeyguardLayoutEnabled &&
|
||||
controlsLockscreen &&
|
||||
controlsComponent.getControlsUiController().isPresent
|
||||
controlsComponent.getVisibility() != UNAVAILABLE
|
||||
}
|
||||
|
||||
override fun newTileState(): QSTile.State {
|
||||
@@ -154,4 +155,4 @@ class DeviceControlsTile @Inject constructor(
|
||||
override fun getTileLabel(): CharSequence {
|
||||
return mContext.getText(R.string.quick_controls_title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone;
|
||||
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
|
||||
import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
|
||||
|
||||
import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE;
|
||||
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
|
||||
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
|
||||
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
|
||||
@@ -183,6 +184,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
private ControlsComponent mControlsComponent;
|
||||
private int mLockScreenMode;
|
||||
private BroadcastDispatcher mBroadcastDispatcher;
|
||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
|
||||
public KeyguardBottomAreaView(Context context) {
|
||||
this(context, null);
|
||||
@@ -295,7 +297,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
|
||||
getContext().registerReceiverAsUser(mDevicePolicyReceiver,
|
||||
UserHandle.ALL, filter, null, null);
|
||||
Dependency.get(KeyguardUpdateMonitor.class).registerCallback(mUpdateMonitorCallback);
|
||||
mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
|
||||
mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
|
||||
mKeyguardStateController.addCallback(this);
|
||||
}
|
||||
|
||||
@@ -307,7 +310,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
mRightExtension.destroy();
|
||||
mLeftExtension.destroy();
|
||||
getContext().unregisterReceiver(mDevicePolicyReceiver);
|
||||
Dependency.get(KeyguardUpdateMonitor.class).removeCallback(mUpdateMonitorCallback);
|
||||
mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
|
||||
}
|
||||
|
||||
private void initAccessibility() {
|
||||
@@ -410,12 +413,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
}
|
||||
|
||||
private void updateLeftAffordanceIcon() {
|
||||
if (mDozing) {
|
||||
mAltLeftButton.setVisibility(GONE);
|
||||
} else if (mAltLeftButton.getDrawable() != null) {
|
||||
mAltLeftButton.setVisibility(VISIBLE);
|
||||
}
|
||||
|
||||
if (!mShowLeftAffordance || mDozing) {
|
||||
mLeftAffordanceView.setVisibility(GONE);
|
||||
return;
|
||||
@@ -430,6 +427,14 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
mLeftAffordanceView.setContentDescription(state.contentDescription);
|
||||
}
|
||||
|
||||
private void updateControlsVisibility() {
|
||||
if (mDozing || mControlsComponent.getVisibility() != AVAILABLE) {
|
||||
mAltLeftButton.setVisibility(GONE);
|
||||
} else {
|
||||
mAltLeftButton.setVisibility(VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isLeftVoiceAssist() {
|
||||
return mLeftIsVoiceAssist;
|
||||
}
|
||||
@@ -769,6 +774,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
|
||||
updateCameraVisibility();
|
||||
updateLeftAffordanceIcon();
|
||||
updateControlsVisibility();
|
||||
|
||||
if (dozing) {
|
||||
mOverlayContainer.setVisibility(INVISIBLE);
|
||||
@@ -889,35 +895,27 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
|
||||
}
|
||||
|
||||
private void setupControls() {
|
||||
if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL) {
|
||||
boolean inNewLayout = mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
|
||||
boolean settingEnabled = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
"controls_lockscreen", 0) == 1;
|
||||
if (!inNewLayout || !settingEnabled || !mControlsComponent.isEnabled()) {
|
||||
mAltLeftButton.setVisibility(View.GONE);
|
||||
mAltLeftButton.setOnClickListener(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.Global.getInt(mContext.getContentResolver(), "controls_lockscreen", 0) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mControlsComponent.getControlsListingController().isPresent()) {
|
||||
mControlsComponent.getControlsListingController().get()
|
||||
.addCallback(list -> {
|
||||
if (!list.isEmpty()) {
|
||||
mAltLeftButton.setImageDrawable(list.get(0).loadIcon());
|
||||
mAltLeftButton.setVisibility(View.VISIBLE);
|
||||
mAltLeftButton.setOnClickListener((v) -> {
|
||||
ControlsUiController ui = mControlsComponent
|
||||
.getControlsUiController().get();
|
||||
mControlsDialog = new ControlsDialog(mContext, mBroadcastDispatcher)
|
||||
.show(ui);
|
||||
});
|
||||
|
||||
} else {
|
||||
mAltLeftButton.setVisibility(View.GONE);
|
||||
mAltLeftButton.setOnClickListener(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
mControlsComponent.getControlsListingController().get()
|
||||
.addCallback(list -> {
|
||||
if (!list.isEmpty()) {
|
||||
mAltLeftButton.setImageDrawable(list.get(0).loadIcon());
|
||||
mAltLeftButton.setOnClickListener((v) -> {
|
||||
ControlsUiController ui = mControlsComponent
|
||||
.getControlsUiController().get();
|
||||
mControlsDialog = new ControlsDialog(mContext, mBroadcastDispatcher)
|
||||
.show(ui);
|
||||
});
|
||||
}
|
||||
updateControlsVisibility();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,11 +17,18 @@
|
||||
package com.android.systemui.controls.dagger
|
||||
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.provider.Settings
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.internal.widget.LockPatternUtils
|
||||
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
|
||||
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.controls.controller.ControlsController
|
||||
import com.android.systemui.controls.management.ControlsListingController
|
||||
import com.android.systemui.controls.ui.ControlsUiController
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.settings.SecureSettings
|
||||
import dagger.Lazy
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
@@ -29,7 +36,11 @@ import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Answers
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.anyInt
|
||||
import org.mockito.Mockito.`when`
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@@ -42,20 +53,29 @@ class ControlsComponentTest : SysuiTestCase() {
|
||||
private lateinit var uiController: ControlsUiController
|
||||
@Mock
|
||||
private lateinit var listingController: ControlsListingController
|
||||
@Mock
|
||||
private lateinit var keyguardStateController: KeyguardStateController
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private lateinit var userTracker: UserTracker
|
||||
@Mock
|
||||
private lateinit var lockPatternUtils: LockPatternUtils
|
||||
@Mock
|
||||
private lateinit var secureSettings: SecureSettings
|
||||
|
||||
companion object {
|
||||
fun <T> eq(value: T): T = Mockito.eq(value) ?: value
|
||||
}
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
`when`(userTracker.userHandle.identifier).thenReturn(0)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFeatureEnabled() {
|
||||
val component = ControlsComponent(
|
||||
true,
|
||||
Lazy { controller },
|
||||
Lazy { uiController },
|
||||
Lazy { listingController }
|
||||
)
|
||||
val component = setupComponent(true)
|
||||
|
||||
assertTrue(component.getControlsController().isPresent)
|
||||
assertEquals(controller, component.getControlsController().get())
|
||||
@@ -67,15 +87,80 @@ class ControlsComponentTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun testFeatureDisabled() {
|
||||
val component = ControlsComponent(
|
||||
false,
|
||||
Lazy { controller },
|
||||
Lazy { uiController },
|
||||
Lazy { listingController }
|
||||
)
|
||||
val component = setupComponent(false)
|
||||
|
||||
assertFalse(component.getControlsController().isPresent)
|
||||
assertFalse(component.getControlsUiController().isPresent)
|
||||
assertFalse(component.getControlsListingController().isPresent)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFeatureDisabledVisibility() {
|
||||
val component = setupComponent(false)
|
||||
|
||||
assertEquals(ControlsComponent.Visibility.UNAVAILABLE, component.getVisibility())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFeatureEnabledAfterBootVisibility() {
|
||||
`when`(controller.available).thenReturn(true)
|
||||
`when`(lockPatternUtils.getStrongAuthForUser(anyInt()))
|
||||
.thenReturn(STRONG_AUTH_REQUIRED_AFTER_BOOT)
|
||||
val component = setupComponent(true)
|
||||
|
||||
assertEquals(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK, component.getVisibility())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFeatureEnabledAndCannotShowOnLockScreenVisibility() {
|
||||
`when`(controller.available).thenReturn(true)
|
||||
`when`(lockPatternUtils.getStrongAuthForUser(anyInt()))
|
||||
.thenReturn(STRONG_AUTH_NOT_REQUIRED)
|
||||
`when`(keyguardStateController.isUnlocked()).thenReturn(false)
|
||||
`when`(secureSettings.getInt(eq(Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT), anyInt()))
|
||||
.thenReturn(0)
|
||||
val component = setupComponent(true)
|
||||
|
||||
assertEquals(ControlsComponent.Visibility.AVAILABLE_AFTER_UNLOCK, component.getVisibility())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFeatureEnabledAndCanShowOnLockScreenVisibility() {
|
||||
`when`(controller.available).thenReturn(true)
|
||||
`when`(lockPatternUtils.getStrongAuthForUser(anyInt()))
|
||||
.thenReturn(STRONG_AUTH_NOT_REQUIRED)
|
||||
`when`(keyguardStateController.isUnlocked()).thenReturn(false)
|
||||
`when`(secureSettings.getInt(eq(Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT), anyInt()))
|
||||
.thenReturn(1)
|
||||
val component = setupComponent(true)
|
||||
|
||||
assertEquals(ControlsComponent.Visibility.AVAILABLE, component.getVisibility())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testFeatureEnabledAndCanShowWhileUnlockedVisibility() {
|
||||
`when`(secureSettings.getInt(eq(Settings.Secure.POWER_MENU_LOCKED_SHOW_CONTENT), anyInt()))
|
||||
.thenReturn(0)
|
||||
`when`(controller.available).thenReturn(true)
|
||||
`when`(lockPatternUtils.getStrongAuthForUser(anyInt()))
|
||||
.thenReturn(STRONG_AUTH_NOT_REQUIRED)
|
||||
`when`(keyguardStateController.isUnlocked()).thenReturn(true)
|
||||
val component = setupComponent(true)
|
||||
|
||||
assertEquals(ControlsComponent.Visibility.AVAILABLE, component.getVisibility())
|
||||
}
|
||||
|
||||
private fun setupComponent(enabled: Boolean): ControlsComponent {
|
||||
return ControlsComponent(
|
||||
enabled,
|
||||
mContext,
|
||||
Lazy { controller },
|
||||
Lazy { uiController },
|
||||
Lazy { listingController },
|
||||
lockPatternUtils,
|
||||
keyguardStateController,
|
||||
userTracker,
|
||||
secureSettings
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,12 +74,14 @@ import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.plugins.GlobalActions;
|
||||
import com.android.systemui.plugins.GlobalActionsPanelPlugin;
|
||||
import com.android.systemui.settings.UserContextProvider;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.NotificationShadeDepthController;
|
||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.util.RingerModeLiveData;
|
||||
import com.android.systemui.util.RingerModeTracker;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -135,6 +137,8 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
|
||||
@Mock GlobalActionsPanelPlugin.PanelViewController mWalletController;
|
||||
@Mock private Handler mHandler;
|
||||
@Mock private UserContextProvider mUserContextProvider;
|
||||
@Mock private UserTracker mUserTracker;
|
||||
@Mock private SecureSettings mSecureSettings;
|
||||
private ControlsComponent mControlsComponent;
|
||||
|
||||
private TestableLooper mTestableLooper;
|
||||
@@ -149,9 +153,14 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
|
||||
when(mUserContextProvider.getUserContext()).thenReturn(mContext);
|
||||
mControlsComponent = new ControlsComponent(
|
||||
true,
|
||||
mContext,
|
||||
() -> mControlsController,
|
||||
() -> mControlsUiController,
|
||||
() -> mControlsListingController
|
||||
() -> mControlsListingController,
|
||||
mLockPatternUtils,
|
||||
mKeyguardStateController,
|
||||
mUserTracker,
|
||||
mSecureSettings
|
||||
);
|
||||
|
||||
mGlobalActionsDialog = new GlobalActionsDialog(mContext,
|
||||
|
||||
@@ -25,6 +25,7 @@ import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.internal.logging.MetricsLogger
|
||||
import com.android.internal.logging.UiEventLogger
|
||||
import com.android.internal.widget.LockPatternUtils
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.controls.ControlsServiceInfo
|
||||
import com.android.systemui.controls.controller.ControlsController
|
||||
@@ -36,15 +37,19 @@ import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.qs.QSHost
|
||||
import com.android.systemui.qs.logging.QSLogger
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.statusbar.FeatureFlags
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.capture
|
||||
import com.android.systemui.util.settings.FakeSettings
|
||||
import com.android.systemui.util.settings.GlobalSettings
|
||||
import com.android.systemui.util.settings.SecureSettings
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
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
|
||||
@@ -91,6 +96,15 @@ class DeviceControlsTileTest : SysuiTestCase() {
|
||||
private lateinit var testableLooper: TestableLooper
|
||||
private lateinit var tile: DeviceControlsTile
|
||||
|
||||
@Mock
|
||||
private lateinit var keyguardStateController: KeyguardStateController
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private lateinit var userTracker: UserTracker
|
||||
@Mock
|
||||
private lateinit var lockPatternUtils: LockPatternUtils
|
||||
@Mock
|
||||
private lateinit var secureSettings: SecureSettings
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
@@ -101,9 +115,14 @@ class DeviceControlsTileTest : SysuiTestCase() {
|
||||
|
||||
controlsComponent = ControlsComponent(
|
||||
true,
|
||||
mContext,
|
||||
{ controlsController },
|
||||
{ controlsUiController },
|
||||
{ controlsListingController }
|
||||
{ controlsListingController },
|
||||
lockPatternUtils,
|
||||
keyguardStateController,
|
||||
userTracker,
|
||||
secureSettings
|
||||
)
|
||||
|
||||
globalSettings = FakeSettings()
|
||||
@@ -111,16 +130,20 @@ class DeviceControlsTileTest : SysuiTestCase() {
|
||||
globalSettings.putInt(DeviceControlsTile.SETTINGS_FLAG, 1)
|
||||
`when`(featureFlags.isKeyguardLayoutEnabled).thenReturn(true)
|
||||
|
||||
`when`(userTracker.userHandle.identifier).thenReturn(0)
|
||||
|
||||
tile = createTile()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAvailable() {
|
||||
`when`(controlsController.available).thenReturn(true)
|
||||
assertThat(tile.isAvailable).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNotAvailableFeature() {
|
||||
`when`(controlsController.available).thenReturn(true)
|
||||
`when`(featureFlags.isKeyguardLayoutEnabled).thenReturn(false)
|
||||
|
||||
assertThat(tile.isAvailable).isFalse()
|
||||
@@ -130,9 +153,14 @@ class DeviceControlsTileTest : SysuiTestCase() {
|
||||
fun testNotAvailableControls() {
|
||||
controlsComponent = ControlsComponent(
|
||||
false,
|
||||
mContext,
|
||||
{ controlsController },
|
||||
{ controlsUiController },
|
||||
{ controlsListingController }
|
||||
{ controlsListingController },
|
||||
lockPatternUtils,
|
||||
keyguardStateController,
|
||||
userTracker,
|
||||
secureSettings
|
||||
)
|
||||
tile = createTile()
|
||||
|
||||
@@ -264,4 +292,4 @@ class DeviceControlsTileTest : SysuiTestCase() {
|
||||
globalSettings
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user