diff options
| author | 2023-08-21 12:22:57 -0700 | |
|---|---|---|
| committer | 2023-08-29 08:52:56 -0700 | |
| commit | 7876ae12560db9cfe8582e6854c87f555e55a047 (patch) | |
| tree | ad45fa38a03dcdd2cae9aaa2b162a82bdd1b4ca7 | |
| parent | 045f04c5e639d51b490ff450ae7de4fca6caafe0 (diff) | |
Change LockIconViewController from view controller
Change from view controller so that we can set lock icon view and change
mView. Ensure that we proactively set a lock icon view in case we
haven't inflated one yet.
Bug: 295555276
Test: test to see that lock icon view can be set later than view
inflation.
Change-Id: I66128eb0a26d346ebde94a30b0e41a960cefa138
7 files changed, 105 insertions, 91 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconView.java b/packages/SystemUI/src/com/android/keyguard/LockIconView.java index 8611dbbbcb70..1d37809a382e 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconView.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconView.java @@ -142,11 +142,13 @@ public class LockIconView extends FrameLayout implements Dumpable { mLockIconCenter.y + mRadius); final FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); - lp.width = (int) (mSensorRect.right - mSensorRect.left); - lp.height = (int) (mSensorRect.bottom - mSensorRect.top); - lp.topMargin = (int) mSensorRect.top; - lp.setMarginStart((int) mSensorRect.left); - setLayoutParams(lp); + if (lp != null) { + lp.width = (int) (mSensorRect.right - mSensorRect.left); + lp.height = (int) (mSensorRect.bottom - mSensorRect.top); + lp.topMargin = (int) mSensorRect.top; + lp.setMarginStart((int) mSensorRect.left); + setLayoutParams(lp); + } } @Override diff --git a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java index 951a6aeef11b..ab9b647f5c2c 100644 --- a/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/LockIconViewController.java @@ -28,6 +28,7 @@ import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLE import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION; import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; +import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Point; @@ -74,7 +75,6 @@ import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.util.ViewController; import com.android.systemui.util.concurrency.DelayableExecutor; import java.io.PrintWriter; @@ -90,7 +90,7 @@ import javax.inject.Inject; * icon will show a set distance from the bottom of the device. */ @SysUISingleton -public class LockIconViewController extends ViewController<LockIconView> implements Dumpable { +public class LockIconViewController implements Dumpable { private static final String TAG = "LockIconViewController"; private static final float sDefaultDensity = (float) DisplayMetrics.DENSITY_DEVICE_STABLE / (float) DisplayMetrics.DENSITY_DEFAULT; @@ -109,6 +109,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme @NonNull private final ConfigurationController mConfigurationController; @NonNull private final DelayableExecutor mExecutor; private boolean mUdfpsEnrolled; + private Resources mResources; + private Context mContext; @NonNull private final AnimatedStateListDrawable mIcon; @@ -120,6 +122,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme @NonNull private final PrimaryBouncerInteractor mPrimaryBouncerInteractor; @NonNull private final KeyguardTransitionInteractor mTransitionInteractor; @NonNull private final KeyguardInteractor mKeyguardInteractor; + @NonNull private final View.AccessibilityDelegate mAccessibilityDelegate; // Tracks the velocity of a touch to help filter out the touches that move too fast. private VelocityTracker mVelocityTracker; @@ -154,6 +157,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme private boolean mDownDetected; private final Rect mSensorTouchLocation = new Rect(); + private LockIconView mView; @VisibleForTesting final Consumer<TransitionStep> mDozeTransitionCallback = (TransitionStep step) -> { @@ -178,7 +182,6 @@ public class LockIconViewController extends ViewController<LockIconView> impleme @Inject public LockIconViewController( - @Nullable LockIconView view, @NonNull StatusBarStateController statusBarStateController, @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor, @NonNull KeyguardViewController keyguardViewController, @@ -195,9 +198,9 @@ public class LockIconViewController extends ViewController<LockIconView> impleme @NonNull KeyguardTransitionInteractor transitionInteractor, @NonNull KeyguardInteractor keyguardInteractor, @NonNull FeatureFlags featureFlags, - PrimaryBouncerInteractor primaryBouncerInteractor + PrimaryBouncerInteractor primaryBouncerInteractor, + Context context ) { - super(view); mStatusBarStateController = statusBarStateController; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mAuthController = authController; @@ -218,16 +221,40 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mMaxBurnInOffsetY = resources.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y); mIcon = (AnimatedStateListDrawable) - resources.getDrawable(R.drawable.super_lock_icon, mView.getContext().getTheme()); - mView.setImageDrawable(mIcon); + resources.getDrawable(R.drawable.super_lock_icon, context.getTheme()); mUnlockedLabel = resources.getString(R.string.accessibility_unlock_button); mLockedLabel = resources.getString(R.string.accessibility_lock_icon); mLongPressTimeout = resources.getInteger(R.integer.config_lockIconLongPress); dumpManager.registerDumpable(TAG, this); + mResources = resources; + mContext = context; + + mAccessibilityDelegate = new View.AccessibilityDelegate() { + private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityAuthenticateHint = + new AccessibilityNodeInfo.AccessibilityAction( + AccessibilityNodeInfoCompat.ACTION_CLICK, + mResources.getString(R.string.accessibility_authenticate_hint)); + private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityEnterHint = + new AccessibilityNodeInfo.AccessibilityAction( + AccessibilityNodeInfoCompat.ACTION_CLICK, + mResources.getString(R.string.accessibility_enter_hint)); + public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(v, info); + if (isActionable()) { + if (mShowLockIcon) { + info.addAction(mAccessibilityAuthenticateHint); + } else if (mShowUnlockIcon) { + info.addAction(mAccessibilityEnterHint); + } + } + } + }; } - @Override - protected void onInit() { + /** Sets the LockIconView to the controller and rebinds any that depend on it. */ + public void setLockIconView(LockIconView lockIconView) { + mView = lockIconView; + mView.setImageDrawable(mIcon); mView.setAccessibilityDelegate(mAccessibilityDelegate); if (mFeatureFlags.isEnabled(DOZING_MIGRATION_1)) { @@ -240,10 +267,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme collectFlow(mView, mKeyguardInteractor.isActiveDreamLockscreenHosted(), mIsActiveDreamLockscreenHostedCallback); } - } - @Override - protected void onViewAttached() { updateIsUdfpsEnrolled(); updateConfiguration(); updateKeyguardShowing(); @@ -256,39 +280,57 @@ public class LockIconViewController extends ViewController<LockIconView> impleme mStatusBarState = mStatusBarStateController.getState(); updateColors(); - mConfigurationController.addCallback(mConfigurationListener); + mDownDetected = false; + updateBurnInOffsets(); + updateVisibility(); + + updateAccessibility(); + + lockIconView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { + @Override + public void onViewAttachedToWindow(View view) { + registerCallbacks(); + } + @Override + public void onViewDetachedFromWindow(View view) { + unregisterCallbacks(); + } + }); + + if (lockIconView.isAttachedToWindow()) { + registerCallbacks(); + } + } + + private void registerCallbacks() { + mConfigurationController.addCallback(mConfigurationListener); mAuthController.addCallback(mAuthControllerCallback); mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback); mStatusBarStateController.addCallback(mStatusBarStateListener); mKeyguardStateController.addCallback(mKeyguardStateCallback); - mDownDetected = false; - updateBurnInOffsets(); - updateVisibility(); - mAccessibilityManager.addAccessibilityStateChangeListener( mAccessibilityStateChangeListener); - updateAccessibility(); - } - private void updateAccessibility() { - if (mAccessibilityManager.isEnabled()) { - mView.setOnClickListener(mA11yClickListener); - } else { - mView.setOnClickListener(null); - } } - @Override - protected void onViewDetached() { + private void unregisterCallbacks() { mAuthController.removeCallback(mAuthControllerCallback); mConfigurationController.removeCallback(mConfigurationListener); mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateMonitorCallback); mStatusBarStateController.removeCallback(mStatusBarStateListener); mKeyguardStateController.removeCallback(mKeyguardStateCallback); - mAccessibilityManager.removeAccessibilityStateChangeListener( mAccessibilityStateChangeListener); + + } + + private void updateAccessibility() { + if (mAccessibilityManager.isEnabled()) { + mView.setOnClickListener(mA11yClickListener); + } else { + mView.setOnClickListener(null); + } } public float getTop() { @@ -363,28 +405,6 @@ public class LockIconViewController extends ViewController<LockIconView> impleme } } - private final View.AccessibilityDelegate mAccessibilityDelegate = - new View.AccessibilityDelegate() { - private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityAuthenticateHint = - new AccessibilityNodeInfo.AccessibilityAction( - AccessibilityNodeInfoCompat.ACTION_CLICK, - getResources().getString(R.string.accessibility_authenticate_hint)); - private final AccessibilityNodeInfo.AccessibilityAction mAccessibilityEnterHint = - new AccessibilityNodeInfo.AccessibilityAction( - AccessibilityNodeInfoCompat.ACTION_CLICK, - getResources().getString(R.string.accessibility_enter_hint)); - public void onInitializeAccessibilityNodeInfo(View v, AccessibilityNodeInfo info) { - super.onInitializeAccessibilityNodeInfo(v, info); - if (isActionable()) { - if (mShowLockIcon) { - info.addAction(mAccessibilityAuthenticateHint); - } else if (mShowUnlockIcon) { - info.addAction(mAccessibilityEnterHint); - } - } - } - }; - private boolean isLockScreen() { return !mIsDozing && !mIsBouncerShowing @@ -401,18 +421,15 @@ public class LockIconViewController extends ViewController<LockIconView> impleme } private void updateConfiguration() { - WindowManager windowManager = getContext().getSystemService(WindowManager.class); + WindowManager windowManager = mContext.getSystemService(WindowManager.class); Rect bounds = windowManager.getCurrentWindowMetrics().getBounds(); mWidthPixels = bounds.right; mHeightPixels = bounds.bottom; - mBottomPaddingPx = getResources().getDimensionPixelSize(R.dimen.lock_icon_margin_bottom); - mDefaultPaddingPx = - getResources().getDimensionPixelSize(R.dimen.lock_icon_padding); - - mUnlockedLabel = mView.getContext().getResources().getString( + mBottomPaddingPx = mResources.getDimensionPixelSize(R.dimen.lock_icon_margin_bottom); + mDefaultPaddingPx = mResources.getDimensionPixelSize(R.dimen.lock_icon_padding); + mUnlockedLabel = mResources.getString( R.string.accessibility_unlock_button); - mLockedLabel = mView.getContext() - .getResources().getString(R.string.accessibility_lock_icon); + mLockedLabel = mResources.getString(R.string.accessibility_lock_icon); updateLockIconLocation(); } @@ -755,7 +772,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme } else { mVibrator.vibrate( Process.myUid(), - getContext().getOpPackageName(), + mContext.getOpPackageName(), UdfpsController.EFFECT_CLICK, "lock-icon-down", TOUCH_VIBRATION_ATTRIBUTES); @@ -769,7 +786,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme } else { mVibrator.vibrate( Process.myUid(), - getContext().getOpPackageName(), + mContext.getOpPackageName(), UdfpsController.EFFECT_CLICK, "lock-screen-lock-icon-longpress", TOUCH_VIBRATION_ATTRIBUTES); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt index 30f2e758eb9a..36d9c8bf43ea 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt @@ -24,6 +24,8 @@ import android.view.View import android.view.ViewGroup import com.android.keyguard.KeyguardStatusView import com.android.keyguard.KeyguardStatusViewController +import com.android.keyguard.LockIconView +import com.android.keyguard.LockIconViewController import com.android.keyguard.dagger.KeyguardStatusViewComponent import com.android.systemui.CoreStartable import com.android.systemui.R @@ -98,6 +100,7 @@ constructor( private val notificationStackScrollerLayoutController: NotificationStackScrollLayoutController, private val context: Context, private val keyguardIndicationController: KeyguardIndicationController, + private val lockIconViewController: LockIconViewController, ) : CoreStartable { private var rootViewHandle: DisposableHandle? = null @@ -190,6 +193,8 @@ constructor( private fun initializeViews() { val indicationArea = KeyguardIndicationArea(context, null) keyguardIndicationController.setIndicationArea(indicationArea) + + lockIconViewController.setLockIconView(LockIconView(context, null)) } private fun bindKeyguardRootView() { @@ -214,6 +219,9 @@ constructor( keyguardRootView.findViewById<View?>(R.id.lock_icon_view)?.let { keyguardRootView.removeView(it) } + legacyParent.requireViewById<LockIconView>(R.id.lock_icon_view).let { + lockIconViewController.setLockIconView(it) + } } } diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java index 1f4e2297eb43..54b806dd8d19 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java @@ -193,7 +193,6 @@ public class NotificationShadeWindowViewController { mLockIconViewController = lockIconViewController; mBackActionInteractor = backActionInteractor; mShadeLogger = shadeLogger; - mLockIconViewController.init(); mService = centralSurfaces; mDozeServiceHost = dozeServiceHost; mDozeScrimController = dozeScrimController; @@ -234,6 +233,8 @@ public class NotificationShadeWindowViewController { progressProvider -> progressProvider.addCallback( mDisableSubpixelTextTransitionListener)); } + + lockIconViewController.setLockIconView(mView.findViewById(R.id.lock_icon_view)); } /** diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt index 05b1ac64a5f6..6585fcb1ae53 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeViewProviderModule.kt @@ -22,7 +22,6 @@ import android.os.Handler import android.view.LayoutInflater import android.view.ViewStub import androidx.constraintlayout.motion.widget.MotionLayout -import com.android.keyguard.LockIconView import com.android.systemui.R import com.android.systemui.battery.BatteryMeterView import com.android.systemui.battery.BatteryMeterViewController @@ -96,11 +95,11 @@ abstract class ShadeViewProviderModule { ?: throw IllegalStateException("Window root view could not be properly inflated") } - @Provides - @SysUISingleton // TODO(b/277762009): Do something similar to // {@link StatusBarWindowModule.InternalWindowView} so that only // {@link NotificationShadeWindowViewController} can inject this view. + @Provides + @SysUISingleton fun providesNotificationShadeWindowView( root: WindowRootView, featureFlags: FeatureFlags, @@ -206,21 +205,6 @@ abstract class ShadeViewProviderModule { // TODO(b/277762009): Only allow this view's controller to inject the view. See above. @Provides @SysUISingleton - fun providesLockIconView( - keyguardRootView: KeyguardRootView, - notificationPanelView: NotificationPanelView, - featureFlags: FeatureFlags - ): LockIconView { - if (featureFlags.isEnabled(Flags.MIGRATE_LOCK_ICON)) { - return keyguardRootView.requireViewById(R.id.lock_icon_view) - } else { - return notificationPanelView.requireViewById(R.id.lock_icon_view) - } - } - - // TODO(b/277762009): Only allow this view's controller to inject the view. See above. - @Provides - @SysUISingleton fun providesTapAgainView( notificationPanelView: NotificationPanelView, ): TapAgainView { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java index b9e3f140a9ab..09ff546120c6 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerBaseTest.java @@ -24,7 +24,6 @@ import static com.android.systemui.flags.Flags.MIGRATE_LOCK_ICON; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -148,7 +147,6 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase { mFeatureFlags.set(MIGRATE_LOCK_ICON, false); mFeatureFlags.set(LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false); mUnderTest = new LockIconViewController( - mLockIconView, mStatusBarStateController, mKeyguardUpdateMonitor, mKeyguardViewController, @@ -167,7 +165,8 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase { .getKeyguardTransitionInteractor(), KeyguardInteractorFactory.create(mFeatureFlags).getKeyguardInteractor(), mFeatureFlags, - mPrimaryBouncerInteractor + mPrimaryBouncerInteractor, + mContext ); } @@ -228,9 +227,6 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase { protected void init(boolean useMigrationFlag) { mFeatureFlags.set(DOZING_MIGRATION_1, useMigrationFlag); - mUnderTest.init(); - - verify(mLockIconView, atLeast(1)).addOnAttachStateChangeListener(mAttachCaptor.capture()); - mAttachCaptor.getValue().onViewAttachedToWindow(mLockIconView); + mUnderTest.setLockIconView(mLockIconView); } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java index 45021ba1b300..979fc83ec43a 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/LockIconViewControllerTest.java @@ -52,6 +52,12 @@ import org.junit.runner.RunWith; @TestableLooper.RunWithLooper public class LockIconViewControllerTest extends LockIconViewControllerBaseTest { + @Override + public void setUp() throws Exception { + super.setUp(); + when(mLockIconView.isAttachedToWindow()).thenReturn(true); + } + @Test public void testUpdateFingerprintLocationOnInit() { // GIVEN fp sensor location is available pre-attached |