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:
Matt Pietal
2021-02-11 08:46:10 -05:00
parent ce7bd34723
commit 4c04832725
7 changed files with 265 additions and 70 deletions

View File

@@ -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
}
}

View File

@@ -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() {

View File

@@ -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)
}
}
}

View File

@@ -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();
});
}
/**

View File

@@ -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
)
}
}

View File

@@ -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,

View File

@@ -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
)
}
}
}