Merge "Hide views on lockscreen when wallpaper dream is active" into udc-qpr-dev
This commit is contained in:
@@ -21,6 +21,8 @@ import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
|
||||
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
|
||||
import static com.android.keyguard.KeyguardClockSwitch.SMALL;
|
||||
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
|
||||
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.database.ContentObserver;
|
||||
@@ -33,12 +35,15 @@ import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
|
||||
import com.android.systemui.log.LogBuffer;
|
||||
import com.android.systemui.log.core.LogLevel;
|
||||
import com.android.systemui.log.dagger.KeyguardClockLog;
|
||||
@@ -58,6 +63,7 @@ import com.android.systemui.util.settings.SecureSettings;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Locale;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@@ -99,8 +105,20 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
||||
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
||||
|
||||
private boolean mOnlyClock = false;
|
||||
private boolean mIsActiveDreamLockscreenHosted = false;
|
||||
private FeatureFlags mFeatureFlags;
|
||||
private KeyguardInteractor mKeyguardInteractor;
|
||||
private final DelayableExecutor mUiExecutor;
|
||||
private boolean mCanShowDoubleLineClock = true;
|
||||
@VisibleForTesting
|
||||
final Consumer<Boolean> mIsActiveDreamLockscreenHostedCallback =
|
||||
(Boolean isLockscreenHosted) -> {
|
||||
if (mIsActiveDreamLockscreenHosted == isLockscreenHosted) {
|
||||
return;
|
||||
}
|
||||
mIsActiveDreamLockscreenHosted = isLockscreenHosted;
|
||||
updateKeyguardStatusAreaVisibility();
|
||||
};
|
||||
private final ContentObserver mDoubleLineClockObserver = new ContentObserver(null) {
|
||||
@Override
|
||||
public void onChange(boolean change) {
|
||||
@@ -137,7 +155,9 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
||||
@Main DelayableExecutor uiExecutor,
|
||||
DumpManager dumpManager,
|
||||
ClockEventController clockEventController,
|
||||
@KeyguardClockLog LogBuffer logBuffer) {
|
||||
@KeyguardClockLog LogBuffer logBuffer,
|
||||
KeyguardInteractor keyguardInteractor,
|
||||
FeatureFlags featureFlags) {
|
||||
super(keyguardClockSwitch);
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
mClockRegistry = clockRegistry;
|
||||
@@ -151,6 +171,8 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
||||
mClockEventController = clockEventController;
|
||||
mLogBuffer = logBuffer;
|
||||
mView.setLogBuffer(mLogBuffer);
|
||||
mFeatureFlags = featureFlags;
|
||||
mKeyguardInteractor = keyguardInteractor;
|
||||
|
||||
mClockChangedListener = new ClockRegistry.ClockChangeListener() {
|
||||
@Override
|
||||
@@ -191,6 +213,12 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
||||
|
||||
mDumpManager.unregisterDumpable(getClass().toString()); // unregister previous clocks
|
||||
mDumpManager.registerDumpable(getClass().toString(), this);
|
||||
|
||||
if (mFeatureFlags.isEnabled(LOCKSCREEN_WALLPAPER_DREAM_ENABLED)) {
|
||||
mStatusArea = mView.findViewById(R.id.keyguard_status_area);
|
||||
collectFlow(mStatusArea, mKeyguardInteractor.isActiveDreamLockscreenHosted(),
|
||||
mIsActiveDreamLockscreenHostedCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -524,6 +552,15 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS
|
||||
}
|
||||
}
|
||||
|
||||
private void updateKeyguardStatusAreaVisibility() {
|
||||
if (mStatusArea != null) {
|
||||
mUiExecutor.execute(() -> {
|
||||
mStatusArea.setVisibility(
|
||||
mIsActiveDreamLockscreenHosted ? View.INVISIBLE : View.VISIBLE);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the clipChildren property on relevant views, to allow the smartspace to draw out of
|
||||
* bounds during the unlock transition.
|
||||
|
||||
@@ -24,6 +24,7 @@ import static com.android.keyguard.LockIconView.ICON_LOCK;
|
||||
import static com.android.keyguard.LockIconView.ICON_UNLOCK;
|
||||
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
|
||||
import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1;
|
||||
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
|
||||
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
|
||||
|
||||
import android.content.res.Configuration;
|
||||
@@ -124,6 +125,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
||||
private int mActivePointerId = -1;
|
||||
|
||||
private boolean mIsDozing;
|
||||
private boolean mIsActiveDreamLockscreenHosted;
|
||||
private boolean mIsBouncerShowing;
|
||||
private boolean mRunningFPS;
|
||||
private boolean mCanDismissLockScreen;
|
||||
@@ -165,6 +167,13 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
||||
updateVisibility();
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
final Consumer<Boolean> mIsActiveDreamLockscreenHostedCallback =
|
||||
(Boolean isLockscreenHosted) -> {
|
||||
mIsActiveDreamLockscreenHosted = isLockscreenHosted;
|
||||
updateVisibility();
|
||||
};
|
||||
|
||||
@Inject
|
||||
public LockIconViewController(
|
||||
@Nullable LockIconView view,
|
||||
@@ -224,6 +233,11 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
||||
mDozeTransitionCallback);
|
||||
collectFlow(mView, mKeyguardInteractor.isDozing(), mIsDozingCallback);
|
||||
}
|
||||
|
||||
if (mFeatureFlags.isEnabled(LOCKSCREEN_WALLPAPER_DREAM_ENABLED)) {
|
||||
collectFlow(mView, mKeyguardInteractor.isActiveDreamLockscreenHosted(),
|
||||
mIsActiveDreamLockscreenHostedCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -289,6 +303,11 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIsKeyguardShowing && mIsActiveDreamLockscreenHosted) {
|
||||
mView.setVisibility(View.INVISIBLE);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean wasShowingFpIcon = mUdfpsEnrolled && !mShowUnlockIcon && !mShowLockIcon
|
||||
&& !mShowAodUnlockedIcon && !mShowAodLockIcon;
|
||||
mShowLockIcon = !mCanDismissLockScreen && isLockScreen()
|
||||
@@ -436,6 +455,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
|
||||
pw.println(" mInterpolatedDarkAmount: " + mInterpolatedDarkAmount);
|
||||
pw.println(" mSensorTouchLocation: " + mSensorTouchLocation);
|
||||
pw.println(" mDefaultPaddingPx: " + mDefaultPaddingPx);
|
||||
pw.println(" mIsActiveDreamLockscreenHosted: " + mIsActiveDreamLockscreenHosted);
|
||||
|
||||
if (mView != null) {
|
||||
mView.dump(pw, args);
|
||||
|
||||
@@ -29,6 +29,7 @@ import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT
|
||||
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
|
||||
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED;
|
||||
import static com.android.systemui.DejankUtils.whitelistIpcs;
|
||||
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.IMPORTANT_MSG_MIN_DURATION;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
|
||||
@@ -43,6 +44,7 @@ import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewCont
|
||||
import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON;
|
||||
import static com.android.systemui.log.core.LogLevel.ERROR;
|
||||
import static com.android.systemui.plugins.FalsingManager.LOW_PENALTY;
|
||||
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
@@ -96,6 +98,7 @@ import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.keyguard.KeyguardIndication;
|
||||
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
|
||||
import com.android.systemui.keyguard.util.IndicationHelper;
|
||||
import com.android.systemui.log.core.LogLevel;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
@@ -114,6 +117,7 @@ import java.io.PrintWriter;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@@ -171,7 +175,7 @@ public class KeyguardIndicationController {
|
||||
public KeyguardIndicationRotateTextViewController mRotateTextViewController;
|
||||
private BroadcastReceiver mBroadcastReceiver;
|
||||
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||
|
||||
private KeyguardInteractor mKeyguardInteractor;
|
||||
private String mPersistentUnlockMessage;
|
||||
private String mAlignmentIndication;
|
||||
private CharSequence mTrustGrantedIndication;
|
||||
@@ -205,7 +209,17 @@ public class KeyguardIndicationController {
|
||||
private KeyguardUpdateMonitorCallback mUpdateMonitorCallback;
|
||||
|
||||
private boolean mDozing;
|
||||
private boolean mIsActiveDreamLockscreenHosted;
|
||||
private final ScreenLifecycle mScreenLifecycle;
|
||||
@VisibleForTesting
|
||||
final Consumer<Boolean> mIsActiveDreamLockscreenHostedCallback =
|
||||
(Boolean isLockscreenHosted) -> {
|
||||
if (mIsActiveDreamLockscreenHosted == isLockscreenHosted) {
|
||||
return;
|
||||
}
|
||||
mIsActiveDreamLockscreenHosted = isLockscreenHosted;
|
||||
updateDeviceEntryIndication(false);
|
||||
};
|
||||
private final ScreenLifecycle.Observer mScreenObserver =
|
||||
new ScreenLifecycle.Observer() {
|
||||
@Override
|
||||
@@ -261,7 +275,8 @@ public class KeyguardIndicationController {
|
||||
UserTracker userTracker,
|
||||
BouncerMessageInteractor bouncerMessageInteractor,
|
||||
FeatureFlags flags,
|
||||
IndicationHelper indicationHelper
|
||||
IndicationHelper indicationHelper,
|
||||
KeyguardInteractor keyguardInteractor
|
||||
) {
|
||||
mContext = context;
|
||||
mBroadcastDispatcher = broadcastDispatcher;
|
||||
@@ -289,6 +304,7 @@ public class KeyguardIndicationController {
|
||||
mBouncerMessageInteractor = bouncerMessageInteractor;
|
||||
mFeatureFlags = flags;
|
||||
mIndicationHelper = indicationHelper;
|
||||
mKeyguardInteractor = keyguardInteractor;
|
||||
|
||||
mFaceAcquiredMessageDeferral = faceHelpMessageDeferral;
|
||||
mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>();
|
||||
@@ -371,6 +387,10 @@ public class KeyguardIndicationController {
|
||||
intentFilter.addAction(Intent.ACTION_USER_REMOVED);
|
||||
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, intentFilter);
|
||||
}
|
||||
if (mFeatureFlags.isEnabled(LOCKSCREEN_WALLPAPER_DREAM_ENABLED)) {
|
||||
collectFlow(mIndicationArea, mKeyguardInteractor.isActiveDreamLockscreenHosted(),
|
||||
mIsActiveDreamLockscreenHostedCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -878,6 +898,12 @@ public class KeyguardIndicationController {
|
||||
return;
|
||||
}
|
||||
|
||||
// Device is dreaming and the dream is hosted in lockscreen
|
||||
if (mIsActiveDreamLockscreenHosted) {
|
||||
mIndicationArea.setVisibility(GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
// A few places might need to hide the indication, so always start by making it visible
|
||||
mIndicationArea.setVisibility(VISIBLE);
|
||||
|
||||
@@ -1069,6 +1095,7 @@ public class KeyguardIndicationController {
|
||||
pw.println(" mBiometricMessageFollowUp: " + mBiometricMessageFollowUp);
|
||||
pw.println(" mBatteryLevel: " + mBatteryLevel);
|
||||
pw.println(" mBatteryPresent: " + mBatteryPresent);
|
||||
pw.println(" mIsActiveDreamLockscreenHosted: " + mIsActiveDreamLockscreenHosted);
|
||||
pw.println(" AOD text: " + (
|
||||
mTopIndicationView == null ? null : mTopIndicationView.getText()));
|
||||
pw.println(" computePowerIndication(): " + computePowerIndication());
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.keyguard;
|
||||
|
||||
import static android.view.View.INVISIBLE;
|
||||
|
||||
import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
|
||||
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.atLeast;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.flags.FakeFeatureFlags;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
|
||||
import com.android.systemui.log.LogBuffer;
|
||||
import com.android.systemui.plugins.ClockAnimations;
|
||||
import com.android.systemui.plugins.ClockController;
|
||||
import com.android.systemui.plugins.ClockEvents;
|
||||
import com.android.systemui.plugins.ClockFaceConfig;
|
||||
import com.android.systemui.plugins.ClockFaceController;
|
||||
import com.android.systemui.plugins.ClockFaceEvents;
|
||||
import com.android.systemui.plugins.ClockTickRate;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.shared.clocks.AnimatableClockView;
|
||||
import com.android.systemui.shared.clocks.ClockRegistry;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
|
||||
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
|
||||
import com.android.systemui.statusbar.phone.NotificationIconContainer;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
public class KeyguardClockSwitchControllerBaseTest extends SysuiTestCase {
|
||||
|
||||
@Mock
|
||||
protected KeyguardClockSwitch mView;
|
||||
@Mock
|
||||
protected StatusBarStateController mStatusBarStateController;
|
||||
@Mock
|
||||
protected ClockRegistry mClockRegistry;
|
||||
@Mock
|
||||
KeyguardSliceViewController mKeyguardSliceViewController;
|
||||
@Mock
|
||||
NotificationIconAreaController mNotificationIconAreaController;
|
||||
@Mock
|
||||
LockscreenSmartspaceController mSmartspaceController;
|
||||
|
||||
@Mock
|
||||
Resources mResources;
|
||||
@Mock
|
||||
KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
||||
@Mock
|
||||
protected ClockController mClockController;
|
||||
@Mock
|
||||
protected ClockFaceController mLargeClockController;
|
||||
@Mock
|
||||
protected ClockFaceController mSmallClockController;
|
||||
@Mock
|
||||
protected ClockAnimations mClockAnimations;
|
||||
@Mock
|
||||
protected ClockEvents mClockEvents;
|
||||
@Mock
|
||||
protected ClockFaceEvents mClockFaceEvents;
|
||||
@Mock
|
||||
DumpManager mDumpManager;
|
||||
@Mock
|
||||
ClockEventController mClockEventController;
|
||||
|
||||
@Mock
|
||||
protected NotificationIconContainer mNotificationIcons;
|
||||
@Mock
|
||||
protected AnimatableClockView mSmallClockView;
|
||||
@Mock
|
||||
protected AnimatableClockView mLargeClockView;
|
||||
@Mock
|
||||
protected FrameLayout mSmallClockFrame;
|
||||
@Mock
|
||||
protected FrameLayout mLargeClockFrame;
|
||||
@Mock
|
||||
protected SecureSettings mSecureSettings;
|
||||
@Mock
|
||||
protected LogBuffer mLogBuffer;
|
||||
|
||||
protected final View mFakeDateView = (View) (new ViewGroup(mContext) {
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {}
|
||||
});
|
||||
protected final View mFakeWeatherView = new View(mContext);
|
||||
protected final View mFakeSmartspaceView = new View(mContext);
|
||||
|
||||
protected KeyguardClockSwitchController mController;
|
||||
protected View mSliceView;
|
||||
protected LinearLayout mStatusArea;
|
||||
protected FakeExecutor mExecutor;
|
||||
protected FakeFeatureFlags mFakeFeatureFlags;
|
||||
@Captor protected ArgumentCaptor<View.OnAttachStateChangeListener> mAttachCaptor =
|
||||
ArgumentCaptor.forClass(View.OnAttachStateChangeListener.class);
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
when(mView.findViewById(R.id.left_aligned_notification_icon_container))
|
||||
.thenReturn(mNotificationIcons);
|
||||
when(mNotificationIcons.getLayoutParams()).thenReturn(
|
||||
mock(RelativeLayout.LayoutParams.class));
|
||||
when(mView.getContext()).thenReturn(getContext());
|
||||
when(mView.getResources()).thenReturn(mResources);
|
||||
when(mResources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin))
|
||||
.thenReturn(100);
|
||||
when(mResources.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin))
|
||||
.thenReturn(-200);
|
||||
when(mResources.getInteger(R.integer.keyguard_date_weather_view_invisibility))
|
||||
.thenReturn(INVISIBLE);
|
||||
|
||||
when(mView.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(mLargeClockFrame);
|
||||
when(mView.findViewById(R.id.lockscreen_clock_view)).thenReturn(mSmallClockFrame);
|
||||
when(mSmallClockView.getContext()).thenReturn(getContext());
|
||||
when(mLargeClockView.getContext()).thenReturn(getContext());
|
||||
|
||||
when(mView.isAttachedToWindow()).thenReturn(true);
|
||||
when(mSmartspaceController.buildAndConnectDateView(any())).thenReturn(mFakeDateView);
|
||||
when(mSmartspaceController.buildAndConnectWeatherView(any())).thenReturn(mFakeWeatherView);
|
||||
when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mFakeSmartspaceView);
|
||||
mExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
mFakeFeatureFlags = new FakeFeatureFlags();
|
||||
mFakeFeatureFlags.set(FACE_AUTH_REFACTOR, false);
|
||||
mFakeFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
|
||||
mController = new KeyguardClockSwitchController(
|
||||
mView,
|
||||
mStatusBarStateController,
|
||||
mClockRegistry,
|
||||
mKeyguardSliceViewController,
|
||||
mNotificationIconAreaController,
|
||||
mSmartspaceController,
|
||||
mKeyguardUnlockAnimationController,
|
||||
mSecureSettings,
|
||||
mExecutor,
|
||||
mDumpManager,
|
||||
mClockEventController,
|
||||
mLogBuffer,
|
||||
KeyguardInteractorFactory.create(mFakeFeatureFlags).getKeyguardInteractor(),
|
||||
mFakeFeatureFlags
|
||||
);
|
||||
|
||||
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
|
||||
when(mLargeClockController.getView()).thenReturn(mLargeClockView);
|
||||
when(mSmallClockController.getView()).thenReturn(mSmallClockView);
|
||||
when(mClockController.getLargeClock()).thenReturn(mLargeClockController);
|
||||
when(mClockController.getSmallClock()).thenReturn(mSmallClockController);
|
||||
when(mClockController.getEvents()).thenReturn(mClockEvents);
|
||||
when(mSmallClockController.getEvents()).thenReturn(mClockFaceEvents);
|
||||
when(mLargeClockController.getEvents()).thenReturn(mClockFaceEvents);
|
||||
when(mLargeClockController.getAnimations()).thenReturn(mClockAnimations);
|
||||
when(mSmallClockController.getAnimations()).thenReturn(mClockAnimations);
|
||||
when(mClockRegistry.createCurrentClock()).thenReturn(mClockController);
|
||||
when(mClockEventController.getClock()).thenReturn(mClockController);
|
||||
when(mSmallClockController.getConfig())
|
||||
.thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
|
||||
when(mLargeClockController.getConfig())
|
||||
.thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
|
||||
|
||||
mSliceView = new View(getContext());
|
||||
when(mView.findViewById(R.id.keyguard_slice_view)).thenReturn(mSliceView);
|
||||
mStatusArea = new LinearLayout(getContext());
|
||||
when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(mStatusArea);
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
mController.init();
|
||||
|
||||
verify(mView, atLeast(1)).addOnAttachStateChangeListener(mAttachCaptor.capture());
|
||||
mAttachCaptor.getValue().onViewAttachedToWindow(mView);
|
||||
}
|
||||
}
|
||||
@@ -21,186 +21,33 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.log.LogBuffer;
|
||||
import com.android.systemui.plugins.ClockAnimations;
|
||||
import com.android.systemui.plugins.ClockController;
|
||||
import com.android.systemui.plugins.ClockEvents;
|
||||
import com.android.systemui.plugins.ClockFaceConfig;
|
||||
import com.android.systemui.plugins.ClockFaceController;
|
||||
import com.android.systemui.plugins.ClockFaceEvents;
|
||||
import com.android.systemui.plugins.ClockTickRate;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.shared.clocks.AnimatableClockView;
|
||||
import com.android.systemui.shared.clocks.ClockRegistry;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController;
|
||||
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
|
||||
import com.android.systemui.statusbar.phone.NotificationIconContainer;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.verification.VerificationMode;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class KeyguardClockSwitchControllerTest extends SysuiTestCase {
|
||||
|
||||
@Mock
|
||||
private KeyguardClockSwitch mView;
|
||||
@Mock
|
||||
private StatusBarStateController mStatusBarStateController;
|
||||
@Mock
|
||||
private ClockRegistry mClockRegistry;
|
||||
@Mock
|
||||
KeyguardSliceViewController mKeyguardSliceViewController;
|
||||
@Mock
|
||||
NotificationIconAreaController mNotificationIconAreaController;
|
||||
@Mock
|
||||
LockscreenSmartspaceController mSmartspaceController;
|
||||
|
||||
@Mock
|
||||
Resources mResources;
|
||||
@Mock
|
||||
KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
|
||||
@Mock
|
||||
private ClockController mClockController;
|
||||
@Mock
|
||||
private ClockFaceController mLargeClockController;
|
||||
@Mock
|
||||
private ClockFaceController mSmallClockController;
|
||||
@Mock
|
||||
private ClockAnimations mClockAnimations;
|
||||
@Mock
|
||||
private ClockEvents mClockEvents;
|
||||
@Mock
|
||||
private ClockFaceEvents mClockFaceEvents;
|
||||
@Mock
|
||||
DumpManager mDumpManager;
|
||||
@Mock
|
||||
ClockEventController mClockEventController;
|
||||
|
||||
@Mock
|
||||
private NotificationIconContainer mNotificationIcons;
|
||||
@Mock
|
||||
private AnimatableClockView mSmallClockView;
|
||||
@Mock
|
||||
private AnimatableClockView mLargeClockView;
|
||||
@Mock
|
||||
private FrameLayout mSmallClockFrame;
|
||||
@Mock
|
||||
private FrameLayout mLargeClockFrame;
|
||||
@Mock
|
||||
private SecureSettings mSecureSettings;
|
||||
@Mock
|
||||
private LogBuffer mLogBuffer;
|
||||
|
||||
private final View mFakeDateView = (View) (new ViewGroup(mContext) {
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {}
|
||||
});
|
||||
private final View mFakeWeatherView = new View(mContext);
|
||||
private final View mFakeSmartspaceView = new View(mContext);
|
||||
|
||||
private KeyguardClockSwitchController mController;
|
||||
private View mSliceView;
|
||||
private FakeExecutor mExecutor;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
when(mView.findViewById(R.id.left_aligned_notification_icon_container))
|
||||
.thenReturn(mNotificationIcons);
|
||||
when(mNotificationIcons.getLayoutParams()).thenReturn(
|
||||
mock(RelativeLayout.LayoutParams.class));
|
||||
when(mView.getContext()).thenReturn(getContext());
|
||||
when(mView.getResources()).thenReturn(mResources);
|
||||
when(mResources.getDimensionPixelSize(R.dimen.keyguard_clock_top_margin))
|
||||
.thenReturn(100);
|
||||
when(mResources.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin))
|
||||
.thenReturn(-200);
|
||||
when(mResources.getInteger(R.integer.keyguard_date_weather_view_invisibility))
|
||||
.thenReturn(View.INVISIBLE);
|
||||
|
||||
when(mView.findViewById(R.id.lockscreen_clock_view_large)).thenReturn(mLargeClockFrame);
|
||||
when(mView.findViewById(R.id.lockscreen_clock_view)).thenReturn(mSmallClockFrame);
|
||||
when(mSmallClockView.getContext()).thenReturn(getContext());
|
||||
when(mLargeClockView.getContext()).thenReturn(getContext());
|
||||
|
||||
when(mView.isAttachedToWindow()).thenReturn(true);
|
||||
when(mSmartspaceController.buildAndConnectDateView(any())).thenReturn(mFakeDateView);
|
||||
when(mSmartspaceController.buildAndConnectWeatherView(any())).thenReturn(mFakeWeatherView);
|
||||
when(mSmartspaceController.buildAndConnectView(any())).thenReturn(mFakeSmartspaceView);
|
||||
mExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
mController = new KeyguardClockSwitchController(
|
||||
mView,
|
||||
mStatusBarStateController,
|
||||
mClockRegistry,
|
||||
mKeyguardSliceViewController,
|
||||
mNotificationIconAreaController,
|
||||
mSmartspaceController,
|
||||
mKeyguardUnlockAnimationController,
|
||||
mSecureSettings,
|
||||
mExecutor,
|
||||
mDumpManager,
|
||||
mClockEventController,
|
||||
mLogBuffer
|
||||
);
|
||||
|
||||
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE);
|
||||
when(mLargeClockController.getView()).thenReturn(mLargeClockView);
|
||||
when(mSmallClockController.getView()).thenReturn(mSmallClockView);
|
||||
when(mClockController.getLargeClock()).thenReturn(mLargeClockController);
|
||||
when(mClockController.getSmallClock()).thenReturn(mSmallClockController);
|
||||
when(mClockController.getEvents()).thenReturn(mClockEvents);
|
||||
when(mSmallClockController.getEvents()).thenReturn(mClockFaceEvents);
|
||||
when(mLargeClockController.getEvents()).thenReturn(mClockFaceEvents);
|
||||
when(mLargeClockController.getAnimations()).thenReturn(mClockAnimations);
|
||||
when(mSmallClockController.getAnimations()).thenReturn(mClockAnimations);
|
||||
when(mClockRegistry.createCurrentClock()).thenReturn(mClockController);
|
||||
when(mClockEventController.getClock()).thenReturn(mClockController);
|
||||
when(mSmallClockController.getConfig())
|
||||
.thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
|
||||
when(mLargeClockController.getConfig())
|
||||
.thenReturn(new ClockFaceConfig(ClockTickRate.PER_MINUTE, false, false));
|
||||
|
||||
mSliceView = new View(getContext());
|
||||
when(mView.findViewById(R.id.keyguard_slice_view)).thenReturn(mSliceView);
|
||||
when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(
|
||||
new LinearLayout(getContext()));
|
||||
}
|
||||
|
||||
public class KeyguardClockSwitchControllerTest extends KeyguardClockSwitchControllerBaseTest {
|
||||
@Test
|
||||
public void testInit_viewAlreadyAttached() {
|
||||
mController.init();
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.keyguard
|
||||
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.view.View
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
class KeyguardClockSwitchControllerWithCoroutinesTest : KeyguardClockSwitchControllerBaseTest() {
|
||||
|
||||
@Test
|
||||
fun testStatusAreaVisibility_onLockscreenHostedDreamStateChanged() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
// GIVEN starting state for the keyguard clock and wallpaper dream enabled
|
||||
mFakeFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, true)
|
||||
init()
|
||||
|
||||
// WHEN dreaming starts
|
||||
mController.mIsActiveDreamLockscreenHostedCallback.accept(
|
||||
true /* isActiveDreamLockscreenHosted */
|
||||
)
|
||||
|
||||
// THEN the status area is hidden
|
||||
mExecutor.runAllReady()
|
||||
assertEquals(View.INVISIBLE, mStatusArea.visibility)
|
||||
|
||||
// WHEN dreaming stops
|
||||
mController.mIsActiveDreamLockscreenHostedCallback.accept(
|
||||
false /* isActiveDreamLockscreenHosted */
|
||||
)
|
||||
mExecutor.runAllReady()
|
||||
|
||||
// THEN status area view is visible
|
||||
assertEquals(View.VISIBLE, mStatusArea.visibility)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val IMMEDIATE = Dispatchers.Main.immediate
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package com.android.keyguard;
|
||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
|
||||
import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1;
|
||||
import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
|
||||
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
|
||||
import static com.android.systemui.flags.Flags.MIGRATE_LOCK_ICON;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
@@ -147,6 +148,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
|
||||
mFeatureFlags = new FakeFeatureFlags();
|
||||
mFeatureFlags.set(FACE_AUTH_REFACTOR, false);
|
||||
mFeatureFlags.set(MIGRATE_LOCK_ICON, false);
|
||||
mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
|
||||
mUnderTest = new LockIconViewController(
|
||||
mLockIconView,
|
||||
mStatusBarStateController,
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
package com.android.keyguard
|
||||
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.view.View
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.keyguard.LockIconView.ICON_LOCK
|
||||
import com.android.systemui.doze.util.getBurnInOffset
|
||||
import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
|
||||
import com.android.systemui.keyguard.shared.model.KeyguardState.AOD
|
||||
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
|
||||
import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
|
||||
@@ -117,6 +119,33 @@ class LockIconViewControllerWithCoroutinesTest : LockIconViewControllerBaseTest(
|
||||
verify(mLockIconView).setTranslationX(0f)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHideLockIconView_onLockscreenHostedDreamStateChanged() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
// GIVEN starting state for the lock icon (keyguard) and wallpaper dream enabled
|
||||
mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, true)
|
||||
setupShowLockIcon()
|
||||
init(/* useMigrationFlag= */ true)
|
||||
reset(mLockIconView)
|
||||
|
||||
// WHEN dream starts
|
||||
mUnderTest.mIsActiveDreamLockscreenHostedCallback.accept(
|
||||
true /* isActiveDreamLockscreenHosted */
|
||||
)
|
||||
|
||||
// THEN the lock icon is hidden
|
||||
verify(mLockIconView).visibility = View.INVISIBLE
|
||||
reset(mLockIconView)
|
||||
|
||||
// WHEN the device is no longer dreaming
|
||||
mUnderTest.mIsActiveDreamLockscreenHostedCallback.accept(
|
||||
false /* isActiveDreamLockscreenHosted */
|
||||
)
|
||||
|
||||
// THEN lock icon is visible
|
||||
verify(mLockIconView).visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val IMMEDIATE = Dispatchers.Main.immediate
|
||||
}
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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;
|
||||
|
||||
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
|
||||
|
||||
import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
|
||||
import static com.android.systemui.flags.Flags.KEYGUARD_TALKBACK_FIX;
|
||||
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
|
||||
import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.Instrumentation;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.admin.DevicePolicyResourcesManager;
|
||||
import android.app.trust.TrustManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.Looper;
|
||||
import android.os.UserManager;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
import com.android.internal.app.IBatteryStats;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.keyguard.logging.KeyguardLogger;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.biometrics.AuthController;
|
||||
import com.android.systemui.biometrics.FaceHelpMessageDeferral;
|
||||
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.dock.DockManager;
|
||||
import com.android.systemui.flags.FakeFeatureFlags;
|
||||
import com.android.systemui.keyguard.KeyguardIndication;
|
||||
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
|
||||
import com.android.systemui.keyguard.util.IndicationHelper;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
import com.android.systemui.util.wakelock.WakeLockFake;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
public class KeyguardIndicationControllerBaseTest extends SysuiTestCase {
|
||||
|
||||
protected static final String ORGANIZATION_NAME = "organization";
|
||||
|
||||
protected static final ComponentName DEVICE_OWNER_COMPONENT = new ComponentName(
|
||||
"com.android.foo",
|
||||
"bar");
|
||||
|
||||
protected static final int TEST_STRING_RES = R.string.keyguard_indication_trust_unlocked;
|
||||
|
||||
protected String mDisclosureWithOrganization;
|
||||
protected String mDisclosureGeneric;
|
||||
protected String mFinancedDisclosureWithOrganization;
|
||||
|
||||
@Mock
|
||||
protected DevicePolicyManager mDevicePolicyManager;
|
||||
@Mock
|
||||
protected DevicePolicyResourcesManager mDevicePolicyResourcesManager;
|
||||
@Mock
|
||||
protected ViewGroup mIndicationArea;
|
||||
@Mock
|
||||
protected KeyguardStateController mKeyguardStateController;
|
||||
@Mock
|
||||
protected KeyguardIndicationTextView mIndicationAreaBottom;
|
||||
@Mock
|
||||
protected BroadcastDispatcher mBroadcastDispatcher;
|
||||
@Mock
|
||||
protected StatusBarStateController mStatusBarStateController;
|
||||
@Mock
|
||||
protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
@Mock
|
||||
protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||
@Mock
|
||||
protected UserManager mUserManager;
|
||||
@Mock
|
||||
protected IBatteryStats mIBatteryStats;
|
||||
@Mock
|
||||
protected DockManager mDockManager;
|
||||
@Mock
|
||||
protected KeyguardIndicationRotateTextViewController mRotateTextViewController;
|
||||
@Mock
|
||||
protected FalsingManager mFalsingManager;
|
||||
@Mock
|
||||
protected LockPatternUtils mLockPatternUtils;
|
||||
@Mock
|
||||
protected KeyguardBypassController mKeyguardBypassController;
|
||||
@Mock
|
||||
protected AccessibilityManager mAccessibilityManager;
|
||||
@Mock
|
||||
protected FaceHelpMessageDeferral mFaceHelpMessageDeferral;
|
||||
@Mock
|
||||
protected AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
@Mock
|
||||
protected ScreenLifecycle mScreenLifecycle;
|
||||
@Mock
|
||||
protected AuthController mAuthController;
|
||||
@Mock
|
||||
protected AlarmManager mAlarmManager;
|
||||
@Mock
|
||||
protected UserTracker mUserTracker;
|
||||
@Captor
|
||||
protected ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
|
||||
@Captor
|
||||
protected ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
|
||||
@Captor
|
||||
protected ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
|
||||
@Captor
|
||||
protected ArgumentCaptor<KeyguardIndication> mKeyguardIndicationCaptor;
|
||||
@Captor
|
||||
protected ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
|
||||
@Captor
|
||||
protected ArgumentCaptor<KeyguardStateController.Callback>
|
||||
mKeyguardStateControllerCallbackCaptor;
|
||||
@Captor
|
||||
protected ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
|
||||
protected KeyguardStateController.Callback mKeyguardStateControllerCallback;
|
||||
protected KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback;
|
||||
protected StatusBarStateController.StateListener mStatusBarStateListener;
|
||||
protected ScreenLifecycle.Observer mScreenObserver;
|
||||
protected BroadcastReceiver mBroadcastReceiver;
|
||||
protected IndicationHelper mIndicationHelper;
|
||||
protected FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
protected TestableLooper mTestableLooper;
|
||||
protected final int mCurrentUserId = 1;
|
||||
|
||||
protected KeyguardIndicationTextView mTextView; // AOD text
|
||||
|
||||
protected KeyguardIndicationController mController;
|
||||
protected WakeLockFake.Builder mWakeLockBuilder;
|
||||
protected WakeLockFake mWakeLock;
|
||||
protected Instrumentation mInstrumentation;
|
||||
protected FakeFeatureFlags mFlags;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
mTestableLooper = TestableLooper.get(this);
|
||||
mTextView = new KeyguardIndicationTextView(mContext);
|
||||
mTextView.setAnimationsEnabled(false);
|
||||
|
||||
// TODO(b/259908270): remove
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
|
||||
DevicePolicyManager.ADD_ISFINANCED_DEVICE_FLAG, "true",
|
||||
/* makeDefault= */ false);
|
||||
mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
|
||||
mContext.addMockSystemService(UserManager.class, mUserManager);
|
||||
mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
|
||||
mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
|
||||
mDisclosureWithOrganization = mContext.getString(R.string.do_disclosure_with_name,
|
||||
ORGANIZATION_NAME);
|
||||
mDisclosureGeneric = mContext.getString(R.string.do_disclosure_generic);
|
||||
mFinancedDisclosureWithOrganization = mContext.getString(
|
||||
R.string.do_financed_disclosure_with_name, ORGANIZATION_NAME);
|
||||
|
||||
when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
||||
when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_ON);
|
||||
when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
|
||||
|
||||
when(mIndicationArea.findViewById(R.id.keyguard_indication_text_bottom))
|
||||
.thenReturn(mIndicationAreaBottom);
|
||||
when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView);
|
||||
|
||||
when(mDevicePolicyManager.getResources()).thenReturn(mDevicePolicyResourcesManager);
|
||||
when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser())
|
||||
.thenReturn(DEVICE_OWNER_COMPONENT);
|
||||
when(mDevicePolicyManager.isFinancedDevice()).thenReturn(false);
|
||||
// TODO(b/259908270): remove
|
||||
when(mDevicePolicyManager.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
|
||||
.thenReturn(DEVICE_OWNER_TYPE_DEFAULT);
|
||||
|
||||
when(mDevicePolicyResourcesManager.getString(anyString(), any()))
|
||||
.thenReturn(mDisclosureGeneric);
|
||||
when(mDevicePolicyResourcesManager.getString(anyString(), any(), anyString()))
|
||||
.thenReturn(mDisclosureWithOrganization);
|
||||
when(mUserTracker.getUserId()).thenReturn(mCurrentUserId);
|
||||
|
||||
mIndicationHelper = new IndicationHelper(mKeyguardUpdateMonitor);
|
||||
|
||||
mWakeLock = new WakeLockFake();
|
||||
mWakeLockBuilder = new WakeLockFake.Builder(mContext);
|
||||
mWakeLockBuilder.setWakeLock(mWakeLock);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
mTextView.setAnimationsEnabled(true);
|
||||
if (mController != null) {
|
||||
mController.destroy();
|
||||
mController = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected void createController() {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
|
||||
mFlags = new FakeFeatureFlags();
|
||||
mFlags.set(KEYGUARD_TALKBACK_FIX, true);
|
||||
mFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false);
|
||||
mFlags.set(FACE_AUTH_REFACTOR, false);
|
||||
mController = new KeyguardIndicationController(
|
||||
mContext,
|
||||
mTestableLooper.getLooper(),
|
||||
mWakeLockBuilder,
|
||||
mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
|
||||
mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
|
||||
mUserManager, mExecutor, mExecutor, mFalsingManager,
|
||||
mAuthController, mLockPatternUtils, mScreenLifecycle,
|
||||
mKeyguardBypassController, mAccessibilityManager,
|
||||
mFaceHelpMessageDeferral, mock(KeyguardLogger.class),
|
||||
mAlternateBouncerInteractor,
|
||||
mAlarmManager,
|
||||
mUserTracker,
|
||||
mock(BouncerMessageInteractor.class),
|
||||
mFlags,
|
||||
mIndicationHelper,
|
||||
KeyguardInteractorFactory.create(mFlags).getKeyguardInteractor()
|
||||
);
|
||||
mController.init();
|
||||
mController.setIndicationArea(mIndicationArea);
|
||||
verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
|
||||
mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
|
||||
verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(), any());
|
||||
mBroadcastReceiver = mBroadcastReceiverCaptor.getValue();
|
||||
mController.mRotateTextViewController = mRotateTextViewController;
|
||||
mController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
|
||||
clearInvocations(mIBatteryStats);
|
||||
|
||||
verify(mKeyguardStateController).addCallback(
|
||||
mKeyguardStateControllerCallbackCaptor.capture());
|
||||
mKeyguardStateControllerCallback = mKeyguardStateControllerCallbackCaptor.getValue();
|
||||
|
||||
verify(mKeyguardUpdateMonitor).registerCallback(
|
||||
mKeyguardUpdateMonitorCallbackCaptor.capture());
|
||||
mKeyguardUpdateMonitorCallback = mKeyguardUpdateMonitorCallbackCaptor.getValue();
|
||||
|
||||
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
|
||||
mScreenObserver = mScreenObserverCaptor.getValue();
|
||||
|
||||
mExecutor.runAllReady();
|
||||
reset(mRotateTextViewController);
|
||||
}
|
||||
}
|
||||
@@ -11,12 +11,11 @@
|
||||
* 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
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar;
|
||||
|
||||
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
|
||||
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
|
||||
import static android.content.pm.UserInfo.FLAG_MANAGED_PROFILE;
|
||||
import static android.hardware.biometrics.BiometricFaceConstants.FACE_ACQUIRED_TOO_DARK;
|
||||
@@ -26,7 +25,6 @@ import static android.hardware.biometrics.BiometricFaceConstants.FACE_ERROR_TIME
|
||||
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
|
||||
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
|
||||
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED;
|
||||
import static com.android.systemui.flags.Flags.KEYGUARD_TALKBACK_FIX;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BATTERY;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_BIOMETRIC_MESSAGE;
|
||||
@@ -38,7 +36,6 @@ import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewCont
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRANSIENT;
|
||||
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_TRUST;
|
||||
import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_OFF;
|
||||
import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_ON;
|
||||
import static com.android.systemui.keyguard.ScreenLifecycle.SCREEN_TURNING_ON;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
@@ -60,73 +57,28 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.Instrumentation;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.admin.DevicePolicyResourcesManager;
|
||||
import android.app.trust.TrustManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.biometrics.BiometricFaceConstants;
|
||||
import android.hardware.biometrics.BiometricFingerprintConstants;
|
||||
import android.hardware.biometrics.BiometricSourceType;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserManager;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.app.IBatteryStats;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.keyguard.TrustGrantFlags;
|
||||
import com.android.keyguard.logging.KeyguardLogger;
|
||||
import com.android.settingslib.fuelgauge.BatteryStatus;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.biometrics.AuthController;
|
||||
import com.android.systemui.biometrics.FaceHelpMessageDeferral;
|
||||
import com.android.systemui.bouncer.domain.interactor.AlternateBouncerInteractor;
|
||||
import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.dock.DockManager;
|
||||
import com.android.systemui.flags.FakeFeatureFlags;
|
||||
import com.android.systemui.keyguard.KeyguardIndication;
|
||||
import com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.keyguard.util.IndicationHelper;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
|
||||
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
import com.android.systemui.util.wakelock.WakeLockFake;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Collections;
|
||||
@@ -137,205 +89,7 @@ import java.util.Set;
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
public class KeyguardIndicationControllerTest extends SysuiTestCase {
|
||||
|
||||
private static final String ORGANIZATION_NAME = "organization";
|
||||
|
||||
private static final ComponentName DEVICE_OWNER_COMPONENT = new ComponentName("com.android.foo",
|
||||
"bar");
|
||||
|
||||
private static final int TEST_STRING_RES = R.string.keyguard_indication_trust_unlocked;
|
||||
|
||||
private String mDisclosureWithOrganization;
|
||||
private String mDisclosureGeneric;
|
||||
private String mFinancedDisclosureWithOrganization;
|
||||
|
||||
@Mock
|
||||
private DevicePolicyManager mDevicePolicyManager;
|
||||
@Mock
|
||||
private DevicePolicyResourcesManager mDevicePolicyResourcesManager;
|
||||
@Mock
|
||||
private ViewGroup mIndicationArea;
|
||||
@Mock
|
||||
private KeyguardStateController mKeyguardStateController;
|
||||
@Mock
|
||||
private KeyguardIndicationTextView mIndicationAreaBottom;
|
||||
@Mock
|
||||
private BroadcastDispatcher mBroadcastDispatcher;
|
||||
@Mock
|
||||
private StatusBarStateController mStatusBarStateController;
|
||||
@Mock
|
||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
@Mock
|
||||
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
@Mock
|
||||
private IBatteryStats mIBatteryStats;
|
||||
@Mock
|
||||
private DockManager mDockManager;
|
||||
@Mock
|
||||
private KeyguardIndicationRotateTextViewController mRotateTextViewController;
|
||||
@Mock
|
||||
private FalsingManager mFalsingManager;
|
||||
@Mock
|
||||
private LockPatternUtils mLockPatternUtils;
|
||||
@Mock
|
||||
private KeyguardBypassController mKeyguardBypassController;
|
||||
@Mock
|
||||
private AccessibilityManager mAccessibilityManager;
|
||||
@Mock
|
||||
private FaceHelpMessageDeferral mFaceHelpMessageDeferral;
|
||||
@Mock
|
||||
private AlternateBouncerInteractor mAlternateBouncerInteractor;
|
||||
@Mock
|
||||
private ScreenLifecycle mScreenLifecycle;
|
||||
@Mock
|
||||
private AuthController mAuthController;
|
||||
@Mock
|
||||
private AlarmManager mAlarmManager;
|
||||
@Mock
|
||||
private UserTracker mUserTracker;
|
||||
@Captor
|
||||
private ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
|
||||
@Captor
|
||||
private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<KeyguardIndication> mKeyguardIndicationCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<KeyguardStateController.Callback> mKeyguardStateControllerCallbackCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<ScreenLifecycle.Observer> mScreenObserverCaptor;
|
||||
private KeyguardStateController.Callback mKeyguardStateControllerCallback;
|
||||
private KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback;
|
||||
private StatusBarStateController.StateListener mStatusBarStateListener;
|
||||
private ScreenLifecycle.Observer mScreenObserver;
|
||||
private BroadcastReceiver mBroadcastReceiver;
|
||||
private IndicationHelper mIndicationHelper;
|
||||
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
private TestableLooper mTestableLooper;
|
||||
private final int mCurrentUserId = 1;
|
||||
|
||||
private KeyguardIndicationTextView mTextView; // AOD text
|
||||
|
||||
private KeyguardIndicationController mController;
|
||||
private WakeLockFake.Builder mWakeLockBuilder;
|
||||
private WakeLockFake mWakeLock;
|
||||
private Instrumentation mInstrumentation;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
mTestableLooper = TestableLooper.get(this);
|
||||
mTextView = new KeyguardIndicationTextView(mContext);
|
||||
mTextView.setAnimationsEnabled(false);
|
||||
|
||||
// TODO(b/259908270): remove
|
||||
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
|
||||
DevicePolicyManager.ADD_ISFINANCED_DEVICE_FLAG, "true",
|
||||
/* makeDefault= */ false);
|
||||
mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
|
||||
mContext.addMockSystemService(UserManager.class, mUserManager);
|
||||
mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
|
||||
mContext.addMockSystemService(Context.FINGERPRINT_SERVICE, mock(FingerprintManager.class));
|
||||
mDisclosureWithOrganization = mContext.getString(R.string.do_disclosure_with_name,
|
||||
ORGANIZATION_NAME);
|
||||
mDisclosureGeneric = mContext.getString(R.string.do_disclosure_generic);
|
||||
mFinancedDisclosureWithOrganization = mContext.getString(
|
||||
R.string.do_financed_disclosure_with_name, ORGANIZATION_NAME);
|
||||
|
||||
when(mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
||||
when(mScreenLifecycle.getScreenState()).thenReturn(SCREEN_ON);
|
||||
when(mKeyguardUpdateMonitor.isUserUnlocked(anyInt())).thenReturn(true);
|
||||
|
||||
when(mIndicationArea.findViewById(R.id.keyguard_indication_text_bottom))
|
||||
.thenReturn(mIndicationAreaBottom);
|
||||
when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView);
|
||||
|
||||
when(mDevicePolicyManager.getResources()).thenReturn(mDevicePolicyResourcesManager);
|
||||
when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser())
|
||||
.thenReturn(DEVICE_OWNER_COMPONENT);
|
||||
when(mDevicePolicyManager.isFinancedDevice()).thenReturn(false);
|
||||
// TODO(b/259908270): remove
|
||||
when(mDevicePolicyManager.getDeviceOwnerType(DEVICE_OWNER_COMPONENT))
|
||||
.thenReturn(DEVICE_OWNER_TYPE_DEFAULT);
|
||||
|
||||
when(mDevicePolicyResourcesManager.getString(anyString(), any()))
|
||||
.thenReturn(mDisclosureGeneric);
|
||||
when(mDevicePolicyResourcesManager.getString(anyString(), any(), anyString()))
|
||||
.thenReturn(mDisclosureWithOrganization);
|
||||
when(mUserTracker.getUserId()).thenReturn(mCurrentUserId);
|
||||
|
||||
mIndicationHelper = new IndicationHelper(mKeyguardUpdateMonitor);
|
||||
|
||||
mWakeLock = new WakeLockFake();
|
||||
mWakeLockBuilder = new WakeLockFake.Builder(mContext);
|
||||
mWakeLockBuilder.setWakeLock(mWakeLock);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
mTextView.setAnimationsEnabled(true);
|
||||
if (mController != null) {
|
||||
mController.destroy();
|
||||
mController = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void createController() {
|
||||
if (Looper.myLooper() == null) {
|
||||
Looper.prepare();
|
||||
}
|
||||
|
||||
FakeFeatureFlags flags = new FakeFeatureFlags();
|
||||
flags.set(KEYGUARD_TALKBACK_FIX, true);
|
||||
mController = new KeyguardIndicationController(
|
||||
mContext,
|
||||
mTestableLooper.getLooper(),
|
||||
mWakeLockBuilder,
|
||||
mKeyguardStateController, mStatusBarStateController, mKeyguardUpdateMonitor,
|
||||
mDockManager, mBroadcastDispatcher, mDevicePolicyManager, mIBatteryStats,
|
||||
mUserManager, mExecutor, mExecutor, mFalsingManager,
|
||||
mAuthController, mLockPatternUtils, mScreenLifecycle,
|
||||
mKeyguardBypassController, mAccessibilityManager,
|
||||
mFaceHelpMessageDeferral, mock(KeyguardLogger.class),
|
||||
mAlternateBouncerInteractor,
|
||||
mAlarmManager,
|
||||
mUserTracker,
|
||||
mock(BouncerMessageInteractor.class),
|
||||
flags,
|
||||
mIndicationHelper
|
||||
);
|
||||
mController.init();
|
||||
mController.setIndicationArea(mIndicationArea);
|
||||
verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
|
||||
mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
|
||||
verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(), any());
|
||||
mBroadcastReceiver = mBroadcastReceiverCaptor.getValue();
|
||||
mController.mRotateTextViewController = mRotateTextViewController;
|
||||
mController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
|
||||
clearInvocations(mIBatteryStats);
|
||||
|
||||
verify(mKeyguardStateController).addCallback(
|
||||
mKeyguardStateControllerCallbackCaptor.capture());
|
||||
mKeyguardStateControllerCallback = mKeyguardStateControllerCallbackCaptor.getValue();
|
||||
|
||||
verify(mKeyguardUpdateMonitor).registerCallback(
|
||||
mKeyguardUpdateMonitorCallbackCaptor.capture());
|
||||
mKeyguardUpdateMonitorCallback = mKeyguardUpdateMonitorCallbackCaptor.getValue();
|
||||
|
||||
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
|
||||
mScreenObserver = mScreenObserverCaptor.getValue();
|
||||
|
||||
mExecutor.runAllReady();
|
||||
reset(mRotateTextViewController);
|
||||
}
|
||||
|
||||
public class KeyguardIndicationControllerTest extends KeyguardIndicationControllerBaseTest {
|
||||
@Test
|
||||
public void createController_setIndicationAreaAgain_destroysPreviousRotateTextViewController() {
|
||||
// GIVEN a controller with a mocked rotate text view controlller
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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
|
||||
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.testing.TestableLooper
|
||||
import android.view.View
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||
class KeyguardIndicationControllerWithCoroutinesTest : KeyguardIndicationControllerBaseTest() {
|
||||
@Test
|
||||
fun testIndicationAreaVisibility_onLockscreenHostedDreamStateChanged() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
// GIVEN starting state for keyguard indication and wallpaper dream enabled
|
||||
createController()
|
||||
mFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, true)
|
||||
mController.setVisible(true)
|
||||
|
||||
// THEN indication area is visible
|
||||
verify(mIndicationArea, times(2)).visibility = View.VISIBLE
|
||||
|
||||
// WHEN the device is dreaming with lockscreen hosted dream
|
||||
mController.mIsActiveDreamLockscreenHostedCallback.accept(
|
||||
true /* isActiveDreamLockscreenHosted */
|
||||
)
|
||||
mExecutor.runAllReady()
|
||||
|
||||
// THEN the indication area is hidden
|
||||
verify(mIndicationArea).visibility = View.GONE
|
||||
|
||||
// WHEN the device stops dreaming with lockscreen hosted dream
|
||||
mController.mIsActiveDreamLockscreenHostedCallback.accept(
|
||||
false /* isActiveDreamLockscreenHosted */
|
||||
)
|
||||
mExecutor.runAllReady()
|
||||
|
||||
// THEN indication area is set visible
|
||||
verify(mIndicationArea, times(3)).visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val IMMEDIATE = Dispatchers.Main.immediate
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user