Merge "Implement AAOS-specific KeyguardViewController and decouple keyguard from statusbar." into rvc-dev am: 0abf11e202
Change-Id: Ib4c6ac8f5c4580d89adedfc6ba2b3199633994d9
This commit is contained in:
@@ -18,15 +18,14 @@
|
||||
Car has solid black background instead of a transparent one
|
||||
-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black"
|
||||
android:fitsSystemWindows="true">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black"
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<include
|
||||
style="@style/BouncerSecurityContainer"
|
||||
layout="@layout/keyguard_host_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
</FrameLayout>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<!-- Car customizations
|
||||
Car has solid black background instead of a transparent one
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/keyguard_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"/>
|
||||
@@ -18,7 +18,8 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/fullscreen_user_switcher"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/car_user_switcher_background_color">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/container"
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
android:layout="@layout/notification_panel_container"
|
||||
android:layout_marginBottom="@dimen/navigation_bar_height"/>
|
||||
|
||||
<ViewStub android:id="@+id/keyguard_stub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout="@layout/keyguard_container" />
|
||||
|
||||
<ViewStub android:id="@+id/fullscreen_user_switcher_stub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
@@ -71,8 +71,9 @@
|
||||
|
||||
<!-- Car System UI's OverlayViewsMediator-->
|
||||
<string-array name="config_carSystemUIOverlayViewsMediators" translatable="false">
|
||||
<item>com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator</item>
|
||||
<item>com.android.systemui.car.notification.NotificationPanelViewMediator</item>
|
||||
<item>com.android.systemui.car.keyguard.CarKeyguardViewMediator</item>
|
||||
<item>com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator</item>
|
||||
</string-array>
|
||||
|
||||
<!-- SystemUI Services: The classes of the stuff to start. -->
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.Context;
|
||||
import com.android.keyguard.KeyguardViewController;
|
||||
import com.android.systemui.car.CarDeviceProvisionedController;
|
||||
import com.android.systemui.car.CarDeviceProvisionedControllerImpl;
|
||||
import com.android.systemui.car.keyguard.CarKeyguardViewController;
|
||||
import com.android.systemui.dagger.SystemUIRootComponent;
|
||||
import com.android.systemui.dock.DockManager;
|
||||
import com.android.systemui.dock.DockManagerImpl;
|
||||
@@ -145,7 +146,7 @@ public abstract class CarSystemUIModule {
|
||||
|
||||
@Binds
|
||||
abstract KeyguardViewController bindKeyguardViewController(
|
||||
CarStatusBarKeyguardViewManager keyguardViewManager);
|
||||
CarKeyguardViewController carKeyguardViewController);
|
||||
|
||||
@Binds
|
||||
abstract DeviceProvisionedController bindDeviceProvisionedController(
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.car.keyguard;
|
||||
|
||||
import android.car.Car;
|
||||
import android.car.user.CarUserManager;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewRootImpl;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardViewController;
|
||||
import com.android.keyguard.ViewMediatorCallback;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SystemUIFactory;
|
||||
import com.android.systemui.car.CarServiceProvider;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.keyguard.DismissCallbackRegistry;
|
||||
import com.android.systemui.navigationbar.car.CarNavigationBarController;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.statusbar.phone.BiometricUnlockController;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBouncer;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
|
||||
import com.android.systemui.statusbar.phone.StatusBar;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.window.OverlayViewController;
|
||||
import com.android.systemui.window.OverlayViewGlobalStateController;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Automotive implementation of the {@link KeyguardViewController}. It controls the Keyguard View
|
||||
* that is mounted to the SystemUIOverlayWindow.
|
||||
*/
|
||||
@Singleton
|
||||
public class CarKeyguardViewController extends OverlayViewController implements
|
||||
KeyguardViewController {
|
||||
private static final String TAG = "CarKeyguardViewController";
|
||||
private static final boolean DEBUG = true;
|
||||
|
||||
private final Context mContext;
|
||||
private final Handler mHandler;
|
||||
private final CarServiceProvider mCarServiceProvider;
|
||||
private final KeyguardStateController mKeyguardStateController;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private final LockPatternUtils mLockPatternUtils;
|
||||
private final FalsingManager mFalsingManager;
|
||||
private final KeyguardBypassController mKeyguardBypassController;
|
||||
private final DismissCallbackRegistry mDismissCallbackRegistry;
|
||||
private final ViewMediatorCallback mViewMediatorCallback;
|
||||
private final CarNavigationBarController mCarNavigationBarController;
|
||||
// Needed to instantiate mBouncer.
|
||||
private final KeyguardBouncer.BouncerExpansionCallback
|
||||
mExpansionCallback = new KeyguardBouncer.BouncerExpansionCallback() {
|
||||
@Override
|
||||
public void onFullyShown() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartingToHide() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartingToShow() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFullyHidden() {
|
||||
}
|
||||
};
|
||||
private final CarUserManager.UserLifecycleListener mUserLifecycleListener = (e) -> {
|
||||
if (e.getEventType() == CarUserManager.USER_LIFECYCLE_EVENT_TYPE_UNLOCKED) {
|
||||
revealKeyguardIfBouncerPrepared();
|
||||
}
|
||||
};
|
||||
|
||||
private KeyguardBouncer mBouncer;
|
||||
private OnKeyguardCancelClickedListener mKeyguardCancelClickedListener;
|
||||
private boolean mShowing;
|
||||
|
||||
@Inject
|
||||
public CarKeyguardViewController(
|
||||
Context context,
|
||||
@Main Handler mainHandler,
|
||||
CarServiceProvider carServiceProvider,
|
||||
OverlayViewGlobalStateController overlayViewGlobalStateController,
|
||||
KeyguardStateController keyguardStateController,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
BiometricUnlockController biometricUnlockController,
|
||||
ViewMediatorCallback viewMediatorCallback,
|
||||
CarNavigationBarController carNavigationBarController,
|
||||
/* The params below are only used to reuse KeyguardBouncer */
|
||||
LockPatternUtils lockPatternUtils,
|
||||
DismissCallbackRegistry dismissCallbackRegistry,
|
||||
FalsingManager falsingManager,
|
||||
KeyguardBypassController keyguardBypassController) {
|
||||
|
||||
super(R.id.keyguard_stub, overlayViewGlobalStateController);
|
||||
|
||||
mContext = context;
|
||||
mHandler = mainHandler;
|
||||
mCarServiceProvider = carServiceProvider;
|
||||
mKeyguardStateController = keyguardStateController;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
mFalsingManager = falsingManager;
|
||||
mKeyguardBypassController = keyguardBypassController;
|
||||
mDismissCallbackRegistry = dismissCallbackRegistry;
|
||||
mViewMediatorCallback = viewMediatorCallback;
|
||||
mCarNavigationBarController = carNavigationBarController;
|
||||
|
||||
biometricUnlockController.setKeyguardViewController(this);
|
||||
registerUserSwitchedListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishInflate() {
|
||||
mBouncer = SystemUIFactory.getInstance().createKeyguardBouncer(mContext,
|
||||
mViewMediatorCallback, mLockPatternUtils,
|
||||
getLayout().findViewById(R.id.keyguard_container), mDismissCallbackRegistry,
|
||||
mExpansionCallback, mKeyguardStateController, mFalsingManager,
|
||||
mKeyguardBypassController);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyKeyguardAuthenticated(boolean strongAuth) {
|
||||
mBouncer.notifyKeyguardAuthenticated(strongAuth);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showBouncer(boolean scrimmed) {
|
||||
if (mShowing && !mBouncer.isShowing()) {
|
||||
mBouncer.show(/* resetSecuritySelection= */ false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(Bundle options) {
|
||||
if (mShowing) return;
|
||||
|
||||
mShowing = true;
|
||||
mKeyguardStateController.notifyKeyguardState(mShowing, /* occluded= */ false);
|
||||
mCarNavigationBarController.showAllKeyguardButtons(/* isSetUp= */ true);
|
||||
start();
|
||||
reset(/* hideBouncerWhenShowing= */ false);
|
||||
notifyKeyguardUpdateMonitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hide(long startTime, long fadeoutDuration) {
|
||||
if (!mShowing) return;
|
||||
|
||||
mViewMediatorCallback.readyForKeyguardDone();
|
||||
mShowing = false;
|
||||
mKeyguardStateController.notifyKeyguardState(mShowing, /* occluded= */ false);
|
||||
mBouncer.hide(/* destroyView= */ true);
|
||||
mCarNavigationBarController.hideAllKeyguardButtons(/* isSetUp= */ true);
|
||||
stop();
|
||||
mKeyguardStateController.notifyKeyguardDoneFading();
|
||||
mViewMediatorCallback.keyguardGone();
|
||||
notifyKeyguardUpdateMonitor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset(boolean hideBouncerWhenShowing) {
|
||||
if (mShowing) {
|
||||
if (mBouncer != null) {
|
||||
if (!mBouncer.isSecure()) {
|
||||
dismissAndCollapse();
|
||||
}
|
||||
mBouncer.show(/* resetSecuritySelection= */ true);
|
||||
}
|
||||
mKeyguardUpdateMonitor.sendKeyguardReset();
|
||||
notifyKeyguardUpdateMonitor();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinishedGoingToSleep() {
|
||||
mBouncer.onScreenTurnedOff();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancelClicked() {
|
||||
mBouncer.hide(/* destroyView= */ true);
|
||||
mKeyguardCancelClickedListener.onCancelClicked();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isShowing() {
|
||||
return mShowing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissAndCollapse() {
|
||||
hide(/* startTime= */ 0, /* fadeoutDuration= */ 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPreHideAnimation(Runnable finishRunnable) {
|
||||
mBouncer.startPreHideAnimation(finishRunnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNeedsInput(boolean needsInput) {
|
||||
getLayout().setFocusable(needsInput);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add listener for keyguard cancel clicked.
|
||||
*/
|
||||
public void registerOnKeyguardCancelClickedListener(
|
||||
OnKeyguardCancelClickedListener keyguardCancelClickedListener) {
|
||||
mKeyguardCancelClickedListener = keyguardCancelClickedListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove listener for keyguard cancel clicked.
|
||||
*/
|
||||
public void unregisterOnKeyguardCancelClickedListener(
|
||||
OnKeyguardCancelClickedListener keyguardCancelClickedListener) {
|
||||
mKeyguardCancelClickedListener = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewRootImpl getViewRootImpl() {
|
||||
return ((View) getLayout().getParent()).getViewRootImpl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBouncerShowing() {
|
||||
return mBouncer.isShowing();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean bouncerIsOrWillBeShowing() {
|
||||
return mBouncer.isShowing() || mBouncer.inTransit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyguardGoingAway() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartedGoingToSleep() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartedWakingUp() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScreenTurningOn() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScreenTurnedOn() {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOccluded(boolean occluded, boolean animate) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDisableWindowAnimationsForUnlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGoingToNotificationShade() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnlockWithWallpaper() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSubtleWindowAnimationsForUnlock() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerStatusBar(StatusBar statusBar, ViewGroup container,
|
||||
NotificationPanelViewController notificationPanelViewController,
|
||||
BiometricUnlockController biometricUnlockController,
|
||||
DismissCallbackRegistry dismissCallbackRegistry, ViewGroup lockIconContainer,
|
||||
View notificationContainer, KeyguardBypassController bypassController,
|
||||
FalsingManager falsingManager) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides Keyguard so that the transitioning Bouncer can be hidden until it is prepared. To be
|
||||
* called by {@link com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator}
|
||||
* when a new user is selected.
|
||||
*/
|
||||
public void hideKeyguardToPrepareBouncer() {
|
||||
getLayout().setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
private void revealKeyguardIfBouncerPrepared() {
|
||||
int reattemptDelayMillis = 50;
|
||||
Runnable revealKeyguard = () -> {
|
||||
if (!mBouncer.inTransit() || !mBouncer.isSecure()) {
|
||||
getLayout().setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "revealKeyguardIfBouncerPrepared: Bouncer is not prepared "
|
||||
+ "yet so reattempting after " + reattemptDelayMillis + "ms.");
|
||||
}
|
||||
mHandler.postDelayed(this::revealKeyguardIfBouncerPrepared, reattemptDelayMillis);
|
||||
}
|
||||
};
|
||||
mHandler.post(revealKeyguard);
|
||||
}
|
||||
|
||||
private void notifyKeyguardUpdateMonitor() {
|
||||
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(mShowing);
|
||||
if (mBouncer != null) {
|
||||
mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(isBouncerShowing());
|
||||
}
|
||||
}
|
||||
|
||||
private void registerUserSwitchedListener() {
|
||||
mCarServiceProvider.addListener(car -> {
|
||||
CarUserManager userManager = (CarUserManager) car.getCarManager(Car.CAR_USER_SERVICE);
|
||||
userManager.addListener(Runnable::run, mUserLifecycleListener);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a callback for keyguard cancel button clicked listeners.
|
||||
*/
|
||||
public interface OnKeyguardCancelClickedListener {
|
||||
/**
|
||||
* Called when keyguard cancel button is clicked.
|
||||
*/
|
||||
void onCancelClicked();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.car.keyguard;
|
||||
|
||||
import com.android.systemui.car.userswitcher.FullScreenUserSwitcherViewController;
|
||||
import com.android.systemui.window.OverlayViewMediator;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Manages events originating from the Keyguard service that cause Keyguard or other OverlayWindow
|
||||
* Components to appear or disappear.
|
||||
*/
|
||||
@Singleton
|
||||
public class CarKeyguardViewMediator implements OverlayViewMediator {
|
||||
|
||||
private final CarKeyguardViewController mCarKeyguardViewController;
|
||||
private final FullScreenUserSwitcherViewController mFullScreenUserSwitcherViewController;
|
||||
|
||||
@Inject
|
||||
public CarKeyguardViewMediator(
|
||||
CarKeyguardViewController carKeyguardViewController,
|
||||
FullScreenUserSwitcherViewController fullScreenUserSwitcherViewController
|
||||
) {
|
||||
mCarKeyguardViewController = carKeyguardViewController;
|
||||
mFullScreenUserSwitcherViewController = fullScreenUserSwitcherViewController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerListeners() {
|
||||
mCarKeyguardViewController.registerOnKeyguardCancelClickedListener(
|
||||
mFullScreenUserSwitcherViewController::start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupOverlayContentViewControllers() {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
@@ -16,20 +16,9 @@
|
||||
|
||||
package com.android.systemui.car.userswitcher;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Handler;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.keyguard.ScreenLifecycle;
|
||||
import com.android.systemui.car.keyguard.CarKeyguardViewController;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.car.CarStatusBar;
|
||||
import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
|
||||
import com.android.systemui.window.OverlayViewMediator;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -42,47 +31,24 @@ import javax.inject.Singleton;
|
||||
public class FullscreenUserSwitcherViewMediator implements OverlayViewMediator {
|
||||
private static final String TAG = FullscreenUserSwitcherViewMediator.class.getSimpleName();
|
||||
|
||||
private final Context mContext;
|
||||
private final CarStatusBarKeyguardViewManager mCarStatusBarKeyguardViewManager;
|
||||
private final Handler mMainHandler;
|
||||
private final StatusBarStateController mStatusBarStateController;
|
||||
private final FullScreenUserSwitcherViewController mFullScreenUserSwitcherViewController;
|
||||
private final ScreenLifecycle mScreenLifecycle;
|
||||
private final CarStatusBar mCarStatusBar;
|
||||
private final boolean mIsUserSwitcherEnabled;
|
||||
private final CarKeyguardViewController mCarKeyguardViewController;
|
||||
|
||||
@Inject
|
||||
public FullscreenUserSwitcherViewMediator(
|
||||
Context context,
|
||||
@Main Resources resources,
|
||||
@Main Handler mainHandler,
|
||||
CarStatusBarKeyguardViewManager carStatusBarKeyguardViewManager,
|
||||
CarStatusBar carStatusBar,
|
||||
StatusBarStateController statusBarStateController,
|
||||
FullScreenUserSwitcherViewController fullScreenUserSwitcherViewController,
|
||||
ScreenLifecycle screenLifecycle) {
|
||||
mContext = context;
|
||||
CarKeyguardViewController carKeyguardViewController,
|
||||
FullScreenUserSwitcherViewController fullScreenUserSwitcherViewController) {
|
||||
|
||||
mIsUserSwitcherEnabled = resources.getBoolean(R.bool.config_enableFullscreenUserSwitcher);
|
||||
|
||||
mMainHandler = mainHandler;
|
||||
|
||||
mCarStatusBarKeyguardViewManager = carStatusBarKeyguardViewManager;
|
||||
mCarStatusBar = carStatusBar;
|
||||
mStatusBarStateController = statusBarStateController;
|
||||
mFullScreenUserSwitcherViewController = fullScreenUserSwitcherViewController;
|
||||
mScreenLifecycle = screenLifecycle;
|
||||
mCarKeyguardViewController = carKeyguardViewController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerListeners() {
|
||||
registerUserSwitcherShowListeners();
|
||||
registerUserSwitcherHideListeners();
|
||||
registerHideKeyguardListeners();
|
||||
}
|
||||
|
||||
private void registerUserSwitcherShowListeners() {
|
||||
mCarStatusBarKeyguardViewManager.addOnKeyguardCancelClickedListener(this::show);
|
||||
}
|
||||
|
||||
private void registerUserSwitcherHideListeners() {
|
||||
@@ -97,37 +63,6 @@ public class FullscreenUserSwitcherViewMediator implements OverlayViewMediator {
|
||||
});
|
||||
}
|
||||
|
||||
private void registerHideKeyguardListeners() {
|
||||
mStatusBarStateController.addCallback(new StatusBarStateController.StateListener() {
|
||||
@Override
|
||||
public void onStateChanged(int newState) {
|
||||
if (newState != StatusBarState.FULLSCREEN_USER_SWITCHER) {
|
||||
return;
|
||||
}
|
||||
dismissKeyguardWhenUserSwitcherNotDisplayed(newState);
|
||||
}
|
||||
});
|
||||
|
||||
mScreenLifecycle.addObserver(new ScreenLifecycle.Observer() {
|
||||
@Override
|
||||
public void onScreenTurnedOn() {
|
||||
dismissKeyguardWhenUserSwitcherNotDisplayed(mStatusBarStateController.getState());
|
||||
}
|
||||
});
|
||||
|
||||
mContext.registerReceiver(new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (!intent.getAction().equals(Intent.ACTION_USER_SWITCHED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to dismiss the keyguard after every user switch.
|
||||
dismissKeyguardWhenUserSwitcherNotDisplayed(mStatusBarStateController.getState());
|
||||
}
|
||||
}, new IntentFilter(Intent.ACTION_USER_SWITCHED));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupOverlayContentViewControllers() {
|
||||
mFullScreenUserSwitcherViewController.setUserGridSelectionListener(this::onUserSelected);
|
||||
@@ -135,33 +70,13 @@ public class FullscreenUserSwitcherViewMediator implements OverlayViewMediator {
|
||||
|
||||
/**
|
||||
* Every time user clicks on an item in the switcher, we hide the switcher.
|
||||
*
|
||||
* We dismiss the entire keyguard if user clicked on the foreground user (user we're already
|
||||
* logged in as).
|
||||
*/
|
||||
private void onUserSelected(UserGridRecyclerView.UserRecord record) {
|
||||
if (record.mType != UserGridRecyclerView.UserRecord.FOREGROUND_USER) {
|
||||
mCarKeyguardViewController.hideKeyguardToPrepareBouncer();
|
||||
}
|
||||
|
||||
hide();
|
||||
if (record.mType == UserGridRecyclerView.UserRecord.FOREGROUND_USER) {
|
||||
mCarStatusBar.dismissKeyguard();
|
||||
}
|
||||
}
|
||||
|
||||
// We automatically dismiss keyguard unless user switcher is being shown above the keyguard.
|
||||
private void dismissKeyguardWhenUserSwitcherNotDisplayed(int state) {
|
||||
if (!mIsUserSwitcherEnabled) {
|
||||
return; // Not using the full screen user switcher.
|
||||
}
|
||||
|
||||
if (state == StatusBarState.FULLSCREEN_USER_SWITCHER
|
||||
&& !mFullScreenUserSwitcherViewController.isVisible()) {
|
||||
// Current execution path continues to set state after this, thus we deffer the
|
||||
// dismissal to the next execution cycle.
|
||||
|
||||
// Dismiss the keyguard if switcher is not visible.
|
||||
// TODO(b/150402329): Remove once keyguard is implemented using Overlay Window
|
||||
// abstractions.
|
||||
mMainHandler.post(mCarStatusBar::dismissKeyguard);
|
||||
}
|
||||
}
|
||||
|
||||
private void hide() {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.window;
|
||||
|
||||
import com.android.systemui.car.keyguard.CarKeyguardViewMediator;
|
||||
import com.android.systemui.car.notification.NotificationPanelViewMediator;
|
||||
import com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator;
|
||||
|
||||
@@ -29,12 +30,6 @@ import dagger.multibindings.IntoMap;
|
||||
*/
|
||||
@Module
|
||||
public abstract class OverlayWindowModule {
|
||||
/** Injects FullscreenUserSwitcherViewsMediator. */
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(FullscreenUserSwitcherViewMediator.class)
|
||||
public abstract OverlayViewMediator bindFullscreenUserSwitcherViewsMediator(
|
||||
FullscreenUserSwitcherViewMediator overlayViewsMediator);
|
||||
|
||||
/** Injects NotificationPanelViewMediator. */
|
||||
@Binds
|
||||
@@ -42,4 +37,18 @@ public abstract class OverlayWindowModule {
|
||||
@ClassKey(NotificationPanelViewMediator.class)
|
||||
public abstract OverlayViewMediator bindNotificationPanelViewMediator(
|
||||
NotificationPanelViewMediator notificationPanelViewMediator);
|
||||
|
||||
/** Inject into CarKeyguardViewMediator. */
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(CarKeyguardViewMediator.class)
|
||||
public abstract OverlayViewMediator bindCarKeyguardViewMediator(
|
||||
CarKeyguardViewMediator carKeyguardViewMediator);
|
||||
|
||||
/** Injects FullscreenUserSwitcherViewsMediator. */
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(FullscreenUserSwitcherViewMediator.class)
|
||||
public abstract OverlayViewMediator bindFullscreenUserSwitcherViewsMediator(
|
||||
FullscreenUserSwitcherViewMediator overlayViewsMediator);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,9 @@ import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
|
||||
import static android.view.ViewRootImpl.sNewInsetsMode;
|
||||
import static android.view.WindowInsets.Type.ime;
|
||||
import static android.view.WindowInsets.Type.systemBars;
|
||||
|
||||
import static com.android.systemui.DejankUtils.whitelistIpcs;
|
||||
|
||||
import static java.lang.Integer.max;
|
||||
|
||||
import android.app.Activity;
|
||||
@@ -28,7 +30,6 @@ import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.Rect;
|
||||
import android.metrics.LogMaker;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
@@ -147,6 +147,28 @@ public interface KeyguardViewController {
|
||||
*/
|
||||
ViewRootImpl getViewRootImpl();
|
||||
|
||||
/**
|
||||
* Notifies that the user has authenticated by other means than using the bouncer, for example,
|
||||
* fingerprint.
|
||||
*/
|
||||
void notifyKeyguardAuthenticated(boolean strongAuth);
|
||||
|
||||
/**
|
||||
* Shows the Bouncer.
|
||||
*
|
||||
*/
|
||||
void showBouncer(boolean scrimmed);
|
||||
|
||||
/**
|
||||
* Returns {@code true} when the bouncer is currently showing
|
||||
*/
|
||||
boolean isBouncerShowing();
|
||||
|
||||
/**
|
||||
* When bouncer is fully visible or it is showing but animation didn't finish yet.
|
||||
*/
|
||||
boolean bouncerIsOrWillBeShowing();
|
||||
|
||||
// TODO: Deprecate registerStatusBar in KeyguardViewController interface. It is currently
|
||||
// only used for testing purposes in StatusBarKeyguardViewManager, and it prevents us from
|
||||
// achieving complete abstraction away from where the Keyguard View is mounted.
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.android.internal.util.LatencyTracker;
|
||||
import com.android.keyguard.KeyguardConstants;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.keyguard.KeyguardViewController;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
@@ -145,7 +146,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
private final Context mContext;
|
||||
private final int mWakeUpDelay;
|
||||
private int mMode;
|
||||
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
|
||||
private KeyguardViewController mKeyguardViewController;
|
||||
private DozeScrimController mDozeScrimController;
|
||||
private KeyguardViewMediator mKeyguardViewMediator;
|
||||
private ScrimController mScrimController;
|
||||
@@ -204,9 +205,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
dumpManager.registerDumpable(getClass().getName(), this);
|
||||
}
|
||||
|
||||
public void setStatusBarKeyguardViewManager(
|
||||
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
|
||||
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
|
||||
public void setKeyguardViewController(KeyguardViewController keyguardViewController) {
|
||||
mKeyguardViewController = keyguardViewController;
|
||||
}
|
||||
|
||||
private final Runnable mReleaseBiometricWakeLockRunnable = new Runnable() {
|
||||
@@ -328,7 +328,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
case MODE_DISMISS_BOUNCER:
|
||||
case MODE_UNLOCK_FADING:
|
||||
Trace.beginSection("MODE_DISMISS_BOUNCER or MODE_UNLOCK_FADING");
|
||||
mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(
|
||||
mKeyguardViewController.notifyKeyguardAuthenticated(
|
||||
false /* strongAuth */);
|
||||
Trace.endSection();
|
||||
break;
|
||||
@@ -376,7 +376,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
|
||||
private void showBouncer() {
|
||||
if (mMode == MODE_SHOW_BOUNCER) {
|
||||
mStatusBarKeyguardViewManager.showBouncer(false);
|
||||
mKeyguardViewController.showBouncer(false);
|
||||
}
|
||||
mShadeController.animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE, true /* force */,
|
||||
false /* delayed */, BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR);
|
||||
@@ -431,7 +431,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
boolean deviceDreaming = mUpdateMonitor.isDreaming();
|
||||
|
||||
if (!mUpdateMonitor.isDeviceInteractive()) {
|
||||
if (!mStatusBarKeyguardViewManager.isShowing()) {
|
||||
if (!mKeyguardViewController.isShowing()) {
|
||||
return MODE_ONLY_WAKE;
|
||||
} else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
|
||||
return MODE_WAKE_AND_UNLOCK_PULSING;
|
||||
@@ -444,12 +444,12 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
if (unlockingAllowed && deviceDreaming) {
|
||||
return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
|
||||
}
|
||||
if (mStatusBarKeyguardViewManager.isShowing()) {
|
||||
if (mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing() && unlockingAllowed) {
|
||||
if (mKeyguardViewController.isShowing()) {
|
||||
if (mKeyguardViewController.bouncerIsOrWillBeShowing() && unlockingAllowed) {
|
||||
return MODE_DISMISS_BOUNCER;
|
||||
} else if (unlockingAllowed) {
|
||||
return MODE_UNLOCK_COLLAPSING;
|
||||
} else if (!mStatusBarKeyguardViewManager.isBouncerShowing()) {
|
||||
} else if (!mKeyguardViewController.isBouncerShowing()) {
|
||||
return MODE_SHOW_BOUNCER;
|
||||
}
|
||||
}
|
||||
@@ -463,7 +463,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
boolean bypass = mKeyguardBypassController.getBypassEnabled();
|
||||
|
||||
if (!mUpdateMonitor.isDeviceInteractive()) {
|
||||
if (!mStatusBarKeyguardViewManager.isShowing()) {
|
||||
if (!mKeyguardViewController.isShowing()) {
|
||||
return bypass ? MODE_WAKE_AND_UNLOCK : MODE_ONLY_WAKE;
|
||||
} else if (!unlockingAllowed) {
|
||||
return bypass ? MODE_SHOW_BOUNCER : MODE_NONE;
|
||||
@@ -484,8 +484,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback imp
|
||||
if (unlockingAllowed && deviceDreaming) {
|
||||
return bypass ? MODE_WAKE_AND_UNLOCK_FROM_DREAM : MODE_ONLY_WAKE;
|
||||
}
|
||||
if (mStatusBarKeyguardViewManager.isShowing()) {
|
||||
if (mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing() && unlockingAllowed) {
|
||||
if (mKeyguardViewController.isShowing()) {
|
||||
if (mKeyguardViewController.bouncerIsOrWillBeShowing() && unlockingAllowed) {
|
||||
if (bypass && mKeyguardBypassController.canPlaySubtleWindowAnimations()) {
|
||||
return MODE_UNLOCK_FADING;
|
||||
} else {
|
||||
|
||||
@@ -1399,7 +1399,7 @@ public class StatusBar extends SystemUI implements DemoMode,
|
||||
mStackScroller, mKeyguardBypassController, mFalsingManager);
|
||||
mKeyguardIndicationController
|
||||
.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
|
||||
mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
|
||||
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
|
||||
mRemoteInputManager.getController().addCallback(mStatusBarKeyguardViewManager);
|
||||
mDynamicPrivacyController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
|
||||
|
||||
|
||||
@@ -744,14 +744,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBouncerShowing() {
|
||||
return mBouncer.isShowing();
|
||||
}
|
||||
|
||||
/**
|
||||
* When bouncer is fully visible or {@link KeyguardBouncer#show(boolean)} was called but
|
||||
* animation didn't finish yet.
|
||||
*/
|
||||
@Override
|
||||
public boolean bouncerIsOrWillBeShowing() {
|
||||
return mBouncer.isShowing() || mBouncer.inTransit();
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
||||
mNotificationShadeWindowController, mKeyguardStateController, mHandler,
|
||||
mUpdateMonitor, res.getResources(), mKeyguardBypassController, mDozeParameters,
|
||||
mMetricsLogger, mDumpManager);
|
||||
mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
|
||||
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -202,7 +202,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void onBiometricAuthenticated_whenFace_andBypass_dismissKeyguard() {
|
||||
when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
|
||||
mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
|
||||
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
|
||||
|
||||
when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(true);
|
||||
// the value of isStrongBiometric doesn't matter here since we only care about the returned
|
||||
@@ -221,7 +221,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
||||
public void onBiometricAuthenticated_whenFace_andBypass_encrypted_showBouncer() {
|
||||
reset(mUpdateMonitor);
|
||||
when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
|
||||
mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
|
||||
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
|
||||
|
||||
when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||
// the value of isStrongBiometric doesn't matter here since we only care about the returned
|
||||
@@ -241,7 +241,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void onBiometricAuthenticated_whenFace_noBypass_encrypted_doNothing() {
|
||||
reset(mUpdateMonitor);
|
||||
mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
|
||||
mBiometricUnlockController.setKeyguardViewController(mStatusBarKeyguardViewManager);
|
||||
|
||||
when(mUpdateMonitor.isUnlockingWithBiometricAllowed(anyBoolean())).thenReturn(false);
|
||||
// the value of isStrongBiometric doesn't matter here since we only care about the returned
|
||||
|
||||
@@ -36,7 +36,6 @@ import android.provider.Settings;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
@@ -59,12 +58,6 @@ final class CarUserSwitchingDialog extends UserSwitchingDialog {
|
||||
String switchingToSystemUserMessage) {
|
||||
super(service, context, oldUser, newUser, aboveSystem, switchingFromSystemUserMessage,
|
||||
switchingToSystemUserMessage);
|
||||
|
||||
// {@link UserSwitchingDialog} uses {@link WindowManager.LayoutParams.TYPE_SYSTEM_ERROR}
|
||||
// when trying to show dialog above system. That window type has been deprecated and since
|
||||
// this is a system dialog, hence, it makes sense to put this in System Dialog Window.
|
||||
// This window also automatically shows status bar.
|
||||
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user