Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7876ae12 authored by Aaron Liu's avatar Aaron Liu
Browse files

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
parent 045f04c5
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -142,12 +142,14 @@ public class LockIconView extends FrameLayout implements Dumpable {
                mLockIconCenter.y + mRadius);

        final FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
        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
    public boolean hasOverlappingRendering() {
+77 −60
Original line number Diff line number Diff line
@@ -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);

        mAuthController.addCallback(mAuthControllerCallback);
        mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
        mStatusBarStateController.addCallback(mStatusBarStateListener);
        mKeyguardStateController.addCallback(mKeyguardStateCallback);
        mDownDetected = false;
        updateBurnInOffsets();
        updateVisibility();

        mAccessibilityManager.addAccessibilityStateChangeListener(
                mAccessibilityStateChangeListener);
        updateAccessibility();

        lockIconView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
            @Override
            public void onViewAttachedToWindow(View view) {
                registerCallbacks();
            }

    private void updateAccessibility() {
        if (mAccessibilityManager.isEnabled()) {
            mView.setOnClickListener(mA11yClickListener);
        } else {
            mView.setOnClickListener(null);
            @Override
            public void onViewDetachedFromWindow(View view) {
                unregisterCallbacks();
            }
        });

        if (lockIconView.isAttachedToWindow()) {
            registerCallbacks();
        }
    }

    @Override
    protected void onViewDetached() {
    private void registerCallbacks() {
        mConfigurationController.addCallback(mConfigurationListener);
        mAuthController.addCallback(mAuthControllerCallback);
        mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback);
        mStatusBarStateController.addCallback(mStatusBarStateListener);
        mKeyguardStateController.addCallback(mKeyguardStateCallback);
        mAccessibilityManager.addAccessibilityStateChangeListener(
                mAccessibilityStateChangeListener);

    }

    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);
+8 −0
Original line number Diff line number Diff line
@@ -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)
            }
        }
    }

+2 −1
Original line number Diff line number Diff line
@@ -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));
    }

    /**
+2 −18
Original line number Diff line number Diff line
@@ -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,
@@ -203,21 +202,6 @@ abstract class ShadeViewProviderModule {
            return notificationShadeWindowView.requireViewById(R.id.auth_ripple)
        }

        // 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
Loading