diff options
8 files changed, 130 insertions, 831 deletions
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml index 0ca19d98a097..8df8c49ee057 100644 --- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml +++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml @@ -83,48 +83,6 @@ android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset" android:visibility="gone" /> - <ImageView - android:id="@+id/wallet_button" - android:layout_height="@dimen/keyguard_affordance_fixed_height" - android:layout_width="@dimen/keyguard_affordance_fixed_width" - android:layout_gravity="bottom|end" - android:scaleType="center" - android:tint="?android:attr/textColorPrimary" - android:src="@drawable/ic_wallet_lockscreen" - android:background="@drawable/keyguard_bottom_affordance_bg" - android:layout_marginEnd="@dimen/keyguard_affordance_horizontal_offset" - android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset" - android:contentDescription="@string/accessibility_wallet_button" - android:visibility="gone" /> - - <ImageView - android:id="@+id/qr_code_scanner_button" - android:layout_height="@dimen/keyguard_affordance_fixed_height" - android:layout_width="@dimen/keyguard_affordance_fixed_width" - android:layout_gravity="bottom|end" - android:scaleType="center" - android:tint="?android:attr/textColorPrimary" - android:src="@drawable/ic_qr_code_scanner" - android:background="@drawable/keyguard_bottom_affordance_bg" - android:layout_marginEnd="@dimen/keyguard_affordance_horizontal_offset" - android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset" - android:contentDescription="@string/accessibility_qr_code_scanner_button" - android:visibility="gone" /> - - <ImageView - android:id="@+id/controls_button" - android:layout_height="@dimen/keyguard_affordance_fixed_height" - android:layout_width="@dimen/keyguard_affordance_fixed_width" - android:layout_gravity="bottom|start" - android:scaleType="center" - android:tint="?android:attr/textColorPrimary" - android:src="@drawable/controls_icon" - android:background="@drawable/keyguard_bottom_affordance_bg" - android:layout_marginStart="@dimen/keyguard_affordance_horizontal_offset" - android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset" - android:contentDescription="@string/quick_controls_title" - android:visibility="gone" /> - <FrameLayout android:id="@+id/overlay_container" android:layout_width="match_parent" diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt b/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt index acbea1beeae3..7d6f377d5287 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt @@ -50,12 +50,10 @@ constructor( viewsIdToTranslate = setOf( ViewIdToTranslate(R.id.keyguard_status_area, LEFT, filterNever), - ViewIdToTranslate(R.id.controls_button, LEFT, filterNever), ViewIdToTranslate(R.id.lockscreen_clock_view_large, LEFT, filterSplitShadeOnly), ViewIdToTranslate(R.id.lockscreen_clock_view, LEFT, filterNever), ViewIdToTranslate( R.id.notification_stack_scroller, RIGHT, filterSplitShadeOnly), - ViewIdToTranslate(R.id.wallet_button, RIGHT, filterNever), ViewIdToTranslate(R.id.start_button, LEFT, filterNever), ViewIdToTranslate(R.id.end_button, RIGHT, filterNever)), progressProvider = unfoldProgressProvider) diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java index 07d3b6dd688b..586585c009e0 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java @@ -92,13 +92,6 @@ public class Flags { public static final ResourceBooleanFlag FACE_SCANNING_ANIM = new ResourceBooleanFlag(205, R.bool.config_enableFaceScanningAnimation); - /** - * Whether the KeyguardBottomArea(View|Controller) should use the modern architecture or the old - * one. - */ - public static final ReleasedFlag MODERN_BOTTOM_AREA = new ReleasedFlag(206, true); - - public static final UnreleasedFlag LOCKSCREEN_CUSTOM_CLOCKS = new UnreleasedFlag(207); /** diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index 91c6a9c892e7..c3b265fec36e 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -117,7 +117,6 @@ import com.android.systemui.biometrics.AuthController; import com.android.systemui.camera.CameraGestureHelper; import com.android.systemui.classifier.Classifier; import com.android.systemui.classifier.FalsingCollector; -import com.android.systemui.controls.dagger.ControlsComponent; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.DisplayId; import com.android.systemui.dagger.qualifiers.Main; @@ -140,7 +139,6 @@ import com.android.systemui.plugins.FalsingManager.FalsingTapListener; import com.android.systemui.plugins.qs.QS; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; -import com.android.systemui.qrcodescanner.controller.QRCodeScannerController; import com.android.systemui.screenrecord.RecordingController; import com.android.systemui.shade.transition.ShadeTransitionController; import com.android.systemui.shared.system.QuickStepContract; @@ -217,7 +215,6 @@ import com.android.systemui.util.LargeScreenUtils; import com.android.systemui.util.ListenerSet; import com.android.systemui.util.Utils; import com.android.systemui.util.time.SystemClock; -import com.android.systemui.wallet.controller.QuickAccessWalletController; import com.android.wm.shell.animation.FlingAnimationUtils; import java.io.PrintWriter; @@ -325,9 +322,6 @@ public final class NotificationPanelViewController extends PanelViewController { private final FragmentService mFragmentService; private final ScrimController mScrimController; private final PrivacyDotViewController mPrivacyDotViewController; - private final QuickAccessWalletController mQuickAccessWalletController; - private final QRCodeScannerController mQRCodeScannerController; - private final ControlsComponent mControlsComponent; private final NotificationRemoteInputManager mRemoteInputManager; private final LockscreenShadeTransitionController mLockscreenShadeTransitionController; @@ -696,8 +690,8 @@ public final class NotificationPanelViewController extends PanelViewController { }; private final CameraGestureHelper mCameraGestureHelper; - private final Provider<KeyguardBottomAreaViewModel> mKeyguardBottomAreaViewModelProvider; - private final Provider<KeyguardBottomAreaInteractor> mKeyguardBottomAreaInteractorProvider; + private final KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel; + private final KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor; @Inject public NotificationPanelViewController(NotificationPanelView view, @@ -746,8 +740,6 @@ public final class NotificationPanelViewController extends PanelViewController { NavigationModeController navigationModeController, FragmentService fragmentService, ContentResolver contentResolver, - QuickAccessWalletController quickAccessWalletController, - QRCodeScannerController qrCodeScannerController, RecordingController recordingController, LargeScreenShadeHeaderController largeScreenShadeHeaderController, ScreenOffAnimationController screenOffAnimationController, @@ -755,7 +747,6 @@ public final class NotificationPanelViewController extends PanelViewController { PanelExpansionStateManager panelExpansionStateManager, NotificationRemoteInputManager remoteInputManager, Optional<SysUIUnfoldComponent> unfoldComponent, - ControlsComponent controlsComponent, InteractionJankMonitor interactionJankMonitor, QsFrameTranslateController qsFrameTranslateController, SysUiState sysUiState, @@ -768,8 +759,8 @@ public final class NotificationPanelViewController extends PanelViewController { ShadeTransitionController shadeTransitionController, SystemClock systemClock, CameraGestureHelper cameraGestureHelper, - Provider<KeyguardBottomAreaViewModel> keyguardBottomAreaViewModelProvider, - Provider<KeyguardBottomAreaInteractor> keyguardBottomAreaInteractorProvider) { + KeyguardBottomAreaViewModel keyguardBottomAreaViewModel, + KeyguardBottomAreaInteractor keyguardBottomAreaInteractor) { super(view, falsingManager, dozeLog, @@ -791,9 +782,6 @@ public final class NotificationPanelViewController extends PanelViewController { mVibratorHelper = vibratorHelper; mKeyguardMediaController = keyguardMediaController; mPrivacyDotViewController = privacyDotViewController; - mQuickAccessWalletController = quickAccessWalletController; - mQRCodeScannerController = qrCodeScannerController; - mControlsComponent = controlsComponent; mMetricsLogger = metricsLogger; mConfigurationController = configurationController; mFlingAnimationUtilsBuilder = flingAnimationUtilsBuilder; @@ -897,7 +885,7 @@ public final class NotificationPanelViewController extends PanelViewController { mQsFrameTranslateController = qsFrameTranslateController; updateUserSwitcherFlags(); - mKeyguardBottomAreaViewModelProvider = keyguardBottomAreaViewModelProvider; + mKeyguardBottomAreaViewModel = keyguardBottomAreaViewModel; onFinishInflate(); keyguardUnlockAnimationController.addKeyguardUnlockAnimationListener( new KeyguardUnlockAnimationController.KeyguardUnlockAnimationListener() { @@ -951,7 +939,7 @@ public final class NotificationPanelViewController extends PanelViewController { } }); mCameraGestureHelper = cameraGestureHelper; - mKeyguardBottomAreaInteractorProvider = keyguardBottomAreaInteractorProvider; + mKeyguardBottomAreaInteractor = keyguardBottomAreaInteractor; } @VisibleForTesting @@ -1276,17 +1264,7 @@ public final class NotificationPanelViewController extends PanelViewController { } private void initBottomArea() { - if (mFeatureFlags.isEnabled(Flags.MODERN_BOTTOM_AREA)) { - mKeyguardBottomArea.init(mKeyguardBottomAreaViewModelProvider.get(), mFalsingManager); - } else { - // TODO(b/235403546): remove this method call when the new implementation is complete - // and these are not needed. - mKeyguardBottomArea.init( - mFalsingManager, - mQuickAccessWalletController, - mControlsComponent, - mQRCodeScannerController); - } + mKeyguardBottomArea.init(mKeyguardBottomAreaViewModel, mFalsingManager); } @VisibleForTesting @@ -1403,7 +1381,6 @@ public final class NotificationPanelViewController extends PanelViewController { } mNotificationStackScrollLayoutController.setIntrinsicPadding(stackScrollerPadding); - mKeyguardBottomArea.setAntiBurnInOffsetX(mClockPositionResult.clockX); mStackScrollerMeasuringPass++; requestScrollerTopPaddingUpdate(animate); @@ -1453,7 +1430,7 @@ public final class NotificationPanelViewController extends PanelViewController { mKeyguardStatusViewController.getClockBottom(mStatusBarHeaderHeightKeyguard), mKeyguardStatusViewController.isClockTopAligned()); mClockPositionAlgorithm.run(mClockPositionResult); - mKeyguardBottomAreaInteractorProvider.get().setClockPosition( + mKeyguardBottomAreaInteractor.setClockPosition( mClockPositionResult.clockX, mClockPositionResult.clockY); boolean animate = mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending(); boolean animateClock = (animate || mAnimateNextPositionUpdate) && shouldAnimateClockChange; @@ -3296,8 +3273,7 @@ public final class NotificationPanelViewController extends PanelViewController { getExpandedFraction()); float alpha = Math.min(expansionAlpha, 1 - computeQsExpansionFraction()); alpha *= mBottomAreaShadeAlpha; - mKeyguardBottomArea.setComponentAlphas(alpha); - mKeyguardBottomAreaInteractorProvider.get().setAlpha(alpha); + mKeyguardBottomAreaInteractor.setAlpha(alpha); mLockIconViewController.setAlpha(alpha); } @@ -3496,8 +3472,7 @@ public final class NotificationPanelViewController extends PanelViewController { } private void updateDozingVisibilities(boolean animate) { - mKeyguardBottomArea.setDozing(mDozing, animate); - mKeyguardBottomAreaInteractorProvider.get().setAnimateDozingTransitions(animate); + mKeyguardBottomAreaInteractor.setAnimateDozingTransitions(animate); if (!mDozing && animate) { mKeyguardStatusBarViewController.animateKeyguardStatusBarIn(); } @@ -3799,8 +3774,7 @@ public final class NotificationPanelViewController extends PanelViewController { mView.setDozing(dozing); mDozing = dozing; mNotificationStackScrollLayoutController.setDozing(mDozing, animate); - mKeyguardBottomArea.setDozing(mDozing, animate); - mKeyguardBottomAreaInteractorProvider.get().setAnimateDozingTransitions(animate); + mKeyguardBottomAreaInteractor.setAnimateDozingTransitions(animate); mKeyguardStatusBarViewController.setDozing(mDozing); if (dozing) { @@ -3849,7 +3823,6 @@ public final class NotificationPanelViewController extends PanelViewController { public void dozeTimeTick() { mLockIconViewController.dozeTimeTick(); - mKeyguardBottomArea.dozeTimeTick(); mKeyguardStatusViewController.dozeTimeTick(); if (mInterpolatedDarkAmount > 0) { positionClockAndNotifications(); @@ -4672,7 +4645,6 @@ public final class NotificationPanelViewController extends PanelViewController { public void onDozeAmountChanged(float linearAmount, float amount) { mInterpolatedDarkAmount = amount; mLinearDarkAmount = linearAmount; - mKeyguardBottomArea.setDarkAmount(mInterpolatedDarkAmount); positionClockAndNotifications(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java deleted file mode 100644 index dc77d10486a3..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ /dev/null @@ -1,682 +0,0 @@ -/* - * Copyright (C) 2014 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.phone; - -import static com.android.internal.util.Preconditions.checkNotNull; -import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE; -import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset; -import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.DEFAULT_PAYMENT_APP_CHANGE; -import static com.android.systemui.wallet.controller.QuickAccessWalletController.WalletChangeEvent.WALLET_PREFERENCE_CHANGE; - -import android.app.ActivityTaskManager; -import android.app.admin.DevicePolicyManager; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.res.ColorStateList; -import android.content.res.Configuration; -import android.graphics.drawable.Drawable; -import android.os.RemoteException; -import android.os.UserHandle; -import android.service.quickaccesswallet.GetWalletCardsError; -import android.service.quickaccesswallet.GetWalletCardsResponse; -import android.service.quickaccesswallet.QuickAccessWalletClient; -import android.util.AttributeSet; -import android.util.Log; -import android.util.TypedValue; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewPropertyAnimator; -import android.view.WindowInsets; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.android.settingslib.Utils; -import com.android.systemui.Dependency; -import com.android.systemui.R; -import com.android.systemui.animation.ActivityLaunchAnimator; -import com.android.systemui.animation.Interpolators; -import com.android.systemui.controls.dagger.ControlsComponent; -import com.android.systemui.controls.management.ControlsListingController; -import com.android.systemui.controls.ui.ControlsActivity; -import com.android.systemui.controls.ui.ControlsUiController; -import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder; -import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel; -import com.android.systemui.plugins.ActivityStarter; -import com.android.systemui.plugins.FalsingManager; -import com.android.systemui.qrcodescanner.controller.QRCodeScannerController; -import com.android.systemui.statusbar.policy.KeyguardStateController; -import com.android.systemui.wallet.controller.QuickAccessWalletController; - -import java.util.ArrayList; -import java.util.List; - -/** - * Implementation for the bottom area of the Keyguard, including camera/phone affordance and status - * text. - */ -public class KeyguardBottomAreaView extends FrameLayout { - - private static final String TAG = "CentralSurfaces/KeyguardBottomAreaView"; - private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250; - - private ImageView mWalletButton; - private ImageView mQRCodeScannerButton; - private ImageView mControlsButton; - private boolean mHasCard = false; - private final WalletCardRetriever mCardRetriever = new WalletCardRetriever(); - private QuickAccessWalletController mQuickAccessWalletController; - private QRCodeScannerController mQRCodeScannerController; - private ControlsComponent mControlsComponent; - private boolean mControlServicesAvailable = false; - - @Nullable private View mAmbientIndicationArea; - private ViewGroup mIndicationArea; - private TextView mIndicationText; - private TextView mIndicationTextBottom; - private ViewGroup mOverlayContainer; - - private ActivityStarter mActivityStarter; - private KeyguardStateController mKeyguardStateController; - private FalsingManager mFalsingManager; - - private boolean mDozing; - private int mIndicationBottomMargin; - private int mIndicationPadding; - private float mDarkAmount; - private int mBurnInXOffset; - private int mBurnInYOffset; - - private final ControlsListingController.ControlsListingCallback mListingCallback = - serviceInfos -> post(() -> { - boolean available = !serviceInfos.isEmpty(); - - if (available != mControlServicesAvailable) { - mControlServicesAvailable = available; - updateControlsVisibility(); - updateAffordanceColors(); - } - }); - - private final KeyguardStateController.Callback mKeyguardStateCallback = - new KeyguardStateController.Callback() { - @Override - public void onKeyguardShowingChanged() { - if (mKeyguardStateController.isShowing()) { - if (mQuickAccessWalletController != null) { - mQuickAccessWalletController.queryWalletCards(mCardRetriever); - } - } - } - }; - - @Nullable private KeyguardBottomAreaViewBinder.Binding mBinding; - private boolean mUsesBinder; - - public KeyguardBottomAreaView(Context context) { - this(context, null); - } - - public KeyguardBottomAreaView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr) { - this(context, attrs, defStyleAttr, 0); - } - - public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr, - int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - /** - * Initializes the view. - */ - public void init( - final KeyguardBottomAreaViewModel viewModel, - final FalsingManager falsingManager) { - Log.i(TAG, System.identityHashCode(this) + " initialized with a binder"); - mUsesBinder = true; - mBinding = KeyguardBottomAreaViewBinder.bind(this, viewModel, falsingManager); - } - - /** - * Initializes the {@link KeyguardBottomAreaView} with the given dependencies - * - * @deprecated Use - * {@link #init(KeyguardBottomAreaViewModel, FalsingManager)} instead - */ - @Deprecated - public void init( - FalsingManager falsingManager, - QuickAccessWalletController controller, - ControlsComponent controlsComponent, - QRCodeScannerController qrCodeScannerController) { - if (mUsesBinder) { - return; - } - - Log.i(TAG, "initialized without a binder"); - mFalsingManager = falsingManager; - - mQuickAccessWalletController = controller; - mQuickAccessWalletController.setupWalletChangeObservers( - mCardRetriever, WALLET_PREFERENCE_CHANGE, DEFAULT_PAYMENT_APP_CHANGE); - mQuickAccessWalletController.updateWalletPreference(); - mQuickAccessWalletController.queryWalletCards(mCardRetriever); - updateWalletVisibility(); - - mControlsComponent = controlsComponent; - mControlsComponent.getControlsListingController().ifPresent( - c -> c.addCallback(mListingCallback)); - - mQRCodeScannerController = qrCodeScannerController; - mQRCodeScannerController.registerQRCodeScannerChangeObservers( - QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE, - QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE); - updateQRCodeButtonVisibility(); - - updateAffordanceColors(); - } - - /** - * Initializes this instance of {@link KeyguardBottomAreaView} based on the given instance of - * another {@link KeyguardBottomAreaView} - */ - public void initFrom(KeyguardBottomAreaView oldBottomArea) { - if (mUsesBinder) { - return; - } - - // if it exists, continue to use the original ambient indication container - // instead of the newly inflated one - if (mAmbientIndicationArea != null) { - // remove old ambient indication from its parent - View originalAmbientIndicationView = - oldBottomArea.findViewById(R.id.ambient_indication_container); - ((ViewGroup) originalAmbientIndicationView.getParent()) - .removeView(originalAmbientIndicationView); - - // remove current ambient indication from its parent (discard) - ViewGroup ambientIndicationParent = (ViewGroup) mAmbientIndicationArea.getParent(); - int ambientIndicationIndex = - ambientIndicationParent.indexOfChild(mAmbientIndicationArea); - ambientIndicationParent.removeView(mAmbientIndicationArea); - - // add the old ambient indication to this view - ambientIndicationParent.addView(originalAmbientIndicationView, ambientIndicationIndex); - mAmbientIndicationArea = originalAmbientIndicationView; - - // update burn-in offsets - dozeTimeTick(); - } - } - - @Override - protected void onFinishInflate() { - super.onFinishInflate(); - if (mUsesBinder) { - return; - } - - mOverlayContainer = findViewById(R.id.overlay_container); - mWalletButton = findViewById(R.id.wallet_button); - mQRCodeScannerButton = findViewById(R.id.qr_code_scanner_button); - mControlsButton = findViewById(R.id.controls_button); - mIndicationArea = findViewById(R.id.keyguard_indication_area); - mAmbientIndicationArea = findViewById(R.id.ambient_indication_container); - mIndicationText = findViewById(R.id.keyguard_indication_text); - mIndicationTextBottom = findViewById(R.id.keyguard_indication_text_bottom); - mIndicationBottomMargin = getResources().getDimensionPixelSize( - R.dimen.keyguard_indication_margin_bottom); - mBurnInYOffset = getResources().getDimensionPixelSize( - R.dimen.default_burn_in_prevention_offset); - mKeyguardStateController = Dependency.get(KeyguardStateController.class); - mKeyguardStateController.addCallback(mKeyguardStateCallback); - setClipChildren(false); - setClipToPadding(false); - mActivityStarter = Dependency.get(ActivityStarter.class); - - mIndicationPadding = getResources().getDimensionPixelSize( - R.dimen.keyguard_indication_area_padding); - updateWalletVisibility(); - updateQRCodeButtonVisibility(); - updateControlsVisibility(); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - if (mUsesBinder) { - return; - } - - final IntentFilter filter = new IntentFilter(); - filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED); - mKeyguardStateController.addCallback(mKeyguardStateCallback); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - if (mUsesBinder) { - return; - } - - mKeyguardStateController.removeCallback(mKeyguardStateCallback); - - if (mQuickAccessWalletController != null) { - mQuickAccessWalletController.unregisterWalletChangeObservers( - WALLET_PREFERENCE_CHANGE, DEFAULT_PAYMENT_APP_CHANGE); - } - - if (mQRCodeScannerController != null) { - mQRCodeScannerController.unregisterQRCodeScannerChangeObservers( - QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE, - QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE); - } - - if (mControlsComponent != null) { - mControlsComponent.getControlsListingController().ifPresent( - c -> c.removeCallback(mListingCallback)); - } - } - - @Override - protected void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - if (mUsesBinder) { - if (mBinding != null) { - mBinding.onConfigurationChanged(); - } - return; - } - - mIndicationBottomMargin = getResources().getDimensionPixelSize( - R.dimen.keyguard_indication_margin_bottom); - mBurnInYOffset = getResources().getDimensionPixelSize( - R.dimen.default_burn_in_prevention_offset); - MarginLayoutParams mlp = (MarginLayoutParams) mIndicationArea.getLayoutParams(); - if (mlp.bottomMargin != mIndicationBottomMargin) { - mlp.bottomMargin = mIndicationBottomMargin; - mIndicationArea.setLayoutParams(mlp); - } - - // Respect font size setting. - mIndicationTextBottom.setTextSize(TypedValue.COMPLEX_UNIT_PX, - getResources().getDimensionPixelSize( - com.android.internal.R.dimen.text_size_small_material)); - mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX, - getResources().getDimensionPixelSize( - com.android.internal.R.dimen.text_size_small_material)); - - ViewGroup.LayoutParams lp = mWalletButton.getLayoutParams(); - lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width); - lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height); - mWalletButton.setLayoutParams(lp); - - lp = mQRCodeScannerButton.getLayoutParams(); - lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width); - lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height); - mQRCodeScannerButton.setLayoutParams(lp); - - lp = mControlsButton.getLayoutParams(); - lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width); - lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height); - mControlsButton.setLayoutParams(lp); - - mIndicationPadding = getResources().getDimensionPixelSize( - R.dimen.keyguard_indication_area_padding); - - updateWalletVisibility(); - updateQRCodeButtonVisibility(); - updateAffordanceColors(); - } - - private void updateWalletVisibility() { - if (mUsesBinder) { - return; - } - - if (mDozing - || mQuickAccessWalletController == null - || !mQuickAccessWalletController.isWalletEnabled() - || !mHasCard) { - mWalletButton.setVisibility(GONE); - - if (mControlsButton.getVisibility() == GONE) { - mIndicationArea.setPadding(0, 0, 0, 0); - } - } else { - mWalletButton.setVisibility(VISIBLE); - mWalletButton.setOnClickListener(this::onWalletClick); - mIndicationArea.setPadding(mIndicationPadding, 0, mIndicationPadding, 0); - } - } - - private void updateControlsVisibility() { - if (mUsesBinder) { - return; - } - - if (mControlsComponent == null) return; - - mControlsButton.setImageResource(mControlsComponent.getTileImageId()); - mControlsButton.setContentDescription(getContext() - .getString(mControlsComponent.getTileTitleId())); - updateAffordanceColors(); - - boolean hasFavorites = mControlsComponent.getControlsController() - .map(c -> c.getFavorites().size() > 0) - .orElse(false); - if (mDozing - || !hasFavorites - || !mControlServicesAvailable - || mControlsComponent.getVisibility() != AVAILABLE) { - mControlsButton.setVisibility(GONE); - if (mWalletButton.getVisibility() == GONE) { - mIndicationArea.setPadding(0, 0, 0, 0); - } - } else { - mControlsButton.setVisibility(VISIBLE); - mControlsButton.setOnClickListener(this::onControlsClick); - mIndicationArea.setPadding(mIndicationPadding, 0, mIndicationPadding, 0); - } - } - - public void setDarkAmount(float darkAmount) { - if (mUsesBinder) { - return; - } - - if (darkAmount == mDarkAmount) { - return; - } - mDarkAmount = darkAmount; - dozeTimeTick(); - } - - /** - * Returns a list of animators to use to animate the indication areas. - */ - public List<ViewPropertyAnimator> getIndicationAreaAnimators() { - if (mUsesBinder) { - return checkNotNull(mBinding).getIndicationAreaAnimators(); - } - - List<ViewPropertyAnimator> animators = - new ArrayList<>(mAmbientIndicationArea != null ? 2 : 1); - animators.add(mIndicationArea.animate()); - if (mAmbientIndicationArea != null) { - animators.add(mAmbientIndicationArea.animate()); - } - return animators; - } - - @Override - public boolean hasOverlappingRendering() { - return false; - } - - private void startFinishDozeAnimation() { - long delay = 0; - if (mWalletButton.getVisibility() == View.VISIBLE) { - startFinishDozeAnimationElement(mWalletButton, delay); - } - if (mQRCodeScannerButton.getVisibility() == View.VISIBLE) { - startFinishDozeAnimationElement(mQRCodeScannerButton, delay); - } - if (mControlsButton.getVisibility() == View.VISIBLE) { - startFinishDozeAnimationElement(mControlsButton, delay); - } - } - - private void startFinishDozeAnimationElement(View element, long delay) { - element.setAlpha(0f); - element.setTranslationY(element.getHeight() / 2); - element.animate() - .alpha(1f) - .translationY(0f) - .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN) - .setStartDelay(delay) - .setDuration(DOZE_ANIMATION_ELEMENT_DURATION); - } - - public void setDozing(boolean dozing, boolean animate) { - if (mUsesBinder) { - return; - } - - mDozing = dozing; - - updateWalletVisibility(); - updateControlsVisibility(); - updateQRCodeButtonVisibility(); - - if (dozing) { - mOverlayContainer.setVisibility(INVISIBLE); - } else { - mOverlayContainer.setVisibility(VISIBLE); - if (animate) { - startFinishDozeAnimation(); - } - } - } - - public void dozeTimeTick() { - if (mUsesBinder) { - return; - } - - int burnInYOffset = getBurnInOffset(mBurnInYOffset * 2, false /* xAxis */) - - mBurnInYOffset; - mIndicationArea.setTranslationY(burnInYOffset * mDarkAmount); - if (mAmbientIndicationArea != null) { - mAmbientIndicationArea.setTranslationY(burnInYOffset * mDarkAmount); - } - } - - public void setAntiBurnInOffsetX(int burnInXOffset) { - if (mUsesBinder) { - return; - } - - if (mBurnInXOffset == burnInXOffset) { - return; - } - mBurnInXOffset = burnInXOffset; - mIndicationArea.setTranslationX(burnInXOffset); - if (mAmbientIndicationArea != null) { - mAmbientIndicationArea.setTranslationX(burnInXOffset); - } - } - - /** - * Sets the alpha of various sub-components, for example the indication areas and bottom quick - * action buttons. Does not set the alpha of the lock icon. - */ - public void setComponentAlphas(float alpha) { - if (mUsesBinder) { - return; - } - - setImportantForAccessibility( - alpha == 0f - ? View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS - : View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); - if (mAmbientIndicationArea != null) { - mAmbientIndicationArea.setAlpha(alpha); - } - mIndicationArea.setAlpha(alpha); - mWalletButton.setAlpha(alpha); - mQRCodeScannerButton.setAlpha(alpha); - mControlsButton.setAlpha(alpha); - } - - @Override - public WindowInsets onApplyWindowInsets(WindowInsets insets) { - int bottom = insets.getDisplayCutout() != null - ? insets.getDisplayCutout().getSafeInsetBottom() : 0; - if (isPaddingRelative()) { - setPaddingRelative(getPaddingStart(), getPaddingTop(), getPaddingEnd(), bottom); - } else { - setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), bottom); - } - return insets; - } - - private void updateQRCodeButtonVisibility() { - if (mUsesBinder) { - return; - } - - if (mQuickAccessWalletController != null - && mQuickAccessWalletController.isWalletEnabled()) { - // Don't enable if quick access wallet is enabled - return; - } - - if (mQRCodeScannerController != null - && mQRCodeScannerController.isEnabledForLockScreenButton()) { - mQRCodeScannerButton.setVisibility(VISIBLE); - mQRCodeScannerButton.setOnClickListener(this::onQRCodeScannerClicked); - mIndicationArea.setPadding(mIndicationPadding, 0, mIndicationPadding, 0); - } else { - mQRCodeScannerButton.setVisibility(GONE); - if (mControlsButton.getVisibility() == GONE) { - mIndicationArea.setPadding(0, 0, 0, 0); - } - } - } - - private void onQRCodeScannerClicked(View view) { - if (mUsesBinder) { - return; - } - - Intent intent = mQRCodeScannerController.getIntent(); - if (intent != null) { - try { - ActivityTaskManager.getService().startActivityAsUser( - null, getContext().getBasePackageName(), - getContext().getAttributionTag(), intent, - intent.resolveTypeIfNeeded(getContext().getContentResolver()), - null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, - UserHandle.CURRENT.getIdentifier()); - } catch (RemoteException e) { - // This is unexpected. Nonetheless, just log the error and prevent the UI from - // crashing - Log.e(TAG, "Unexpected intent: " + intent - + " when the QR code scanner button was clicked"); - } - } - } - - private void updateAffordanceColors() { - if (mUsesBinder) { - return; - } - - int iconColor = Utils.getColorAttrDefaultColor( - mContext, - com.android.internal.R.attr.textColorPrimary); - mWalletButton.getDrawable().setTint(iconColor); - mControlsButton.getDrawable().setTint(iconColor); - mQRCodeScannerButton.getDrawable().setTint(iconColor); - - ColorStateList bgColor = Utils.getColorAttr( - mContext, - com.android.internal.R.attr.colorSurface); - mWalletButton.setBackgroundTintList(bgColor); - mControlsButton.setBackgroundTintList(bgColor); - mQRCodeScannerButton.setBackgroundTintList(bgColor); - } - - private void onWalletClick(View v) { - if (mUsesBinder) { - return; - } - - // More coming here; need to inform the user about how to proceed - if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { - return; - } - - ActivityLaunchAnimator.Controller animationController = createLaunchAnimationController(v); - mQuickAccessWalletController.startQuickAccessUiIntent( - mActivityStarter, animationController, mHasCard); - } - - protected ActivityLaunchAnimator.Controller createLaunchAnimationController(View view) { - return ActivityLaunchAnimator.Controller.fromView(view, null); - } - - private void onControlsClick(View v) { - if (mUsesBinder) { - return; - } - - if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { - return; - } - - Intent intent = new Intent(mContext, ControlsActivity.class) - .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK) - .putExtra(ControlsUiController.EXTRA_ANIMATE, true); - - ActivityLaunchAnimator.Controller controller = - v != null ? ActivityLaunchAnimator.Controller.fromView(v, null /* cujType */) - : null; - if (mControlsComponent.getVisibility() == AVAILABLE) { - mActivityStarter.startActivity(intent, true /* dismissShade */, controller, - true /* showOverLockscreenWhenLocked */); - } else { - mActivityStarter.postStartActivityDismissingKeyguard(intent, 0 /* delay */, controller); - } - } - - private class WalletCardRetriever implements - QuickAccessWalletClient.OnWalletCardsRetrievedCallback { - - @Override - public void onWalletCardsRetrieved(@NonNull GetWalletCardsResponse response) { - mHasCard = !response.getWalletCards().isEmpty(); - Drawable tileIcon = mQuickAccessWalletController.getWalletClient().getTileIcon(); - if (tileIcon != null) { - mWalletButton.setImageDrawable(tileIcon); - } - post(() -> { - updateWalletVisibility(); - updateAffordanceColors(); - }); - } - - @Override - public void onWalletCardRetrievalError(@NonNull GetWalletCardsError error) { - mHasCard = false; - post(() -> { - updateWalletVisibility(); - updateAffordanceColors(); - }); - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt new file mode 100644 index 000000000000..4897c529dd51 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.kt @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2014 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.phone + +import android.content.Context +import android.content.res.Configuration +import android.util.AttributeSet +import android.view.View +import android.view.ViewGroup +import android.view.ViewPropertyAnimator +import android.view.WindowInsets +import android.widget.FrameLayout +import com.android.systemui.R +import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder +import com.android.systemui.keyguard.ui.binder.KeyguardBottomAreaViewBinder.bind +import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel +import com.android.systemui.plugins.FalsingManager + +/** + * Renders the bottom area of the lock-screen. Concerned primarily with the quick affordance UI + * elements. A secondary concern is the interaction of the quick affordance elements with the + * indication area between them, though the indication area is primarily controlled elsewhere. + */ +class KeyguardBottomAreaView +@JvmOverloads +constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, + defStyleRes: Int = 0, +) : + FrameLayout( + context, + attrs, + defStyleAttr, + defStyleRes, + ) { + + private var ambientIndicationArea: View? = null + private lateinit var binding: KeyguardBottomAreaViewBinder.Binding + + /** Initializes the view. */ + fun init( + viewModel: KeyguardBottomAreaViewModel, + falsingManager: FalsingManager, + ) { + binding = bind(this, viewModel, falsingManager) + } + + /** + * Initializes this instance of [KeyguardBottomAreaView] based on the given instance of another + * [KeyguardBottomAreaView] + */ + fun initFrom(oldBottomArea: KeyguardBottomAreaView) { + // if it exists, continue to use the original ambient indication container + // instead of the newly inflated one + ambientIndicationArea?.let { nonNullAmbientIndicationArea -> + // remove old ambient indication from its parent + val originalAmbientIndicationView = + oldBottomArea.findViewById<View>(R.id.ambient_indication_container) + (originalAmbientIndicationView.parent as ViewGroup).removeView( + originalAmbientIndicationView + ) + + // remove current ambient indication from its parent (discard) + val ambientIndicationParent = nonNullAmbientIndicationArea.parent as ViewGroup + val ambientIndicationIndex = + ambientIndicationParent.indexOfChild(nonNullAmbientIndicationArea) + ambientIndicationParent.removeView(nonNullAmbientIndicationArea) + + // add the old ambient indication to this view + ambientIndicationParent.addView(originalAmbientIndicationView, ambientIndicationIndex) + ambientIndicationArea = originalAmbientIndicationView + } + } + + override fun onFinishInflate() { + super.onFinishInflate() + ambientIndicationArea = findViewById(R.id.ambient_indication_container) + } + + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + binding.onConfigurationChanged() + } + + /** Returns a list of animators to use to animate the indication areas. */ + val indicationAreaAnimators: List<ViewPropertyAnimator> + get() = binding.getIndicationAreaAnimators() + + override fun hasOverlappingRendering(): Boolean { + return false + } + + override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets { + val bottom = insets.displayCutout?.safeInsetBottom ?: 0 + if (isPaddingRelative) { + setPaddingRelative(paddingStart, paddingTop, paddingEnd, bottom) + } else { + setPadding(paddingLeft, paddingTop, paddingRight, bottom) + } + return insets + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java index f2670131081f..3224a6f970be 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java @@ -547,8 +547,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mNavigationModeController, mFragmentService, mContentResolver, - mQuickAccessWalletController, - mQrCodeScannerController, mRecordingController, mLargeScreenShadeHeaderController, mScreenOffAnimationController, @@ -556,7 +554,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mPanelExpansionStateManager, mNotificationRemoteInputManager, mSysUIUnfoldComponent, - mControlsComponent, mInteractionJankMonitor, mQsFrameTranslateController, mSysUiState, @@ -569,8 +566,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mShadeTransitionController, mSystemClock, mock(CameraGestureHelper.class), - () -> mKeyguardBottomAreaViewModel, - () -> mKeyguardBottomAreaInteractor); + mKeyguardBottomAreaViewModel, + mKeyguardBottomAreaInteractor); mNotificationPanelViewController.initDependencies( mCentralSurfaces, () -> {}, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt deleted file mode 100644 index 3440fa5ac9b1..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.android.systemui.statusbar.phone - -import android.testing.AndroidTestingRunner -import android.testing.TestableLooper -import android.view.LayoutInflater -import androidx.test.filters.SmallTest -import com.android.systemui.R -import com.android.systemui.SysuiTestCase -import com.android.systemui.assist.AssistManager -import com.android.systemui.plugins.ActivityStarter -import com.android.systemui.statusbar.policy.AccessibilityController -import com.android.systemui.statusbar.policy.FlashlightController -import com.android.systemui.statusbar.policy.KeyguardStateController -import com.android.systemui.tuner.TunerService -import java.util.concurrent.Executor -import org.junit.Before -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.MockitoAnnotations - -@SmallTest -@RunWith(AndroidTestingRunner::class) -@TestableLooper.RunWithLooper(setAsMainLooper = true) -class KeyguardBottomAreaTest : SysuiTestCase() { - - @Mock - private lateinit var mCentralSurfaces: CentralSurfaces - private lateinit var mKeyguardBottomArea: KeyguardBottomAreaView - - @Before - fun setup() { - MockitoAnnotations.initMocks(this) - // Mocked dependencies - mDependency.injectMockDependency(AccessibilityController::class.java) - mDependency.injectMockDependency(ActivityStarter::class.java) - mDependency.injectMockDependency(AssistManager::class.java) - mDependency.injectTestDependency(Executor::class.java, Executor { it.run() }) - mDependency.injectMockDependency(FlashlightController::class.java) - mDependency.injectMockDependency(KeyguardStateController::class.java) - mDependency.injectMockDependency(TunerService::class.java) - - mKeyguardBottomArea = LayoutInflater.from(mContext).inflate( - R.layout.keyguard_bottom_area, null, false) as KeyguardBottomAreaView - } - - @Test - fun initFrom_doesntCrash() { - val other = LayoutInflater.from(mContext).inflate(R.layout.keyguard_bottom_area, - null, false) as KeyguardBottomAreaView - - other.initFrom(mKeyguardBottomArea) - } -} |