Merge tag 'android-13.0.0_r52' into int/13/fp3
Android 13.0.0 Release 52 (TQ3A.230605.012)
* tag 'android-13.0.0_r52': (22 commits)
Update pre-hide animation logic
[DO NOT MERGE] Re-focus pin view when focus becomes allowed
Change order of views in notification_center_activity.xml
[DO NOT MERGE] Update constructor
Revert "[DO NOT MERGE] Update constructor"
Revert "[DO NOT MERGE] Update constructor"
Revert "[DO NOT MERGE] Update constructor"
[DO NOT MERGE] Update constructor
Import translations. DO NOT MERGE ANYWHERE
Remove BouncerInteractor#onFinishedGoingToSleep
[DO NOT MERGE] Add StatusBarEventsModule to CarSystemUIModule
Revert^2 "Remove host_view xml"
Removed GarbageMonitor Service Bind
Revert "Remove host_view xml"
Remove host_view xml
DO NOT MERGE Prevent privacy dot from showing on status bar
Remove keyguard bouncer in carsysui.
Handle config changes in ActivityBlockingActivity to prevent restart
[DO NOT MERGE] Update dependencies for DisplayTracker
Import translations. DO NOT MERGE ANYWHERE
...
Change-Id: Ic9d4d87073c3544be158f491ddeb4cd46852145c
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1de33dc..8222822 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -55,6 +55,7 @@
android:name=".car.activity.ActivityBlockingActivity"
android:documentLaunchMode="always"
android:excludeFromRecents="true"
+ android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:exported="false"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
diff --git a/res-keyguard/layout/keyguard_bouncer.xml b/res-keyguard/layout/keyguard_bouncer.xml
index e3e32bd..a6fd243 100644
--- a/res-keyguard/layout/keyguard_bouncer.xml
+++ b/res-keyguard/layout/keyguard_bouncer.xml
@@ -23,7 +23,7 @@
android:background="@android:color/black"
android:fitsSystemWindows="true">
<include
- layout="@layout/keyguard_host_view"
+ layout="@layout/keyguard_security_container_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/managed_device"/>
diff --git a/res/layout/notification_center_activity.xml b/res/layout/notification_center_activity.xml
index 6343f05..def7dde 100644
--- a/res/layout/notification_center_activity.xml
+++ b/res/layout/notification_center_activity.xml
@@ -30,8 +30,17 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"
- />
+ app:layout_constraintTop_toTopOf="parent"/>
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/notifications"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingBottom="@dimen/notification_shade_list_padding_bottom"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/empty_notification_text"
@@ -60,18 +69,7 @@
android:text="@string/manage_text"
android:visibility="gone"/>
- <androidx.recyclerview.widget.RecyclerView
- android:id="@+id/notifications"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:paddingBottom="@dimen/notification_shade_list_padding_bottom"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toTopOf="parent"/>
-
<include
layout="@layout/notification_handle_bar"
app:layout_constraintBottom_toBottomOf="parent"/>
-
</com.android.car.notification.CarNotificationView>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index ddeb519..11137bf 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -77,7 +77,7 @@
<string name="exit_button_go_back" msgid="7988866855775300902">"Indietro"</string>
<string name="qc_footer_settings" msgid="5471523941092316743">"Impostazioni"</string>
<string name="qc_footer_bluetooth_settings" msgid="2870204430643762847">"Impostazioni Bluetooth"</string>
- <string name="qc_footer_network_internet_settings" msgid="2480582764252681575">"Impostazioni di rete e Internet"</string>
+ <string name="qc_footer_network_internet_settings" msgid="2480582764252681575">"Impostazioni di rete e internet"</string>
<string name="qc_footer_display_settings" msgid="2950539240110437704">"Impostazioni Display"</string>
<string name="qc_footer_network_sound_settings" msgid="5117011034908775097">"Impostazioni audio"</string>
<string name="qc_footer_profiles_accounts_settings" msgid="4456419248123950232">"Impostazioni del profilo e dell\'account"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index a51f526..38c015a 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -36,7 +36,7 @@
<string name="privacy_chip_off_content" msgid="8406415098507955316">"<xliff:g id="SENSOR">%1$s</xliff:g> өчүк."</string>
<string name="privacy_chip_use_sensor" msgid="7688230720803089653">"<xliff:g id="SENSOR">%1$s</xliff:g> колдонуу"</string>
<string name="privacy_chip_use_sensor_subtext" msgid="5655148288310815742">"Уруксаты бар колдонмолор үчүн"</string>
- <string name="mic_privacy_chip_microphone_settings" msgid="4520886720588226450">"Микрофондун жөндөөлөрү"</string>
+ <string name="mic_privacy_chip_microphone_settings" msgid="4520886720588226450">"Микрофондун параметрлери"</string>
<string name="privacy_chip_app_using_sensor_suffix" msgid="7921315376271490004">"<xliff:g id="APP">%1$s</xliff:g> төмөнкүнү колдонуп жатат: <xliff:g id="SENSOR">%2$s</xliff:g>"</string>
<string name="mic_privacy_chip_apps_using_mic_suffix" msgid="6656026041668305817">"<xliff:g id="APP_LIST">%s</xliff:g> микрофонду колдонуп жатышат"</string>
<string name="privacy_chip_app_recently_used_sensor_suffix" msgid="4632772067170022529">"<xliff:g id="APP">%1$s</xliff:g> жакында төмөнкүнү колдонду: <xliff:g id="SENSOR">%2$s</xliff:g>"</string>
@@ -46,7 +46,7 @@
<string name="mic_privacy_chip_dialog_ok" msgid="2298690833121720237">"Макул"</string>
<string name="sensor_privacy_start_use_mic_dialog_title" msgid="8774244900043105266">"Унаанын микрофону күйгүзүлсүнбү?"</string>
<string name="sensor_privacy_start_use_mic_dialog_content" msgid="8382980879434990801">"Улантуу үчүн инфозоок тутумунун микрофонун күйгүзүңүз. Ушуну менен уруксаты бар бардык колдонмолор үчүн микрофон иштетилет."</string>
- <string name="camera_privacy_chip_camera_settings" msgid="96342672670928980">"Камеранын жөндөөлөрү"</string>
+ <string name="camera_privacy_chip_camera_settings" msgid="96342672670928980">"Камеранын параметрлери"</string>
<string name="camera_privacy_chip_app_using_camera_suffix" msgid="2591363552459967509">"<xliff:g id="APP">%s</xliff:g> камераны колдонуп жатат"</string>
<string name="camera_privacy_chip_apps_using_camera_suffix" msgid="8033118959615498419">"<xliff:g id="APP_LIST">%s</xliff:g> камераны колдонуп жатышат"</string>
<string name="camera_privacy_chip_app_recently_used_camera_suffix" msgid="4534950658276502559">"<xliff:g id="APP">%s</xliff:g> жакында камераны колдонду"</string>
@@ -75,11 +75,11 @@
<string name="activity_blocked_text" msgid="5353157279548801554">"Бул функцияны унаа айдап баратканда колдоно албайсыз"</string>
<string name="exit_button_close_application" msgid="112227710467017144">"Колдонмону жабуу"</string>
<string name="exit_button_go_back" msgid="7988866855775300902">"Артка"</string>
- <string name="qc_footer_settings" msgid="5471523941092316743">"Жөндөөлөр"</string>
- <string name="qc_footer_bluetooth_settings" msgid="2870204430643762847">"Bluetooth жөндөөлөрү"</string>
- <string name="qc_footer_network_internet_settings" msgid="2480582764252681575">"Тармактын жана Интернеттин жөндөөлөрү"</string>
- <string name="qc_footer_display_settings" msgid="2950539240110437704">"Көрүнүш жөндөөлөрү"</string>
- <string name="qc_footer_network_sound_settings" msgid="5117011034908775097">"Добуштун жөндөөлөрү"</string>
- <string name="qc_footer_profiles_accounts_settings" msgid="4456419248123950232">"Профилдердин жана аккаунттардын жөндөөлөрү"</string>
+ <string name="qc_footer_settings" msgid="5471523941092316743">"Параметрлер"</string>
+ <string name="qc_footer_bluetooth_settings" msgid="2870204430643762847">"Bluetooth параметрлери"</string>
+ <string name="qc_footer_network_internet_settings" msgid="2480582764252681575">"Тармактын жана Интернеттин параметрлери"</string>
+ <string name="qc_footer_display_settings" msgid="2950539240110437704">"Көрүнүш параметрлери"</string>
+ <string name="qc_footer_network_sound_settings" msgid="5117011034908775097">"Добуштун параметрлери"</string>
+ <string name="qc_footer_profiles_accounts_settings" msgid="4456419248123950232">"Профилдердин жана аккаунттардын параметрлери"</string>
<string name="lockpattern_does_not_support_rotary" msgid="4605787900312103476">"Графикалык ачкычта буруу колдоого алынбайт; тийүүнү колдонуңуз"</string>
</resources>
diff --git a/src/com/android/systemui/CarSystemUICoreStartableModule.kt b/src/com/android/systemui/CarSystemUICoreStartableModule.kt
index 1497667..062c74c 100644
--- a/src/com/android/systemui/CarSystemUICoreStartableModule.kt
+++ b/src/com/android/systemui/CarSystemUICoreStartableModule.kt
@@ -32,7 +32,6 @@
import com.android.systemui.theme.ThemeOverlayController
import com.android.systemui.usb.StorageNotification
import com.android.systemui.util.NotificationChannels
-import com.android.systemui.util.leak.GarbageMonitor
import com.android.systemui.wmshell.WMShell
import dagger.Binds
import dagger.Module
@@ -79,12 +78,6 @@
service: ConnectedDeviceVoiceRecognitionNotifier
): CoreStartable
- /** Inject into GarbageMonitor.Service. */
- @Binds
- @IntoMap
- @ClassKey(GarbageMonitor::class)
- abstract fun bindGarbageMonitorService(sysui: GarbageMonitor.Service): CoreStartable
-
/** Inject into KeyguardBiometricLockoutLogger. */
@Binds
@IntoMap
@@ -161,4 +154,4 @@
@IntoMap
@ClassKey(WMShell::class)
abstract fun bindWMShell(sysui: WMShell): CoreStartable
-}
\ No newline at end of file
+}
diff --git a/src/com/android/systemui/CarSystemUIModule.java b/src/com/android/systemui/CarSystemUIModule.java
index 31a2d62..2bb3209 100644
--- a/src/com/android/systemui/CarSystemUIModule.java
+++ b/src/com/android/systemui/CarSystemUIModule.java
@@ -28,6 +28,7 @@
import com.android.keyguard.KeyguardViewController;
import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.car.CarDeviceProvisionedControllerImpl;
+import com.android.systemui.car.decor.CarPrivacyChipViewController;
import com.android.systemui.car.keyguard.CarKeyguardViewController;
import com.android.systemui.car.notification.NotificationShadeWindowControllerImpl;
import com.android.systemui.car.statusbar.DozeServiceHost;
@@ -54,6 +55,8 @@
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
import com.android.systemui.statusbar.NotificationShadeWindowController;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
+import com.android.systemui.statusbar.events.StatusBarEventsModule;
import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
@@ -84,7 +87,8 @@
GestureModule.class,
PowerModule.class,
QSModule.class,
- ReferenceScreenshotModule.class
+ ReferenceScreenshotModule.class,
+ StatusBarEventsModule.class,
}
)
abstract class CarSystemUIModule {
@@ -206,4 +210,8 @@
@Binds
abstract DozeHost bindDozeHost(DozeServiceHost dozeServiceHost);
+
+ @Binds
+ abstract PrivacyDotViewController providePrivacyDotViewController(
+ CarPrivacyChipViewController carPrivacyChipViewController);
}
diff --git a/src/com/android/systemui/car/decor/CarPrivacyChipViewController.java b/src/com/android/systemui/car/decor/CarPrivacyChipViewController.java
new file mode 100644
index 0000000..f33904a
--- /dev/null
+++ b/src/com/android/systemui/car/decor/CarPrivacyChipViewController.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2022 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.decor;
+
+import android.view.View;
+
+import androidx.annotation.UiThread;
+
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.shade.ShadeExpansionStateManager;
+import com.android.systemui.statusbar.events.PrivacyDotViewController;
+import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
+import com.android.systemui.statusbar.phone.StatusBarContentInsetsProvider;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.concurrent.Executor;
+
+import javax.inject.Inject;
+
+/**
+ * Subclass of {@link PrivacyDotViewController}.
+ * This class is used to avoid showing the privacy dot.
+ */
+@SysUISingleton
+public class CarPrivacyChipViewController extends PrivacyDotViewController {
+
+ @Inject
+ public CarPrivacyChipViewController(
+ @NotNull @Main Executor mainExecutor,
+ @NotNull StatusBarStateController stateController,
+ @NotNull ConfigurationController configurationController,
+ @NotNull StatusBarContentInsetsProvider contentInsetsProvider,
+ @NotNull SystemStatusAnimationScheduler animationScheduler,
+ ShadeExpansionStateManager shadeExpansionStateManager) {
+ super(mainExecutor, stateController, configurationController, contentInsetsProvider,
+ animationScheduler, shadeExpansionStateManager);
+ }
+
+ @Override
+ @UiThread
+ public void showDotView(View dot, boolean animate) {
+ // Do nothing.
+ }
+
+ @Override
+ @UiThread
+ public void hideDotView(View dot, boolean animate) {
+ // Do nothing.
+ }
+}
diff --git a/src/com/android/systemui/car/keyguard/CarKeyguardPatternView.java b/src/com/android/systemui/car/keyguard/CarKeyguardPatternView.java
index d11b2e1..6000e91 100644
--- a/src/com/android/systemui/car/keyguard/CarKeyguardPatternView.java
+++ b/src/com/android/systemui/car/keyguard/CarKeyguardPatternView.java
@@ -54,9 +54,4 @@
Log.w(TAG, "Pattern is inivisble for the current user. Setting it to be visible.");
}
}
-
- @Override
- public void startAppearAnimation() {
- setAlpha(1f);
- }
}
diff --git a/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java b/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
index 9307e30..347e08c 100644
--- a/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
+++ b/src/com/android/systemui/car/keyguard/CarKeyguardViewController.java
@@ -26,17 +26,19 @@
import android.util.Log;
import android.view.Gravity;
import android.view.View;
+import android.view.ViewGroup;
import android.view.ViewRootImpl;
import android.view.WindowManager;
import androidx.annotation.MainThread;
-import androidx.annotation.VisibleForTesting;
import com.android.car.ui.FocusParkingView;
import com.android.internal.widget.LockPatternView;
+import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardViewController;
import com.android.keyguard.ViewMediatorCallback;
+import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.R;
import com.android.systemui.car.systembar.CarSystemBarController;
import com.android.systemui.car.window.OverlayViewController;
@@ -44,12 +46,16 @@
import com.android.systemui.car.window.SystemUIOverlayWindowController;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
+import com.android.systemui.keyguard.ui.binder.KeyguardBouncerViewBinder;
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.KeyguardBouncer;
-import com.android.systemui.statusbar.phone.KeyguardBouncer.Factory;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.toast.SystemUIToast;
@@ -82,10 +88,12 @@
private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
private final ViewMediatorCallback mViewMediatorCallback;
private final CarSystemBarController mCarSystemBarController;
- private final Factory mKeyguardBouncerFactory;
- // Needed to instantiate mBouncer.
- private final KeyguardBouncer.PrimaryBouncerExpansionCallback mExpansionCallback =
- new KeyguardBouncer.PrimaryBouncerExpansionCallback() {
+ private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
+ private final KeyguardSecurityModel mKeyguardSecurityModel;
+ private final KeyguardBouncerViewModel mKeyguardBouncerViewModel;
+ private final KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
+ private final PrimaryBouncerExpansionCallback mExpansionCallback =
+ new PrimaryBouncerExpansionCallback() {
@Override
public void onFullyShown() {
LockPatternView patternView = getLayout().findViewById(R.id.lockPatternView);
@@ -112,14 +120,23 @@
@Override
public void onFullyHidden() {
}
+
+ @Override
+ public void onVisibilityChanged(boolean isVisible) {
+ }
+
+ @Override
+ public void onExpansionChanged(float bouncerHideAmount) {
+ }
};
- private KeyguardBouncer mBouncer;
private OnKeyguardCancelClickedListener mKeyguardCancelClickedListener;
private boolean mShowing;
private boolean mIsOccluded;
private boolean mIsSleeping;
private int mToastShowDurationMillisecond;
+ private ViewGroup mKeyguardContainer;
+ private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
@Inject
public CarKeyguardViewController(
@@ -134,7 +151,12 @@
Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
ViewMediatorCallback viewMediatorCallback,
CarSystemBarController carSystemBarController,
- KeyguardBouncer.Factory keyguardBouncerFactory) {
+ PrimaryBouncerCallbackInteractor primaryBouncerCallbackInteractor,
+ PrimaryBouncerInteractor primaryBouncerInteractor,
+ KeyguardSecurityModel keyguardSecurityModel,
+ KeyguardBouncerViewModel keyguardBouncerViewModel,
+ PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel,
+ KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory) {
super(R.id.keyguard_stub, overlayViewGlobalStateController);
@@ -149,10 +171,15 @@
mBiometricUnlockControllerLazy = biometricUnlockControllerLazy;
mViewMediatorCallback = viewMediatorCallback;
mCarSystemBarController = carSystemBarController;
- mKeyguardBouncerFactory = keyguardBouncerFactory;
+ mPrimaryBouncerInteractor = primaryBouncerInteractor;
+ mKeyguardSecurityModel = keyguardSecurityModel;
+ mKeyguardBouncerViewModel = keyguardBouncerViewModel;
+ mKeyguardBouncerComponentFactory = keyguardBouncerComponentFactory;
+ mPrimaryBouncerToGoneTransitionViewModel = primaryBouncerToGoneTransitionViewModel;
mToastShowDurationMillisecond = mContext.getResources().getInteger(
R.integer.car_keyguard_toast_show_duration_millisecond);
+ primaryBouncerCallbackInteractor.addBouncerExpansionCallback(mExpansionCallback);
}
@Override
@@ -167,24 +194,24 @@
@Override
public void onFinishInflate() {
- mBouncer = mKeyguardBouncerFactory
- .create(getLayout().findViewById(R.id.keyguard_container), mExpansionCallback);
+ mKeyguardContainer = getLayout().findViewById(R.id.keyguard_container);
+ KeyguardBouncerViewBinder.bind(mKeyguardContainer,
+ mKeyguardBouncerViewModel, mPrimaryBouncerToGoneTransitionViewModel,
+ mKeyguardBouncerComponentFactory);
mBiometricUnlockControllerLazy.get().setKeyguardViewController(this);
}
@Override
@MainThread
public void notifyKeyguardAuthenticated(boolean strongAuth) {
- if (mBouncer != null) {
- mBouncer.notifyKeyguardAuthenticated(strongAuth);
- }
+ mPrimaryBouncerInteractor.notifyKeyguardAuthenticated(strongAuth);
}
@Override
@MainThread
public void showPrimaryBouncer(boolean scrimmed) {
- if (mShowing && !mBouncer.isShowing()) {
- mBouncer.show(/* resetSecuritySelection= */ false);
+ if (mShowing && !mPrimaryBouncerInteractor.isFullyShowing()) {
+ mPrimaryBouncerInteractor.show(/* isScrimmed= */ true);
}
}
@@ -209,7 +236,7 @@
mViewMediatorCallback.readyForKeyguardDone();
mShowing = false;
mKeyguardStateController.notifyKeyguardState(mShowing, /* occluded= */ false);
- mBouncer.hide(/* destroyView= */ true);
+ mPrimaryBouncerInteractor.hide();
mCarSystemBarController.showAllNavigationButtons(/* isSetUp= */ true);
stop();
mKeyguardStateController.notifyKeyguardDoneFading();
@@ -223,12 +250,10 @@
mMainExecutor.execute(() -> {
if (mShowing) {
- if (mBouncer != null) {
- if (!mBouncer.isSecure()) {
- dismissAndCollapse();
- }
- resetBouncer();
+ if (!isSecure()) {
+ dismissAndCollapse();
}
+ resetBouncer();
mKeyguardUpdateMonitor.sendKeyguardReset();
notifyKeyguardUpdateMonitor();
} else {
@@ -248,9 +273,7 @@
@Override
@MainThread
public void onFinishedGoingToSleep() {
- if (mBouncer != null) {
- mBouncer.onScreenTurnedOff();
- }
+ mPrimaryBouncerInteractor.hide();
}
@Override
@@ -261,7 +284,7 @@
if (occluded) {
mCarSystemBarController.showAllOcclusionButtons(/* isSetup= */ true);
} else {
- if (mShowing && mBouncer.isSecure()) {
+ if (mShowing && isSecure()) {
mCarSystemBarController.showAllKeyguardButtons(/* isSetup= */ true);
} else {
mCarSystemBarController.showAllNavigationButtons(/* isSetUp= */ true);
@@ -272,11 +295,8 @@
@Override
@MainThread
public void onCancelClicked() {
- if (mBouncer == null) return;
-
getOverlayViewGlobalStateController().setWindowNeedsInput(/* needsInput= */ false);
-
- mBouncer.hide(/* destroyView= */ true);
+ mPrimaryBouncerInteractor.hide();
mKeyguardCancelClickedListener.onCancelClicked();
}
@@ -289,7 +309,7 @@
if (mIsOccluded) {
setOccluded(/* occluded= */ false, /* animate= */ false);
}
- if (mBouncer != null && !mBouncer.isSecure()) {
+ if (!isSecure()) {
hide(/* startTime= */ 0, /* fadeoutDuration= */ 0);
}
}
@@ -297,9 +317,11 @@
@Override
@MainThread
public void startPreHideAnimation(Runnable finishRunnable) {
- if (mBouncer == null) return;
-
- mBouncer.startPreHideAnimation(finishRunnable);
+ if (isBouncerShowing()) {
+ mPrimaryBouncerInteractor.startDisappearAnimation(finishRunnable);
+ } else if (finishRunnable != null) {
+ finishRunnable.run();
+ }
}
@Override
@@ -342,13 +364,14 @@
@Override
@MainThread
public boolean isBouncerShowing() {
- return mBouncer != null && mBouncer.isShowing();
+ return mPrimaryBouncerInteractor.isFullyShowing();
}
@Override
@MainThread
public boolean primaryBouncerIsOrWillBeShowing() {
- return mBouncer != null && (mBouncer.isShowing() || mBouncer.inTransit());
+ return mPrimaryBouncerInteractor.isFullyShowing()
+ || mPrimaryBouncerInteractor.isInTransit();
}
@Override
@@ -408,22 +431,28 @@
getLayout().setVisibility(View.INVISIBLE);
}
- @VisibleForTesting
- void setKeyguardBouncer(KeyguardBouncer keyguardBouncer) {
- mBouncer = keyguardBouncer;
+ @Override
+ public boolean setAllowRotaryFocus(boolean allowRotaryFocus) {
+ boolean changed = super.setAllowRotaryFocus(allowRotaryFocus);
+ // When focus on keyguard becomes allowed, focus needs to be restored back to the pin entry
+ // view. Depending on the timing of the calls, pinView may believe it is focused
+ // (isFocused()=true) but the root view does not believe anything is focused
+ // (findFocus()=null). To guarantee that the view is fully focused, it is necessary to
+ // clear and refocus the element.
+ if (changed && allowRotaryFocus && getLayout() != null) {
+ View pinView = getLayout().findViewById(R.id.pinEntry);
+ if (pinView != null) {
+ pinView.clearFocus();
+ pinView.requestFocus();
+ }
+ }
+ return changed;
}
private void revealKeyguardIfBouncerPrepared() {
int reattemptDelayMillis = 50;
Runnable revealKeyguard = () -> {
- if (mBouncer == null) {
- if (DEBUG) {
- Log.d(TAG, "revealKeyguardIfBouncerPrepared: revealKeyguard request is ignored "
- + "since the Bouncer has not been initialized yet.");
- }
- return;
- }
- if (!mBouncer.inTransit() || !mBouncer.isSecure()) {
+ if (!mPrimaryBouncerInteractor.isInTransit() || !isSecure()) {
if (mShowing) {
// Only set the layout as visible if the keyguard should be showing
showInternal();
@@ -441,17 +470,24 @@
}
private void notifyKeyguardUpdateMonitor() {
- if (mBouncer != null) {
- mKeyguardUpdateMonitor.sendPrimaryBouncerChanged(
- primaryBouncerIsOrWillBeShowing(), isBouncerShowing());
- }
+ mKeyguardUpdateMonitor.sendPrimaryBouncerChanged(
+ primaryBouncerIsOrWillBeShowing(), isBouncerShowing());
}
+ /**
+ * WARNING: This method might cause Binder calls.
+ */
+ private boolean isSecure() {
+ return mKeyguardSecurityModel.getSecurityMode(
+ KeyguardUpdateMonitor.getCurrentUser()) != KeyguardSecurityModel.SecurityMode.None;
+ }
+
+
private void resetBouncer() {
mMainExecutor.execute(() -> {
hideInternal();
- mBouncer.hide(/* destroyView= */ false);
- mBouncer.show(/* resetSecuritySelection= */ true);
+ mPrimaryBouncerInteractor.hide();
+ mPrimaryBouncerInteractor.show(/* isScrimmed= */ true);
revealKeyguardIfBouncerPrepared();
});
}
diff --git a/src/com/android/systemui/car/window/OverlayViewController.java b/src/com/android/systemui/car/window/OverlayViewController.java
index 45b2d00..87d5e23 100644
--- a/src/com/android/systemui/car/window/OverlayViewController.java
+++ b/src/com/android/systemui/car/window/OverlayViewController.java
@@ -177,20 +177,23 @@
/**
* Sets whether this view allows rotary focus. This should be set to {@code true} for the
* topmost layer in the overlay window and {@code false} for the others.
+ *
+ * @return true if the rotary focus allowed state has changed.
*/
- public void setAllowRotaryFocus(boolean allowRotaryFocus) {
- if (!isInflated()) {
- return;
- }
-
- if (!(mLayout instanceof ViewGroup)) {
- return;
+ public boolean setAllowRotaryFocus(boolean allowRotaryFocus) {
+ if (!isInflated() || !(mLayout instanceof ViewGroup)) {
+ return false;
}
ViewGroup viewGroup = (ViewGroup) mLayout;
- viewGroup.setDescendantFocusability(allowRotaryFocus
+ int newFocusability = allowRotaryFocus
? ViewGroup.FOCUS_BEFORE_DESCENDANTS
- : ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+ : ViewGroup.FOCUS_BLOCK_DESCENDANTS;
+ if (viewGroup.getDescendantFocusability() == newFocusability) {
+ return false;
+ }
+ viewGroup.setDescendantFocusability(newFocusability);
+ return true;
}
/**
diff --git a/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java b/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
index 3d49259..24dd694 100644
--- a/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
+++ b/tests/src/com/android/systemui/car/keyguard/CarKeyguardViewControllerTest.java
@@ -17,7 +17,7 @@
package com.android.systemui.car.keyguard;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
@@ -35,16 +35,22 @@
import androidx.test.filters.SmallTest;
+import com.android.keyguard.KeyguardSecurityContainerController;
+import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
+import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.car.CarSystemUiTest;
import com.android.systemui.car.systembar.CarSystemBarController;
import com.android.systemui.car.window.OverlayViewGlobalStateController;
import com.android.systemui.car.window.SystemUIOverlayWindowController;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor;
+import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor;
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
+import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
-import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.toast.ToastFactory;
import com.android.systemui.util.concurrency.FakeExecutor;
@@ -55,11 +61,12 @@
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
@CarSystemUiTest
@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
public class CarKeyguardViewControllerTest extends SysuiTestCase {
@@ -73,9 +80,17 @@
@Mock
private CarKeyguardViewController.OnKeyguardCancelClickedListener mCancelClickedListener;
@Mock
- private KeyguardBouncer.Factory mKeyguardBouncerFactory;
+ private PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor;
@Mock
- private KeyguardBouncer mBouncer;
+ private PrimaryBouncerInteractor mPrimaryBouncerInteractor;
+ @Mock
+ private KeyguardSecurityModel mKeyguardSecurityModel;
+ @Mock
+ private KeyguardBouncerViewModel mKeyguardBouncerViewModel;
+ @Mock
+ private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
+ @Mock
+ private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
@Before
public void setUp() {
@@ -83,13 +98,17 @@
ViewGroup mockBaseLayout = new FrameLayout(mContext);
- when(mKeyguardBouncerFactory.create(
- any(ViewGroup.class),
- any(KeyguardBouncer.PrimaryBouncerExpansionCallback.class)))
- .thenReturn(mBouncer);
when(mSystemUIOverlayWindowController.getBaseLayout()).thenReturn(mockBaseLayout);
mExecutor = new FakeExecutor(new FakeSystemClock());
+ KeyguardBouncerComponent keyguardBouncerComponent = mock(KeyguardBouncerComponent.class);
+ KeyguardSecurityContainerController securityContainerController = mock(
+ KeyguardSecurityContainerController.class);
+ when(mKeyguardBouncerComponentFactory.create(any(ViewGroup.class))).thenReturn(
+ keyguardBouncerComponent);
+ when(keyguardBouncerComponent.getSecurityContainerController()).thenReturn(
+ securityContainerController);
+
mCarKeyguardViewController = new CarKeyguardViewController(
mContext,
mExecutor,
@@ -102,7 +121,12 @@
() -> mock(BiometricUnlockController.class),
mock(ViewMediatorCallback.class),
mock(CarSystemBarController.class),
- mKeyguardBouncerFactory
+ mPrimaryBouncerCallbackInteractor,
+ mPrimaryBouncerInteractor,
+ mKeyguardSecurityModel,
+ mKeyguardBouncerViewModel,
+ mPrimaryBouncerToGoneTransitionViewModel,
+ mKeyguardBouncerComponentFactory
);
mCarKeyguardViewController.inflate((ViewGroup) LayoutInflater.from(mContext).inflate(
R.layout.sysui_overlay_window, /* root= */ null));
@@ -110,16 +134,16 @@
@Test
public void onShow_bouncerIsSecure_showsBouncerWithSecuritySelectionReset() {
- when(mBouncer.isSecure()).thenReturn(true);
+ setIsSecure(true);
mCarKeyguardViewController.show(/* options= */ null);
waitForDelayableExecutor();
- verify(mBouncer).show(/* resetSecuritySelection= */ true);
+ verify(mPrimaryBouncerInteractor).show(/* isScrimmed= */ true);
}
@Test
public void onShow_bouncerIsSecure_keyguardIsVisible() {
- when(mBouncer.isSecure()).thenReturn(true);
+ setIsSecure(true);
mCarKeyguardViewController.show(/* options= */ null);
verify(mOverlayViewGlobalStateController).showView(eq(mCarKeyguardViewController), any());
@@ -127,16 +151,16 @@
@Test
public void onShow_bouncerNotSecure_hidesBouncerAndDestroysTheView() {
- when(mBouncer.isSecure()).thenReturn(false);
+ setIsSecure(false);
mCarKeyguardViewController.show(/* options= */ null);
waitForDelayableExecutor();
- verify(mBouncer).hide(/* destroyView= */ true);
+ verify(mPrimaryBouncerInteractor, Mockito.times(2)).hide();
}
@Test
public void onShow_bouncerNotSecure_keyguardIsNotVisible() {
- when(mBouncer.isSecure()).thenReturn(false);
+ setIsSecure(false);
mCarKeyguardViewController.show(/* options= */ null);
waitForDelayableExecutor();
@@ -155,23 +179,23 @@
@Test
public void onHide_keyguardShowing_hidesBouncerAndDestroysTheView() {
- when(mBouncer.isSecure()).thenReturn(true);
+ setIsSecure(true);
mCarKeyguardViewController.show(/* options= */ null);
mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
- verify(mBouncer).hide(/* destroyView= */ true);
+ verify(mPrimaryBouncerInteractor).hide();
}
@Test
public void onHide_keyguardNotShown_doesNotHideOrDestroyBouncer() {
mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
- verify(mBouncer, never()).hide(anyBoolean());
+ verify(mPrimaryBouncerInteractor, never()).hide();
}
@Test
public void onHide_KeyguardNotVisible() {
- when(mBouncer.isSecure()).thenReturn(true);
+ setIsSecure(true);
mCarKeyguardViewController.show(/* options= */ null);
mCarKeyguardViewController.hide(/* startTime= */ 0, /* fadeoutDelay= */ 0);
@@ -184,20 +208,20 @@
@Test
public void setOccludedFalse_currentlyOccluded_showsKeyguard() {
- when(mBouncer.isSecure()).thenReturn(true);
+ setIsSecure(true);
mCarKeyguardViewController.show(/* options= */ null);
mCarKeyguardViewController.setOccluded(/* occluded= */ true, /* animate= */ false);
- reset(mBouncer);
+ reset(mPrimaryBouncerInteractor);
mCarKeyguardViewController.setOccluded(/* occluded= */ false, /* animate= */ false);
waitForDelayableExecutor();
- verify(mBouncer).show(true);
+ verify(mPrimaryBouncerInteractor).show(/* isScrimmed= */ true);
}
@Test
public void onCancelClicked_callsCancelClickedListener() {
- when(mBouncer.isSecure()).thenReturn(true);
+ setIsSecure(true);
mCarKeyguardViewController.show(/* options= */ null);
mCarKeyguardViewController.registerOnKeyguardCancelClickedListener(mCancelClickedListener);
mCarKeyguardViewController.onCancelClicked();
@@ -207,7 +231,7 @@
@Test
public void onEnterSleepModeAndThenShowKeyguard_bouncerNotSecure_keyguardIsVisible() {
- when(mBouncer.isSecure()).thenReturn(false);
+ setIsSecure(false);
mCarKeyguardViewController.onStartedGoingToSleep();
mCarKeyguardViewController.show(/* options= */ null);
waitForDelayableExecutor();
@@ -222,8 +246,14 @@
}
@Test
+ public void onFinishedGoingToSleep() {
+ mCarKeyguardViewController.onFinishedGoingToSleep();
+ verify(mPrimaryBouncerInteractor).hide();
+ }
+
+ @Test
public void onDeviceWakeUpWhileKeyguardShown_bouncerNotSecure_keyguardIsNotVisible() {
- when(mBouncer.isSecure()).thenReturn(false);
+ setIsSecure(false);
mCarKeyguardViewController.onStartedGoingToSleep();
mCarKeyguardViewController.show(/* options= */ null);
mCarKeyguardViewController.onStartedWakingUp();
@@ -240,16 +270,22 @@
@Test
public void onCancelClicked_hidesBouncerAndDestroysTheView() {
- when(mBouncer.isSecure()).thenReturn(true);
+ setIsSecure(true);
mCarKeyguardViewController.show(/* options= */ null);
mCarKeyguardViewController.registerOnKeyguardCancelClickedListener(mCancelClickedListener);
mCarKeyguardViewController.onCancelClicked();
- verify(mBouncer).hide(/* destroyView= */ true);
+ verify(mPrimaryBouncerInteractor).hide();
}
private void waitForDelayableExecutor() {
mExecutor.advanceClockToLast();
mExecutor.runAllReady();
}
+
+ private void setIsSecure(boolean isSecure) {
+ when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(
+ isSecure ? KeyguardSecurityModel.SecurityMode.PIN
+ : KeyguardSecurityModel.SecurityMode.None);
+ }
}
diff --git a/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java b/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java
index f7f2b42..17c9442 100644
--- a/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java
+++ b/tests/src/com/android/systemui/car/systembar/CarSystemBarTest.java
@@ -56,6 +56,7 @@
import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.car.CarSystemUiTest;
import com.android.systemui.car.hvac.HvacController;
+import com.android.systemui.settings.FakeDisplayTracker;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.LightBarController;
@@ -169,9 +170,9 @@
private void initCarSystemBar() {
mCarSystemBar = new CarSystemBar(mContext, mCarSystemBarController, mLightBarController,
mStatusBarIconController, mWindowManager, mDeviceProvisionedController,
- new CommandQueue(mContext), mAutoHideController, mButtonSelectionStateListener,
- mExecutor, mUiBgExecutor, mBarService, () -> mKeyguardStateController,
- () -> mIconPolicy, mHvacController, mSignalPolicy,
+ new CommandQueue(mContext, new FakeDisplayTracker(mContext)), mAutoHideController,
+ mButtonSelectionStateListener, mExecutor, mUiBgExecutor, mBarService,
+ () -> mKeyguardStateController, () -> mIconPolicy, mHvacController, mSignalPolicy,
new SystemBarConfigs(mTestableResources.getResources()),
mock(ConfigurationController.class));
mCarSystemBar.setSignalPolicy(mSignalPolicy);