Merge "KeyguardBottomAreaView: cleanup." into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
bd23b31777
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
() -> {},
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user