summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--PREUPLOAD.cfg2
-rw-r--r--core/api/system-current.txt32
-rw-r--r--core/java/android/app/NotificationChannel.java2
-rw-r--r--core/java/android/util/FeatureFlagUtils.java14
-rw-r--r--core/java/android/widget/Editor.java24
-rw-r--r--core/java/android/widget/SelectionActionModeHelper.java2
-rw-r--r--core/java/android/widget/TextView.java17
-rw-r--r--core/java/com/android/internal/widget/LocalImageResolver.java65
-rw-r--r--core/jni/OWNERS4
-rw-r--r--core/res/res/values/config.xml5
-rw-r--r--core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java47
-rw-r--r--data/etc/com.android.systemui.xml1
-rw-r--r--ktfmt_includes.txt17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java4
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt29
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt2
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt3
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt1
-rw-r--r--libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt1
-rw-r--r--media/java/android/media/AudioDeviceVolumeManager.java29
-rw-r--r--media/java/android/media/AudioSystem.java6
-rw-r--r--media/java/android/media/VolumeInfo.java8
-rw-r--r--media/java/android/media/session/ISession.aidl2
-rw-r--r--media/java/android/media/session/MediaSession.java2
-rw-r--r--packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt2
-rw-r--r--packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt2
-rw-r--r--packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt4
-rw-r--r--packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt75
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt19
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt23
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt12
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/SettingsSlider.kt (renamed from packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/SettingsSlider.kt)2
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt4
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt2
-rw-r--r--packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt131
-rw-r--r--packages/SettingsLib/Spa/tests/Android.bp1
-rw-r--r--packages/SettingsLib/Spa/tests/build.gradle1
-rw-r--r--packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/SettingsSliderTest.kt45
-rw-r--r--packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/SpinnerTest.kt71
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt7
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt (renamed from packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListModel.kt)42
-rw-r--r--packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt12
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java4
-rw-r--r--packages/SystemUI/AndroidManifest.xml12
-rw-r--r--packages/SystemUI/ktfmt_includes.txt870
-rw-r--r--packages/SystemUI/res/layout/media_ttt_chip.xml4
-rw-r--r--packages/SystemUI/res/layout/volume_panel_dialog.xml101
-rw-r--r--packages/SystemUI/res/layout/volume_panel_slice_slider_row.xml31
-rw-r--r--packages/SystemUI/res/values/dimens.xml4
-rw-r--r--packages/SystemUI/res/values/strings.xml5
-rw-r--r--packages/SystemUI/res/values/styles.xml24
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/ChooserSelector.kt67
-rw-r--r--packages/SystemUI/src/com/android/systemui/ChooserSelectorResourceHelper.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/flags/Flags.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt17
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt38
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt124
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt13
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java299
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumePanelFactory.kt67
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java137
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt179
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt125
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt82
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt45
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt227
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt34
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java3
-rw-r--r--packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt68
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java11
-rw-r--r--services/core/java/com/android/server/am/HostingRecord.java17
-rw-r--r--services/core/java/com/android/server/audio/BtHelper.java4
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java21
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java222
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java18
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java525
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java7
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java2
-rw-r--r--services/core/java/com/android/server/display/BrightnessMappingStrategy.java6
-rw-r--r--services/core/java/com/android/server/display/DisplayDeviceConfig.java113
-rw-r--r--services/core/java/com/android/server/logcat/OWNERS2
-rw-r--r--services/core/java/com/android/server/media/MediaButtonReceiverHolder.java2
-rw-r--r--services/core/java/com/android/server/media/MediaSessionRecord.java15
-rw-r--r--services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java39
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java21
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java4
-rw-r--r--services/core/java/com/android/server/wm/Task.java7
-rw-r--r--services/core/xsd/display-device-config/autobrightness.xsd33
-rw-r--r--services/core/xsd/display-device-config/display-device-config.xsd71
-rw-r--r--services/core/xsd/display-device-config/schema/current.txt15
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java99
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java573
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java105
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt1
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt1
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt13
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt1
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt3
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt2
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt2
-rw-r--r--tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java121
-rw-r--r--tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java2
-rw-r--r--tests/RollbackTest/Android.bp1
-rw-r--r--tests/StagedInstallTest/Android.bp1
-rw-r--r--tools/aapt2/format/binary/TableFlattener.cpp10
-rw-r--r--tools/aapt2/format/binary/TableFlattener_test.cpp44
183 files changed, 3853 insertions, 2164 deletions
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 1d92778a9117..9a4323a119f0 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -25,6 +25,6 @@ hidden_api_txt_checksorted_hook = ${REPO_ROOT}/tools/platform-compat/hiddenapi/c
hidden_api_txt_exclude_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/exclude.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
-ktfmt_hook = ${REPO_ROOT}/external/ktfmt/ktfmt.py --check -i ${REPO_ROOT}/frameworks/base/ktfmt_includes.txt ${PREUPLOAD_FILES}
+ktfmt_hook = ${REPO_ROOT}/external/ktfmt/ktfmt.py --check -i ${REPO_ROOT}/frameworks/base/packages/SystemUI/ktfmt_includes.txt ${PREUPLOAD_FILES}
ktlint_hook = ${REPO_ROOT}/prebuilts/ktlint/ktlint.py -f ${PREUPLOAD_FILES}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index ef8ae7095d65..a87f2e2bdaee 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -6134,6 +6134,11 @@ package android.media {
field public static final int ROLE_OUTPUT = 2; // 0x2
}
+ public class AudioDeviceVolumeManager {
+ ctor public AudioDeviceVolumeManager(@NonNull android.content.Context);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolume(@NonNull android.media.VolumeInfo, @NonNull android.media.AudioDeviceAttributes);
+ }
+
public final class AudioFocusInfo implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.media.AudioAttributes getAttributes();
@@ -6453,6 +6458,33 @@ package android.media {
method public void onSpatializerOutputChanged(@NonNull android.media.Spatializer, @IntRange(from=0) int);
}
+ public final class VolumeInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public static android.media.VolumeInfo getDefaultVolumeInfo();
+ method public int getMaxVolumeIndex();
+ method public int getMinVolumeIndex();
+ method public int getStreamType();
+ method @Nullable public android.media.audiopolicy.AudioVolumeGroup getVolumeGroup();
+ method public int getVolumeIndex();
+ method public boolean hasStreamType();
+ method public boolean hasVolumeGroup();
+ method public boolean isMuted();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.media.VolumeInfo> CREATOR;
+ field public static final int INDEX_NOT_SET = -100; // 0xffffff9c
+ }
+
+ public static final class VolumeInfo.Builder {
+ ctor public VolumeInfo.Builder(int);
+ ctor public VolumeInfo.Builder(@NonNull android.media.audiopolicy.AudioVolumeGroup);
+ ctor public VolumeInfo.Builder(@NonNull android.media.VolumeInfo);
+ method @NonNull public android.media.VolumeInfo build();
+ method @NonNull public android.media.VolumeInfo.Builder setMaxVolumeIndex(int);
+ method @NonNull public android.media.VolumeInfo.Builder setMinVolumeIndex(int);
+ method @NonNull public android.media.VolumeInfo.Builder setMuted(boolean);
+ method @NonNull public android.media.VolumeInfo.Builder setVolumeIndex(int);
+ }
+
}
package android.media.audiofx {
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index b9ad595778e4..7215987b0d87 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -753,7 +753,7 @@ public final class NotificationChannel implements Parcelable {
/**
* Returns the vibration pattern for notifications posted to this channel. Will be ignored if
- * vibration is not enabled ({@link #shouldVibrate()}.
+ * vibration is not enabled ({@link #shouldVibrate()}).
*/
public long[] getVibrationPattern() {
return mVibration;
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index bca100a1d81e..20f01ae3ae0d 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -68,6 +68,12 @@ public class FeatureFlagUtils {
public static final String SETTINGS_APP_LOCALE_OPT_IN_ENABLED =
"settings_app_locale_opt_in_enabled";
+ /**
+ * Launch the Volume panel in SystemUI.
+ * @hide
+ */
+ public static final String SETTINGS_VOLUME_PANEL_IN_SYSTEMUI =
+ "settings_volume_panel_in_systemui";
/** @hide */
public static final String SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS =
@@ -110,6 +116,12 @@ public class FeatureFlagUtils {
*/
public static final String SETTINGS_NEW_KEYBOARD_UI = "settings_new_keyboard_ui";
+ /**
+ * Enable the new pages which is implemented with SPA.
+ * @hide
+ */
+ public static final String SETTINGS_ENABLE_SPA = "settings_enable_spa";
+
private static final Map<String, String> DEFAULT_FLAGS;
static {
@@ -134,6 +146,7 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put("settings_search_always_expand", "true");
DEFAULT_FLAGS.put(SETTINGS_ALLOW_INTENT_REDIRECTION_FOR_CLONE_PROFILE, "false");
DEFAULT_FLAGS.put(SETTINGS_APP_LOCALE_OPT_IN_ENABLED, "true");
+ DEFAULT_FLAGS.put(SETTINGS_VOLUME_PANEL_IN_SYSTEMUI, "false");
DEFAULT_FLAGS.put(SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS, "true");
DEFAULT_FLAGS.put(SETTINGS_APP_ALLOW_DARK_THEME_ACTIVATION_AT_BEDTIME, "true");
DEFAULT_FLAGS.put(SETTINGS_HIDE_SECOND_LAYER_PAGE_NAVIGATE_UP_BUTTON_IN_TWO_PANE, "true");
@@ -141,6 +154,7 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put(SETTINGS_ENABLE_CLEAR_CALLING, "false");
DEFAULT_FLAGS.put(SETTINGS_ACCESSIBILITY_SIMPLE_CURSOR, "false");
DEFAULT_FLAGS.put(SETTINGS_NEW_KEYBOARD_UI, "false");
+ DEFAULT_FLAGS.put(SETTINGS_ENABLE_SPA, "false");
}
private static final Set<String> PERSISTENT_FLAGS;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 6825f034f5b3..f93b8b7c1b5f 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -226,8 +226,6 @@ public class Editor {
final UndoInputFilter mUndoInputFilter = new UndoInputFilter(this);
boolean mAllowUndo = true;
- private int mLastInputSource = InputDevice.SOURCE_UNKNOWN;
-
private final MetricsLogger mMetricsLogger = new MetricsLogger();
// Cursor Controllers.
@@ -1735,8 +1733,6 @@ public class Editor {
public void onTouchEvent(MotionEvent event) {
final boolean filterOutEvent = shouldFilterOutTouchEvent(event);
- mLastInputSource = event.getSource();
-
mLastButtonState = event.getButtonState();
if (filterOutEvent) {
if (event.getActionMasked() == MotionEvent.ACTION_UP) {
@@ -1789,7 +1785,7 @@ public class Editor {
}
private void showFloatingToolbar() {
- if (mTextActionMode != null && showUIForTouchScreen()) {
+ if (mTextActionMode != null && mTextView.showUIForTouchScreen()) {
// Delay "show" so it doesn't interfere with click confirmations
// or double-clicks that could "dismiss" the floating toolbar.
int delay = ViewConfiguration.getDoubleTapTimeout();
@@ -1870,7 +1866,7 @@ public class Editor {
? getSelectionController() : getInsertionController();
if (cursorController != null && !cursorController.isActive()
&& !cursorController.isCursorBeingModified()
- && showUIForTouchScreen()) {
+ && mTextView.showUIForTouchScreen()) {
cursorController.show();
}
}
@@ -2521,7 +2517,7 @@ public class Editor {
return false;
}
- if (!showUIForTouchScreen()) {
+ if (!mTextView.showUIForTouchScreen()) {
return false;
}
@@ -2677,7 +2673,7 @@ public class Editor {
mTextView.postDelayed(mShowSuggestionRunnable,
ViewConfiguration.getDoubleTapTimeout());
} else if (hasInsertionController()) {
- if (shouldInsertCursor && showUIForTouchScreen()) {
+ if (shouldInsertCursor && mTextView.showUIForTouchScreen()) {
getInsertionController().show();
} else {
getInsertionController().hide();
@@ -5408,7 +5404,7 @@ public class Editor {
final boolean shouldShow = checkForTransforms() /*check not rotated and compute scale*/
&& !tooLargeTextForMagnifier()
&& obtainMagnifierShowCoordinates(event, showPosInView)
- && showUIForTouchScreen();
+ && mTextView.showUIForTouchScreen();
if (shouldShow) {
// Make the cursor visible and stop blinking.
mRenderCursorRegardlessTiming = true;
@@ -6354,16 +6350,6 @@ public class Editor {
}
}
- /**
- * Returns true when need to show UIs, e.g. floating toolbar, etc, for finger based interaction.
- *
- * @return true if UIs need to show for finger interaciton. false if UIs are not necessary.
- */
- public boolean showUIForTouchScreen() {
- return (mLastInputSource & InputDevice.SOURCE_TOUCHSCREEN)
- == InputDevice.SOURCE_TOUCHSCREEN;
- }
-
/** Controller for the insertion cursor. */
@VisibleForTesting
public class InsertionPointCursorController implements CursorController {
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 4ccd77b2713e..be6b08fbddae 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -301,7 +301,7 @@ public final class SelectionActionModeHelper {
final SelectionModifierCursorController controller = mEditor.getSelectionController();
if (controller != null
&& (mTextView.isTextSelectable() || mTextView.isTextEditable())) {
- if (mEditor.showUIForTouchScreen()) {
+ if (mTextView.showUIForTouchScreen()) {
controller.show();
} else {
controller.hide();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 28b83b2068ba..f53dd0c53ef5 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -973,6 +973,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private int mDeviceProvisionedState = DEVICE_PROVISIONED_UNKNOWN;
/**
+ * The last input source on this TextView.
+ */
+ private int mLastInputSource = InputDevice.SOURCE_UNKNOWN;
+
+ /**
* The TextView does not auto-size text (default).
*/
public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0;
@@ -11565,6 +11570,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
MotionEvent.actionToString(event.getActionMasked()),
event.getX(), event.getY());
}
+ mLastInputSource = event.getSource();
final int action = event.getActionMasked();
if (mEditor != null) {
if (!isFromPrimePointer(event, false)) {
@@ -11654,6 +11660,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
+ * Returns true when need to show UIs, e.g. floating toolbar, etc, for finger based interaction.
+ *
+ * @return true if UIs need to show for finger interaciton. false if UIs are not necessary.
+ * @hide
+ */
+ public final boolean showUIForTouchScreen() {
+ return (mLastInputSource & InputDevice.SOURCE_TOUCHSCREEN)
+ == InputDevice.SOURCE_TOUCHSCREEN;
+ }
+
+ /**
* The fill dialog UI is a more conspicuous and efficient interface than dropdown UI.
* If autofill suggestions are available when the user clicks on a field that supports filling
* the dialog UI, Autofill will pop up a fill dialog. The dialog will take up a larger area
diff --git a/core/java/com/android/internal/widget/LocalImageResolver.java b/core/java/com/android/internal/widget/LocalImageResolver.java
index b11ea2961c17..9ef7ce38fc09 100644
--- a/core/java/com/android/internal/widget/LocalImageResolver.java
+++ b/core/java/com/android/internal/widget/LocalImageResolver.java
@@ -19,6 +19,8 @@ package com.android.internal.widget;
import android.annotation.DrawableRes;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.ImageDecoder;
@@ -109,13 +111,13 @@ public class LocalImageResolver {
}
break;
case Icon.TYPE_RESOURCE:
- if (!(TextUtils.isEmpty(icon.getResPackage())
- || context.getPackageName().equals(icon.getResPackage()))) {
- // We can't properly resolve icons from other packages here, so fall back.
+ Resources res = resolveResourcesForIcon(context, icon);
+ if (res == null) {
+ // We couldn't resolve resources properly, fall back to icon loading.
return icon.loadDrawable(context);
}
- Drawable result = resolveImage(icon.getResId(), context, maxWidth, maxHeight);
+ Drawable result = resolveImage(res, icon.getResId(), maxWidth, maxHeight);
if (result != null) {
return tintDrawable(icon, result);
}
@@ -159,6 +161,13 @@ public class LocalImageResolver {
}
@Nullable
+ private static Drawable resolveImage(Resources res, @DrawableRes int resId, int maxWidth,
+ int maxHeight) {
+ final ImageDecoder.Source source = ImageDecoder.createSource(res, resId);
+ return resolveImage(source, maxWidth, maxHeight);
+ }
+
+ @Nullable
private static Drawable resolveBitmapImage(Icon icon, Context context, int maxWidth,
int maxHeight) {
@@ -259,4 +268,52 @@ public class LocalImageResolver {
}
return icon.getUri();
}
+
+ /**
+ * Resolves the correct resources package for a given Icon - it may come from another
+ * package.
+ *
+ * @see Icon#loadDrawableInner(Context)
+ * @hide
+ *
+ * @return resources instance if the operation succeeded, null otherwise
+ */
+ @Nullable
+ @VisibleForTesting
+ public static Resources resolveResourcesForIcon(Context context, Icon icon) {
+ if (icon.getType() != Icon.TYPE_RESOURCE) {
+ return null;
+ }
+
+ // Icons cache resolved resources, use cache if available.
+ Resources res = icon.getResources();
+ if (res != null) {
+ return res;
+ }
+
+ String resPackage = icon.getResPackage();
+ // No package means we try to use current context.
+ if (TextUtils.isEmpty(resPackage) || context.getPackageName().equals(resPackage)) {
+ return context.getResources();
+ }
+
+ if ("android".equals(resPackage)) {
+ return Resources.getSystem();
+ }
+
+ final PackageManager pm = context.getPackageManager();
+ try {
+ ApplicationInfo ai = pm.getApplicationInfo(resPackage,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES
+ | PackageManager.GET_SHARED_LIBRARY_FILES);
+ if (ai != null) {
+ return pm.getResourcesForApplication(ai);
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, String.format("Unable to resolve package %s for icon %s", resPackage, icon));
+ return null;
+ }
+
+ return null;
+ }
}
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index 7f50204fb842..14699e7097f4 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -95,3 +95,7 @@ per-file android_os_VintfRuntimeInfo* = file:platform/system/libvintf:/OWNERS
# Battery
per-file com_android_internal_os_Kernel* = file:/BATTERY_STATS_OWNERS
per-file com_android_internal_os_*MultiStateCounter* = file:/BATTERY_STATS_OWNERS
+
+# PM
+per-file com_android_internal_content_* = file:/PACKAGE_MANAGER_OWNERS
+
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6a52ec91fa32..e7cae76c60fc 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1565,7 +1565,8 @@
<bool name="config_enableIdleScreenBrightnessMode">false</bool>
<!-- Array of desired screen brightness in nits corresponding to the lux values
- in the config_autoBrightnessLevels array. The display brightness is defined as the measured
+ in the config_autoBrightnessLevels array. As with config_screenBrightnessMinimumNits and
+ config_screenBrightnessMaximumNits, the display brightness is defined as the measured
brightness of an all-white image.
If this is defined then:
@@ -1586,7 +1587,7 @@
<array name="config_autoBrightnessDisplayValuesNitsIdle">
</array>
- <!-- Array of output values for button backlight corresponding to the lux values
+ <!-- Array of output values for button backlight corresponding to the luX values
in the config_autoBrightnessLevels array. This array should have size one greater
than the size of the config_autoBrightnessLevels array.
The brightness values must be between 0 and 255 and be non-decreasing.
diff --git a/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java b/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java
index 0cee526651a6..271a20b71106 100644
--- a/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java
@@ -17,6 +17,8 @@
package com.android.internal.widget;
import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
import android.graphics.BitmapFactory;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.BitmapDrawable;
@@ -279,4 +281,49 @@ public class LocalImageResolverTest {
// This drawable must not be loaded - if it was, the code ignored the package specification.
assertThat(d).isNull();
}
+
+ @Test
+ public void resolveResourcesForIcon_notAResourceIcon_returnsNull() {
+ Icon icon = Icon.createWithContentUri(Uri.parse("some_uri"));
+ assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon)).isNull();
+ }
+
+ @Test
+ public void resolveResourcesForIcon_localPackageIcon_returnsPackageResources() {
+ Icon icon = Icon.createWithResource(mContext, R.drawable.test32x24);
+ assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon))
+ .isSameInstanceAs(mContext.getResources());
+ }
+
+ @Test
+ public void resolveResourcesForIcon_iconWithoutPackageSpecificed_returnsPackageResources() {
+ Icon icon = Icon.createWithResource("", R.drawable.test32x24);
+ assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon))
+ .isSameInstanceAs(mContext.getResources());
+ }
+
+ @Test
+ public void resolveResourcesForIcon_systemPackageSpecified_returnsSystemPackage() {
+ Icon icon = Icon.createWithResource("android", R.drawable.test32x24);
+ assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon)).isSameInstanceAs(
+ Resources.getSystem());
+ }
+
+ @Test
+ public void resolveResourcesForIcon_differentPackageSpecified_returnsPackageResources() throws
+ PackageManager.NameNotFoundException {
+ String pkg = "com.android.settings";
+ Resources res = mContext.getPackageManager().getResourcesForApplication(pkg);
+ int resId = res.getIdentifier("ic_android", "drawable", pkg);
+ Icon icon = Icon.createWithResource(pkg, resId);
+
+ assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon).getDrawable(resId,
+ mContext.getTheme())).isNotNull();
+ }
+
+ @Test
+ public void resolveResourcesForIcon_invalidPackageSpecified_returnsNull() {
+ Icon icon = Icon.createWithResource("invalid.package", R.drawable.test32x24);
+ assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon)).isNull();
+ }
}
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index f030d80a3533..e0e13f59b706 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -81,5 +81,6 @@
<permission name="android.permission.READ_DEVICE_CONFIG" />
<permission name="android.permission.READ_SAFETY_CENTER_STATUS" />
<permission name="android.permission.SET_UNRESTRICTED_KEEP_CLEAR_AREAS" />
+ <permission name="android.permission.READ_SEARCH_INDEXABLES" />
</privapp-permissions>
</permissions>
diff --git a/ktfmt_includes.txt b/ktfmt_includes.txt
deleted file mode 100644
index c7062e093135..000000000000
--- a/ktfmt_includes.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-packages/SystemUI/compose/
-packages/SystemUI/screenshot/
-packages/SystemUI/src/com/android/systemui/people/data
-packages/SystemUI/src/com/android/systemui/people/ui
-packages/SystemUI/src/com/android/systemui/keyguard/data
-packages/SystemUI/src/com/android/systemui/keyguard/dagger
-packages/SystemUI/src/com/android/systemui/keyguard/domain
-packages/SystemUI/src/com/android/systemui/keyguard/shared
-packages/SystemUI/src/com/android/systemui/keyguard/ui
-packages/SystemUI/src/com/android/systemui/qs/footer
-packages/SystemUI/src/com/android/systemui/security
-packages/SystemUI/src/com/android/systemui/common/
-packages/SystemUI/tests/utils/src/com/android/systemui/qs/
-packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeSecurityController.kt
-packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeUserInfoController.kt
-packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/MockUserSwitcherControllerWrapper.kt
-packages/SystemUI/tests/src/com/android/systemui/qs/footer/ \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 0d75bc451b72..f1465f421c5b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -105,8 +105,8 @@ public class FullscreenTaskListener<T extends AutoCloseable>
state.mTaskInfo = taskInfo;
mTasks.put(taskInfo.taskId, state);
- updateRecentsForVisibleFullscreenTask(taskInfo);
if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
+ updateRecentsForVisibleFullscreenTask(taskInfo);
if (shouldShowWindowDecor(taskInfo) && mWindowDecorViewModelOptional.isPresent()) {
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
state.mWindowDecoration =
@@ -135,8 +135,8 @@ public class FullscreenTaskListener<T extends AutoCloseable>
mWindowDecorViewModelOptional.get().onTaskInfoChanged(
state.mTaskInfo, state.mWindowDecoration);
}
- updateRecentsForVisibleFullscreenTask(taskInfo);
if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
+ updateRecentsForVisibleFullscreenTask(taskInfo);
final Point positionInParent = state.mTaskInfo.positionInParent;
if (!oldPositionInParent.equals(state.mTaskInfo.positionInParent)) {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
index 67d7aca8db8c..298bf68c41a7 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt
@@ -86,8 +86,7 @@ abstract class BaseBubbleScreen(
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
- repetitions = 3)
+ .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
}
const val FIND_OBJECT_TIMEOUT = 2000L
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
index 293eb7cd5581..47557bcead2f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt
@@ -18,7 +18,6 @@ package com.android.wm.shell.flicker.bubble
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Postsubmit
-import android.platform.test.annotations.Presubmit
import android.view.WindowInsets
import android.view.WindowManager
import androidx.test.filters.RequiresDevice
@@ -92,7 +91,7 @@ class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScr
}
}
- @Presubmit
+ @FlakyTest(bugId = 242088970)
@Test
fun testAppIsVisibleAtEnd() {
testSpec.assertLayersEnd {
@@ -125,7 +124,7 @@ class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScr
super.navBarWindowIsAlwaysVisible()
/** {@inheritDoc} */
- @Postsubmit
+ @FlakyTest(bugId = 242088970)
@Test
override fun taskBarLayerIsVisibleAtStartAndEnd() =
super.taskBarLayerIsVisibleAtStartAndEnd()
@@ -135,4 +134,28 @@ class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScr
@Test
override fun taskBarWindowIsAlwaysVisible() =
super.taskBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 242088970)
+ @Test
+ override fun statusBarLayerIsVisibleAtStartAndEnd() =
+ super.statusBarLayerIsVisibleAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 242088970)
+ @Test
+ override fun statusBarLayerPositionAtStartAndEnd() =
+ super.statusBarLayerPositionAtStartAndEnd()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 242088970)
+ @Test
+ override fun statusBarWindowIsAlwaysVisible() =
+ super.statusBarWindowIsAlwaysVisible()
+
+ /** {@inheritDoc} */
+ @FlakyTest(bugId = 242088970)
+ @Test
+ override fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
+ super.visibleWindowsShownMoreThanOneConsecutiveEntry()
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
index d194472b9000..6fcd17ae5f8a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt
@@ -185,8 +185,7 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- supportedRotations = listOf(Surface.ROTATION_0),
- repetitions = 3
+ supportedRotations = listOf(Surface.ROTATION_0)
)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
index 507562b00f4f..a99439e35291 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt
@@ -246,8 +246,7 @@ class EnterPipToOtherOrientationTest(
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- supportedRotations = listOf(Surface.ROTATION_0),
- repetitions = 3
+ supportedRotations = listOf(Surface.ROTATION_0)
)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
index b5a3c78b67a7..39a7017a16d0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt
@@ -100,7 +100,7 @@ class ExitPipViaExpandButtonClickTest(
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3)
+ supportedRotations = listOf(Surface.ROTATION_0))
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
index 1d266140f2e6..421a6fc38e4c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt
@@ -125,7 +125,7 @@ class ExitPipViaIntentTest(testSpec: FlickerTestParameter) : ExitPipToAppTransit
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3)
+ supportedRotations = listOf(Surface.ROTATION_0))
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt
index b71a9d85d8cc..3bffef0ca793 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt
@@ -86,8 +86,7 @@ class ExitPipWithDismissButtonTest(testSpec: FlickerTestParameter) : ExitPipTran
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
- repetitions = 3)
+ .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
index 31a39c190dd6..75d25e6ef67e 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt
@@ -105,8 +105,7 @@ class ExitPipWithSwipeDownTest(testSpec: FlickerTestParameter) : ExitPipTransiti
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
- repetitions = 3)
+ .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
index fd661cfc3ee1..825aca3aaa16 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt
@@ -178,8 +178,7 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- supportedRotations = listOf(Surface.ROTATION_0),
- repetitions = 3
+ supportedRotations = listOf(Surface.ROTATION_0)
)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
index b3f0fb91ab73..d3e2ce1571b4 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt
@@ -89,7 +89,7 @@ open class MovePipDownShelfHeightChangeTest(
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3
+ supportedRotations = listOf(Surface.ROTATION_0)
)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
index 8bd5c548f6bd..3d64bbeb720b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt
@@ -105,7 +105,7 @@ class MovePipUpShelfHeightChangeTest(
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3
+ supportedRotations = listOf(Surface.ROTATION_0)
)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
index 454927e57aa2..be39faeff321 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt
@@ -116,8 +116,7 @@ open class PipKeyboardTest(testSpec: FlickerTestParameter) : PipTransition(testS
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
- repetitions = 3)
+ .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
index 09248a167308..4dc98588217a 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt
@@ -264,8 +264,7 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigRotationTests(
- supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90),
- repetitions = 3
+ supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)
)
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
index 6d64cb9e0dee..d5de22fb49c0 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt
@@ -224,8 +224,7 @@ open class SetRequestedOrientationWhilePinnedTest(
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0),
- repetitions = 1)
+ .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0))
}
}
}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
index d23881475ad6..6cbb685850fa 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt
@@ -178,7 +178,6 @@ class CopyContentInSplit(testSpec: FlickerTestParameter) : SplitScreenBase(testS
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- repetitions = SplitScreenHelper.TEST_REPETITIONS,
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes =
listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
index ba40c2740bb1..581826ef889f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt
@@ -195,7 +195,6 @@ class DismissSplitScreenByDivider (testSpec: FlickerTestParameter) : SplitScreen
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- repetitions = SplitScreenHelper.TEST_REPETITIONS,
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes =
listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
index 6828589656d6..5c051e859d59 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt
@@ -182,7 +182,6 @@ class DismissSplitScreenByGoHome(
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- repetitions = SplitScreenHelper.TEST_REPETITIONS,
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes =
listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
index 9ac7c230096b..9ca9ab01fd7b 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt
@@ -186,7 +186,6 @@ class DragDividerToResize (testSpec: FlickerTestParameter) : SplitScreenBase(tes
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- repetitions = SplitScreenHelper.TEST_REPETITIONS,
supportedRotations = listOf(Surface.ROTATION_0),
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes =
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
index 8401c1a910b8..8e2769fb75bd 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
@@ -180,7 +180,6 @@ class EnterSplitScreenByDragFromAllApps(
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- repetitions = SplitScreenHelper.TEST_REPETITIONS,
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes =
listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
index 168afda119a9..531d376e3588 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
@@ -195,7 +195,6 @@ class EnterSplitScreenByDragFromNotification(
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- repetitions = SplitScreenHelper.TEST_REPETITIONS,
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes =
listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
index c1fce5f40b57..ea43c7ea0ddf 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt
@@ -183,7 +183,6 @@ class EnterSplitScreenByDragFromTaskbar(
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- repetitions = SplitScreenHelper.TEST_REPETITIONS,
supportedNavigationModes =
listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)
)
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
index 153056188d24..525e09a19d2f 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt
@@ -180,7 +180,6 @@ class SwitchAppByDoubleTapDivider (testSpec: FlickerTestParameter) : SplitScreen
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- repetitions = SplitScreenHelper.TEST_REPETITIONS,
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes =
listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
index 20544bd2fc2f..c030603a6b55 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt
@@ -184,7 +184,6 @@ class SwitchBackToSplitFromAnotherApp(testSpec: FlickerTestParameter) : SplitScr
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- repetitions = SplitScreenHelper.TEST_REPETITIONS,
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes =
listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
index 5a8604f2dccc..b8565f3e89b2 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt
@@ -183,7 +183,6 @@ class SwitchBackToSplitFromHome(testSpec: FlickerTestParameter) : SplitScreenBas
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- repetitions = SplitScreenHelper.TEST_REPETITIONS,
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes =
listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
index adea66a49c46..20d7f2cf57e8 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt
@@ -185,7 +185,6 @@ class SwitchBackToSplitFromRecent(testSpec: FlickerTestParameter) : SplitScreenB
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests(
- repetitions = SplitScreenHelper.TEST_REPETITIONS,
// TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy.
supportedNavigationModes =
listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY))
diff --git a/media/java/android/media/AudioDeviceVolumeManager.java b/media/java/android/media/AudioDeviceVolumeManager.java
index c70887672f9e..40f6dc541f86 100644
--- a/media/java/android/media/AudioDeviceVolumeManager.java
+++ b/media/java/android/media/AudioDeviceVolumeManager.java
@@ -21,6 +21,8 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
@@ -39,23 +41,29 @@ import java.util.concurrent.Executor;
* @hide
* AudioDeviceVolumeManager provides access to audio device volume control.
*/
+@SystemApi
public class AudioDeviceVolumeManager {
// define when using Log.*
//private static final String TAG = "AudioDeviceVolumeManager";
- /** Indicates no special treatment in the handling of the volume adjustment */
+ /** @hide
+ * Indicates no special treatment in the handling of the volume adjustment */
public static final int ADJUST_MODE_NORMAL = 0;
- /** Indicates the start of a volume adjustment */
+ /** @hide
+ * Indicates the start of a volume adjustment */
public static final int ADJUST_MODE_START = 1;
- /** Indicates the end of a volume adjustment */
+ /** @hide
+ * Indicates the end of a volume adjustment */
public static final int ADJUST_MODE_END = 2;
+ /** @hide */
@IntDef(flag = false, prefix = "ADJUST_MODE", value = {
ADJUST_MODE_NORMAL,
ADJUST_MODE_START,
ADJUST_MODE_END}
)
+ /** @hide */
@Retention(RetentionPolicy.SOURCE)
public @interface VolumeAdjustmentMode {}
@@ -64,7 +72,16 @@ public class AudioDeviceVolumeManager {
private final @NonNull String mPackageName;
private final @Nullable String mAttributionTag;
- public AudioDeviceVolumeManager(Context context) {
+ /**
+ * Constructor
+ * @param context the Context for the device volume operations
+ */
+ @SuppressLint("ManagerConstructor")
+ // reason for suppression: even though the functionality handled by this class is implemented in
+ // AudioService, we want to avoid bloating android.media.AudioManager
+ // with @SystemApi functionality
+ public AudioDeviceVolumeManager(@NonNull Context context) {
+ Objects.requireNonNull(context);
mPackageName = context.getApplicationContext().getOpPackageName();
mAttributionTag = context.getApplicationContext().getAttributionTag();
}
@@ -101,6 +118,7 @@ public class AudioDeviceVolumeManager {
@VolumeAdjustmentMode int mode);
}
+ /** @hide */
static class ListenerInfo {
final @NonNull OnAudioDeviceVolumeChangedListener mListener;
final @NonNull Executor mExecutor;
@@ -127,6 +145,7 @@ public class AudioDeviceVolumeManager {
@GuardedBy("mDeviceVolumeListenerLock")
private DeviceVolumeDispatcherStub mDeviceVolumeDispatcherStub;
+ /** @hide */
final class DeviceVolumeDispatcherStub extends IAudioDeviceVolumeDispatcher.Stub {
/**
* Register / unregister the stub
@@ -305,6 +324,7 @@ public class AudioDeviceVolumeManager {
* @param vi the volume information, only stream-based volumes are supported
* @param ada the device for which volume is to be modified
*/
+ @SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada) {
try {
@@ -315,6 +335,7 @@ public class AudioDeviceVolumeManager {
}
/**
+ * @hide
* Return human-readable name for volume behavior
* @param behavior one of the volume behaviors defined in AudioManager
* @return a string for the given behavior
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 650f36059495..72190e370129 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -65,8 +65,6 @@ public class AudioSystem
private static final String TAG = "AudioSystem";
- private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO remove in U
-
// private constructor to prevent instantiating AudioSystem
private AudioSystem() {
throw new UnsupportedOperationException("Trying to instantiate AudioSystem");
@@ -293,7 +291,7 @@ public class AudioSystem
case AUDIO_FORMAT_APTX_HD: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
case AUDIO_FORMAT_LDAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
case AUDIO_FORMAT_LC3: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3;
- case AUDIO_FORMAT_OPUS: return SOURCE_CODEC_TYPE_OPUS; // TODO update in U
+ case AUDIO_FORMAT_OPUS: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS;
default:
Log.e(TAG, "Unknown audio format 0x" + Integer.toHexString(audioFormat)
+ " for conversion to BT codec");
@@ -336,7 +334,7 @@ public class AudioSystem
return AudioSystem.AUDIO_FORMAT_LDAC;
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3:
return AudioSystem.AUDIO_FORMAT_LC3;
- case SOURCE_CODEC_TYPE_OPUS: // TODO update in U
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS:
return AudioSystem.AUDIO_FORMAT_OPUS;
default:
Log.e(TAG, "Unknown BT codec 0x" + Integer.toHexString(btCodec)
diff --git a/media/java/android/media/VolumeInfo.java b/media/java/android/media/VolumeInfo.java
index c61b0e57db1a..6b4f604025e2 100644
--- a/media/java/android/media/VolumeInfo.java
+++ b/media/java/android/media/VolumeInfo.java
@@ -18,6 +18,7 @@ package android.media;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.content.Context;
import android.media.audiopolicy.AudioVolumeGroup;
import android.os.IBinder;
@@ -32,16 +33,13 @@ import java.util.Objects;
/**
* @hide
- * A class to represent type of volume information.
+ * A class to represent volume information.
* Can be used to represent volume associated with a stream type or {@link AudioVolumeGroup}.
* Volume index is optional when used to represent a category of volume.
* Index ranges are supported too, making the representation of volume changes agnostic to the
* range (e.g. can be used to map BT A2DP absolute volume range to internal range).
- *
- * Note: this class is not yet part of the SystemApi but is intended to be gradually introduced
- * particularly in parts of the audio framework that suffer from code ambiguity when
- * dealing with different volume ranges / units.
*/
+@SystemApi
public final class VolumeInfo implements Parcelable {
private static final String TAG = "VolumeInfo";
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index 31fb8d03c4a0..9bf126b7a875 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -35,7 +35,7 @@ interface ISession {
ISessionController getController();
void setFlags(int flags);
void setActive(boolean active);
- void setMediaButtonReceiver(in PendingIntent mbr);
+ void setMediaButtonReceiver(in PendingIntent mbr, String sessionPackageName);
void setMediaButtonBroadcastReceiver(in ComponentName broadcastReceiver);
void setLaunchPendingIntent(in PendingIntent pi);
void destroySession();
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 1bd12afdc026..9e265d8339dd 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -286,7 +286,7 @@ public final class MediaSession {
@Deprecated
public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
try {
- mBinder.setMediaButtonReceiver(mbr);
+ mBinder.setMediaButtonReceiver(mbr, mContext.getPackageName());
} catch (RemoteException e) {
Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
}
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt
index e300624bcc95..3f375345f30f 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt
@@ -24,6 +24,7 @@ import com.android.settingslib.spa.gallery.page.PreferencePageProvider
import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider
import com.android.settingslib.spa.gallery.page.SliderPageProvider
import com.android.settingslib.spa.gallery.page.SwitchPreferencePageProvider
+import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
val galleryPageProviders = SettingsPageProviderRepository(
allPagesList = listOf(
@@ -32,6 +33,7 @@ val galleryPageProviders = SettingsPageProviderRepository(
SwitchPreferencePageProvider,
ArgumentPageProvider,
SliderPageProvider,
+ SpinnerPageProvider,
SettingsPagerPageProvider,
FooterPageProvider,
),
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
index a85ee2a2a309..089920c8e8cf 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/home/HomePage.kt
@@ -29,6 +29,7 @@ import com.android.settingslib.spa.gallery.page.PreferencePageProvider
import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider
import com.android.settingslib.spa.gallery.page.SliderPageProvider
import com.android.settingslib.spa.gallery.page.SwitchPreferencePageProvider
+import com.android.settingslib.spa.gallery.ui.SpinnerPageProvider
import com.android.settingslib.spa.widget.scaffold.HomeScaffold
object HomePageProvider : SettingsPageProvider {
@@ -48,6 +49,7 @@ private fun HomePage() {
ArgumentPageProvider.EntryItem(stringParam = "foo", intParam = 0)
SliderPageProvider.EntryItem()
+ SpinnerPageProvider.EntryItem()
SettingsPagerPageProvider.EntryItem()
FooterPageProvider.EntryItem()
}
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
index 314635176889..130cbd9f7b7b 100644
--- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/page/SliderPage.kt
@@ -30,11 +30,11 @@ import androidx.compose.ui.tooling.preview.Preview
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.theme.SettingsTheme
+import com.android.settingslib.spa.widget.SettingsSlider
+import com.android.settingslib.spa.widget.SettingsSliderModel
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
-import com.android.settingslib.spa.widget.ui.SettingsSlider
-import com.android.settingslib.spa.widget.ui.SettingsSliderModel
private const val TITLE = "Sample Slider"
diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt
new file mode 100644
index 000000000000..7efa85b4ad78
--- /dev/null
+++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/ui/SpinnerPage.kt
@@ -0,0 +1,75 @@
+/*
+ * 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.settingslib.spa.gallery.ui
+
+import android.os.Bundle
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.ui.tooling.preview.Preview
+import com.android.settingslib.spa.framework.common.SettingsPageProvider
+import com.android.settingslib.spa.framework.compose.navigator
+import com.android.settingslib.spa.framework.theme.SettingsTheme
+import com.android.settingslib.spa.widget.preference.Preference
+import com.android.settingslib.spa.widget.preference.PreferenceModel
+import com.android.settingslib.spa.widget.scaffold.RegularScaffold
+import com.android.settingslib.spa.widget.ui.Spinner
+
+private const val TITLE = "Sample Spinner"
+
+object SpinnerPageProvider : SettingsPageProvider {
+ override val name = "Spinner"
+
+ @Composable
+ override fun Page(arguments: Bundle?) {
+ SpinnerPage()
+ }
+
+ @Composable
+ fun EntryItem() {
+ Preference(object : PreferenceModel {
+ override val title = TITLE
+ override val onClick = navigator(name)
+ })
+ }
+}
+
+@Composable
+private fun SpinnerPage() {
+ RegularScaffold(title = TITLE) {
+ val selectedIndex = rememberSaveable { mutableStateOf(0) }
+ Spinner(
+ options = (1..3).map { "Option $it" },
+ selectedIndex = selectedIndex.value,
+ setIndex = { selectedIndex.value = it },
+ )
+ Preference(object : PreferenceModel {
+ override val title = "Selected index"
+ override val summary = remember { derivedStateOf { selectedIndex.value.toString() } }
+ })
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun SpinnerPagePreview() {
+ SettingsTheme {
+ SpinnerPage()
+ }
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
index 6a7b17ab1b27..e8d1ea2c7680 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/BrowseActivity.kt
@@ -21,6 +21,8 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
+import androidx.compose.runtime.LaunchedEffect
+import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
@@ -46,12 +48,11 @@ open class BrowseActivity(
@Composable
private fun MainContent() {
- val startDestination =
- intent?.getStringExtra(KEY_START_DESTINATION) ?: sppRepository.getDefaultStartPageName()
+ val destination = intent?.getStringExtra(KEY_DESTINATION)
val navController = rememberNavController()
CompositionLocalProvider(navController.localNavController()) {
- NavHost(navController, startDestination) {
+ NavHost(navController, sppRepository.getDefaultStartPageName()) {
for (page in sppRepository.getAllProviders()) {
composable(
route = page.route,
@@ -61,6 +62,16 @@ open class BrowseActivity(
}
}
}
+
+ if (!destination.isNullOrEmpty()) {
+ LaunchedEffect(Unit) {
+ navController.navigate(destination) {
+ popUpTo(navController.graph.findStartDestination().id) {
+ inclusive = true
+ }
+ }
+ }
+ }
}
}
@@ -68,6 +79,6 @@ open class BrowseActivity(
get() = name + arguments.joinToString("") { argument -> "/{${argument.name}}" }
companion object {
- const val KEY_START_DESTINATION = "spa:SpaActivity:startDestination"
+ const val KEY_DESTINATION = "spa:SpaActivity:destination"
}
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
index c68d5de0d7c7..32ef0bb3d19b 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/compose/NavControllerWrapper.kt
@@ -16,25 +16,35 @@
package com.android.settingslib.spa.framework.compose
+import androidx.activity.OnBackPressedDispatcher
+import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ProvidedValue
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember
import androidx.navigation.NavHostController
interface NavControllerWrapper {
fun navigate(route: String)
- fun navigateUp()
+ fun navigateBack()
}
@Composable
-fun NavHostController.localNavController() =
- LocalNavController provides remember { NavControllerWrapperImpl(this) }
+fun NavHostController.localNavController(): ProvidedValue<NavControllerWrapper> {
+ val onBackPressedDispatcherOwner = LocalOnBackPressedDispatcherOwner.current
+ return LocalNavController provides remember {
+ NavControllerWrapperImpl(
+ navController = this,
+ onBackPressedDispatcher = onBackPressedDispatcherOwner?.onBackPressedDispatcher,
+ )
+ }
+}
val LocalNavController = compositionLocalOf<NavControllerWrapper> {
object : NavControllerWrapper {
override fun navigate(route: String) {}
- override fun navigateUp() {}
+ override fun navigateBack() {}
}
}
@@ -46,12 +56,13 @@ fun navigator(route: String): () -> Unit {
internal class NavControllerWrapperImpl(
private val navController: NavHostController,
+ private val onBackPressedDispatcher: OnBackPressedDispatcher?,
) : NavControllerWrapper {
override fun navigate(route: String) {
navController.navigate(route)
}
- override fun navigateUp() {
- navController.navigateUp()
+ override fun navigateBack() {
+ onBackPressedDispatcher?.onBackPressed()
}
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
index 27fdc916a434..bc316f71cf23 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsColors.kt
@@ -31,6 +31,10 @@ data class SettingsColorScheme(
val secondaryText: Color = Color.Unspecified,
val primaryContainer: Color = Color.Unspecified,
val onPrimaryContainer: Color = Color.Unspecified,
+ val spinnerHeaderContainer: Color = Color.Unspecified,
+ val onSpinnerHeaderContainer: Color = Color.Unspecified,
+ val spinnerItemContainer: Color = Color.Unspecified,
+ val onSpinnerItemContainer: Color = Color.Unspecified,
)
internal val LocalColorScheme = staticCompositionLocalOf { SettingsColorScheme() }
@@ -65,6 +69,10 @@ private fun dynamicLightColorScheme(context: Context): SettingsColorScheme {
secondaryText = tonalPalette.neutralVariant30,
primaryContainer = tonalPalette.primary90,
onPrimaryContainer = tonalPalette.neutral10,
+ spinnerHeaderContainer = tonalPalette.primary90,
+ onSpinnerHeaderContainer = tonalPalette.neutral10,
+ spinnerItemContainer = tonalPalette.secondary90,
+ onSpinnerItemContainer = tonalPalette.neutralVariant30,
)
}
@@ -87,5 +95,9 @@ private fun dynamicDarkColorScheme(context: Context): SettingsColorScheme {
secondaryText = tonalPalette.neutralVariant80,
primaryContainer = tonalPalette.secondary90,
onPrimaryContainer = tonalPalette.neutral10,
+ spinnerHeaderContainer = tonalPalette.primary90,
+ onSpinnerHeaderContainer = tonalPalette.neutral10,
+ spinnerItemContainer = tonalPalette.secondary90,
+ onSpinnerItemContainer = tonalPalette.neutralVariant30,
)
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/SettingsSlider.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/SettingsSlider.kt
index 0454ac37cfb7..4f77a89577ea 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/SettingsSlider.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/SettingsSlider.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settingslib.spa.widget.ui
+package com.android.settingslib.spa.widget
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.AccessAlarm
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
index c9602543b364..b8e43609708d 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/Actions.kt
@@ -26,13 +26,13 @@ import androidx.compose.ui.res.stringResource
import com.android.settingslib.spa.framework.compose.LocalNavController
@Composable
-internal fun NavigateUp() {
+internal fun NavigateBack() {
val navController = LocalNavController.current
val contentDescription = stringResource(
id = androidx.appcompat.R.string.abc_action_bar_up_description,
)
BackAction(contentDescription) {
- navController.navigateUp()
+ navController.navigateBack()
}
}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt
index ee453f246623..8b530b0d7b9b 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/SettingsScaffold.kt
@@ -49,7 +49,7 @@ fun SettingsScaffold(
modifier = Modifier.padding(SettingsDimension.itemPaddingAround),
)
},
- navigationIcon = { NavigateUp() },
+ navigationIcon = { NavigateBack() },
actions = actions,
colors = settingsTopAppBarColors(),
)
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
new file mode 100644
index 000000000000..429b81a04659
--- /dev/null
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/ui/Spinner.kt
@@ -0,0 +1,131 @@
+/*
+ * 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.settingslib.spa.widget.ui
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.selection.selectableGroup
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.ArrowDropDown
+import androidx.compose.material.icons.outlined.ArrowDropUp
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.DropdownMenu
+import androidx.compose.material3.DropdownMenuItem
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.DpOffset
+import androidx.compose.ui.unit.dp
+import com.android.settingslib.spa.framework.theme.SettingsDimension
+import com.android.settingslib.spa.framework.theme.SettingsTheme
+
+@Composable
+fun Spinner(options: List<String>, selectedIndex: Int, setIndex: (index: Int) -> Unit) {
+ if (options.isEmpty()) {
+ return
+ }
+
+ var expanded by rememberSaveable { mutableStateOf(false) }
+
+ Box(
+ modifier = Modifier
+ .padding(SettingsDimension.itemPadding)
+ .selectableGroup(),
+ ) {
+ val contentPadding = PaddingValues(horizontal = SettingsDimension.itemPaddingEnd)
+ Button(
+ onClick = { expanded = true },
+ modifier = Modifier.height(36.dp),
+ colors = ButtonDefaults.buttonColors(
+ containerColor = SettingsTheme.colorScheme.spinnerHeaderContainer,
+ contentColor = SettingsTheme.colorScheme.onSpinnerHeaderContainer,
+ ),
+ contentPadding = contentPadding,
+ ) {
+ SpinnerText(options[selectedIndex])
+ Icon(
+ imageVector = when {
+ expanded -> Icons.Outlined.ArrowDropUp
+ else -> Icons.Outlined.ArrowDropDown
+ },
+ contentDescription = null,
+ )
+ }
+ DropdownMenu(
+ expanded = expanded,
+ onDismissRequest = { expanded = false },
+ modifier = Modifier.background(SettingsTheme.colorScheme.spinnerItemContainer),
+ offset = DpOffset(x = 0.dp, y = 4.dp),
+ ) {
+ options.forEachIndexed { index, option ->
+ DropdownMenuItem(
+ text = {
+ SpinnerText(
+ text = option,
+ modifier = Modifier.padding(end = 24.dp),
+ color = SettingsTheme.colorScheme.onSpinnerItemContainer,
+ )
+ },
+ onClick = {
+ expanded = false
+ setIndex(index)
+ },
+ contentPadding = contentPadding,
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun SpinnerText(
+ text: String,
+ modifier: Modifier = Modifier,
+ color: Color = Color.Unspecified,
+) {
+ Text(
+ text = text,
+ modifier = modifier.padding(end = SettingsDimension.itemPaddingEnd),
+ color = color,
+ style = MaterialTheme.typography.labelLarge,
+ )
+}
+
+@Preview(showBackground = true)
+@Composable
+private fun SpinnerPreview() {
+ SettingsTheme {
+ var selectedIndex by rememberSaveable { mutableStateOf(0) }
+ Spinner(
+ options = (1..3).map { "Option $it" },
+ selectedIndex = selectedIndex,
+ setIndex = { selectedIndex = it },
+ )
+ }
+}
diff --git a/packages/SettingsLib/Spa/tests/Android.bp b/packages/SettingsLib/Spa/tests/Android.bp
index 037d8c4e78b1..1ce49fa520b9 100644
--- a/packages/SettingsLib/Spa/tests/Android.bp
+++ b/packages/SettingsLib/Spa/tests/Android.bp
@@ -31,6 +31,7 @@ android_test {
"androidx.compose.runtime_runtime",
"androidx.compose.ui_ui-test-junit4",
"androidx.compose.ui_ui-test-manifest",
+ "truth-prebuilt",
],
kotlincflags: ["-Xjvm-default=all"],
}
diff --git a/packages/SettingsLib/Spa/tests/build.gradle b/packages/SettingsLib/Spa/tests/build.gradle
index be5a5ec40c4f..5f93a9f4e4b5 100644
--- a/packages/SettingsLib/Spa/tests/build.gradle
+++ b/packages/SettingsLib/Spa/tests/build.gradle
@@ -63,5 +63,6 @@ dependencies {
androidTestImplementation(project(":spa"))
androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.3'
androidTestImplementation("androidx.compose.ui:ui-test-junit4:$jetpack_compose_version")
+ androidTestImplementation 'com.google.truth:truth:1.1.3'
androidTestDebugImplementation "androidx.compose.ui:ui-test-manifest:$jetpack_compose_version"
}
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/SettingsSliderTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/SettingsSliderTest.kt
new file mode 100644
index 000000000000..1d95e3383b51
--- /dev/null
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/SettingsSliderTest.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.settingslib.spa.widget
+
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithText
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class SettingsSliderTest {
+ @get:Rule
+ val composeTestRule = createComposeRule()
+
+ @Test
+ fun title_displayed() {
+ composeTestRule.setContent {
+ SettingsSlider(object : SettingsSliderModel {
+ override val title = "Slider"
+ override val initValue = 40
+ })
+ }
+
+ composeTestRule.onNodeWithText("Slider").assertIsDisplayed()
+ }
+
+ // TODO: Add more unit tests for SettingsSlider widget.
+}
diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/SpinnerTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/SpinnerTest.kt
new file mode 100644
index 000000000000..6c56d63c18c7
--- /dev/null
+++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/ui/SpinnerTest.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.settingslib.spa.widget.ui
+
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.performClick
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class SpinnerTest {
+ @get:Rule
+ val composeTestRule = createComposeRule()
+
+ @Test
+ fun spinner_initialState() {
+ var selectedIndex by mutableStateOf(0)
+ composeTestRule.setContent {
+ Spinner(
+ options = (1..3).map { "Option $it" },
+ selectedIndex = selectedIndex,
+ setIndex = { selectedIndex = it },
+ )
+ }
+
+ composeTestRule.onNodeWithText("Option 1").assertIsDisplayed()
+ composeTestRule.onNodeWithText("Option 2").assertDoesNotExist()
+ assertThat(selectedIndex).isEqualTo(0)
+ }
+
+ @Test
+ fun spinner_canChangeState() {
+ var selectedIndex by mutableStateOf(0)
+ composeTestRule.setContent {
+ Spinner(
+ options = (1..3).map { "Option $it" },
+ selectedIndex = selectedIndex,
+ setIndex = { selectedIndex = it },
+ )
+ }
+
+ composeTestRule.onNodeWithText("Option 1").performClick()
+ composeTestRule.onNodeWithText("Option 2").performClick()
+
+ composeTestRule.onNodeWithText("Option 1").assertDoesNotExist()
+ composeTestRule.onNodeWithText("Option 2").assertIsDisplayed()
+ assertThat(selectedIndex).isEqualTo(1)
+ }
+}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
index dac79a0fbb16..eb9ce5e77c93 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppInfoPage.kt
@@ -30,7 +30,6 @@ import androidx.navigation.NavType
import androidx.navigation.navArgument
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator
-import com.android.settingslib.spa.framework.compose.rememberContext
import com.android.settingslib.spa.widget.preference.SwitchPreference
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import com.android.settingslib.spaprivileged.model.app.AppRecord
@@ -44,7 +43,7 @@ private const val PACKAGE_NAME = "packageName"
private const val USER_ID = "userId"
internal class TogglePermissionAppInfoPageProvider(
- private val factory: TogglePermissionAppListModelFactory,
+ private val appListTemplate: TogglePermissionAppListTemplate,
) : SettingsPageProvider {
override val name = NAME
@@ -57,10 +56,10 @@ internal class TogglePermissionAppInfoPageProvider(
@Composable
override fun Page(arguments: Bundle?) {
checkNotNull(arguments)
- val permission = checkNotNull(arguments.getString(PERMISSION))
+ val permissionType = checkNotNull(arguments.getString(PERMISSION))
val packageName = checkNotNull(arguments.getString(PACKAGE_NAME))
val userId = arguments.getInt(USER_ID)
- val listModel = rememberContext { context -> factory.createModel(permission, context) }
+ val listModel = appListTemplate.rememberModel(permissionType)
TogglePermissionAppInfoPage(listModel, packageName, userId)
}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListModel.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
index e1354bdd9871..3cc5854b95e4 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListModel.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppList.kt
@@ -47,20 +47,14 @@ interface TogglePermissionAppListModel<T : AppRecord> {
fun setAllowed(record: T, newAllowed: Boolean)
}
-interface TogglePermissionAppListModelFactory {
- fun createModel(
- permission: String,
- context: Context,
- ): TogglePermissionAppListModel<out AppRecord>
+interface TogglePermissionAppListProvider {
+ val permissionType: String
- fun createPageProviders(): List<SettingsPageProvider> = listOf(
- TogglePermissionAppListPageProvider(this),
- TogglePermissionAppInfoPageProvider(this),
- )
+ fun createModel(context: Context): TogglePermissionAppListModel<out AppRecord>
@Composable
- fun EntryItem(permissionType: String) {
- val listModel = rememberModel(permissionType)
+ fun EntryItem() {
+ val listModel = rememberContext(::createModel)
Preference(
object : PreferenceModel {
override val title = stringResource(listModel.pageTitleResId)
@@ -68,8 +62,28 @@ interface TogglePermissionAppListModelFactory {
}
)
}
+
+ /**
+ * Gets the route to the toggle permission App List page.
+ *
+ * Expose route to enable enter from non-SPA pages.
+ */
+ fun getRoute(): String =
+ TogglePermissionAppListPageProvider.getRoute(permissionType)
}
-@Composable
-internal fun TogglePermissionAppListModelFactory.rememberModel(permission: String) =
- rememberContext { context -> createModel(permission, context) }
+class TogglePermissionAppListTemplate(
+ allProviders: List<TogglePermissionAppListProvider>,
+) {
+ private val listModelProviderMap = allProviders.associateBy { it.permissionType }
+
+ fun createPageProviders(): List<SettingsPageProvider> = listOf(
+ TogglePermissionAppListPageProvider(this),
+ TogglePermissionAppInfoPageProvider(this),
+ )
+
+ @Composable
+ internal fun rememberModel(permissionType: String) = rememberContext { context ->
+ listModelProviderMap.getValue(permissionType).createModel(context)
+ }
+}
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
index 6d00d56e6952..f2eb96277b9b 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/app/TogglePermissionAppListPage.kt
@@ -38,7 +38,7 @@ private const val NAME = "TogglePermissionAppList"
private const val PERMISSION = "permission"
internal class TogglePermissionAppListPageProvider(
- private val factory: TogglePermissionAppListModelFactory,
+ private val appListTemplate: TogglePermissionAppListTemplate,
) : SettingsPageProvider {
override val name = NAME
@@ -55,7 +55,7 @@ internal class TogglePermissionAppListPageProvider(
@Composable
private fun TogglePermissionAppList(permissionType: String) {
- val listModel = factory.rememberModel(permissionType)
+ val listModel = appListTemplate.rememberModel(permissionType)
val context = LocalContext.current
val internalListModel = remember {
TogglePermissionInternalAppListModel(context, listModel)
@@ -75,8 +75,14 @@ internal class TogglePermissionAppListPageProvider(
}
companion object {
+ /**
+ * Gets the route to this page.
+ *
+ * Expose route to enable enter from non-SPA pages.
+ */
+ internal fun getRoute(permissionType: String) = "$NAME/$permissionType"
@Composable
- internal fun navigator(permissionType: String) = navigator(route = "$NAME/$permissionType")
+ internal fun navigator(permissionType: String) = navigator(route = getRoute(permissionType))
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 19409865284c..b64dcca63ac9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -43,8 +43,6 @@ import java.util.List;
public class A2dpProfile implements LocalBluetoothProfile {
private static final String TAG = "A2dpProfile";
- private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO remove in U
-
private Context mContext;
private BluetoothA2dp mService;
@@ -333,7 +331,7 @@ public class A2dpProfile implements LocalBluetoothProfile {
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3:
index = 6;
break;
- case SOURCE_CODEC_TYPE_OPUS: // TODO update in U
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS:
index = 7;
break;
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 78dea891bc12..abcd65b5071a 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -85,7 +85,6 @@
<uses-permission android:name="android.permission.CONTROL_VPN" />
<uses-permission android:name="android.permission.PEERS_MAC_ADDRESS"/>
<uses-permission android:name="android.permission.READ_WIFI_CREDENTIAL"/>
- <uses-permission android:name="android.permission.NETWORK_STACK"/>
<!-- Physical hardware -->
<uses-permission android:name="android.permission.MANAGE_USB" />
<uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS" />
@@ -152,6 +151,9 @@
<uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" />
<uses-permission android:name="android.permission.GET_RUNTIME_PERMISSIONS" />
+ <!-- For auto-grant the access to the Settings' slice preferences, e.g. volume slices. -->
+ <uses-permission android:name="android.permission.READ_SEARCH_INDEXABLES" />
+
<!-- Needed for WallpaperManager.clear in ImageWallpaper.updateWallpaperLocked -->
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
@@ -956,5 +958,13 @@
</intent-filter>
</receiver>
+ <receiver android:name=".volume.VolumePanelDialogReceiver"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.settings.panel.action.VOLUME" />
+ <action android:name="com.android.systemui.action.LAUNCH_VOLUME_PANEL_DIALOG" />
+ <action android:name="com.android.systemui.action.DISMISS_VOLUME_PANEL_DIALOG" />
+ </intent-filter>
+ </receiver>
</application>
</manifest>
diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt
new file mode 100644
index 000000000000..3ca8dfe4fd38
--- /dev/null
+++ b/packages/SystemUI/ktfmt_includes.txt
@@ -0,0 +1,870 @@
++packages/SystemUI
+-packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/BindServiceViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/BroadcastSentViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/GetMainLooperViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/RegisterReceiverViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/SoftwareBitmapDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/BindServiceViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/BroadcastSentViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/GetMainLooperViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/RegisterReceiverViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/SoftwareBitmapDetectorTest.kt
+-packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
+-packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+-packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainerController.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagListenable.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagSerializer.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagSettingsHelper.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionDarkness.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonPositionCalculator.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerManager.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/system/smartspace/SmartspaceState.kt
+-packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
+-packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateManagerFoldProvider.kt
+-packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
+-packages/SystemUI/src-debug/com/android/systemui/flags/FlagsModule.kt
+-packages/SystemUI/src-release/com/android/systemui/flags/FlagsModule.kt
+-packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
+-packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardBiometricLockoutLogger.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardListenQueue.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt
+-packages/SystemUI/src/com/android/keyguard/clock/ClockPalette.kt
+-packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+-packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/BootCompleteCache.kt
+-packages/SystemUI/src/com/android/systemui/BootCompleteCacheImpl.kt
+-packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt
+-packages/SystemUI/src/com/android/systemui/ChooserSelector.kt
+-packages/SystemUI/src/com/android/systemui/DarkReceiverImpl.kt
+-packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
+-packages/SystemUI/src/com/android/systemui/DualToneHandler.kt
+-packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
+-packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
+-packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt
+-packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt
+-packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
+-packages/SystemUI/src/com/android/systemui/assist/AssistLogger.kt
+-packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt
+-packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt
+-packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AlternateUdfpsTouchProvider.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/BiometricDisplayListener.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/DwellRippleShader.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpDrawable.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHapticsSimulator.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayParams.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcherStartable.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/PendingRemovalStore.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt
+-packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
+-packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt
+-packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt
+-packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlStatus.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlsMetricsLogger.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlsMetricsLoggerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt
+-packages/SystemUI/src/com/android/systemui/controls/CustomIconCache.kt
+-packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlInfo.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapper.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfiguration.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/StatefulControlSubscriber.kt
+-packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt
+-packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsFeatureEnabled.kt
+-packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/AllModel.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingController.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestReceiver.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/FavoritesModel.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ManagementPageIndicator.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlWithState.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/CornerDrawable.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
+-packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+-packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
+-packages/SystemUI/src/com/android/systemui/decor/DecorProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
+-packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
+-packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
+-packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt
+-packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
+-packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
+-packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelper.kt
+-packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt
+-packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt
+-packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
+-packages/SystemUI/src/com/android/systemui/dump/DumpsysTableLogger.kt
+-packages/SystemUI/src/com/android/systemui/dump/LogBufferEulogizer.kt
+-packages/SystemUI/src/com/android/systemui/dump/LogBufferFreezer.kt
+-packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt
+-packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
+-packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt
+-packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
+-packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt
+-packages/SystemUI/src/com/android/systemui/log/LogLevel.kt
+-packages/SystemUI/src/com/android/systemui/log/LogMessage.kt
+-packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt
+-packages/SystemUI/src/com/android/systemui/log/LogcatEchoTracker.kt
+-packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerDebug.kt
+-packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerProd.kt
+-packages/SystemUI/src/com/android/systemui/media/AnimationBindHandler.kt
+-packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt
+-packages/SystemUI/src/com/android/systemui/media/GutsViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/media/IlluminationDrawable.kt
+-packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
+-packages/SystemUI/src/com/android/systemui/media/LightSourceDrawable.kt
+-packages/SystemUI/src/com/android/systemui/media/LocalMediaManagerFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaCarouselControllerLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaFeatureFlag.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaHostStatesManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaProjectionCaptureTarget.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaScrollView.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaTimeoutLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaViewLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MetadataAnimationHandler.kt
+-packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
+-packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
+-packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt
+-packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaDataProvider.kt
+-packages/SystemUI/src/com/android/systemui/media/SquigglyProgress.kt
+-packages/SystemUI/src/com/android/systemui/media/dagger/MediaProjectionModule.kt
+-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionCli.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesManager.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttFlags.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
+-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
+-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+-packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt
+-packages/SystemUI/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitor.kt
+-packages/SystemUI/src/com/android/systemui/privacy/MediaProjectionPrivacyItemMonitor.kt
+-packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipEvent.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyConfig.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogEvent.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+-packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.kt
+-packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+-packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
+-packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
+-packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSExpansionPathInterpolator.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSFragmentDisableFlagsLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSSquishinessController.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSUtils.kt
+-packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt
+-packages/SystemUI/src/com/android/systemui/qs/VisibilityChangedDispatcher.kt
+-packages/SystemUI/src/com/android/systemui/qs/carrier/CellSignalState.kt
+-packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/QSExternalModule.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialogEventLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt
+-packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/tileimpl/HeightOverrideable.kt
+-packages/SystemUI/src/com/android/systemui/qs/tileimpl/IgnorableChildLinearLayout.kt
+-packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+-packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
+-packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+-packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
+-packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
+-packages/SystemUI/src/com/android/systemui/ripple/RippleShader.kt
+-packages/SystemUI/src/com/android/systemui/ripple/RippleShaderUtilLibrary.kt
+-packages/SystemUI/src/com/android/systemui/ripple/RippleView.kt
+-packages/SystemUI/src/com/android/systemui/ripple/SdfShaderLibrary.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotProxyService.kt
+-packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt
+-packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserContentResolverProvider.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserContextProvider.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+-packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessMirrorHandler.kt
+-packages/SystemUI/src/com/android/systemui/settings/brightness/MirroredBrightnessController.kt
+-packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManager.kt
+-packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
+-packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
+-packages/SystemUI/src/com/android/systemui/shade/NPVCDownEventState.kt
+-packages/SystemUI/src/com/android/systemui/shade/NotifPanelEvents.kt
+-packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
+-packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
+-packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+-packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/SmartspacePrecondition.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/SmartspaceTargetFilter.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenAndDreamTargetFilter.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/preconditions/LockscreenPrecondition.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/ActionClickLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBarWifiView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/DisableFlagsLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockScreenShadeOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/commandline/CommandRegistry.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/AccessPointController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalControllerFactory.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileStatusTrackerFactory.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalCallback.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiStatusTrackerFactory.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartCentralSurfacesModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/TapGestureDetector.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/FeedbackIcon.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClickerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManagerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineDumper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SuppressedAttachState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolver.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DebugModeCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/BindEventManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/BindEventManagerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifStabilityManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTracker.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifEvent.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtender.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/DebugModeFilterProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGroupController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewListener.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifRowController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifShadeEventSource.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifStackController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewBarn.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewRenderer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotificationVisibilityProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RenderExtensions.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RootNodeController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/NotificationPersonExtractor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/ViewPipeline.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStageLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/RemoteInputViewModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenOffAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHideIconsForBouncerManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallFlags.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelStateListener.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserInfoTracker.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherFeatureController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiActivityModel.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/RemoteInput.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/SmartRepliesInflationModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/tv/VpnStatusObserver.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt
+-packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt
+-packages/SystemUI/src/com/android/systemui/toast/ToastLogger.kt
+-packages/SystemUI/src/com/android/systemui/tv/TVSystemUICoreStartableModule.kt
+-packages/SystemUI/src/com/android/systemui/unfold/FoldStateLogger.kt
+-packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
+-packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt
+-packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+-packages/SystemUI/src/com/android/systemui/unfold/UnfoldProgressProvider.kt
+-packages/SystemUI/src/com/android/systemui/user/UserCreator.kt
+-packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
+-packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
+-packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt
+-packages/SystemUI/src/com/android/systemui/util/AsyncActivityLauncher.kt
+-packages/SystemUI/src/com/android/systemui/util/ColorUtil.kt
+-packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
+-packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt
+-packages/SystemUI/src/com/android/systemui/util/DumpUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/InitializationChecker.kt
+-packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/ListenerSet.kt
+-packages/SystemUI/src/com/android/systemui/util/NeverExactlyLinearLayout.kt
+-packages/SystemUI/src/com/android/systemui/util/NoRemeasureMotionLayout.kt
+-packages/SystemUI/src/com/android/systemui/util/PluralMessageFormater.kt
+-packages/SystemUI/src/com/android/systemui/util/RingerModeTracker.kt
+-packages/SystemUI/src/com/android/systemui/util/RingerModeTrackerImpl.kt
+-packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt
+-packages/SystemUI/src/com/android/systemui/util/SafeMarqueeTextView.kt
+-packages/SystemUI/src/com/android/systemui/util/SparseArrayUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/TraceUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/UserAwareController.kt
+-packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/MeasurementInput.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt
+-packages/SystemUI/src/com/android/systemui/util/collection/RingBuffer.kt
+-packages/SystemUI/src/com/android/systemui/util/concurrency/Execution.kt
+-packages/SystemUI/src/com/android/systemui/util/concurrency/PendingTasksContainer.kt
+-packages/SystemUI/src/com/android/systemui/util/drawable/DrawableSize.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/IpcSerializer.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt
+-packages/SystemUI/src/com/android/systemui/util/view/ViewUtil.kt
+-packages/SystemUI/src/com/android/systemui/util/wrapper/RotationPolicyWrapper.kt
+-packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt
+-packages/SystemUI/src/com/android/systemui/volume/VolumePanelFactory.kt
+-packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardBiometricLockoutLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/clock/ClockPaletteTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/BootCompleteCacheTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/DisplayCutoutBaseViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/InstanceIdSequenceFake.kt
+-packages/SystemUI/tests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewLaunchAnimatorControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/PendingRemovalStoreTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/camera/CameraIntentsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/CustomIconCacheTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ServiceWrapperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/StatefulControlSubscriberTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/AllModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/DumpsysTableLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/lifecycle/InstantTaskExecutorRule.kt
+-packages/SystemUI/tests/src/com/android/systemui/log/LogBufferTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/AnimationBindHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/KeyguardMediaControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaResumeListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaTestUtils.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MetadataAnimationHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SmartspaceMediaDataTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SquigglyProgressTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyChipBuilderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyConfigFlagsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/HeaderPrivacyIconsControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentDisableFlagsLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelSwitchToParentTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSSquishinessControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/SettingObserverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/carrier/CellSignalStateTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileStatePersisterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogEventLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceRequestControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/ResourceIconTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/ripple/RippleViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenshot/ImageCaptureImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplingInstanceTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/DisableFlagsLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/MediaArtworkProcessorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/CommandRegistryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FoldStateListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryStateNotifierTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/VariableDateViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
+-packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/FakeSharedPreferencesTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/FloatingContentCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/ListenerSetTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/RingerModeLiveDataTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/animation/AnimationUtilTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/collection/RingBufferTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/drawable/DrawableSizeTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/kotlin/IpcSerializerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/view/ViewUtilTest.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/util/FakeSharedPreferences.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/util/mockito/KotlinMockitoHelpers.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/ScreenSizeFoldProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/SizeScreenStatusProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBackground.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldMain.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
diff --git a/packages/SystemUI/res/layout/media_ttt_chip.xml b/packages/SystemUI/res/layout/media_ttt_chip.xml
index d88680669fe0..ae8e38e2634b 100644
--- a/packages/SystemUI/res/layout/media_ttt_chip.xml
+++ b/packages/SystemUI/res/layout/media_ttt_chip.xml
@@ -16,7 +16,7 @@
<!-- Wrap in a frame layout so that we can update the margins on the inner layout. (Since this view
is the root view of a window, we cannot change the root view's margins.) -->
<!-- Alphas start as 0 because the view will be animated in. -->
-<FrameLayout
+<com.android.systemui.media.taptotransfer.sender.MediaTttChipRootView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/media_ttt_sender_chip"
@@ -97,4 +97,4 @@
/>
</LinearLayout>
-</FrameLayout>
+</com.android.systemui.media.taptotransfer.sender.MediaTttChipRootView>
diff --git a/packages/SystemUI/res/layout/volume_panel_dialog.xml b/packages/SystemUI/res/layout/volume_panel_dialog.xml
new file mode 100644
index 000000000000..99a1b5cc19dd
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_panel_dialog.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/volume_panel_dialog"
+ android:layout_width="@dimen/large_dialog_width"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/Widget.SliceView.Panel"
+ android:gravity="center_vertical|center_horizontal"
+ android:layout_marginTop="@dimen/dialog_top_padding"
+ android:layout_marginBottom="@dimen/dialog_bottom_padding"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/volume_panel_dialog_title"
+ android:ellipsize="end"
+ android:gravity="center_vertical|center_horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/sound_settings"
+ android:textAppearance="@style/TextAppearance.Dialog.Title"/>
+ </LinearLayout>
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/volume_panel_parent_layout"
+ android:scrollbars="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:minHeight="304dp"
+ android:layout_weight="1"
+ android:overScrollMode="never"/>
+
+ <LinearLayout
+ android:id="@+id/button_layout"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/dialog_button_vertical_padding"
+ android:layout_marginStart="@dimen/dialog_side_padding"
+ android:layout_marginEnd="@dimen/dialog_side_padding"
+ android:layout_marginBottom="@dimen/dialog_bottom_padding"
+ android:baselineAligned="false"
+ android:clickable="false"
+ android:focusable="false">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:layout_gravity="start|center_vertical"
+ android:orientation="vertical">
+ <Button
+ android:id="@+id/settings_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/volume_panel_dialog_settings_button"
+ android:ellipsize="end"
+ android:maxLines="1"
+ style="@style/Widget.Dialog.Button.BorderButton"
+ android:clickable="true"
+ android:focusable="true"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/dialog_button_horizontal_padding"
+ android:layout_gravity="end|center_vertical">
+ <Button
+ android:id="@+id/done_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/inline_done_button"
+ style="@style/Widget.Dialog.Button"
+ android:maxLines="1"
+ android:ellipsize="end"
+ android:clickable="true"
+ android:focusable="true"/>
+ </LinearLayout>
+ </LinearLayout>
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/volume_panel_slice_slider_row.xml b/packages/SystemUI/res/layout/volume_panel_slice_slider_row.xml
new file mode 100644
index 000000000000..d1303ed88964
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_panel_slice_slider_row.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/slice_slider_layout"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <androidx.slice.widget.SliceView
+ android:id="@+id/slice_view"
+ style="@style/Widget.SliceView.Panel.Slider"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingVertical="@dimen/volume_panel_slice_vertical_padding"
+ android:paddingHorizontal="@dimen/volume_panel_slice_horizontal_padding"/>
+</LinearLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e34d422b6dbc..a19145ddba6b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -479,6 +479,10 @@
<dimen name="volume_tool_tip_arrow_corner_radius">2dp</dimen>
+ <!-- Volume panel slices dimensions -->
+ <dimen name="volume_panel_slice_vertical_padding">8dp</dimen>
+ <dimen name="volume_panel_slice_horizontal_padding">24dp</dimen>
+
<!-- Size of each item in the ringer selector drawer. -->
<dimen name="volume_ringer_drawer_item_size">42dp</dimen>
<dimen name="volume_ringer_drawer_item_size_half">21dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index bfdb17041ad7..c7b2ff34c55f 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1139,6 +1139,11 @@
<!-- Content description for accessibility: Hint if click will disable. [CHAR LIMIT=NONE] -->
<string name="volume_odi_captions_hint_disable">disable</string>
+ <!-- Sound and vibration settings dialog title. [CHAR LIMIT=30] -->
+ <string name="sound_settings">Sound &amp; vibration</string>
+ <!-- Label for button to go to sound settings screen [CHAR_LIMIT=30] -->
+ <string name="volume_panel_dialog_settings_button">Settings</string>
+
<!-- content description for audio output chooser [CHAR LIMIT=NONE]-->
<!-- Screen pinning dialog title. -->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index f7acf06350c6..6d1bcbbb8c99 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -935,6 +935,10 @@
<item name="rowStyle">@style/SliceRow</item>
</style>
+ <style name="Widget.SliceView.Panel.Slider">
+ <item name="rowStyle">@style/SliceRow.Slider</item>
+ </style>
+
<style name="SliceRow">
<!-- 2dp start padding for the start icon -->
<item name="titleItemStartPadding">2dp</item>
@@ -956,6 +960,26 @@
<item name="actionDividerHeight">32dp</item>
</style>
+ <style name="SliceRow.Slider">
+ <!-- Padding between content and the start icon is 5dp -->
+ <item name="contentStartPadding">5dp</item>
+ <item name="contentEndPadding">0dp</item>
+
+ <!-- 0dp start padding for the end item -->
+ <item name="endItemStartPadding">0dp</item>
+ <!-- 8dp end padding for the end item -->
+ <item name="endItemEndPadding">8dp</item>
+
+ <item name="titleSize">20sp</item>
+ <!-- Align text with slider -->
+ <item name="titleStartPadding">11dp</item>
+ <item name="subContentStartPadding">11dp</item>
+
+ <!-- Padding for indeterminate progress bar -->
+ <item name="progressBarStartPadding">12dp</item>
+ <item name="progressBarEndPadding">16dp</item>
+ </style>
+
<style name="TextAppearance.Dialog.Title" parent="@android:style/TextAppearance.DeviceDefault.Large">
<item name="android:textColor">?android:attr/textColorPrimary</item>
<item name="android:textSize">24sp</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index e1957c09fef5..93175e19a287 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -418,6 +418,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, state);
getCurrentSecurityController().onResume(reason);
+ updateSideFpsVisibility();
}
mView.onResume(
mSecurityModel.getSecurityMode(KeyguardUpdateMonitor.getCurrentUser()),
diff --git a/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt b/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt
new file mode 100644
index 000000000000..109be40ce10f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ChooserSelector.kt
@@ -0,0 +1,67 @@
+package com.android.systemui
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.PackageManager
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.FlagListenable
+import com.android.systemui.flags.Flags
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.suspendCancellableCoroutine
+import kotlinx.coroutines.withContext
+
+@SysUISingleton
+class ChooserSelector @Inject constructor(
+ context: Context,
+ private val featureFlags: FeatureFlags,
+ @Application private val coroutineScope: CoroutineScope,
+ @Background private val bgDispatcher: CoroutineDispatcher
+) : CoreStartable(context) {
+
+ private val packageManager = context.packageManager
+ private val chooserComponent = ComponentName.unflattenFromString(
+ context.resources.getString(ChooserSelectorResourceHelper.CONFIG_CHOOSER_ACTIVITY))
+
+ override fun start() {
+ coroutineScope.launch {
+ val listener = FlagListenable.Listener { event ->
+ if (event.flagId == Flags.CHOOSER_UNBUNDLED.id) {
+ launch { updateUnbundledChooserEnabled() }
+ event.requestNoRestart()
+ }
+ }
+ featureFlags.addListener(Flags.CHOOSER_UNBUNDLED, listener)
+ updateUnbundledChooserEnabled()
+
+ awaitCancellationAndThen { featureFlags.removeListener(listener) }
+ }
+ }
+
+ private suspend fun updateUnbundledChooserEnabled() {
+ setUnbundledChooserEnabled(withContext(bgDispatcher) {
+ featureFlags.isEnabled(Flags.CHOOSER_UNBUNDLED)
+ })
+ }
+
+ private fun setUnbundledChooserEnabled(enabled: Boolean) {
+ val newState = if (enabled) {
+ PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ } else {
+ PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+ }
+ packageManager.setComponentEnabledSetting(chooserComponent, newState, /* flags = */ 0)
+ }
+
+ suspend inline fun awaitCancellation(): Nothing = suspendCancellableCoroutine { }
+ suspend inline fun awaitCancellationAndThen(block: () -> Unit): Nothing = try {
+ awaitCancellation()
+ } finally {
+ block()
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/ChooserSelectorResourceHelper.java b/packages/SystemUI/src/com/android/systemui/ChooserSelectorResourceHelper.java
new file mode 100644
index 000000000000..7a2de7b6a78d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/ChooserSelectorResourceHelper.java
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+import androidx.annotation.StringRes;
+
+import com.android.internal.R;
+
+/** Helper class for referencing resources */
+class ChooserSelectorResourceHelper {
+
+ private ChooserSelectorResourceHelper() {
+ }
+
+ @StringRes
+ static final int CONFIG_CHOOSER_ACTIVITY = R.string.config_chooserActivity;
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
index 8ba6f1c4a411..d60a22204b3d 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
@@ -26,6 +26,7 @@ import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
import com.android.systemui.screenshot.ActionProxyReceiver;
import com.android.systemui.screenshot.DeleteScreenshotReceiver;
import com.android.systemui.screenshot.SmartActionsReceiver;
+import com.android.systemui.volume.VolumePanelDialogReceiver;
import dagger.Binds;
import dagger.Module;
@@ -78,6 +79,15 @@ public abstract class DefaultBroadcastReceiverBinder {
*/
@Binds
@IntoMap
+ @ClassKey(VolumePanelDialogReceiver.class)
+ public abstract BroadcastReceiver bindVolumePanelDialogReceiver(
+ VolumePanelDialogReceiver broadcastReceiver);
+
+ /**
+ *
+ */
+ @Binds
+ @IntoMap
@ClassKey(PeopleSpaceWidgetPinnedReceiver.class)
public abstract BroadcastReceiver bindPeopleSpaceWidgetPinnedReceiver(
PeopleSpaceWidgetPinnedReceiver broadcastReceiver);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
index 6db3e82a77b0..8bb27a7bc217 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
@@ -17,6 +17,7 @@
package com.android.systemui.dagger
import com.android.keyguard.KeyguardBiometricLockoutLogger
+import com.android.systemui.ChooserSelector
import com.android.systemui.CoreStartable
import com.android.systemui.LatencyTester
import com.android.systemui.ScreenDecorations
@@ -60,6 +61,12 @@ abstract class SystemUICoreStartableModule {
@ClassKey(AuthController::class)
abstract fun bindAuthController(service: AuthController): CoreStartable
+ /** Inject into ChooserCoreStartable. */
+ @Binds
+ @IntoMap
+ @ClassKey(ChooserSelector::class)
+ abstract fun bindChooserSelector(sysui: ChooserSelector): CoreStartable
+
/** Inject into ClipboardListener. */
@Binds
@IntoMap
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
index 567bdbc01170..a981f255a873 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
@@ -70,11 +70,7 @@ public class SmartSpaceComplication implements Complication {
new BcSmartspaceDataPlugin.SmartspaceTargetListener() {
@Override
public void onSmartspaceTargetsUpdated(List<? extends Parcelable> targets) {
- if (!targets.isEmpty()) {
- mDreamOverlayStateController.addComplication(mComplication);
- } else {
- mDreamOverlayStateController.removeComplication(mComplication);
- }
+ mDreamOverlayStateController.addComplication(mComplication);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index 45237a358700..c4553c4cb299 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -252,6 +252,9 @@ public class Flags {
// 1400 - columbus, b/242800729
public static final UnreleasedFlag QUICK_TAP_IN_PCC = new UnreleasedFlag(1400);
+ // 1500 - chooser
+ public static final UnreleasedFlag CHOOSER_UNBUNDLED = new UnreleasedFlag(1500);
+
// Pay no attention to the reflection behind the curtain.
// ========================== Curtain ==========================
// | |
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
index 9e2b7c748631..a3dc77993d30 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
@@ -50,7 +50,6 @@ import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.systemui.CoreStartable;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
@@ -61,6 +60,7 @@ import java.util.List;
import java.util.Set;
import javax.inject.Inject;
+import javax.inject.Provider;
/** */
@SysUISingleton
@@ -106,6 +106,8 @@ public class KeyboardUI extends CoreStartable implements InputManager.OnTabletMo
protected volatile Context mContext;
+ private final Provider<LocalBluetoothManager> mBluetoothManagerProvider;
+
private boolean mEnabled;
private String mKeyboardName;
private CachedBluetoothDeviceManager mCachedDeviceManager;
@@ -122,8 +124,9 @@ public class KeyboardUI extends CoreStartable implements InputManager.OnTabletMo
private int mState;
@Inject
- public KeyboardUI(Context context) {
+ public KeyboardUI(Context context, Provider<LocalBluetoothManager> bluetoothManagerProvider) {
super(context);
+ this.mBluetoothManagerProvider = bluetoothManagerProvider;
}
@Override
@@ -181,7 +184,7 @@ public class KeyboardUI extends CoreStartable implements InputManager.OnTabletMo
return;
}
- LocalBluetoothManager bluetoothManager = Dependency.get(LocalBluetoothManager.class);
+ LocalBluetoothManager bluetoothManager = mBluetoothManagerProvider.get();
if (bluetoothManager == null) {
if (DEBUG) {
Slog.e(TAG, "Failed to retrieve LocalBluetoothManager instance");
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 012d76651b23..b02393b4f73a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -488,8 +488,8 @@ public class MediaControlPanel {
TextView deviceName = mMediaViewHolder.getSeamlessText();
final MediaDeviceData device = data.getDevice();
- final boolean enabled;
- final boolean seamlessDisabled;
+ final boolean isTapEnabled;
+ final boolean useDisabledAlpha;
final int iconResource;
CharSequence deviceString;
if (showBroadcastButton) {
@@ -499,21 +499,25 @@ public class MediaControlPanel {
&& TextUtils.equals(device.getName(),
MediaDataUtils.getAppLabel(mContext, mPackageName, mContext.getString(
R.string.bt_le_audio_broadcast_dialog_unknown_name)));
- seamlessDisabled = !mIsCurrentBroadcastedApp;
+ useDisabledAlpha = !mIsCurrentBroadcastedApp;
// Always be enabled if the broadcast button is shown
- enabled = true;
+ isTapEnabled = true;
+
+ // Defaults for broadcasting state
deviceString = mContext.getString(R.string.bt_le_audio_broadcast_dialog_unknown_name);
iconResource = R.drawable.settings_input_antenna;
} else {
// Disable clicking on output switcher for invalid devices and resumption controls
- seamlessDisabled = (device != null && !device.getEnabled()) || data.getResumption();
- enabled = !seamlessDisabled;
+ useDisabledAlpha = (device != null && !device.getEnabled()) || data.getResumption();
+ isTapEnabled = !useDisabledAlpha;
+
+ // Defaults for non-broadcasting state
deviceString = mContext.getString(R.string.media_seamless_other_device);
iconResource = R.drawable.ic_media_home_devices;
}
- mMediaViewHolder.getSeamlessButton().setAlpha(seamlessDisabled ? DISABLED_ALPHA : 1.0f);
- seamlessView.setEnabled(enabled);
+ mMediaViewHolder.getSeamlessButton().setAlpha(useDisabledAlpha ? DISABLED_ALPHA : 1.0f);
+ seamlessView.setEnabled(isTapEnabled);
if (device != null) {
Drawable icon = device.getIcon();
@@ -524,7 +528,9 @@ public class MediaControlPanel {
} else {
iconView.setImageDrawable(icon);
}
- deviceString = device.getName();
+ if (device.getName() != null) {
+ deviceString = device.getName();
+ }
} else {
// Set to default icon
iconView.setImageResource(iconResource);
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index 7b497ade683c..c48271e0348a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -518,9 +518,20 @@ class MediaDataManager(
}
val actions = createActionsFromState(it.packageName,
mediaControllerFactory.create(it.token), UserHandle(it.userId))
- val data = it.copy(
- semanticActions = actions,
- isPlaying = isPlayingState(state.state))
+
+ // Control buttons
+ // If flag is enabled and controller has a PlaybackState,
+ // create actions from session info
+ // otherwise, no need to update semantic actions.
+ val data = if (actions != null) {
+ it.copy(
+ semanticActions = actions,
+ isPlaying = isPlayingState(state.state))
+ } else {
+ it.copy(
+ isPlaying = isPlayingState(state.state)
+ )
+ }
if (DEBUG) Log.d(TAG, "State updated outside of notification")
onMediaDataLoaded(key, key, data)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
index 25186597e0e1..b3a4ddf8ec1f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
@@ -348,7 +348,11 @@ class MediaDeviceManager @Inject constructor(
// If we have a controller but get a null route, then don't trust the device
val enabled = device != null && (controller == null || route != null)
- val name = route?.name?.toString() ?: device?.name
+ val name = if (controller == null || route != null) {
+ route?.name?.toString() ?: device?.name
+ } else {
+ null
+ }
current = MediaDeviceData(enabled, device?.iconWithoutBackground, name,
id = device?.id, showBroadcastButton = false)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
index a153cb6c0d31..f93c671f6740 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
@@ -26,6 +26,7 @@ import com.android.internal.logging.UiEventLogger
import com.android.internal.statusbar.IUndoMediaTransferCallback
import com.android.systemui.R
import com.android.systemui.media.taptotransfer.common.DEFAULT_TIMEOUT_MILLIS
+import com.android.systemui.plugins.FalsingManager
/**
* A class enumerating all the possible states of the media tap-to-transfer chip on the sender
@@ -106,12 +107,15 @@ enum class ChipStateSender(
controllerSender: MediaTttChipControllerSender,
routeInfo: MediaRoute2Info,
undoCallback: IUndoMediaTransferCallback?,
- uiEventLogger: MediaTttSenderUiEventLogger
+ uiEventLogger: MediaTttSenderUiEventLogger,
+ falsingManager: FalsingManager,
): View.OnClickListener? {
if (undoCallback == null) {
return null
}
return View.OnClickListener {
+ if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@OnClickListener
+
uiEventLogger.logUndoClicked(
MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED
)
@@ -141,12 +145,15 @@ enum class ChipStateSender(
controllerSender: MediaTttChipControllerSender,
routeInfo: MediaRoute2Info,
undoCallback: IUndoMediaTransferCallback?,
- uiEventLogger: MediaTttSenderUiEventLogger
+ uiEventLogger: MediaTttSenderUiEventLogger,
+ falsingManager: FalsingManager,
): View.OnClickListener? {
if (undoCallback == null) {
return null
}
return View.OnClickListener {
+ if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@OnClickListener
+
uiEventLogger.logUndoClicked(
MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED
)
@@ -212,7 +219,8 @@ enum class ChipStateSender(
controllerSender: MediaTttChipControllerSender,
routeInfo: MediaRoute2Info,
undoCallback: IUndoMediaTransferCallback?,
- uiEventLogger: MediaTttSenderUiEventLogger
+ uiEventLogger: MediaTttSenderUiEventLogger,
+ falsingManager: FalsingManager,
): View.OnClickListener? = null
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
index 933548963390..5ad82fd9fd8f 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
@@ -22,21 +22,25 @@ import android.media.MediaRoute2Info
import android.os.PowerManager
import android.util.Log
import android.view.Gravity
+import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.accessibility.AccessibilityManager
import android.widget.TextView
import com.android.internal.statusbar.IUndoMediaTransferCallback
+import com.android.systemui.Gefingerpoken
import com.android.systemui.R
import com.android.systemui.animation.Interpolators
import com.android.systemui.animation.ViewHierarchyAnimator
+import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.media.taptotransfer.common.ChipInfoCommon
import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCommon
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
import com.android.systemui.media.taptotransfer.common.MediaTttRemovalReason
+import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.DelayableExecutor
@@ -58,7 +62,9 @@ class MediaTttChipControllerSender @Inject constructor(
accessibilityManager: AccessibilityManager,
configurationController: ConfigurationController,
powerManager: PowerManager,
- private val uiEventLogger: MediaTttSenderUiEventLogger
+ private val uiEventLogger: MediaTttSenderUiEventLogger,
+ private val falsingManager: FalsingManager,
+ private val falsingCollector: FalsingCollector,
) : MediaTttChipControllerCommon<ChipSenderInfo>(
context,
logger,
@@ -70,6 +76,9 @@ class MediaTttChipControllerSender @Inject constructor(
powerManager,
R.layout.media_ttt_chip,
) {
+
+ private lateinit var parent: MediaTttChipRootView
+
override val windowLayoutParams = commonWindowLayoutParams.apply {
gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL)
}
@@ -121,6 +130,15 @@ class MediaTttChipControllerSender @Inject constructor(
val chipState = newChipInfo.state
+ // Detect falsing touches on the chip.
+ parent = currentChipView as MediaTttChipRootView
+ parent.touchHandler = object : Gefingerpoken {
+ override fun onTouchEvent(ev: MotionEvent?): Boolean {
+ falsingCollector.onTouchEvent(ev)
+ return false
+ }
+ }
+
// App icon
val iconName = setIcon(currentChipView, newChipInfo.routeInfo.clientPackageName)
@@ -136,7 +154,11 @@ class MediaTttChipControllerSender @Inject constructor(
// Undo
val undoView = currentChipView.requireViewById<View>(R.id.undo)
val undoClickListener = chipState.undoClickListener(
- this, newChipInfo.routeInfo, newChipInfo.undoCallback, uiEventLogger
+ this,
+ newChipInfo.routeInfo,
+ newChipInfo.undoCallback,
+ uiEventLogger,
+ falsingManager,
)
undoView.setOnClickListener(undoClickListener)
undoView.visibility = (undoClickListener != null).visibleIfTrue()
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt
new file mode 100644
index 000000000000..3373159fba4e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt
@@ -0,0 +1,38 @@
+/*
+ * 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.media.taptotransfer.sender
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.widget.FrameLayout
+import com.android.systemui.Gefingerpoken
+
+/** A simple subclass that allows for observing touch events on chip. */
+class MediaTttChipRootView(
+ context: Context,
+ attrs: AttributeSet?
+) : FrameLayout(context, attrs) {
+
+ /** Assign this field to observe touch events. */
+ var touchHandler: Gefingerpoken? = null
+
+ override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
+ touchHandler?.onTouchEvent(ev)
+ return super.dispatchTouchEvent(ev)
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
index 3f931088ec83..5da480968b89 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java
@@ -17,7 +17,14 @@ import java.util.Set;
import javax.inject.Inject;
-/** */
+/**
+ * Plays a animation to reveal newly added QS tiles.
+ *
+ * The aniumation is played when the user fully opens Quick Settings, and is only shown for
+ * <li> tiles added automatically (not through user customization)
+ * <li> tiles not have been revealed before (memoized via {@code QS_TILE_SPECS_REVEALED}
+ * preference)
+ */
public class QSTileRevealController {
private static final long QS_REVEAL_TILES_DELAY = 500L;
@@ -39,6 +46,7 @@ public class QSTileRevealController {
});
}
};
+
QSTileRevealController(Context context, QSPanelController qsPanelController,
PagedTileLayout pagedTileLayout, QSCustomizerController qsCustomizerController) {
mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
index a918e5d9e106..309059fdb9ad 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
@@ -17,6 +17,7 @@
package com.android.systemui.screenshot
import android.graphics.Insets
+import android.util.Log
import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
import com.android.internal.util.ScreenshotHelper.HardwareBitmapBundler
import com.android.internal.util.ScreenshotHelper.ScreenshotRequest
@@ -61,8 +62,9 @@ class RequestProcessor @Inject constructor(
) {
val info = policy.findPrimaryContent(policy.getDefaultDisplayId())
+ Log.d(TAG, "findPrimaryContent: $info")
- result = if (policy.isManagedProfile(info.userId)) {
+ result = if (policy.isManagedProfile(info.user.identifier)) {
val image = capture.captureTask(info.taskId)
?: error("Task snapshot returned a null Bitmap!")
@@ -70,7 +72,7 @@ class RequestProcessor @Inject constructor(
ScreenshotRequest(
TAKE_SCREENSHOT_PROVIDED_IMAGE, request.source,
HardwareBitmapBundler.hardwareBitmapToBundle(image),
- info.bounds, Insets.NONE, info.taskId, info.userId, info.component
+ info.bounds, Insets.NONE, info.taskId, info.user.identifier, info.component
)
} else {
// Create a new request of the same type which includes the top component
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt
index 3580010cc1e8..f73d2041af95 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt
@@ -19,6 +19,7 @@ package com.android.systemui.screenshot
import android.annotation.UserIdInt
import android.content.ComponentName
import android.graphics.Rect
+import android.os.UserHandle
import android.view.Display
/**
@@ -42,7 +43,7 @@ interface ScreenshotPolicy {
data class DisplayContentInfo(
val component: ComponentName,
val bounds: Rect,
- @UserIdInt val userId: Int,
+ val user: UserHandle,
val taskId: Int,
)
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt
index ba809f676f1e..c2a50609b6a5 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt
@@ -29,9 +29,11 @@ import android.content.Intent
import android.graphics.Rect
import android.os.Process
import android.os.RemoteException
+import android.os.UserHandle
import android.os.UserManager
import android.util.Log
import android.view.Display.DEFAULT_DISPLAY
+import com.android.internal.annotations.VisibleForTesting
import com.android.internal.infra.ServiceConnector
import com.android.systemui.SystemUIService
import com.android.systemui.dagger.SysUISingleton
@@ -45,21 +47,13 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
@SysUISingleton
-internal class ScreenshotPolicyImpl @Inject constructor(
+internal open class ScreenshotPolicyImpl @Inject constructor(
context: Context,
private val userMgr: UserManager,
private val atmService: IActivityTaskManager,
@Background val bgDispatcher: CoroutineDispatcher,
) : ScreenshotPolicy {
- private val systemUiContent =
- DisplayContentInfo(
- ComponentName(context, SystemUIService::class.java),
- Rect(),
- ActivityTaskManager.INVALID_TASK_ID,
- Process.myUserHandle().identifier,
- )
-
private val proxyConnector: ServiceConnector<IScreenshotProxy> =
ServiceConnector.Impl(
context,
@@ -78,6 +72,9 @@ internal class ScreenshotPolicyImpl @Inject constructor(
}
private fun nonPipVisibleTask(info: RootTaskInfo): Boolean {
+ if (DEBUG) {
+ debugLogRootTaskInfo(info)
+ }
return info.windowingMode != WindowConfiguration.WINDOWING_MODE_PINNED &&
info.isVisible &&
info.isRunning &&
@@ -99,58 +96,46 @@ internal class ScreenshotPolicyImpl @Inject constructor(
}
val taskInfoList = getAllRootTaskInfosOnDisplay(displayId)
- if (DEBUG) {
- debugLogRootTaskInfos(taskInfoList)
- }
// If no visible task is located, then report SystemUI as the foreground content
val target = taskInfoList.firstOrNull(::nonPipVisibleTask) ?: return systemUiContent
-
- val topActivity: ComponentName = target.topActivity ?: error("should not be null")
- val topChildTask = target.childTaskIds.size - 1
- val childTaskId = target.childTaskIds[topChildTask]
- val childTaskUserId = target.childTaskUserIds[topChildTask]
- val childTaskBounds = target.childTaskBounds[topChildTask]
-
- return DisplayContentInfo(topActivity, childTaskBounds, childTaskId, childTaskUserId)
+ return target.toDisplayContentInfo()
}
- private fun debugLogRootTaskInfos(taskInfoList: List<RootTaskInfo>) {
- for (info in taskInfoList) {
- Log.d(
- TAG,
- "[root task info] " +
- "taskId=${info.taskId} " +
- "parentTaskId=${info.parentTaskId} " +
- "position=${info.position} " +
- "positionInParent=${info.positionInParent} " +
- "isVisible=${info.isVisible()} " +
- "visible=${info.visible} " +
- "isFocused=${info.isFocused} " +
- "isSleeping=${info.isSleeping} " +
- "isRunning=${info.isRunning} " +
- "windowMode=${windowingModeToString(info.windowingMode)} " +
- "activityType=${activityTypeToString(info.activityType)} " +
- "topActivity=${info.topActivity} " +
- "topActivityInfo=${info.topActivityInfo} " +
- "numActivities=${info.numActivities} " +
- "childTaskIds=${Arrays.toString(info.childTaskIds)} " +
- "childUserIds=${Arrays.toString(info.childTaskUserIds)} " +
- "childTaskBounds=${Arrays.toString(info.childTaskBounds)} " +
- "childTaskNames=${Arrays.toString(info.childTaskNames)}"
- )
-
- for (j in 0 until info.childTaskIds.size) {
- Log.d(TAG, " *** [$j] ******")
- Log.d(TAG, " *** childTaskIds[$j]: ${info.childTaskIds[j]}")
- Log.d(TAG, " *** childTaskUserIds[$j]: ${info.childTaskUserIds[j]}")
- Log.d(TAG, " *** childTaskBounds[$j]: ${info.childTaskBounds[j]}")
- Log.d(TAG, " *** childTaskNames[$j]: ${info.childTaskNames[j]}")
- }
+ private fun debugLogRootTaskInfo(info: RootTaskInfo) {
+ Log.d(TAG, "RootTaskInfo={" +
+ "taskId=${info.taskId} " +
+ "parentTaskId=${info.parentTaskId} " +
+ "position=${info.position} " +
+ "positionInParent=${info.positionInParent} " +
+ "isVisible=${info.isVisible()} " +
+ "visible=${info.visible} " +
+ "isFocused=${info.isFocused} " +
+ "isSleeping=${info.isSleeping} " +
+ "isRunning=${info.isRunning} " +
+ "windowMode=${windowingModeToString(info.windowingMode)} " +
+ "activityType=${activityTypeToString(info.activityType)} " +
+ "topActivity=${info.topActivity} " +
+ "topActivityInfo=${info.topActivityInfo} " +
+ "numActivities=${info.numActivities} " +
+ "childTaskIds=${Arrays.toString(info.childTaskIds)} " +
+ "childUserIds=${Arrays.toString(info.childTaskUserIds)} " +
+ "childTaskBounds=${Arrays.toString(info.childTaskBounds)} " +
+ "childTaskNames=${Arrays.toString(info.childTaskNames)}" +
+ "}"
+ )
+
+ for (j in 0 until info.childTaskIds.size) {
+ Log.d(TAG, " *** [$j] ******")
+ Log.d(TAG, " *** childTaskIds[$j]: ${info.childTaskIds[j]}")
+ Log.d(TAG, " *** childTaskUserIds[$j]: ${info.childTaskUserIds[j]}")
+ Log.d(TAG, " *** childTaskBounds[$j]: ${info.childTaskBounds[j]}")
+ Log.d(TAG, " *** childTaskNames[$j]: ${info.childTaskNames[j]}")
}
}
- private suspend fun getAllRootTaskInfosOnDisplay(displayId: Int): List<RootTaskInfo> =
+ @VisibleForTesting
+ open suspend fun getAllRootTaskInfosOnDisplay(displayId: Int): List<RootTaskInfo> =
withContext(bgDispatcher) {
try {
atmService.getAllRootTaskInfosOnDisplay(displayId)
@@ -160,7 +145,8 @@ internal class ScreenshotPolicyImpl @Inject constructor(
}
}
- private suspend fun isNotificationShadeExpanded(): Boolean = suspendCoroutine { k ->
+ @VisibleForTesting
+ open suspend fun isNotificationShadeExpanded(): Boolean = suspendCoroutine { k ->
proxyConnector
.postForResult { it.isNotificationShadeExpanded }
.whenComplete { expanded, error ->
@@ -171,8 +157,30 @@ internal class ScreenshotPolicyImpl @Inject constructor(
}
}
- companion object {
- const val TAG: String = "ScreenshotPolicyImpl"
- const val DEBUG: Boolean = false
- }
+ @VisibleForTesting
+ internal val systemUiContent =
+ DisplayContentInfo(
+ ComponentName(context, SystemUIService::class.java),
+ Rect(),
+ Process.myUserHandle(),
+ ActivityTaskManager.INVALID_TASK_ID
+ )
+}
+
+private const val TAG: String = "ScreenshotPolicyImpl"
+private const val DEBUG: Boolean = false
+
+@VisibleForTesting
+internal fun RootTaskInfo.toDisplayContentInfo(): DisplayContentInfo {
+ val topActivity: ComponentName = topActivity ?: error("should not be null")
+ val topChildTask = childTaskIds.size - 1
+ val childTaskId = childTaskIds[topChildTask]
+ val childTaskUserId = childTaskUserIds[topChildTask]
+ val childTaskBounds = childTaskBounds[topChildTask]
+
+ return DisplayContentInfo(
+ topActivity,
+ childTaskBounds,
+ UserHandle.of(childTaskUserId),
+ childTaskId)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
index 2ca1bebfcf9f..7b49ecdcd981 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
@@ -1,7 +1,6 @@
package com.android.systemui.statusbar
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.notification.NotificationEntryManager
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import javax.inject.Inject
@@ -12,14 +11,12 @@ import javax.inject.Inject
*/
@SysUISingleton
class NotificationInteractionTracker @Inject constructor(
- private val clicker: NotificationClickNotifier,
- private val entryManager: NotificationEntryManager
+ clicker: NotificationClickNotifier,
) : NotifCollectionListener, NotificationInteractionListener {
private val interactions = mutableMapOf<String, Boolean>()
init {
clicker.addNotificationInteractionListener(this)
- entryManager.addCollectionListener(this)
}
fun hasUserInteractedWith(key: String): Boolean {
@@ -38,5 +35,3 @@ class NotificationInteractionTracker @Inject constructor(
interactions[key] = true
}
}
-
-private const val TAG = "NotificationInteractionTracker"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
index 8cb18a06057e..59022c0ffbf2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -50,7 +50,6 @@ import android.util.Pair;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.systemui.CoreStartable;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.UiBackground;
@@ -76,20 +75,22 @@ public class InstantAppNotifier extends CoreStartable
private final Executor mUiBgExecutor;
private final ArraySet<Pair<String, Integer>> mCurrentNotifs = new ArraySet<>();
private final CommandQueue mCommandQueue;
- private KeyguardStateController mKeyguardStateController;
+ private final KeyguardStateController mKeyguardStateController;
@Inject
- public InstantAppNotifier(Context context, CommandQueue commandQueue,
- @UiBackground Executor uiBgExecutor) {
+ public InstantAppNotifier(
+ Context context,
+ CommandQueue commandQueue,
+ @UiBackground Executor uiBgExecutor,
+ KeyguardStateController keyguardStateController) {
super(context);
mCommandQueue = commandQueue;
mUiBgExecutor = uiBgExecutor;
+ mKeyguardStateController = keyguardStateController;
}
@Override
public void start() {
- mKeyguardStateController = Dependency.get(KeyguardStateController.class);
-
// listen for user / profile change.
try {
ActivityManager.getService().registerUserSwitchObserver(mUserSwitchListener, TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index dbf4810b4fd7..126a986ee5f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -18,10 +18,8 @@ package com.android.systemui.statusbar.notification
import android.animation.ObjectAnimator
import android.util.FloatProperty
-import com.android.systemui.Dumpable
import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -34,20 +32,17 @@ import com.android.systemui.statusbar.phone.panelstate.PanelExpansionChangeEvent
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
-import java.io.PrintWriter
import javax.inject.Inject
import kotlin.math.min
@SysUISingleton
class NotificationWakeUpCoordinator @Inject constructor(
- dumpManager: DumpManager,
private val mHeadsUpManager: HeadsUpManager,
private val statusBarStateController: StatusBarStateController,
private val bypassController: KeyguardBypassController,
private val dozeParameters: DozeParameters,
private val screenOffAnimationController: ScreenOffAnimationController
-) : OnHeadsUpChangedListener, StatusBarStateController.StateListener, PanelExpansionListener,
- Dumpable {
+) : OnHeadsUpChangedListener, StatusBarStateController.StateListener, PanelExpansionListener {
private val mNotificationVisibility = object : FloatProperty<NotificationWakeUpCoordinator>(
"notificationVisibility") {
@@ -65,7 +60,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
private var mLinearDozeAmount: Float = 0.0f
private var mDozeAmount: Float = 0.0f
- private var mDozeAmountSource: String = "init"
private var mNotificationVisibleAmount = 0.0f
private var mNotificationsVisible = false
private var mNotificationsVisibleForExpansion = false
@@ -148,7 +142,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
init {
- dumpManager.registerDumpable(this)
mHeadsUpManager.addListener(this)
statusBarStateController.addCallback(this)
addListener(object : WakeUpListener {
@@ -255,14 +248,13 @@ class NotificationWakeUpCoordinator @Inject constructor(
// Let's notify the scroller that an animation started
notifyAnimationStart(mLinearDozeAmount == 1.0f)
}
- setDozeAmount(linear, eased, source = "StatusBar")
+ setDozeAmount(linear, eased)
}
- fun setDozeAmount(linear: Float, eased: Float, source: String) {
+ fun setDozeAmount(linear: Float, eased: Float) {
val changed = linear != mLinearDozeAmount
mLinearDozeAmount = linear
mDozeAmount = eased
- mDozeAmountSource = source
mStackScrollerController.setDozeAmount(mDozeAmount)
updateHideAmount()
if (changed && linear == 0.0f) {
@@ -279,7 +271,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
// undefined state, so it's an indication that we should do state cleanup. We override
// the doze amount to 0f (not dozing) so that the notifications are no longer hidden.
// See: UnlockedScreenOffAnimationController.onFinishedWakingUp()
- setDozeAmount(0f, 0f, source = "Override: Shade->Shade (lock cancelled by unlock)")
+ setDozeAmount(0f, 0f)
}
if (overrideDozeAmountIfAnimatingScreenOff(mLinearDozeAmount)) {
@@ -319,11 +311,12 @@ class NotificationWakeUpCoordinator @Inject constructor(
*/
private fun overrideDozeAmountIfBypass(): Boolean {
if (bypassController.bypassEnabled) {
- if (statusBarStateController.state == StatusBarState.KEYGUARD) {
- setDozeAmount(1f, 1f, source = "Override: bypass (keyguard)")
- } else {
- setDozeAmount(0f, 0f, source = "Override: bypass (shade)")
+ var amount = 1.0f
+ if (statusBarStateController.state == StatusBarState.SHADE ||
+ statusBarStateController.state == StatusBarState.SHADE_LOCKED) {
+ amount = 0.0f
}
+ setDozeAmount(amount, amount)
return true
}
return false
@@ -339,7 +332,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
*/
private fun overrideDozeAmountIfAnimatingScreenOff(linearDozeAmount: Float): Boolean {
if (screenOffAnimationController.overrideNotificationsFullyDozingOnKeyguard()) {
- setDozeAmount(1f, 1f, source = "Override: animating screen off")
+ setDozeAmount(1f, 1f)
return true
}
@@ -433,24 +426,4 @@ class NotificationWakeUpCoordinator @Inject constructor(
*/
@JvmDefault fun onPulseExpansionChanged(expandingChanged: Boolean) {}
}
-
- override fun dump(pw: PrintWriter, args: Array<out String>) {
- pw.println("mLinearDozeAmount: $mLinearDozeAmount")
- pw.println("mDozeAmount: $mDozeAmount")
- pw.println("mDozeAmountSource: $mDozeAmountSource")
- pw.println("mNotificationVisibleAmount: $mNotificationVisibleAmount")
- pw.println("mNotificationsVisible: $mNotificationsVisible")
- pw.println("mNotificationsVisibleForExpansion: $mNotificationsVisibleForExpansion")
- pw.println("mVisibilityAmount: $mVisibilityAmount")
- pw.println("mLinearVisibilityAmount: $mLinearVisibilityAmount")
- pw.println("pulseExpanding: $pulseExpanding")
- pw.println("state: ${StatusBarState.toString(state)}")
- pw.println("fullyAwake: $fullyAwake")
- pw.println("wakingUp: $wakingUp")
- pw.println("willWakeUp: $willWakeUp")
- pw.println("collapsedEnoughToHide: $collapsedEnoughToHide")
- pw.println("pulsing: $pulsing")
- pw.println("notificationsFullyHidden: $notificationsFullyHidden")
- pw.println("canShowPulsingHuns: $canShowPulsingHuns")
- }
-}
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index ed186ab6a10b..8273d5737c2f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -33,7 +33,6 @@ import android.widget.LinearLayout.LayoutParams;
import androidx.annotation.VisibleForTesting;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.demomode.DemoModeCommandReceiver;
@@ -137,11 +136,12 @@ public interface StatusBarIconController {
LinearLayout linearLayout,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
- Provider<WifiViewModel> wifiViewModelProvider) {
+ Provider<WifiViewModel> wifiViewModelProvider,
+ DarkIconDispatcher darkIconDispatcher) {
super(linearLayout, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
mIconHPadding = mContext.getResources().getDimensionPixelSize(
R.dimen.status_bar_icon_padding);
- mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
+ mDarkIconDispatcher = darkIconDispatcher;
}
@Override
@@ -198,20 +198,24 @@ public interface StatusBarIconController {
private final FeatureFlags mFeatureFlags;
private final StatusBarPipelineFlags mStatusBarPipelineFlags;
private final Provider<WifiViewModel> mWifiViewModelProvider;
+ private final DarkIconDispatcher mDarkIconDispatcher;
@Inject
public Factory(
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
- Provider<WifiViewModel> wifiViewModelProvider) {
+ Provider<WifiViewModel> wifiViewModelProvider,
+ DarkIconDispatcher darkIconDispatcher) {
mFeatureFlags = featureFlags;
mStatusBarPipelineFlags = statusBarPipelineFlags;
mWifiViewModelProvider = wifiViewModelProvider;
+ mDarkIconDispatcher = darkIconDispatcher;
}
public DarkIconManager create(LinearLayout group) {
return new DarkIconManager(
- group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider);
+ group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider,
+ mDarkIconDispatcher);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
index 77654273bde4..103f3fc21f91 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
@@ -46,7 +46,7 @@ import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.stateIn
/**
* Provides data related to the wifi state.
@@ -118,12 +118,19 @@ class WifiRepositoryImpl @Inject constructor(
}
}
- trySend(WIFI_NETWORK_DEFAULT)
connectivityManager.registerNetworkCallback(WIFI_NETWORK_CALLBACK_REQUEST, callback)
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
}
- .shareIn(scope, started = SharingStarted.WhileSubscribed())
+ // There will be multiple wifi icons in different places that will frequently
+ // subscribe/unsubscribe to flows as the views attach/detach. Using [stateIn] ensures that
+ // new subscribes will get the latest value immediately upon subscription. Otherwise, the
+ // views could show stale data. See b/244173280.
+ .stateIn(
+ scope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = WIFI_NETWORK_DEFAULT
+ )
override val wifiActivity: Flow<WifiActivityModel> =
if (wifiManager == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 13c3df3acb69..c7ba5182eef8 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -48,7 +48,6 @@ import android.app.KeyguardManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
@@ -248,6 +247,7 @@ public class VolumeDialogImpl implements VolumeDialog,
private final ConfigurationController mConfigurationController;
private final MediaOutputDialogFactory mMediaOutputDialogFactory;
+ private final VolumePanelFactory mVolumePanelFactory;
private final ActivityStarter mActivityStarter;
private boolean mShowing;
@@ -279,6 +279,7 @@ public class VolumeDialogImpl implements VolumeDialog,
DeviceProvisionedController deviceProvisionedController,
ConfigurationController configurationController,
MediaOutputDialogFactory mediaOutputDialogFactory,
+ VolumePanelFactory volumePanelFactory,
ActivityStarter activityStarter,
InteractionJankMonitor interactionJankMonitor) {
mContext =
@@ -290,6 +291,7 @@ public class VolumeDialogImpl implements VolumeDialog,
mDeviceProvisionedController = deviceProvisionedController;
mConfigurationController = configurationController;
mMediaOutputDialogFactory = mediaOutputDialogFactory;
+ mVolumePanelFactory = volumePanelFactory;
mActivityStarter = activityStarter;
mShowActiveStreamOnly = showActiveStreamOnly();
mHasSeenODICaptionsTooltip =
@@ -1045,10 +1047,9 @@ public class VolumeDialogImpl implements VolumeDialog,
if (mSettingsIcon != null) {
mSettingsIcon.setOnClickListener(v -> {
Events.writeEvent(Events.EVENT_SETTINGS_CLICK);
- Intent intent = new Intent(Settings.Panel.ACTION_VOLUME);
dismissH(DISMISS_REASON_SETTINGS_CLICKED);
mMediaOutputDialogFactory.dismiss();
- mActivityStarter.startActivity(intent, true /* dismissShade */);
+ mVolumePanelFactory.create(true /* aboveStatusBar */, null);
});
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java
new file mode 100644
index 000000000000..2c74fb911688
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialog.java
@@ -0,0 +1,299 @@
+/*
+ * 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.volume;
+
+import android.bluetooth.BluetoothDevice;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.Settings;
+import android.provider.SettingsSlicesContract;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Button;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LifecycleRegistry;
+import androidx.lifecycle.LiveData;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.slice.Slice;
+import androidx.slice.SliceMetadata;
+import androidx.slice.widget.EventInfo;
+import androidx.slice.widget.SliceLiveData;
+
+import com.android.settingslib.bluetooth.A2dpProfile;
+import com.android.settingslib.bluetooth.BluetoothUtils;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.settingslib.media.MediaOutputConstants;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.SystemUIDialog;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Visual presentation of the volume panel dialog.
+ */
+public class VolumePanelDialog extends SystemUIDialog implements LifecycleOwner {
+ private static final String TAG = "VolumePanelDialog";
+
+ private static final int DURATION_SLICE_BINDING_TIMEOUT_MS = 200;
+ private static final int DEFAULT_SLICE_SIZE = 4;
+
+ private RecyclerView mVolumePanelSlices;
+ private VolumePanelSlicesAdapter mVolumePanelSlicesAdapter;
+ private final LifecycleRegistry mLifecycleRegistry;
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+ private final Map<Uri, LiveData<Slice>> mSliceLiveData = new LinkedHashMap<>();
+ private final HashSet<Uri> mLoadedSlices = new HashSet<>();
+ private boolean mSlicesReadyToLoad;
+ private LocalBluetoothProfileManager mProfileManager;
+
+ public VolumePanelDialog(Context context, boolean aboveStatusBar) {
+ super(context);
+ mLifecycleRegistry = new LifecycleRegistry(this);
+ if (!aboveStatusBar) {
+ getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Log.d(TAG, "onCreate");
+
+ View dialogView = LayoutInflater.from(getContext()).inflate(R.layout.volume_panel_dialog,
+ null);
+ final Window window = getWindow();
+ window.setContentView(dialogView);
+
+ Button doneButton = dialogView.findViewById(R.id.done_button);
+ doneButton.setOnClickListener(v -> dismiss());
+ Button settingsButton = dialogView.findViewById(R.id.settings_button);
+ settingsButton.setOnClickListener(v -> {
+ getContext().startActivity(new Intent(Settings.ACTION_SOUND_SETTINGS).addFlags(
+ Intent.FLAG_ACTIVITY_NEW_TASK));
+ dismiss();
+ });
+
+ LocalBluetoothManager localBluetoothManager = LocalBluetoothManager.getInstance(
+ getContext(), null);
+ if (localBluetoothManager != null) {
+ mProfileManager = localBluetoothManager.getProfileManager();
+ }
+
+ mVolumePanelSlices = dialogView.findViewById(R.id.volume_panel_parent_layout);
+ mVolumePanelSlices.setLayoutManager(new LinearLayoutManager(getContext()));
+
+ loadAllSlices();
+
+ mLifecycleRegistry.setCurrentState(Lifecycle.State.CREATED);
+ }
+
+ private void loadAllSlices() {
+ mSliceLiveData.clear();
+ mLoadedSlices.clear();
+ final List<Uri> sliceUris = getSlices();
+
+ for (Uri uri : sliceUris) {
+ final LiveData<Slice> sliceLiveData = SliceLiveData.fromUri(getContext(), uri,
+ (int type, Throwable source) -> {
+ if (!removeSliceLiveData(uri)) {
+ mLoadedSlices.add(uri);
+ }
+ });
+
+ // Add slice first to make it in order. Will remove it later if there's an error.
+ mSliceLiveData.put(uri, sliceLiveData);
+
+ sliceLiveData.observe(this, slice -> {
+ if (mLoadedSlices.contains(uri)) {
+ return;
+ }
+ Log.d(TAG, "received slice: " + (slice == null ? null : slice.getUri()));
+ final SliceMetadata metadata = SliceMetadata.from(getContext(), slice);
+ if (slice == null || metadata.isErrorSlice()) {
+ if (!removeSliceLiveData(uri)) {
+ mLoadedSlices.add(uri);
+ }
+ } else if (metadata.getLoadingState() == SliceMetadata.LOADED_ALL) {
+ mLoadedSlices.add(uri);
+ } else {
+ mHandler.postDelayed(() -> {
+ mLoadedSlices.add(uri);
+ setupAdapterWhenReady();
+ }, DURATION_SLICE_BINDING_TIMEOUT_MS);
+ }
+
+ setupAdapterWhenReady();
+ });
+ }
+ }
+
+ private void setupAdapterWhenReady() {
+ if (mLoadedSlices.size() == mSliceLiveData.size() && !mSlicesReadyToLoad) {
+ mSlicesReadyToLoad = true;
+ mVolumePanelSlicesAdapter = new VolumePanelSlicesAdapter(this, mSliceLiveData);
+ mVolumePanelSlicesAdapter.setOnSliceActionListener((eventInfo, sliceItem) -> {
+ if (eventInfo.actionType == EventInfo.ACTION_TYPE_SLIDER) {
+ return;
+ }
+ this.dismiss();
+ });
+ if (mSliceLiveData.size() < DEFAULT_SLICE_SIZE) {
+ mVolumePanelSlices.setMinimumHeight(0);
+ }
+ mVolumePanelSlices.setAdapter(mVolumePanelSlicesAdapter);
+ }
+ }
+
+ private boolean removeSliceLiveData(Uri uri) {
+ boolean removed = false;
+ // Keeps observe media output slice
+ if (!uri.equals(MEDIA_OUTPUT_INDICATOR_SLICE_URI)) {
+ Log.d(TAG, "remove uri: " + uri);
+ removed = mSliceLiveData.remove(uri) != null;
+ if (mVolumePanelSlicesAdapter != null) {
+ mVolumePanelSlicesAdapter.updateDataSet(new ArrayList<>(mSliceLiveData.values()));
+ }
+ }
+ return removed;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ Log.d(TAG, "onStart");
+ mLifecycleRegistry.setCurrentState(Lifecycle.State.STARTED);
+ mLifecycleRegistry.setCurrentState(Lifecycle.State.RESUMED);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ Log.d(TAG, "onStop");
+ mLifecycleRegistry.setCurrentState(Lifecycle.State.DESTROYED);
+ }
+
+ private List<Uri> getSlices() {
+ final List<Uri> uris = new ArrayList<>();
+ uris.add(REMOTE_MEDIA_SLICE_URI);
+ uris.add(VOLUME_MEDIA_URI);
+ Uri controlUri = getExtraControlUri();
+ if (controlUri != null) {
+ Log.d(TAG, "add extra control slice");
+ uris.add(controlUri);
+ }
+ uris.add(MEDIA_OUTPUT_INDICATOR_SLICE_URI);
+ uris.add(VOLUME_CALL_URI);
+ uris.add(VOLUME_RINGER_URI);
+ uris.add(VOLUME_ALARM_URI);
+ return uris;
+ }
+
+ private static final String SETTINGS_SLICE_AUTHORITY = "com.android.settings.slices";
+ private static final Uri REMOTE_MEDIA_SLICE_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SETTINGS_SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath(MediaOutputConstants.KEY_REMOTE_MEDIA)
+ .build();
+ private static final Uri VOLUME_MEDIA_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SETTINGS_SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath("media_volume")
+ .build();
+ private static final Uri MEDIA_OUTPUT_INDICATOR_SLICE_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SETTINGS_SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_INTENT)
+ .appendPath("media_output_indicator")
+ .build();
+ private static final Uri VOLUME_CALL_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SETTINGS_SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath("call_volume")
+ .build();
+ private static final Uri VOLUME_RINGER_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SETTINGS_SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath("ring_volume")
+ .build();
+ private static final Uri VOLUME_ALARM_URI = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(SETTINGS_SLICE_AUTHORITY)
+ .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
+ .appendPath("alarm_volume")
+ .build();
+
+ private Uri getExtraControlUri() {
+ Uri controlUri = null;
+ final BluetoothDevice bluetoothDevice = findActiveDevice();
+ if (bluetoothDevice != null) {
+ // The control slice width = dialog width - horizontal padding of two sides
+ final int dialogWidth =
+ getWindow().getWindowManager().getCurrentWindowMetrics().getBounds().width();
+ final int controlSliceWidth = dialogWidth
+ - getContext().getResources().getDimensionPixelSize(
+ R.dimen.volume_panel_slice_horizontal_padding) * 2;
+ final String uri = BluetoothUtils.getControlUriMetaData(bluetoothDevice);
+ if (!TextUtils.isEmpty(uri)) {
+ try {
+ controlUri = Uri.parse(uri + controlSliceWidth);
+ } catch (NullPointerException exception) {
+ Log.d(TAG, "unable to parse extra control uri");
+ controlUri = null;
+ }
+ }
+ }
+ return controlUri;
+ }
+
+ private BluetoothDevice findActiveDevice() {
+ if (mProfileManager != null) {
+ final A2dpProfile a2dpProfile = mProfileManager.getA2dpProfile();
+ if (a2dpProfile != null) {
+ return a2dpProfile.getActiveDevice();
+ }
+ }
+ return null;
+ }
+
+ @NonNull
+ @Override
+ public Lifecycle getLifecycle() {
+ return mLifecycleRegistry;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt
new file mode 100644
index 000000000000..f11d5d18ac84
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.volume
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.provider.Settings
+import android.text.TextUtils
+import android.util.Log
+import javax.inject.Inject
+
+private const val TAG = "VolumePanelDialogReceiver"
+private const val LAUNCH_ACTION = "com.android.systemui.action.LAUNCH_VOLUME_PANEL_DIALOG"
+private const val DISMISS_ACTION = "com.android.systemui.action.DISMISS_VOLUME_PANEL_DIALOG"
+
+/**
+ * BroadcastReceiver for handling volume panel dialog intent
+ */
+class VolumePanelDialogReceiver @Inject constructor(
+ private val volumePanelFactory: VolumePanelFactory
+) : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) {
+ Log.d(TAG, "onReceive intent" + intent.action)
+ if (TextUtils.equals(LAUNCH_ACTION, intent.action) ||
+ TextUtils.equals(Settings.Panel.ACTION_VOLUME, intent.action)) {
+ volumePanelFactory.create(true, null)
+ } else if (TextUtils.equals(DISMISS_ACTION, intent.action)) {
+ volumePanelFactory.dismiss()
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelFactory.kt b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelFactory.kt
new file mode 100644
index 000000000000..c2fafbf9f55b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelFactory.kt
@@ -0,0 +1,67 @@
+/*
+ * 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.volume
+
+import android.content.Context
+import android.util.Log
+import android.view.View
+import com.android.systemui.animation.DialogLaunchAnimator
+import com.android.systemui.dagger.SysUISingleton
+import javax.inject.Inject
+
+private const val TAG = "VolumePanelFactory"
+private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
+
+/**
+ * Factory to create [VolumePanelDialog] objects. This is the dialog that allows the user to adjust
+ * multiple streams with sliders.
+ */
+@SysUISingleton
+class VolumePanelFactory @Inject constructor(
+ private val context: Context,
+ private val dialogLaunchAnimator: DialogLaunchAnimator
+) {
+ companion object {
+ var volumePanelDialog: VolumePanelDialog? = null
+ }
+
+ /** Creates a [VolumePanelDialog]. The dialog will be animated from [view] if it is not null. */
+ fun create(aboveStatusBar: Boolean, view: View? = null) {
+ if (volumePanelDialog?.isShowing == true) {
+ return
+ }
+
+ val dialog = VolumePanelDialog(context, aboveStatusBar)
+ volumePanelDialog = dialog
+
+ // Show the dialog.
+ if (view != null) {
+ dialogLaunchAnimator.showFromView(dialog, view, animateBackgroundBoundsChange = true)
+ } else {
+ dialog.show()
+ }
+ }
+
+ /** Dismiss [VolumePanelDialog] if exist. */
+ fun dismiss() {
+ if (DEBUG) {
+ Log.d(TAG, "dismiss dialog")
+ }
+ volumePanelDialog?.dismiss()
+ volumePanelDialog = null
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java
new file mode 100644
index 000000000000..23714021a2cc
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanelSlicesAdapter.java
@@ -0,0 +1,137 @@
+/*
+ * 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.volume;
+
+import static android.app.slice.Slice.HINT_ERROR;
+import static android.app.slice.SliceItem.FORMAT_SLICE;
+
+import android.content.Context;
+import android.net.Uri;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.LiveData;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.slice.Slice;
+import androidx.slice.SliceItem;
+import androidx.slice.widget.SliceView;
+
+import com.android.systemui.R;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * RecyclerView adapter for Slices in Settings Panels.
+ */
+public class VolumePanelSlicesAdapter extends
+ RecyclerView.Adapter<VolumePanelSlicesAdapter.SliceRowViewHolder> {
+
+ private final List<LiveData<Slice>> mSliceLiveData;
+ private final LifecycleOwner mLifecycleOwner;
+ private SliceView.OnSliceActionListener mOnSliceActionListener;
+
+ public VolumePanelSlicesAdapter(LifecycleOwner lifecycleOwner,
+ Map<Uri, LiveData<Slice>> sliceLiveData) {
+ mLifecycleOwner = lifecycleOwner;
+ mSliceLiveData = new ArrayList<>(sliceLiveData.values());
+ }
+
+ @NonNull
+ @Override
+ public SliceRowViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
+ final Context context = viewGroup.getContext();
+ final LayoutInflater inflater = LayoutInflater.from(context);
+ View view = inflater.inflate(R.layout.volume_panel_slice_slider_row, viewGroup, false);
+ return new SliceRowViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull SliceRowViewHolder sliceRowViewHolder, int position) {
+ sliceRowViewHolder.onBind(mSliceLiveData.get(position), position);
+ }
+
+ @Override
+ public int getItemCount() {
+ return mSliceLiveData.size();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return position;
+ }
+
+ void setOnSliceActionListener(SliceView.OnSliceActionListener listener) {
+ mOnSliceActionListener = listener;
+ }
+
+ void updateDataSet(ArrayList<LiveData<Slice>> list) {
+ mSliceLiveData.clear();
+ mSliceLiveData.addAll(list);
+ notifyDataSetChanged();
+ }
+
+ /**
+ * ViewHolder for binding Slices to SliceViews.
+ */
+ public class SliceRowViewHolder extends RecyclerView.ViewHolder {
+
+ private final SliceView mSliceView;
+
+ public SliceRowViewHolder(View view) {
+ super(view);
+ mSliceView = view.findViewById(R.id.slice_view);
+ mSliceView.setMode(SliceView.MODE_LARGE);
+ mSliceView.setShowTitleItems(true);
+ mSliceView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
+ mSliceView.setOnSliceActionListener(mOnSliceActionListener);
+ }
+
+ /**
+ * Called when the view is displayed.
+ */
+ public void onBind(LiveData<Slice> sliceLiveData, int position) {
+ sliceLiveData.observe(mLifecycleOwner, mSliceView);
+
+ // Do not show the divider above media devices switcher slice per request
+ final Slice slice = sliceLiveData.getValue();
+
+ // Hides slice which reports with error hint or not contain any slice sub-item.
+ if (slice == null || !isValidSlice(slice)) {
+ mSliceView.setVisibility(View.GONE);
+ } else {
+ mSliceView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ private boolean isValidSlice(Slice slice) {
+ if (slice.getHints().contains(HINT_ERROR)) {
+ return false;
+ }
+ for (SliceItem item : slice.getItems()) {
+ if (item.getFormat().equals(FORMAT_SLICE)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
index f3855bddfe48..c5792b923e48 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/dagger/VolumeModule.java
@@ -30,6 +30,7 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.volume.VolumeComponent;
import com.android.systemui.volume.VolumeDialogComponent;
import com.android.systemui.volume.VolumeDialogImpl;
+import com.android.systemui.volume.VolumePanelFactory;
import dagger.Binds;
import dagger.Module;
@@ -52,6 +53,7 @@ public interface VolumeModule {
DeviceProvisionedController deviceProvisionedController,
ConfigurationController configurationController,
MediaOutputDialogFactory mediaOutputDialogFactory,
+ VolumePanelFactory volumePanelFactory,
ActivityStarter activityStarter,
InteractionJankMonitor interactionJankMonitor) {
VolumeDialogImpl impl = new VolumeDialogImpl(
@@ -61,6 +63,7 @@ public interface VolumeModule {
deviceProvisionedController,
configurationController,
mediaOutputDialogFactory,
+ volumePanelFactory,
activityStarter,
interactionJankMonitor);
impl.setStreamImportant(AudioManager.STREAM_SYSTEM, false);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index aecec9d100cc..d68e8bd36c40 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -387,6 +387,33 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
}
@Test
+ public void onResume_sideFpsHintShouldBeShown_sideFpsHintShown() {
+ setupGetSecurityView();
+ setupConditionsToEnableSideFpsHint();
+ mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+ reset(mSidefpsController);
+
+ mKeyguardSecurityContainerController.onResume(0);
+
+ verify(mSidefpsController).show();
+ verify(mSidefpsController, never()).hide();
+ }
+
+ @Test
+ public void onResume_sideFpsHintShouldNotBeShown_sideFpsHintHidden() {
+ setupGetSecurityView();
+ setupConditionsToEnableSideFpsHint();
+ setSideFpsHintEnabledFromResources(false);
+ mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE);
+ reset(mSidefpsController);
+
+ mKeyguardSecurityContainerController.onResume(0);
+
+ verify(mSidefpsController).hide();
+ verify(mSidefpsController, never()).show();
+ }
+
+ @Test
public void showNextSecurityScreenOrFinish_setsSecurityScreenToPinAfterSimPinUnlock() {
// GIVEN the current security method is SimPin
when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt
new file mode 100644
index 000000000000..6b1ef389a98e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt
@@ -0,0 +1,179 @@
+package com.android.systemui
+
+import android.content.ComponentName
+import android.content.Context
+import android.content.pm.PackageManager
+import android.content.res.Resources
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flag
+import com.android.systemui.flags.FlagListenable
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.UnreleasedFlag
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.kotlinArgumentCaptor
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.cancel
+import kotlinx.coroutines.test.TestCoroutineDispatcher
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.clearInvocations
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ChooserSelectorTest : SysuiTestCase() {
+
+ private val flagListener = kotlinArgumentCaptor<FlagListenable.Listener>()
+
+ private val testDispatcher = TestCoroutineDispatcher()
+ private val testScope = CoroutineScope(testDispatcher)
+
+ private lateinit var chooserSelector: ChooserSelector
+
+ @Mock private lateinit var mockContext: Context
+ @Mock private lateinit var mockPackageManager: PackageManager
+ @Mock private lateinit var mockResources: Resources
+ @Mock private lateinit var mockFeatureFlags: FeatureFlags
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+
+ `when`(mockContext.packageManager).thenReturn(mockPackageManager)
+ `when`(mockContext.resources).thenReturn(mockResources)
+ `when`(mockResources.getString(anyInt())).thenReturn(
+ ComponentName("TestPackage", "TestClass").flattenToString())
+
+ chooserSelector = ChooserSelector(mockContext, mockFeatureFlags, testScope, testDispatcher)
+ }
+
+ @After
+ fun tearDown() {
+ testDispatcher.cleanupTestCoroutines()
+ }
+
+ @Test
+ fun initialize_registersFlagListenerUntilScopeCancelled() {
+ // Arrange
+
+ // Act
+ chooserSelector.start()
+
+ // Assert
+ verify(mockFeatureFlags).addListener(
+ eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture())
+ verify(mockFeatureFlags, never()).removeListener(any())
+
+ // Act
+ testScope.cancel()
+
+ // Assert
+ verify(mockFeatureFlags).removeListener(eq(flagListener.value))
+ }
+
+ @Test
+ fun initialize_enablesUnbundledChooser_whenFlagEnabled() {
+ // Arrange
+ `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true)
+
+ // Act
+ chooserSelector.start()
+
+ // Assert
+ verify(mockPackageManager).setComponentEnabledSetting(
+ eq(ComponentName("TestPackage", "TestClass")),
+ eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
+ anyInt())
+ }
+
+ @Test
+ fun initialize_disablesUnbundledChooser_whenFlagDisabled() {
+ // Arrange
+ `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false)
+
+ // Act
+ chooserSelector.start()
+
+ // Assert
+ verify(mockPackageManager).setComponentEnabledSetting(
+ eq(ComponentName("TestPackage", "TestClass")),
+ eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED),
+ anyInt())
+ }
+
+ @Test
+ fun enablesUnbundledChooser_whenFlagBecomesEnabled() {
+ // Arrange
+ `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false)
+ chooserSelector.start()
+ verify(mockFeatureFlags).addListener(
+ eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture())
+ verify(mockPackageManager, never()).setComponentEnabledSetting(
+ any(), eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED), anyInt())
+
+ // Act
+ `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true)
+ flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.id))
+
+ // Assert
+ verify(mockPackageManager).setComponentEnabledSetting(
+ eq(ComponentName("TestPackage", "TestClass")),
+ eq(PackageManager.COMPONENT_ENABLED_STATE_ENABLED),
+ anyInt())
+ }
+
+ @Test
+ fun disablesUnbundledChooser_whenFlagBecomesDisabled() {
+ // Arrange
+ `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(true)
+ chooserSelector.start()
+ verify(mockFeatureFlags).addListener(
+ eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture())
+ verify(mockPackageManager, never()).setComponentEnabledSetting(
+ any(), eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED), anyInt())
+
+ // Act
+ `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false)
+ flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.id))
+
+ // Assert
+ verify(mockPackageManager).setComponentEnabledSetting(
+ eq(ComponentName("TestPackage", "TestClass")),
+ eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED),
+ anyInt())
+ }
+
+ @Test
+ fun doesNothing_whenAnotherFlagChanges() {
+ // Arrange
+ `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false)
+ chooserSelector.start()
+ verify(mockFeatureFlags).addListener(
+ eq<Flag<*>>(Flags.CHOOSER_UNBUNDLED), flagListener.capture())
+ clearInvocations(mockPackageManager)
+
+ // Act
+ `when`(mockFeatureFlags.isEnabled(any<UnreleasedFlag>())).thenReturn(false)
+ flagListener.value.onFlagChanged(TestFlagEvent(Flags.CHOOSER_UNBUNDLED.id + 1))
+
+ // Assert
+ verifyZeroInteractions(mockPackageManager)
+ }
+
+ private class TestFlagEvent(override val flagId: Int) : FlagListenable.FlagEvent {
+ override fun requestNoRestart() {}
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
index 7d54758acee7..fa8f88a08368 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
@@ -43,7 +43,7 @@ import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-import java.util.Arrays;
+import java.util.Collections;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -61,9 +61,6 @@ public class SmartSpaceComplicationTest extends SysuiTestCase {
private SmartSpaceComplication mComplication;
@Mock
- private ComplicationViewModel mComplicationViewModel;
-
- @Mock
private View mBcSmartspaceView;
@Before
@@ -125,12 +122,12 @@ public class SmartSpaceComplicationTest extends SysuiTestCase {
// Test
final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
- listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
+ listenerCaptor.getValue().onSmartspaceTargetsUpdated(Collections.singletonList(target));
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
}
@Test
- public void testOverlayActive_targetsEmpty_removesComplication() {
+ public void testOverlayActive_targetsEmpty_addsComplication() {
final SmartSpaceComplication.Registrant registrant = getRegistrant();
registrant.start();
@@ -145,13 +142,9 @@ public class SmartSpaceComplicationTest extends SysuiTestCase {
ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
verify(mSmartspaceController).addListener(listenerCaptor.capture());
- final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
- listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
- verify(mDreamOverlayStateController).addComplication(eq(mComplication));
-
// Test
- listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList());
- verify(mDreamOverlayStateController).removeComplication(eq(mComplication));
+ listenerCaptor.getValue().onSmartspaceTargetsUpdated(Collections.emptyList());
+ verify(mDreamOverlayStateController).addComplication(eq(mComplication));
}
@Test
@@ -170,8 +163,7 @@ public class SmartSpaceComplicationTest extends SysuiTestCase {
ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
verify(mSmartspaceController).addListener(listenerCaptor.capture());
- final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
- listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
+ listenerCaptor.getValue().onSmartspaceTargetsUpdated(Collections.emptyList());
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
// Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt
index ff579a1cc4aa..318f2bc1c227 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FakeFeatureFlagsTest.kt
@@ -41,7 +41,7 @@ class FakeFeatureFlagsTest : SysuiTestCase() {
* specified. If not, an exception is thrown.
*/
@Test
- fun throwsIfUnspecifiedFlagIsAccessed() {
+ fun accessingUnspecifiedFlags_throwsException() {
val flags: FeatureFlags = FakeFeatureFlags()
try {
assertThat(flags.isEnabled(Flags.TEAMFOOD)).isFalse()
@@ -88,7 +88,7 @@ class FakeFeatureFlagsTest : SysuiTestCase() {
}
@Test
- fun specifiedFlagsReturnCorrectValues() {
+ fun specifiedFlags_returnCorrectValues() {
val flags = FakeFeatureFlags()
flags.set(unreleasedFlag, false)
flags.set(releasedFlag, false)
@@ -114,4 +114,125 @@ class FakeFeatureFlagsTest : SysuiTestCase() {
assertThat(flags.isEnabled(sysPropBooleanFlag)).isTrue()
assertThat(flags.getString(resourceStringFlag)).isEqualTo("Android")
}
+
+ @Test
+ fun listenerForBooleanFlag_calledOnlyWhenFlagChanged() {
+ val flags = FakeFeatureFlags()
+ val listener = VerifyingListener()
+ flags.addListener(unreleasedFlag, listener)
+
+ flags.set(unreleasedFlag, true)
+ flags.set(unreleasedFlag, true)
+ flags.set(unreleasedFlag, false)
+ flags.set(unreleasedFlag, false)
+
+ listener.verifyInOrder(unreleasedFlag.id, unreleasedFlag.id)
+ }
+
+ @Test
+ fun listenerForStringFlag_calledOnlyWhenFlagChanged() {
+ val flags = FakeFeatureFlags()
+ val listener = VerifyingListener()
+ flags.addListener(stringFlag, listener)
+
+ flags.set(stringFlag, "Test")
+ flags.set(stringFlag, "Test")
+
+ listener.verifyInOrder(stringFlag.id)
+ }
+
+ @Test
+ fun listenerForBooleanFlag_notCalledAfterRemoved() {
+ val flags = FakeFeatureFlags()
+ val listener = VerifyingListener()
+ flags.addListener(unreleasedFlag, listener)
+ flags.set(unreleasedFlag, true)
+ flags.removeListener(listener)
+ flags.set(unreleasedFlag, false)
+
+ listener.verifyInOrder(unreleasedFlag.id)
+ }
+
+ @Test
+ fun listenerForStringFlag_notCalledAfterRemoved() {
+ val flags = FakeFeatureFlags()
+ val listener = VerifyingListener()
+
+ flags.addListener(stringFlag, listener)
+ flags.set(stringFlag, "Test")
+ flags.removeListener(listener)
+ flags.set(stringFlag, "Other")
+
+ listener.verifyInOrder(stringFlag.id)
+ }
+
+ @Test
+ fun listenerForMultipleFlags_calledWhenFlagsChange() {
+ val flags = FakeFeatureFlags()
+ val listener = VerifyingListener()
+ flags.addListener(unreleasedFlag, listener)
+ flags.addListener(releasedFlag, listener)
+
+ flags.set(releasedFlag, true)
+ flags.set(unreleasedFlag, true)
+
+ listener.verifyInOrder(releasedFlag.id, unreleasedFlag.id)
+ }
+
+ @Test
+ fun listenerForMultipleFlags_notCalledAfterRemoved() {
+ val flags = FakeFeatureFlags()
+ val listener = VerifyingListener()
+
+ flags.addListener(unreleasedFlag, listener)
+ flags.addListener(releasedFlag, listener)
+ flags.set(releasedFlag, true)
+ flags.set(unreleasedFlag, true)
+ flags.removeListener(listener)
+ flags.set(releasedFlag, false)
+ flags.set(unreleasedFlag, false)
+
+ listener.verifyInOrder(releasedFlag.id, unreleasedFlag.id)
+ }
+
+ @Test
+ fun multipleListenersForSingleFlag_allAreCalledWhenChanged() {
+ val flags = FakeFeatureFlags()
+ val listener1 = VerifyingListener()
+ val listener2 = VerifyingListener()
+ flags.addListener(releasedFlag, listener1)
+ flags.addListener(releasedFlag, listener2)
+
+ flags.set(releasedFlag, true)
+
+ listener1.verifyInOrder(releasedFlag.id)
+ listener2.verifyInOrder(releasedFlag.id)
+ }
+
+ @Test
+ fun multipleListenersForSingleFlag_removedListenerNotCalledAfterRemoval() {
+ val flags = FakeFeatureFlags()
+ val listener1 = VerifyingListener()
+ val listener2 = VerifyingListener()
+ flags.addListener(releasedFlag, listener1)
+ flags.addListener(releasedFlag, listener2)
+
+ flags.set(releasedFlag, true)
+ flags.removeListener(listener2)
+ flags.set(releasedFlag, false)
+
+ listener1.verifyInOrder(releasedFlag.id, releasedFlag.id)
+ listener2.verifyInOrder(releasedFlag.id)
+ }
+
+ class VerifyingListener : FlagListenable.Listener {
+ var flagEventIds = mutableListOf<Int>()
+ override fun onFlagChanged(event: FlagListenable.FlagEvent) {
+ flagEventIds.add(event.flagId)
+ }
+
+ fun verifyInOrder(vararg eventIds: Int) {
+ assertThat(flagEventIds).containsExactlyElementsIn(eventIds.asList())
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index 178502269e73..bef46953395b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -1051,6 +1051,17 @@ public class MediaControlPanelTest : SysuiTestCase() {
}
@Test
+ fun bindDeviceWithNullName() {
+ val fallbackString = context.getResources().getString(R.string.media_seamless_other_device)
+ player.attachPlayer(viewHolder)
+ val state = mediaData.copy(device = device.copy(name = null))
+ player.bindPlayer(state, PACKAGE)
+ assertThat(seamless.isEnabled()).isTrue()
+ assertThat(seamlessText.getText()).isEqualTo(fallbackString)
+ assertThat(seamless.contentDescription).isEqualTo(fallbackString)
+ }
+
+ @Test
fun bindDeviceResumptionPlayer() {
player.attachPlayer(viewHolder)
val state = mediaData.copy(resumption = true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
index d1ed8e983cdd..f9c7d2d5cb41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
@@ -31,7 +31,6 @@ import com.android.systemui.statusbar.SbnBuilder
import com.android.systemui.tuner.TunerService
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.capture
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.time.FakeSystemClock
@@ -108,6 +107,7 @@ class MediaDataManagerTest : SysuiTestCase() {
private val clock = FakeSystemClock()
@Mock private lateinit var tunerService: TunerService
@Captor lateinit var tunableCaptor: ArgumentCaptor<TunerService.Tunable>
+ @Captor lateinit var callbackCaptor: ArgumentCaptor<(String, PlaybackState) -> Unit>
private val instanceIdSequence = InstanceIdSequenceFake(1 shl 20)
@@ -974,7 +974,6 @@ class MediaDataManagerTest : SysuiTestCase() {
fun testPlaybackStateChange_keyExists_callsListener() {
// Notification has been added
addNotificationAndLoad()
- val callbackCaptor = argumentCaptor<(String, PlaybackState) -> Unit>()
verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
// Callback gets an updated state
@@ -992,7 +991,6 @@ class MediaDataManagerTest : SysuiTestCase() {
@Test
fun testPlaybackStateChange_keyDoesNotExist_doesNothing() {
val state = PlaybackState.Builder().build()
- val callbackCaptor = argumentCaptor<(String, PlaybackState) -> Unit>()
verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
// No media added with this key
@@ -1013,7 +1011,6 @@ class MediaDataManagerTest : SysuiTestCase() {
// And then get a state update
val state = PlaybackState.Builder().build()
- val callbackCaptor = argumentCaptor<(String, PlaybackState) -> Unit>()
verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
// Then no changes are made
@@ -1022,6 +1019,83 @@ class MediaDataManagerTest : SysuiTestCase() {
anyBoolean())
}
+ @Test
+ fun testPlaybackState_PauseWhenFlagTrue_keyExists_callsListener() {
+ whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(true)
+ val state = PlaybackState.Builder()
+ .setState(PlaybackState.STATE_PAUSED, 0L, 1f)
+ .build()
+ whenever(controller.playbackState).thenReturn(state)
+
+ addNotificationAndLoad()
+ verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
+ callbackCaptor.value.invoke(KEY, state)
+
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY),
+ capture(mediaDataCaptor), eq(true), eq(0), eq(false))
+ assertThat(mediaDataCaptor.value.isPlaying).isFalse()
+ assertThat(mediaDataCaptor.value.semanticActions).isNotNull()
+ }
+
+ @Test
+ fun testPlaybackState_PauseStateAfterAddingResumption_keyExists_callsListener() {
+ val desc = MediaDescription.Builder().run {
+ setTitle(SESSION_TITLE)
+ build()
+ }
+ val state = PlaybackState.Builder()
+ .setState(PlaybackState.STATE_PAUSED, 0L, 1f)
+ .setActions(PlaybackState.ACTION_PLAY_PAUSE)
+ .build()
+
+ // Add resumption controls in order to have semantic actions.
+ // To make sure that they are not null after changing state.
+ mediaDataManager.addResumptionControls(
+ USER_ID,
+ desc,
+ Runnable {},
+ session.sessionToken,
+ APP_NAME,
+ pendingIntent,
+ PACKAGE_NAME
+ )
+ backgroundExecutor.runAllReady()
+ foregroundExecutor.runAllReady()
+
+ verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
+ callbackCaptor.value.invoke(PACKAGE_NAME, state)
+
+ verify(listener)
+ .onMediaDataLoaded(
+ eq(PACKAGE_NAME),
+ eq(PACKAGE_NAME),
+ capture(mediaDataCaptor),
+ eq(true),
+ eq(0),
+ eq(false)
+ )
+ assertThat(mediaDataCaptor.value.isPlaying).isFalse()
+ assertThat(mediaDataCaptor.value.semanticActions).isNotNull()
+ }
+
+ @Test
+ fun testPlaybackStateNull_Pause_keyExists_callsListener() {
+ whenever(controller.playbackState).thenReturn(null)
+ val state = PlaybackState.Builder()
+ .setState(PlaybackState.STATE_PAUSED, 0L, 1f)
+ .setActions(PlaybackState.ACTION_PLAY_PAUSE)
+ .build()
+
+ addNotificationAndLoad()
+ verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor)
+ callbackCaptor.value.invoke(KEY, state)
+
+ verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY),
+ capture(mediaDataCaptor), eq(true), eq(0), eq(false))
+ assertThat(mediaDataCaptor.value.isPlaying).isFalse()
+ assertThat(mediaDataCaptor.value.semanticActions).isNull()
+ }
+
/**
* Helper function to add a media notification and capture the resulting MediaData
*/
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
index ee104262dc29..121c8946d164 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
@@ -59,8 +59,8 @@ import org.mockito.Mockito.reset
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
-import org.mockito.junit.MockitoJUnit
import org.mockito.Mockito.`when` as whenever
+import org.mockito.junit.MockitoJUnit
private const val KEY = "TEST_KEY"
private const val KEY_OLD = "TEST_KEY_OLD"
@@ -402,9 +402,10 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
manager.onMediaDataLoaded(KEY, null, mediaData)
fakeBgExecutor.runAllReady()
fakeFgExecutor.runAllReady()
- // THEN the device is disabled
+ // THEN the device is disabled and name is set to null
val data = captureDeviceData(KEY)
assertThat(data.enabled).isFalse()
+ assertThat(data.name).isNull()
}
@Test
@@ -421,9 +422,10 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
deviceCallback.onSelectedDeviceStateChanged(device, 1)
fakeBgExecutor.runAllReady()
fakeFgExecutor.runAllReady()
- // THEN the device is disabled
+ // THEN the device is disabled and name is set to null
val data = captureDeviceData(KEY)
assertThat(data.enabled).isFalse()
+ assertThat(data.name).isNull()
}
@Test
@@ -440,9 +442,24 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
deviceCallback.onDeviceListUpdate(mutableListOf(device))
fakeBgExecutor.runAllReady()
fakeFgExecutor.runAllReady()
- // THEN the device is disabled
+ // THEN the device is disabled and name is set to null
val data = captureDeviceData(KEY)
assertThat(data.enabled).isFalse()
+ assertThat(data.name).isNull()
+ }
+
+ @Test
+ fun mr2ReturnsRouteWithNullName_useLocalDeviceName() {
+ // GIVEN that MR2Manager returns a routing session that does not have a name
+ whenever(route.name).thenReturn(null)
+ // WHEN a notification is added
+ manager.onMediaDataLoaded(KEY, null, mediaData)
+ fakeBgExecutor.runAllReady()
+ fakeFgExecutor.runAllReady()
+ // THEN the device is enabled and uses the current connected device name
+ val data = captureDeviceData(KEY)
+ assertThat(data.name).isEqualTo(DEVICE_NAME)
+ assertThat(data.enabled).isTrue()
}
@Test
@@ -647,12 +664,14 @@ public class MediaDeviceManagerTest : SysuiTestCase() {
override fun onPlaybackStopped(reason: Int, broadcastId: Int) {}
override fun onBroadcastUpdated(reason: Int, broadcastId: Int) {}
override fun onBroadcastUpdateFailed(reason: Int, broadcastId: Int) {}
- override fun onBroadcastMetadataChanged(broadcastId: Int,
- metadata: BluetoothLeBroadcastMetadata) {}
+ override fun onBroadcastMetadataChanged(
+ broadcastId: Int,
+ metadata: BluetoothLeBroadcastMetadata
+ ) {}
}
bluetoothLeBroadcast.registerCallback(fakeFgExecutor, callback)
- return callback;
+ return callback
}
fun setupLeAudioConfiguration(isLeAudio: Boolean) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
index 1061e3c6b0d5..fa47a746f8ba 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
@@ -35,7 +35,9 @@ import com.android.internal.logging.testing.UiEventLoggerFake
import com.android.internal.statusbar.IUndoMediaTransferCallback
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.media.taptotransfer.common.MediaTttLogger
+import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.concurrency.FakeExecutor
@@ -48,11 +50,12 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
+import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -78,6 +81,10 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
private lateinit var viewUtil: ViewUtil
@Mock
private lateinit var commandQueue: CommandQueue
+ @Mock
+ private lateinit var falsingManager: FalsingManager
+ @Mock
+ private lateinit var falsingCollector: FalsingCollector
private lateinit var commandQueueCallback: CommandQueue.Callbacks
private lateinit var fakeAppIconDrawable: Drawable
private lateinit var fakeClock: FakeSystemClock
@@ -115,7 +122,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
accessibilityManager,
configurationController,
powerManager,
- senderUiEventLogger
+ senderUiEventLogger,
+ falsingManager,
+ falsingCollector
)
val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
@@ -421,6 +430,38 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
}
@Test
+ fun transferToReceiverSucceeded_withUndoRunnable_falseTap_callbackNotRun() {
+ whenever(falsingManager.isFalseTap(anyInt())).thenReturn(true)
+ var undoCallbackCalled = false
+ val undoCallback = object : IUndoMediaTransferCallback.Stub() {
+ override fun onUndoTriggered() {
+ undoCallbackCalled = true
+ }
+ }
+
+ controllerSender.displayChip(transferToReceiverSucceeded(undoCallback))
+ getChipView().getUndoButton().performClick()
+
+ assertThat(undoCallbackCalled).isFalse()
+ }
+
+ @Test
+ fun transferToReceiverSucceeded_withUndoRunnable_realTap_callbackRun() {
+ whenever(falsingManager.isFalseTap(anyInt())).thenReturn(false)
+ var undoCallbackCalled = false
+ val undoCallback = object : IUndoMediaTransferCallback.Stub() {
+ override fun onUndoTriggered() {
+ undoCallbackCalled = true
+ }
+ }
+
+ controllerSender.displayChip(transferToReceiverSucceeded(undoCallback))
+ getChipView().getUndoButton().performClick()
+
+ assertThat(undoCallbackCalled).isTrue()
+ }
+
+ @Test
fun transferToReceiverSucceeded_undoButtonClick_switchesToTransferToThisDeviceTriggered() {
val undoCallback = object : IUndoMediaTransferCallback.Stub() {
override fun onUndoTriggered() {}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
index 48fbd354b98d..073c23cec569 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
@@ -23,6 +23,7 @@ import android.graphics.Insets
import android.graphics.Rect
import android.hardware.HardwareBuffer
import android.os.Bundle
+import android.os.UserHandle
import android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_CHORD
import android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER
import android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN
@@ -97,7 +98,7 @@ class RequestProcessorTest {
policy.setManagedProfile(USER_ID, false)
policy.setDisplayContentInfo(
policy.getDefaultDisplayId(),
- DisplayContentInfo(component, bounds, USER_ID, TASK_ID))
+ DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID))
val request = ScreenshotRequest(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD)
val processor = RequestProcessor(imageCapture, policy, flags, scope)
@@ -120,7 +121,7 @@ class RequestProcessorTest {
// Indicate that the primary content belongs to a manged profile
policy.setManagedProfile(USER_ID, true)
policy.setDisplayContentInfo(policy.getDefaultDisplayId(),
- DisplayContentInfo(component, bounds, USER_ID, TASK_ID))
+ DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID))
val request = ScreenshotRequest(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD)
val processor = RequestProcessor(imageCapture, policy, flags, scope)
@@ -160,7 +161,7 @@ class RequestProcessorTest {
policy.setManagedProfile(USER_ID, false)
policy.setDisplayContentInfo(policy.getDefaultDisplayId(),
- DisplayContentInfo(component, bounds, USER_ID, TASK_ID))
+ DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID))
val processedRequest = processor.process(request)
@@ -183,7 +184,7 @@ class RequestProcessorTest {
// Indicate that the primary content belongs to a manged profile
policy.setManagedProfile(USER_ID, true)
policy.setDisplayContentInfo(policy.getDefaultDisplayId(),
- DisplayContentInfo(component, bounds, USER_ID, TASK_ID))
+ DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID))
val processedRequest = processor.process(request)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt
new file mode 100644
index 000000000000..17396b13036c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt
@@ -0,0 +1,227 @@
+/*
+ * 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.screenshot
+
+import android.app.ActivityTaskManager.RootTaskInfo
+import android.app.IActivityTaskManager
+import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
+import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD
+import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED
+import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.app.WindowConfiguration.WINDOWING_MODE_PINNED
+import android.content.ComponentName
+import android.content.Context
+import android.graphics.Rect
+import android.os.UserHandle
+import android.os.UserManager
+import android.testing.AndroidTestingRunner
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.screenshot.ScreenshotPolicy.DisplayContentInfo
+import com.android.systemui.util.mockito.mock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.runBlocking
+import org.junit.Test
+import org.junit.runner.RunWith
+
+// The following values are chosen to be distinct from commonly seen real values
+private const val DISPLAY_ID = 100
+private const val PRIMARY_USER = 2000
+private const val MANAGED_PROFILE_USER = 3000
+
+@RunWith(AndroidTestingRunner::class)
+class ScreenshotPolicyImplTest : SysuiTestCase() {
+
+ @Test
+ fun testToDisplayContentInfo() {
+ assertThat(fullScreenWorkProfileTask.toDisplayContentInfo())
+ .isEqualTo(
+ DisplayContentInfo(
+ ComponentName(
+ "com.google.android.apps.nbu.files",
+ "com.google.android.apps.nbu.files.home.HomeActivity"
+ ),
+ Rect(0, 0, 1080, 2400),
+ UserHandle.of(MANAGED_PROFILE_USER),
+ 65))
+ }
+
+ @Test
+ fun findPrimaryContent_ignoresPipTask() = runBlocking {
+ val policy = fakeTasksPolicyImpl(
+ mContext,
+ shadeExpanded = false,
+ tasks = listOf(
+ pipTask,
+ fullScreenWorkProfileTask,
+ launcherTask,
+ emptyTask)
+ )
+
+ val info = policy.findPrimaryContent(DISPLAY_ID)
+ assertThat(info).isEqualTo(fullScreenWorkProfileTask.toDisplayContentInfo())
+ }
+
+ @Test
+ fun findPrimaryContent_shadeExpanded_ignoresTopTask() = runBlocking {
+ val policy = fakeTasksPolicyImpl(
+ mContext,
+ shadeExpanded = true,
+ tasks = listOf(
+ fullScreenWorkProfileTask,
+ launcherTask,
+ emptyTask)
+ )
+
+ val info = policy.findPrimaryContent(DISPLAY_ID)
+ assertThat(info).isEqualTo(policy.systemUiContent)
+ }
+
+ @Test
+ fun findPrimaryContent_emptyTaskList() = runBlocking {
+ val policy = fakeTasksPolicyImpl(
+ mContext,
+ shadeExpanded = false,
+ tasks = listOf()
+ )
+
+ val info = policy.findPrimaryContent(DISPLAY_ID)
+ assertThat(info).isEqualTo(policy.systemUiContent)
+ }
+
+ @Test
+ fun findPrimaryContent_workProfileNotOnTop() = runBlocking {
+ val policy = fakeTasksPolicyImpl(
+ mContext,
+ shadeExpanded = false,
+ tasks = listOf(
+ launcherTask,
+ fullScreenWorkProfileTask,
+ emptyTask)
+ )
+
+ val info = policy.findPrimaryContent(DISPLAY_ID)
+ assertThat(info).isEqualTo(launcherTask.toDisplayContentInfo())
+ }
+
+ private fun fakeTasksPolicyImpl(
+ context: Context,
+ shadeExpanded: Boolean,
+ tasks: List<RootTaskInfo>
+ ): ScreenshotPolicyImpl {
+ val userManager = mock<UserManager>()
+ val atmService = mock<IActivityTaskManager>()
+ val dispatcher = Dispatchers.Unconfined
+
+ return object : ScreenshotPolicyImpl(context, userManager, atmService, dispatcher) {
+ override suspend fun isManagedProfile(userId: Int) = (userId == MANAGED_PROFILE_USER)
+ override suspend fun getAllRootTaskInfosOnDisplay(displayId: Int) = tasks
+ override suspend fun isNotificationShadeExpanded() = shadeExpanded
+ }
+ }
+
+ private val pipTask = RootTaskInfo().apply {
+ configuration.windowConfiguration.apply {
+ windowingMode = WINDOWING_MODE_PINNED
+ bounds = Rect(628, 1885, 1038, 2295)
+ activityType = ACTIVITY_TYPE_STANDARD
+ }
+ displayId = DISPLAY_ID
+ userId = PRIMARY_USER
+ taskId = 66
+ visible = true
+ isVisible = true
+ isRunning = true
+ numActivities = 1
+ topActivity = ComponentName(
+ "com.google.android.youtube",
+ "com.google.android.apps.youtube.app.watchwhile.WatchWhileActivity"
+ )
+ childTaskIds = intArrayOf(66)
+ childTaskNames = arrayOf("com.google.android.youtube/" +
+ "com.google.android.youtube.app.honeycomb.Shell\$HomeActivity")
+ childTaskUserIds = intArrayOf(0)
+ childTaskBounds = arrayOf(Rect(628, 1885, 1038, 2295))
+ }
+
+ private val fullScreenWorkProfileTask = RootTaskInfo().apply {
+ configuration.windowConfiguration.apply {
+ windowingMode = WINDOWING_MODE_FULLSCREEN
+ bounds = Rect(0, 0, 1080, 2400)
+ activityType = ACTIVITY_TYPE_STANDARD
+ }
+ displayId = DISPLAY_ID
+ userId = MANAGED_PROFILE_USER
+ taskId = 65
+ visible = true
+ isVisible = true
+ isRunning = true
+ numActivities = 1
+ topActivity = ComponentName(
+ "com.google.android.apps.nbu.files",
+ "com.google.android.apps.nbu.files.home.HomeActivity"
+ )
+ childTaskIds = intArrayOf(65)
+ childTaskNames = arrayOf("com.google.android.apps.nbu.files/" +
+ "com.google.android.apps.nbu.files.home.HomeActivity")
+ childTaskUserIds = intArrayOf(MANAGED_PROFILE_USER)
+ childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400))
+ }
+
+ private val launcherTask = RootTaskInfo().apply {
+ configuration.windowConfiguration.apply {
+ windowingMode = WINDOWING_MODE_FULLSCREEN
+ bounds = Rect(0, 0, 1080, 2400)
+ activityType = ACTIVITY_TYPE_HOME
+ }
+ displayId = DISPLAY_ID
+ taskId = 1
+ userId = PRIMARY_USER
+ visible = true
+ isVisible = true
+ isRunning = true
+ numActivities = 1
+ topActivity = ComponentName(
+ "com.google.android.apps.nexuslauncher",
+ "com.google.android.apps.nexuslauncher.NexusLauncherActivity",
+ )
+ childTaskIds = intArrayOf(1)
+ childTaskNames = arrayOf("com.google.android.apps.nexuslauncher/" +
+ "com.google.android.apps.nexuslauncher.NexusLauncherActivity")
+ childTaskUserIds = intArrayOf(0)
+ childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400))
+ }
+
+ private val emptyTask = RootTaskInfo().apply {
+ configuration.windowConfiguration.apply {
+ windowingMode = WINDOWING_MODE_FULLSCREEN
+ bounds = Rect(0, 0, 1080, 2400)
+ activityType = ACTIVITY_TYPE_UNDEFINED
+ }
+ displayId = DISPLAY_ID
+ taskId = 2
+ userId = PRIMARY_USER
+ visible = false
+ isVisible = false
+ isRunning = false
+ numActivities = 0
+ childTaskIds = intArrayOf(3, 4)
+ childTaskNames = arrayOf("", "")
+ childTaskUserIds = intArrayOf(0, 0)
+ childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400), Rect(0, 2400, 1080, 4800))
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 98389c2c7a6f..e2ce939cb66c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -458,7 +458,6 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
NotificationWakeUpCoordinator coordinator =
new NotificationWakeUpCoordinator(
- mDumpManager,
mock(HeadsUpManagerPhone.class),
new StatusBarStateControllerImpl(new UiEventLoggerFake(), mDumpManager,
mInteractionJankMonitor),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
index a6b7e5103c78..ca98143044c1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
@@ -58,7 +58,6 @@ public class StatusBarIconControllerTest extends LeakCheckedTest {
@Before
public void setup() {
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
- mDependency.injectMockDependency(DarkIconDispatcher.class);
}
@Test
@@ -75,7 +74,8 @@ public class StatusBarIconControllerTest extends LeakCheckedTest {
layout,
mock(FeatureFlags.class),
mock(StatusBarPipelineFlags.class),
- () -> mock(WifiViewModel.class));
+ () -> mock(WifiViewModel.class),
+ mock(DarkIconDispatcher.class));
testCallOnAdd_forManager(manager);
}
@@ -116,8 +116,10 @@ public class StatusBarIconControllerTest extends LeakCheckedTest {
LinearLayout group,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
- Provider<WifiViewModel> wifiViewModelProvider) {
- super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
+ Provider<WifiViewModel> wifiViewModelProvider,
+ DarkIconDispatcher darkIconDispatcher) {
+ super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider,
+ darkIconDispatcher);
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
index 982927148a2e..d070ba0e47be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
@@ -473,6 +473,40 @@ class WifiRepositoryImplTest : SysuiTestCase() {
job.cancel()
}
+ /** Regression test for b/244173280. */
+ @Test
+ fun wifiNetwork_multipleSubscribers_newSubscribersGetCurrentValue() = runBlocking(IMMEDIATE) {
+ var latest1: WifiNetworkModel? = null
+ val job1 = underTest
+ .wifiNetwork
+ .onEach { latest1 = it }
+ .launchIn(this)
+
+ getNetworkCallback()
+ .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
+
+ assertThat(latest1 is WifiNetworkModel.Active).isTrue()
+ val latest1Active = latest1 as WifiNetworkModel.Active
+ assertThat(latest1Active.networkId).isEqualTo(NETWORK_ID)
+ assertThat(latest1Active.ssid).isEqualTo(SSID)
+
+ // WHEN we add a second subscriber after having already emitted a value
+ var latest2: WifiNetworkModel? = null
+ val job2 = underTest
+ .wifiNetwork
+ .onEach { latest2 = it }
+ .launchIn(this)
+
+ // THEN the second subscribe receives the already-emitted value
+ assertThat(latest2 is WifiNetworkModel.Active).isTrue()
+ val latest2Active = latest2 as WifiNetworkModel.Active
+ assertThat(latest2Active.networkId).isEqualTo(NETWORK_ID)
+ assertThat(latest2Active.ssid).isEqualTo(SSID)
+
+ job1.cancel()
+ job2.cancel()
+ }
+
@Test
fun wifiActivity_nullWifiManager_receivesDefault() = runBlocking(IMMEDIATE) {
underTest = WifiRepositoryImpl(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
index 312db2d7066a..2e74bf5474f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/volume/VolumeDialogImplTest.java
@@ -85,6 +85,8 @@ public class VolumeDialogImplTest extends SysuiTestCase {
@Mock
MediaOutputDialogFactory mMediaOutputDialogFactory;
@Mock
+ VolumePanelFactory mVolumePanelFactory;
+ @Mock
ActivityStarter mActivityStarter;
@Mock
InteractionJankMonitor mInteractionJankMonitor;
@@ -102,6 +104,7 @@ public class VolumeDialogImplTest extends SysuiTestCase {
mDeviceProvisionedController,
mConfigurationController,
mMediaOutputDialogFactory,
+ mVolumePanelFactory,
mActivityStarter,
mInteractionJankMonitor);
mDialog.init(0, null);
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt
index b53ad0a3726f..c56fdb17b5f1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt
@@ -16,14 +16,12 @@
package com.android.systemui.flags
-import android.util.SparseArray
-import android.util.SparseBooleanArray
-import androidx.core.util.containsKey
-
class FakeFeatureFlags : FeatureFlags {
- private val booleanFlags = SparseBooleanArray()
- private val stringFlags = SparseArray<String>()
+ private val booleanFlags = mutableMapOf<Int, Boolean>()
+ private val stringFlags = mutableMapOf<Int, String>()
private val knownFlagNames = mutableMapOf<Int, String>()
+ private val flagListeners = mutableMapOf<Int, MutableSet<FlagListenable.Listener>>()
+ private val listenerFlagIds = mutableMapOf<FlagListenable.Listener, MutableSet<Int>>()
init {
Flags.getFlagFields().forEach { field ->
@@ -33,27 +31,52 @@ class FakeFeatureFlags : FeatureFlags {
}
fun set(flag: BooleanFlag, value: Boolean) {
- booleanFlags.put(flag.id, value)
+ if (booleanFlags.put(flag.id, value)?.let { value != it } != false) {
+ notifyFlagChanged(flag)
+ }
}
fun set(flag: DeviceConfigBooleanFlag, value: Boolean) {
- booleanFlags.put(flag.id, value)
+ if (booleanFlags.put(flag.id, value)?.let { value != it } != false) {
+ notifyFlagChanged(flag)
+ }
}
fun set(flag: ResourceBooleanFlag, value: Boolean) {
- booleanFlags.put(flag.id, value)
+ if (booleanFlags.put(flag.id, value)?.let { value != it } != false) {
+ notifyFlagChanged(flag)
+ }
}
fun set(flag: SysPropBooleanFlag, value: Boolean) {
- booleanFlags.put(flag.id, value)
+ if (booleanFlags.put(flag.id, value)?.let { value != it } != false) {
+ notifyFlagChanged(flag)
+ }
}
fun set(flag: StringFlag, value: String) {
- stringFlags.put(flag.id, value)
+ if (stringFlags.put(flag.id, value)?.let { value != it } == null) {
+ notifyFlagChanged(flag)
+ }
}
fun set(flag: ResourceStringFlag, value: String) {
- stringFlags.put(flag.id, value)
+ if (stringFlags.put(flag.id, value)?.let { value != it } == null) {
+ notifyFlagChanged(flag)
+ }
+ }
+
+ private fun notifyFlagChanged(flag: Flag<*>) {
+ flagListeners[flag.id]?.let { listeners ->
+ listeners.forEach { listener ->
+ listener.onFlagChanged(
+ object : FlagListenable.FlagEvent {
+ override val flagId = flag.id
+ override fun requestNoRestart() {}
+ }
+ )
+ }
+ }
}
override fun isEnabled(flag: UnreleasedFlag): Boolean = requireBooleanValue(flag.id)
@@ -70,25 +93,30 @@ class FakeFeatureFlags : FeatureFlags {
override fun getString(flag: ResourceStringFlag): String = requireStringValue(flag.id)
- override fun addListener(flag: Flag<*>, listener: FlagListenable.Listener) {}
+ override fun addListener(flag: Flag<*>, listener: FlagListenable.Listener) {
+ flagListeners.getOrPut(flag.id) { mutableSetOf() }.add(listener)
+ listenerFlagIds.getOrPut(listener) { mutableSetOf() }.add(flag.id)
+ }
- override fun removeListener(listener: FlagListenable.Listener) {}
+ override fun removeListener(listener: FlagListenable.Listener) {
+ listenerFlagIds.remove(listener)?.let {
+ flagIds -> flagIds.forEach {
+ id -> flagListeners[id]?.remove(listener)
+ }
+ }
+ }
private fun flagName(flagId: Int): String {
return knownFlagNames[flagId] ?: "UNKNOWN(id=$flagId)"
}
private fun requireBooleanValue(flagId: Int): Boolean {
- if (!booleanFlags.containsKey(flagId)) {
- throw IllegalStateException("Flag ${flagName(flagId)} was accessed but not specified.")
- }
return booleanFlags[flagId]
+ ?: error("Flag ${flagName(flagId)} was accessed but not specified.")
}
private fun requireStringValue(flagId: Int): String {
- if (!stringFlags.containsKey(flagId)) {
- throw IllegalStateException("Flag ${flagName(flagId)} was accessed but not specified.")
- }
return stringFlags[flagId]
+ ?: error("Flag ${flagName(flagId)} was accessed but not specified.")
}
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 6aa472fcd586..01af23da0f99 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -4248,7 +4248,8 @@ public final class ActiveServices {
final String procName = r.processName;
HostingRecord hostingRecord = new HostingRecord(
HostingRecord.HOSTING_TYPE_SERVICE, r.instanceName,
- r.definingPackageName, r.definingUid, r.serviceInfo.processName);
+ r.definingPackageName, r.definingUid, r.serviceInfo.processName,
+ getHostingRecordTriggerType(r));
ProcessRecord app;
if (!isolated) {
@@ -4358,6 +4359,14 @@ public final class ActiveServices {
return null;
}
+ private String getHostingRecordTriggerType(ServiceRecord r) {
+ if (Manifest.permission.BIND_JOB_SERVICE.equals(r.permission)
+ && r.mRecentCallingUid == SYSTEM_UID) {
+ return HostingRecord.TRIGGER_TYPE_JOB;
+ }
+ return HostingRecord.TRIGGER_TYPE_UNKNOWN;
+ }
+
private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
throws TransactionTooLargeException {
for (int i=r.bindings.size()-1; i>=0; i--) {
diff --git a/services/core/java/com/android/server/am/HostingRecord.java b/services/core/java/com/android/server/am/HostingRecord.java
index 2498f763ff77..30811a175bac 100644
--- a/services/core/java/com/android/server/am/HostingRecord.java
+++ b/services/core/java/com/android/server/am/HostingRecord.java
@@ -30,9 +30,10 @@ import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HO
import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_SERVICE;
import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_SYSTEM;
import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__HOSTING_TYPE_ID__HOSTING_TYPE_TOP_ACTIVITY;
-import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_PUSH_MESSAGE;
-import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_PUSH_MESSAGE_OVER_QUOTA;
import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_ALARM;
+import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_JOB;
+import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE;
+import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA;
import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_UNKNOWN;
import static com.android.internal.util.FrameworkStatsLog.PROCESS_START_TIME__TYPE__UNKNOWN;
@@ -97,6 +98,7 @@ public final class HostingRecord {
public static final String TRIGGER_TYPE_ALARM = "alarm";
public static final String TRIGGER_TYPE_PUSH_MESSAGE = "push_message";
public static final String TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA = "push_message_over_quota";
+ public static final String TRIGGER_TYPE_JOB = "job";
@NonNull private final String mHostingType;
private final String mHostingName;
@@ -126,10 +128,11 @@ public final class HostingRecord {
}
public HostingRecord(@NonNull String hostingType, ComponentName hostingName,
- String definingPackageName, int definingUid, String definingProcessName) {
+ String definingPackageName, int definingUid, String definingProcessName,
+ String triggerType) {
this(hostingType, hostingName.toShortString(), REGULAR_ZYGOTE, definingPackageName,
definingUid, false /* isTopApp */, definingProcessName, null /* action */,
- TRIGGER_TYPE_UNKNOWN);
+ triggerType);
}
public HostingRecord(@NonNull String hostingType, ComponentName hostingName, boolean isTopApp) {
@@ -313,9 +316,11 @@ public final class HostingRecord {
case TRIGGER_TYPE_ALARM:
return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_ALARM;
case TRIGGER_TYPE_PUSH_MESSAGE:
- return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_PUSH_MESSAGE;
+ return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE;
case TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA:
- return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_PUSH_MESSAGE_OVER_QUOTA;
+ return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_PUSH_MESSAGE_OVER_QUOTA;
+ case TRIGGER_TYPE_JOB:
+ return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_JOB;
default:
return PROCESS_START_TIME__TRIGGER_TYPE__TRIGGER_TYPE_UNKNOWN;
}
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 66a4527bc2cb..4adbfaa79c69 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -53,8 +53,6 @@ public class BtHelper {
private static final String TAG = "AS.BtHelper";
- private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO remove in U
-
private final @NonNull AudioDeviceBroker mDeviceBroker;
BtHelper(@NonNull AudioDeviceBroker broker) {
@@ -913,7 +911,7 @@ public class BtHelper {
return "ENCODING_APTX_HD";
case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
return "ENCODING_LDAC";
- case SOURCE_CODEC_TYPE_OPUS: // TODO update in U
+ case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS:
return "ENCODING_OPUS";
default:
return "ENCODING_BT_CODEC_TYPE(" + btCodecType + ")";
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 689ddd2fb9ee..c29755aaa845 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -72,7 +72,6 @@ import com.android.internal.os.SomeArgs;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.DumpUtils;
import com.android.server.SystemService;
-import com.android.server.biometrics.sensors.CoexCoordinator;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -951,16 +950,6 @@ public class BiometricService extends SystemService {
return new ArrayList<>();
}
- public boolean isAdvancedCoexLogicEnabled(Context context) {
- return Settings.Secure.getInt(context.getContentResolver(),
- CoexCoordinator.SETTING_ENABLE_NAME, 1) != 0;
- }
-
- public boolean isCoexFaceNonBypassHapticsDisabled(Context context) {
- return Settings.Secure.getInt(context.getContentResolver(),
- CoexCoordinator.FACE_HAPTIC_DISABLE, 0) != 0;
- }
-
public Supplier<Long> getRequestGenerator() {
final AtomicLong generator = new AtomicLong(0);
return () -> generator.incrementAndGet();
@@ -992,14 +981,6 @@ public class BiometricService extends SystemService {
mEnabledOnKeyguardCallbacks);
mRequestCounter = mInjector.getRequestGenerator();
- // TODO(b/193089985) This logic lives here (outside of CoexCoordinator) so that it doesn't
- // need to depend on context. We can remove this code once the advanced logic is enabled
- // by default.
- CoexCoordinator coexCoordinator = CoexCoordinator.getInstance();
- coexCoordinator.setAdvancedLogicEnabled(injector.isAdvancedCoexLogicEnabled(context));
- coexCoordinator.setFaceHapticDisabledWhenNonBypass(
- injector.isCoexFaceNonBypassHapticsDisabled(context));
-
try {
injector.getActivityManagerService().registerUserSwitchObserver(
new UserSwitchObserver() {
@@ -1333,7 +1314,5 @@ public class BiometricService extends SystemService {
pw.println();
pw.println("CurrentSession: " + mAuthSession);
pw.println();
- pw.println("CoexCoordinator: " + CoexCoordinator.getInstance().toString());
- pw.println();
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 4eb6d38d9227..8a24ff6cffde 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -29,7 +29,6 @@ import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.os.IBinder;
import android.os.RemoteException;
-import android.os.SystemClock;
import android.security.KeyStore;
import android.util.EventLog;
import android.util.Slog;
@@ -46,9 +45,7 @@ import java.util.function.Supplier;
* A class to keep track of the authentication state for a given client.
*/
public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
- implements AuthenticationConsumer {
-
- private static final String TAG = "Biometrics/AuthenticationClient";
+ implements AuthenticationConsumer {
// New, has not started yet
public static final int STATE_NEW = 0;
@@ -67,28 +64,27 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
STATE_STARTED_PAUSED_ATTEMPTED,
STATE_STOPPED})
@interface State {}
-
+ private static final String TAG = "Biometrics/AuthenticationClient";
+ protected final long mOperationId;
private final boolean mIsStrongBiometric;
private final boolean mRequireConfirmation;
private final ActivityTaskManager mActivityTaskManager;
private final BiometricManager mBiometricManager;
- @Nullable private final TaskStackListener mTaskStackListener;
+ @Nullable
+ private final TaskStackListener mTaskStackListener;
private final LockoutTracker mLockoutTracker;
private final boolean mIsRestricted;
private final boolean mAllowBackgroundAuthentication;
private final boolean mIsKeyguardBypassEnabled;
-
- protected final long mOperationId;
-
+ // TODO: This is currently hard to maintain, as each AuthenticationClient subclass must update
+ // the state. We should think of a way to improve this in the future.
+ @State
+ protected int mState = STATE_NEW;
private long mStartTimeMs;
private boolean mAuthAttempted;
private boolean mAuthSuccess = false;
- // TODO: This is currently hard to maintain, as each AuthenticationClient subclass must update
- // the state. We should think of a way to improve this in the future.
- protected @State int mState = STATE_NEW;
-
public AuthenticationClient(@NonNull Context context, @NonNull Supplier<T> lazyDaemon,
@NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener,
int targetUserId, long operationId, boolean restricted, @NonNull String owner,
@@ -111,8 +107,9 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
mIsKeyguardBypassEnabled = isKeyguardBypassEnabled;
}
- public @LockoutTracker.LockoutMode int handleFailedAttempt(int userId) {
- final @LockoutTracker.LockoutMode int lockoutMode =
+ @LockoutTracker.LockoutMode
+ public int handleFailedAttempt(int userId) {
+ @LockoutTracker.LockoutMode final int lockoutMode =
mLockoutTracker.getLockoutModeForUser(userId);
final PerformanceTracker performanceTracker =
PerformanceTracker.getInstanceForSensorId(getSensorId());
@@ -173,14 +170,16 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
final ClientMonitorCallbackConverter listener = getListener();
- if (DEBUG) Slog.v(TAG, "onAuthenticated(" + authenticated + ")"
- + ", ID:" + identifier.getBiometricId()
- + ", Owner: " + getOwnerString()
- + ", isBP: " + isBiometricPrompt()
- + ", listener: " + listener
- + ", requireConfirmation: " + mRequireConfirmation
- + ", user: " + getTargetUserId()
- + ", clientMonitor: " + toString());
+ if (DEBUG) {
+ Slog.v(TAG, "onAuthenticated(" + authenticated + ")"
+ + ", ID:" + identifier.getBiometricId()
+ + ", Owner: " + getOwnerString()
+ + ", isBP: " + isBiometricPrompt()
+ + ", listener: " + listener
+ + ", requireConfirmation: " + mRequireConfirmation
+ + ", user: " + getTargetUserId()
+ + ", clientMonitor: " + this);
+ }
final PerformanceTracker pm = PerformanceTracker.getInstanceForSensorId(getSensorId());
if (isCryptoOperation()) {
@@ -239,142 +238,57 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
getSensorId(), getTargetUserId(), byteToken);
}
- final CoexCoordinator coordinator = CoexCoordinator.getInstance();
- coordinator.onAuthenticationSucceeded(SystemClock.uptimeMillis(), this,
- new CoexCoordinator.Callback() {
- @Override
- public void sendAuthenticationResult(boolean addAuthTokenIfStrong) {
- if (addAuthTokenIfStrong && mIsStrongBiometric) {
- final int result = KeyStore.getInstance().addAuthToken(byteToken);
- Slog.d(TAG, "addAuthToken: " + result);
- } else {
- Slog.d(TAG, "Skipping addAuthToken");
- }
-
- if (listener != null) {
- try {
- // Explicitly have if/else here to make it super obvious in case the
- // code is touched in the future.
- if (!mIsRestricted) {
- listener.onAuthenticationSucceeded(getSensorId(),
- identifier,
- byteToken,
- getTargetUserId(),
- mIsStrongBiometric);
- } else {
- listener.onAuthenticationSucceeded(getSensorId(),
- null /* identifier */,
- byteToken,
- getTargetUserId(),
- mIsStrongBiometric);
- }
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to notify listener", e);
- }
- } else {
- Slog.w(TAG, "Client not listening");
- }
+ // For BP, BiometricService will add the authToken to Keystore.
+ if (!isBiometricPrompt() && mIsStrongBiometric) {
+ final int result = KeyStore.getInstance().addAuthToken(byteToken);
+ if (result != KeyStore.NO_ERROR) {
+ Slog.d(TAG, "Error adding auth token : " + result);
+ } else {
+ Slog.d(TAG, "addAuthToken: " + result);
}
-
- @Override
- public void sendHapticFeedback() {
- if (listener != null && mShouldVibrate) {
- vibrateSuccess();
+ } else {
+ Slog.d(TAG, "Skipping addAuthToken");
+ }
+ try {
+ if (listener != null) {
+ if (!mIsRestricted) {
+ listener.onAuthenticationSucceeded(getSensorId(), identifier, byteToken,
+ getTargetUserId(), mIsStrongBiometric);
+ } else {
+ listener.onAuthenticationSucceeded(getSensorId(), null /* identifier */,
+ byteToken,
+ getTargetUserId(), mIsStrongBiometric);
}
+ } else {
+ Slog.e(TAG, "Received successful auth, but client was not listening");
}
-
- @Override
- public void handleLifecycleAfterAuth() {
- AuthenticationClient.this.handleLifecycleAfterAuth(true /* authenticated */);
- }
-
- @Override
- public void sendAuthenticationCanceled() {
- sendCancelOnly(listener);
- }
- });
- } else { // not authenticated
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to notify listener", e);
+ mCallback.onClientFinished(this, false);
+ return;
+ }
+ } else {
if (isBackgroundAuth) {
Slog.e(TAG, "cancelling due to background auth");
cancel();
} else {
// Allow system-defined limit of number of attempts before giving up
- final @LockoutTracker.LockoutMode int lockoutMode =
+ @LockoutTracker.LockoutMode final int lockoutMode =
handleFailedAttempt(getTargetUserId());
if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
markAlreadyDone();
}
- final CoexCoordinator coordinator = CoexCoordinator.getInstance();
- coordinator.onAuthenticationRejected(SystemClock.uptimeMillis(), this, lockoutMode,
- new CoexCoordinator.Callback() {
- @Override
- public void sendAuthenticationResult(boolean addAuthTokenIfStrong) {
- if (listener != null) {
- try {
- listener.onAuthenticationFailed(getSensorId());
- } catch (RemoteException e) {
- Slog.e(TAG, "Unable to notify listener", e);
- }
- }
- }
-
- @Override
- public void sendHapticFeedback() {
- if (listener != null && mShouldVibrate) {
- vibrateError();
- }
- }
-
- @Override
- public void handleLifecycleAfterAuth() {
- AuthenticationClient.this.handleLifecycleAfterAuth(false /* authenticated */);
- }
-
- @Override
- public void sendAuthenticationCanceled() {
- sendCancelOnly(listener);
- }
- });
- }
- }
- }
-
- /**
- * Only call this method on interfaces where lockout does not come from onError, I.E. the
- * old HIDL implementation.
- */
- protected void onLockoutTimed(long durationMillis) {
- final ClientMonitorCallbackConverter listener = getListener();
- final CoexCoordinator coordinator = CoexCoordinator.getInstance();
- coordinator.onAuthenticationError(this, BiometricConstants.BIOMETRIC_ERROR_LOCKOUT,
- new CoexCoordinator.ErrorCallback() {
- @Override
- public void sendHapticFeedback() {
- if (listener != null && mShouldVibrate) {
- vibrateError();
- }
- }
- });
- }
-
- /**
- * Only call this method on interfaces where lockout does not come from onError, I.E. the
- * old HIDL implementation.
- */
- protected void onLockoutPermanent() {
- final ClientMonitorCallbackConverter listener = getListener();
- final CoexCoordinator coordinator = CoexCoordinator.getInstance();
- coordinator.onAuthenticationError(this,
- BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT,
- new CoexCoordinator.ErrorCallback() {
- @Override
- public void sendHapticFeedback() {
- if (listener != null && mShouldVibrate) {
- vibrateError();
+ try {
+ listener.onAuthenticationFailed(getSensorId());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to notify listener", e);
+ mCallback.onClientFinished(this, false);
+ return;
}
}
- });
+ }
+ AuthenticationClient.this.handleLifecycleAfterAuth(authenticated);
}
private void sendCancelOnly(@Nullable ClientMonitorCallbackConverter listener) {
@@ -396,7 +310,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
public void onAcquired(int acquiredInfo, int vendorCode) {
super.onAcquired(acquiredInfo, vendorCode);
- final @LockoutTracker.LockoutMode int lockoutMode =
+ @LockoutTracker.LockoutMode final int lockoutMode =
mLockoutTracker.getLockoutModeForUser(getTargetUserId());
if (lockoutMode == LockoutTracker.LOCKOUT_NONE) {
PerformanceTracker pt = PerformanceTracker.getInstanceForSensorId(getSensorId());
@@ -408,8 +322,6 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
public void onError(@BiometricConstants.Errors int errorCode, int vendorCode) {
super.onError(errorCode, vendorCode);
mState = STATE_STOPPED;
-
- CoexCoordinator.getInstance().onAuthenticationError(this, errorCode, this::vibrateError);
}
/**
@@ -419,7 +331,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
public void start(@NonNull ClientMonitorCallback callback) {
super.start(callback);
- final @LockoutTracker.LockoutMode int lockoutMode =
+ @LockoutTracker.LockoutMode final int lockoutMode =
mLockoutTracker.getLockoutModeForUser(getTargetUserId());
if (lockoutMode != LockoutTracker.LOCKOUT_NONE) {
Slog.v(TAG, "In lockout mode(" + lockoutMode + ") ; disallowing authentication");
@@ -450,22 +362,20 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
}
/**
- * Handles lifecycle, e.g. {@link BiometricScheduler},
- * {@link com.android.server.biometrics.sensors.BaseClientMonitor.Callback} after authentication
- * results are known. Note that this happens asynchronously from (but shortly after)
- * {@link #onAuthenticated(BiometricAuthenticator.Identifier, boolean, ArrayList)} and allows
- * {@link CoexCoordinator} a chance to invoke/delay this event.
- * @param authenticated
+ * Handles lifecycle, e.g. {@link BiometricScheduler} after authentication. This is necessary
+ * as different clients handle the lifecycle of authentication success/reject differently. I.E.
+ * Fingerprint does not finish authentication when it is rejected.
*/
protected abstract void handleLifecycleAfterAuth(boolean authenticated);
/**
* @return true if a user was detected (i.e. face was found, fingerprint sensor was touched.
- * etc)
+ * etc)
*/
public abstract boolean wasUserDetected();
- public @State int getState() {
+ @State
+ public int getState() {
return mState;
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index 63609f77dc75..9317c4ec12b5 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -54,7 +54,7 @@ import java.util.function.Consumer;
* interactions with the HAL before finishing.
*
* We currently assume (and require) that each biometric sensor have its own instance of a
- * {@link BiometricScheduler}. See {@link CoexCoordinator}.
+ * {@link BiometricScheduler}.
*/
@MainThread
public class BiometricScheduler {
@@ -156,7 +156,6 @@ public class BiometricScheduler {
private int mTotalOperationsHandled;
private final int mRecentOperationsLimit;
@NonNull private final List<Integer> mRecentOperations;
- @NonNull private final CoexCoordinator mCoexCoordinator;
// Internal callback, notified when an operation is complete. Notifies the requester
// that the operation is complete, before performing internal scheduler work (such as
@@ -165,11 +164,6 @@ public class BiometricScheduler {
@Override
public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
Slog.d(getTag(), "[Started] " + clientMonitor);
-
- if (clientMonitor instanceof AuthenticationClient) {
- mCoexCoordinator.addAuthenticationClient(mSensorType,
- (AuthenticationClient<?>) clientMonitor);
- }
}
@Override
@@ -189,10 +183,6 @@ public class BiometricScheduler {
}
Slog.d(getTag(), "[Finishing] " + clientMonitor + ", success: " + success);
- if (clientMonitor instanceof AuthenticationClient) {
- mCoexCoordinator.removeAuthenticationClient(mSensorType,
- (AuthenticationClient<?>) clientMonitor);
- }
if (mGestureAvailabilityDispatcher != null) {
mGestureAvailabilityDispatcher.markSensorActive(
@@ -216,8 +206,7 @@ public class BiometricScheduler {
@SensorType int sensorType,
@Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
@NonNull IBiometricService biometricService,
- int recentOperationsLimit,
- @NonNull CoexCoordinator coexCoordinator) {
+ int recentOperationsLimit) {
mBiometricTag = tag;
mHandler = handler;
mSensorType = sensorType;
@@ -227,7 +216,6 @@ public class BiometricScheduler {
mCrashStates = new ArrayDeque<>();
mRecentOperationsLimit = recentOperationsLimit;
mRecentOperations = new ArrayList<>();
- mCoexCoordinator = coexCoordinator;
}
/**
@@ -244,7 +232,7 @@ public class BiometricScheduler {
this(tag, new Handler(Looper.getMainLooper()), sensorType, gestureAvailabilityDispatcher,
IBiometricService.Stub.asInterface(
ServiceManager.getService(Context.BIOMETRIC_SERVICE)),
- LOG_NUM_RECENT_OPERATIONS, CoexCoordinator.getInstance());
+ LOG_NUM_RECENT_OPERATIONS);
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
deleted file mode 100644
index c8a90e7a564b..000000000000
--- a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java
+++ /dev/null
@@ -1,525 +0,0 @@
-/*
- * Copyright (C) 2021 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.server.biometrics.sensors;
-
-import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FACE;
-import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_UDFPS;
-import static com.android.server.biometrics.sensors.BiometricScheduler.sensorTypeToString;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.hardware.biometrics.BiometricConstants;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Slog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.biometrics.sensors.BiometricScheduler.SensorType;
-import com.android.server.biometrics.sensors.fingerprint.Udfps;
-
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Map;
-
-/**
- * Singleton that contains the core logic for determining if haptics and authentication callbacks
- * should be sent to receivers. Note that this class is used even when coex is not required (e.g.
- * single sensor devices, or multi-sensor devices where only a single sensor is authenticating).
- * This allows us to have all business logic in one testable place.
- */
-public class CoexCoordinator {
-
- private static final String TAG = "BiometricCoexCoordinator";
- public static final String SETTING_ENABLE_NAME =
- "com.android.server.biometrics.sensors.CoexCoordinator.enable";
- public static final String FACE_HAPTIC_DISABLE =
- "com.android.server.biometrics.sensors.CoexCoordinator.disable_face_haptics";
- private static final boolean DEBUG = true;
-
- // Successful authentications should be used within this amount of time.
- static final long SUCCESSFUL_AUTH_VALID_DURATION_MS = 5000;
-
- /**
- * Callback interface notifying the owner of "results" from the CoexCoordinator's business
- * logic for accept and reject.
- */
- interface Callback {
- /**
- * Requests the owner to send the result (success/reject) and any associated info to the
- * receiver (e.g. keyguard, BiometricService, etc).
- */
- void sendAuthenticationResult(boolean addAuthTokenIfStrong);
-
- /**
- * Requests the owner to initiate a vibration for this event.
- */
- void sendHapticFeedback();
-
- /**
- * Requests the owner to handle the AuthenticationClient's lifecycle (e.g. finish and remove
- * from scheduler if auth was successful).
- */
- void handleLifecycleAfterAuth();
-
- /**
- * Requests the owner to notify the caller that authentication was canceled.
- */
- void sendAuthenticationCanceled();
- }
-
- /**
- * Callback interface notifying the owner of "results" from the CoexCoordinator's business
- * logic for errors.
- */
- interface ErrorCallback {
- /**
- * Requests the owner to initiate a vibration for this event.
- */
- void sendHapticFeedback();
- }
-
- private static final CoexCoordinator sInstance = new CoexCoordinator();
-
- @VisibleForTesting
- public static class SuccessfulAuth {
- final long mAuthTimestamp;
- final @SensorType int mSensorType;
- final AuthenticationClient<?> mAuthenticationClient;
- final Callback mCallback;
- final CleanupRunnable mCleanupRunnable;
-
- public static class CleanupRunnable implements Runnable {
- @NonNull final LinkedList<SuccessfulAuth> mSuccessfulAuths;
- @NonNull final SuccessfulAuth mAuth;
- @NonNull final Callback mCallback;
-
- public CleanupRunnable(@NonNull LinkedList<SuccessfulAuth> successfulAuths,
- @NonNull SuccessfulAuth auth, @NonNull Callback callback) {
- mSuccessfulAuths = successfulAuths;
- mAuth = auth;
- mCallback = callback;
- }
-
- @Override
- public void run() {
- final boolean removed = mSuccessfulAuths.remove(mAuth);
- Slog.w(TAG, "Removing stale successfulAuth: " + mAuth.toString()
- + ", success: " + removed);
- mCallback.handleLifecycleAfterAuth();
- }
- }
-
- public SuccessfulAuth(@NonNull Handler handler,
- @NonNull LinkedList<SuccessfulAuth> successfulAuths,
- long currentTimeMillis,
- @SensorType int sensorType,
- @NonNull AuthenticationClient<?> authenticationClient,
- @NonNull Callback callback) {
- mAuthTimestamp = currentTimeMillis;
- mSensorType = sensorType;
- mAuthenticationClient = authenticationClient;
- mCallback = callback;
-
- mCleanupRunnable = new CleanupRunnable(successfulAuths, this, callback);
-
- handler.postDelayed(mCleanupRunnable, SUCCESSFUL_AUTH_VALID_DURATION_MS);
- }
-
- @Override
- public String toString() {
- return "SensorType: " + sensorTypeToString(mSensorType)
- + ", mAuthTimestamp: " + mAuthTimestamp
- + ", authenticationClient: " + mAuthenticationClient;
- }
- }
-
- /** The singleton instance. */
- @NonNull
- public static CoexCoordinator getInstance() {
- return sInstance;
- }
-
- @VisibleForTesting
- public void setAdvancedLogicEnabled(boolean enabled) {
- mAdvancedLogicEnabled = enabled;
- }
-
- public void setFaceHapticDisabledWhenNonBypass(boolean disabled) {
- mFaceHapticDisabledWhenNonBypass = disabled;
- }
-
- @VisibleForTesting
- void reset() {
- mClientMap.clear();
- }
-
- // SensorType to AuthenticationClient map
- private final Map<Integer, AuthenticationClient<?>> mClientMap = new HashMap<>();
- @VisibleForTesting final LinkedList<SuccessfulAuth> mSuccessfulAuths = new LinkedList<>();
- private boolean mAdvancedLogicEnabled;
- private boolean mFaceHapticDisabledWhenNonBypass;
- private final Handler mHandler = new Handler(Looper.getMainLooper());
-
- private CoexCoordinator() {}
-
- public void addAuthenticationClient(@BiometricScheduler.SensorType int sensorType,
- @NonNull AuthenticationClient<?> client) {
- if (DEBUG) {
- Slog.d(TAG, "addAuthenticationClient(" + sensorTypeToString(sensorType) + ")"
- + ", client: " + client);
- }
-
- if (mClientMap.containsKey(sensorType)) {
- Slog.w(TAG, "Overwriting existing client: " + mClientMap.get(sensorType)
- + " with new client: " + client);
- }
-
- mClientMap.put(sensorType, client);
- }
-
- public void removeAuthenticationClient(@BiometricScheduler.SensorType int sensorType,
- @NonNull AuthenticationClient<?> client) {
- if (DEBUG) {
- Slog.d(TAG, "removeAuthenticationClient(" + sensorTypeToString(sensorType) + ")"
- + ", client: " + client);
- }
-
- if (!mClientMap.containsKey(sensorType)) {
- Slog.e(TAG, "sensorType: " + sensorType + " does not exist in map. Client: " + client);
- return;
- }
- mClientMap.remove(sensorType);
- }
-
- /**
- * Notify the coordinator that authentication succeeded (accepted)
- */
- public void onAuthenticationSucceeded(long currentTimeMillis,
- @NonNull AuthenticationClient<?> client,
- @NonNull Callback callback) {
- final boolean isUsingSingleModality = isSingleAuthOnly(client);
-
- if (client.isBiometricPrompt()) {
- if (!isUsingSingleModality && hasMultipleSuccessfulAuthentications()) {
- // only send feedback on the first one
- } else {
- callback.sendHapticFeedback();
- }
- // For BP, BiometricService will add the authToken to Keystore.
- callback.sendAuthenticationResult(false /* addAuthTokenIfStrong */);
- callback.handleLifecycleAfterAuth();
- } else if (isUnknownClient(client)) {
- // Client doesn't exist in our map for some reason. Give the user feedback so the
- // device doesn't feel like it's stuck. All other cases below can assume that the
- // client exists in our map.
- callback.sendHapticFeedback();
- callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
- callback.handleLifecycleAfterAuth();
- } else if (mAdvancedLogicEnabled && client.isKeyguard()) {
- if (isUsingSingleModality) {
- // Single sensor authentication
- callback.sendHapticFeedback();
- callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
- callback.handleLifecycleAfterAuth();
- } else {
- // Multi sensor authentication
- AuthenticationClient<?> udfps = mClientMap.getOrDefault(SENSOR_TYPE_UDFPS, null);
- AuthenticationClient<?> face = mClientMap.getOrDefault(SENSOR_TYPE_FACE, null);
- if (isCurrentFaceAuth(client)) {
- if (isUdfpsActivelyAuthing(udfps)) {
- // Face auth success while UDFPS is actively authing. No callback, no haptic
- // Feedback will be provided after UDFPS result:
- // 1) UDFPS succeeds - simply remove this from the queue
- // 2) UDFPS rejected - use this face auth success to notify clients
- mSuccessfulAuths.add(new SuccessfulAuth(mHandler, mSuccessfulAuths,
- currentTimeMillis, SENSOR_TYPE_FACE, client, callback));
- } else {
- if (mFaceHapticDisabledWhenNonBypass && !face.isKeyguardBypassEnabled()) {
- Slog.w(TAG, "Skipping face success haptic");
- } else {
- callback.sendHapticFeedback();
- }
- callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
- callback.handleLifecycleAfterAuth();
- }
- } else if (isCurrentUdfps(client)) {
- if (isFaceScanning()) {
- // UDFPS succeeds while face is still scanning
- // Cancel face auth and/or prevent it from invoking haptics/callbacks after
- face.cancel();
- }
-
- removeAndFinishAllFaceFromQueue();
-
- callback.sendHapticFeedback();
- callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
- callback.handleLifecycleAfterAuth();
- } else {
- // Capacitive fingerprint sensor (or other)
- callback.sendHapticFeedback();
- callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
- callback.handleLifecycleAfterAuth();
- }
- }
- } else {
- // Non-keyguard authentication. For example, Fingerprint Settings use of
- // FingerprintManager for highlighting fingers
- callback.sendHapticFeedback();
- callback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
- callback.handleLifecycleAfterAuth();
- }
- }
-
- /**
- * Notify the coordinator that a rejection has occurred.
- */
- public void onAuthenticationRejected(long currentTimeMillis,
- @NonNull AuthenticationClient<?> client,
- @LockoutTracker.LockoutMode int lockoutMode,
- @NonNull Callback callback) {
- final boolean isUsingSingleModality = isSingleAuthOnly(client);
-
- if (mAdvancedLogicEnabled && client.isKeyguard()) {
- if (isUsingSingleModality) {
- callback.sendHapticFeedback();
- callback.handleLifecycleAfterAuth();
- } else {
- // Multi sensor authentication
- AuthenticationClient<?> udfps = mClientMap.getOrDefault(SENSOR_TYPE_UDFPS, null);
- AuthenticationClient<?> face = mClientMap.getOrDefault(SENSOR_TYPE_FACE, null);
- if (isCurrentFaceAuth(client)) {
- if (isUdfpsActivelyAuthing(udfps)) {
- // UDFPS should still be running in this case, do not vibrate. However, we
- // should notify the callback and finish the client, so that Keyguard and
- // BiometricScheduler do not get stuck.
- Slog.d(TAG, "Face rejected in multi-sensor auth, udfps: " + udfps);
- callback.handleLifecycleAfterAuth();
- } else if (isUdfpsAuthAttempted(udfps)) {
- // If UDFPS is STATE_STARTED_PAUSED (e.g. finger rejected but can still
- // auth after pointer goes down, it means UDFPS encountered a rejection. In
- // this case, we need to play the final reject haptic since face auth is
- // also done now.
- callback.sendHapticFeedback();
- callback.handleLifecycleAfterAuth();
- } else {
- // UDFPS auth has never been attempted.
- if (mFaceHapticDisabledWhenNonBypass && !face.isKeyguardBypassEnabled()) {
- Slog.w(TAG, "Skipping face reject haptic");
- } else {
- callback.sendHapticFeedback();
- }
- callback.handleLifecycleAfterAuth();
- }
- } else if (isCurrentUdfps(client)) {
- // Face should either be running, or have already finished
- SuccessfulAuth auth = popSuccessfulFaceAuthIfExists(currentTimeMillis);
- if (auth != null) {
- Slog.d(TAG, "Using recent auth: " + auth);
- callback.handleLifecycleAfterAuth();
-
- auth.mCallback.sendHapticFeedback();
- auth.mCallback.sendAuthenticationResult(true /* addAuthTokenIfStrong */);
- auth.mCallback.handleLifecycleAfterAuth();
- } else {
- Slog.d(TAG, "UDFPS rejected in multi-sensor auth");
- callback.sendHapticFeedback();
- callback.handleLifecycleAfterAuth();
- }
- } else {
- Slog.d(TAG, "Unknown client rejected: " + client);
- callback.sendHapticFeedback();
- callback.handleLifecycleAfterAuth();
- }
- }
- } else if (client.isBiometricPrompt() && !isUsingSingleModality) {
- if (!isCurrentFaceAuth(client)) {
- callback.sendHapticFeedback();
- }
- callback.handleLifecycleAfterAuth();
- } else {
- callback.sendHapticFeedback();
- callback.handleLifecycleAfterAuth();
- }
-
- // Always notify keyguard, otherwise the cached "running" state in KeyguardUpdateMonitor
- // will get stuck.
- if (lockoutMode == LockoutTracker.LOCKOUT_NONE) {
- // Don't send onAuthenticationFailed if we're in lockout, it causes a
- // janky UI on Keyguard/BiometricPrompt since "authentication failed"
- // will show briefly and be replaced by "device locked out" message.
- callback.sendAuthenticationResult(false /* addAuthTokenIfStrong */);
- }
- }
-
- /**
- * Notify the coordinator that an error has occurred.
- */
- public void onAuthenticationError(@NonNull AuthenticationClient<?> client,
- @BiometricConstants.Errors int error, @NonNull ErrorCallback callback) {
- final boolean isUsingSingleModality = isSingleAuthOnly(client);
-
- // Figure out non-coex state
- final boolean shouldUsuallyVibrate;
- if (isCurrentFaceAuth(client)) {
- final boolean notDetectedOnKeyguard = client.isKeyguard() && !client.wasUserDetected();
- final boolean authAttempted = client.wasAuthAttempted();
-
- switch (error) {
- case BiometricConstants.BIOMETRIC_ERROR_TIMEOUT:
- case BiometricConstants.BIOMETRIC_ERROR_LOCKOUT:
- case BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT:
- shouldUsuallyVibrate = authAttempted && !notDetectedOnKeyguard;
- break;
- default:
- shouldUsuallyVibrate = false;
- break;
- }
- } else {
- shouldUsuallyVibrate = false;
- }
-
- // Figure out coex state
- final boolean hapticSuppressedByCoex;
- if (mAdvancedLogicEnabled && client.isKeyguard()) {
- if (isUsingSingleModality) {
- hapticSuppressedByCoex = false;
- } else {
- hapticSuppressedByCoex = isCurrentFaceAuth(client)
- && !client.isKeyguardBypassEnabled();
- }
- } else if (client.isBiometricPrompt() && !isUsingSingleModality) {
- hapticSuppressedByCoex = isCurrentFaceAuth(client);
- } else {
- hapticSuppressedByCoex = false;
- }
-
- // Combine and send feedback if appropriate
- if (shouldUsuallyVibrate && !hapticSuppressedByCoex) {
- callback.sendHapticFeedback();
- } else {
- Slog.v(TAG, "no haptic shouldUsuallyVibrate: " + shouldUsuallyVibrate
- + ", hapticSuppressedByCoex: " + hapticSuppressedByCoex);
- }
- }
-
- @Nullable
- private SuccessfulAuth popSuccessfulFaceAuthIfExists(long currentTimeMillis) {
- for (SuccessfulAuth auth : mSuccessfulAuths) {
- if (currentTimeMillis - auth.mAuthTimestamp >= SUCCESSFUL_AUTH_VALID_DURATION_MS) {
- // TODO(b/193089985): This removes the auth but does not notify the client with
- // an appropriate lifecycle event (such as ERROR_CANCELED), and violates the
- // API contract. However, this might be OK for now since the validity duration
- // is way longer than the time it takes to auth with fingerprint.
- Slog.e(TAG, "Removing stale auth: " + auth);
- mSuccessfulAuths.remove(auth);
- } else if (auth.mSensorType == SENSOR_TYPE_FACE) {
- mSuccessfulAuths.remove(auth);
- return auth;
- }
- }
- return null;
- }
-
- private void removeAndFinishAllFaceFromQueue() {
- // Note that these auth are all successful, but have never notified the client (e.g.
- // keyguard). To comply with the authentication lifecycle, we must notify the client that
- // auth is "done". The safest thing to do is to send ERROR_CANCELED.
- for (SuccessfulAuth auth : mSuccessfulAuths) {
- if (auth.mSensorType == SENSOR_TYPE_FACE) {
- Slog.d(TAG, "Removing from queue, canceling, and finishing: " + auth);
- auth.mCallback.sendAuthenticationCanceled();
- auth.mCallback.handleLifecycleAfterAuth();
- mSuccessfulAuths.remove(auth);
- }
- }
- }
-
- private boolean isCurrentFaceAuth(@NonNull AuthenticationClient<?> client) {
- return client == mClientMap.getOrDefault(SENSOR_TYPE_FACE, null);
- }
-
- private boolean isCurrentUdfps(@NonNull AuthenticationClient<?> client) {
- return client == mClientMap.getOrDefault(SENSOR_TYPE_UDFPS, null);
- }
-
- private boolean isFaceScanning() {
- AuthenticationClient<?> client = mClientMap.getOrDefault(SENSOR_TYPE_FACE, null);
- return client != null && client.getState() == AuthenticationClient.STATE_STARTED;
- }
-
- private static boolean isUdfpsActivelyAuthing(@Nullable AuthenticationClient<?> client) {
- if (client instanceof Udfps) {
- return client.getState() == AuthenticationClient.STATE_STARTED;
- }
- return false;
- }
-
- private static boolean isUdfpsAuthAttempted(@Nullable AuthenticationClient<?> client) {
- if (client instanceof Udfps) {
- return client.getState() == AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED;
- }
- return false;
- }
-
- private boolean isUnknownClient(@NonNull AuthenticationClient<?> client) {
- for (AuthenticationClient<?> c : mClientMap.values()) {
- if (c == client) {
- return false;
- }
- }
- return true;
- }
-
- private boolean isSingleAuthOnly(@NonNull AuthenticationClient<?> client) {
- if (mClientMap.values().size() != 1) {
- return false;
- }
-
- for (AuthenticationClient<?> c : mClientMap.values()) {
- if (c != client) {
- return false;
- }
- }
- return true;
- }
-
- private boolean hasMultipleSuccessfulAuthentications() {
- int count = 0;
- for (AuthenticationClient<?> c : mClientMap.values()) {
- if (c.wasAuthSuccessful()) {
- count++;
- }
- if (count > 1) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("Enabled: ").append(mAdvancedLogicEnabled);
- sb.append(", Face Haptic Disabled: ").append(mFaceHapticDisabledWhenNonBypass);
- sb.append(", Queue size: " ).append(mSuccessfulAuths.size());
- for (SuccessfulAuth auth : mSuccessfulAuths) {
- sb.append(", Auth: ").append(auth.toString());
- }
-
- return sb.toString();
- }
-}
diff --git a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
index ae75b7dcc101..a486d16189fa 100644
--- a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java
@@ -95,10 +95,9 @@ public class UserAwareBiometricScheduler extends BiometricScheduler {
@Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
@NonNull IBiometricService biometricService,
@NonNull CurrentUserRetriever currentUserRetriever,
- @NonNull UserSwitchCallback userSwitchCallback,
- @NonNull CoexCoordinator coexCoordinator) {
+ @NonNull UserSwitchCallback userSwitchCallback) {
super(tag, handler, sensorType, gestureAvailabilityDispatcher, biometricService,
- LOG_NUM_RECENT_OPERATIONS, coexCoordinator);
+ LOG_NUM_RECENT_OPERATIONS);
mCurrentUserRetriever = currentUserRetriever;
mUserSwitchCallback = userSwitchCallback;
@@ -112,7 +111,7 @@ public class UserAwareBiometricScheduler extends BiometricScheduler {
this(tag, new Handler(Looper.getMainLooper()), sensorType, gestureAvailabilityDispatcher,
IBiometricService.Stub.asInterface(
ServiceManager.getService(Context.BIOMETRIC_SERVICE)),
- currentUserRetriever, userSwitchCallback, CoexCoordinator.getInstance());
+ currentUserRetriever, userSwitchCallback);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index ca4b7475f7dc..e18e31ec33ea 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -274,7 +274,6 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
@Override
public void onLockoutTimed(long durationMillis) {
- super.onLockoutTimed(durationMillis);
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
// Lockout metrics are logged as an error code.
final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT;
@@ -290,7 +289,6 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
@Override
public void onLockoutPermanent() {
- super.onLockoutPermanent();
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
// Lockout metrics are logged as an error code.
final int error = BiometricFaceConstants.FACE_ERROR_LOCKOUT_PERMANENT;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index 1688f966eccd..f2c5b970d52c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -424,7 +424,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
@Override
public void onLockoutTimed(long durationMillis) {
- super.onLockoutTimed(durationMillis);
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_TIMED);
// Lockout metrics are logged as an error code.
final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT;
@@ -448,7 +447,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
@Override
public void onLockoutPermanent() {
- super.onLockoutPermanent();
mLockoutCache.setLockoutModeForUser(getTargetUserId(), LockoutTracker.LOCKOUT_PERMANENT);
// Lockout metrics are logged as an error code.
final int error = BiometricFingerprintConstants.FINGERPRINT_ERROR_LOCKOUT_PERMANENT;
diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
index 25d0752844fd..c835d2fe1bbd 100644
--- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
+++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java
@@ -116,8 +116,10 @@ public abstract class BrightnessMappingStrategy {
luxLevels = getLuxLevels(resources.getIntArray(
com.android.internal.R.array.config_autoBrightnessLevelsIdle));
} else {
- brightnessLevelsNits = displayDeviceConfig.getAutoBrightnessBrighteningLevelsNits();
- luxLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevelsLux();
+ brightnessLevelsNits = getFloatArray(resources.obtainTypedArray(
+ com.android.internal.R.array.config_autoBrightnessDisplayValuesNits));
+ luxLevels = getLuxLevels(resources.getIntArray(
+ com.android.internal.R.array.config_autoBrightnessLevels));
}
// Display independent, mode independent values
diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
index 3b627ef6a786..4f3fd6409cd8 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java
@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.content.res.TypedArray;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation;
import android.os.Environment;
@@ -150,22 +149,12 @@ import javax.xml.datatype.DatatypeConfigurationException;
* </quirks>
*
* <autoBrightness>
- * <brighteningLightDebounceMillis>
+ * <brighteningLightDebounceMillis>
* 2000
- * </brighteningLightDebounceMillis>
+ * </brighteningLightDebounceMillis>
* <darkeningLightDebounceMillis>
* 1000
* </darkeningLightDebounceMillis>
- * <displayBrightnessMapping>
- * <displayBrightnessPoint>
- * <lux>50</lux>
- * <nits>45</nits>
- * </displayBrightnessPoint>
- * <displayBrightnessPoint>
- * <lux>80</lux>
- * <nits>75</nits>
- * </displayBrightnessPoint>
- * </displayBrightnessMapping>
* </autoBrightness>
*
* <screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease>
@@ -279,39 +268,6 @@ public class DisplayDeviceConfig {
// for the corresponding values above
private float[] mBrightness;
-
- /**
- * Array of desired screen brightness in nits corresponding to the lux values
- * in the mBrightnessLevelsLux array. The display brightness is defined as the
- * measured brightness of an all-white image. The brightness values must be non-negative and
- * non-decreasing. This must be overridden in platform specific overlays
- */
- private float[] mBrightnessLevelsNits;
-
- /**
- * Array of light sensor lux values to define our levels for auto backlight
- * brightness support.
- * The N entries of this array define N + 1 control points as follows:
- * (1-based arrays)
- *
- * Point 1: (0, value[1]): lux <= 0
- * Point 2: (level[1], value[2]): 0 < lux <= level[1]
- * Point 3: (level[2], value[3]): level[2] < lux <= level[3]
- * ...
- * Point N+1: (level[N], value[N+1]): level[N] < lux
- *
- * The control points must be strictly increasing. Each control point
- * corresponds to an entry in the brightness backlight values arrays.
- * For example, if lux == level[1] (first element of the levels array)
- * then the brightness will be determined by value[2] (second element
- * of the brightness values array).
- *
- * Spline interpolation is used to determine the auto-brightness
- * backlight values for lux levels between these control points.
- *
- */
- private float[] mBrightnessLevelsLux;
-
private float mBacklightMinimum = Float.NaN;
private float mBacklightMaximum = Float.NaN;
private float mBrightnessDefault = Float.NaN;
@@ -705,20 +661,6 @@ public class DisplayDeviceConfig {
return mAutoBrightnessBrighteningLightDebounce;
}
- /**
- * @return Auto brightness brightening ambient lux levels
- */
- public float[] getAutoBrightnessBrighteningLevelsLux() {
- return mBrightnessLevelsLux;
- }
-
- /**
- * @return Auto brightness brightening nits levels
- */
- public float[] getAutoBrightnessBrighteningLevelsNits() {
- return mBrightnessLevelsNits;
- }
-
@Override
public String toString() {
return "DisplayDeviceConfig{"
@@ -761,8 +703,6 @@ public class DisplayDeviceConfig {
+ mAutoBrightnessBrighteningLightDebounce
+ ", mAutoBrightnessDarkeningLightDebounce= "
+ mAutoBrightnessDarkeningLightDebounce
- + ", mBrightnessLevelsLux= " + Arrays.toString(mBrightnessLevelsLux)
- + ", mBrightnessLevelsNits= " + Arrays.toString(mBrightnessLevelsNits)
+ "}";
}
@@ -839,7 +779,6 @@ public class DisplayDeviceConfig {
loadBrightnessRampsFromConfigXml();
loadAmbientLightSensorFromConfigXml();
setProxSensorUnspecified();
- loadAutoBrightnessConfigsFromConfigXml();
mLoadedFrom = "<config.xml>";
}
@@ -1052,7 +991,6 @@ public class DisplayDeviceConfig {
private void loadAutoBrightnessConfigValues(DisplayConfiguration config) {
loadAutoBrightnessBrighteningLightDebounce(config.getAutoBrightness());
loadAutoBrightnessDarkeningLightDebounce(config.getAutoBrightness());
- loadAutoBrightnessDisplayBrightnessMapping(config.getAutoBrightness());
}
/**
@@ -1085,33 +1023,6 @@ public class DisplayDeviceConfig {
}
}
- /**
- * Loads the auto-brightness display brightness mappings. Internally, this takes care of
- * loading the value from the display config, and if not present, falls back to config.xml.
- */
- private void loadAutoBrightnessDisplayBrightnessMapping(AutoBrightness autoBrightnessConfig) {
- if (autoBrightnessConfig == null
- || autoBrightnessConfig.getDisplayBrightnessMapping() == null) {
- mBrightnessLevelsNits = getFloatArray(mContext.getResources()
- .obtainTypedArray(com.android.internal.R.array
- .config_autoBrightnessDisplayValuesNits));
- mBrightnessLevelsLux = getFloatArray(mContext.getResources()
- .obtainTypedArray(com.android.internal.R.array
- .config_autoBrightnessLevels));
- } else {
- final int size = autoBrightnessConfig.getDisplayBrightnessMapping()
- .getDisplayBrightnessPoint().size();
- mBrightnessLevelsNits = new float[size];
- mBrightnessLevelsLux = new float[size];
- for (int i = 0; i < size; i++) {
- mBrightnessLevelsNits[i] = autoBrightnessConfig.getDisplayBrightnessMapping()
- .getDisplayBrightnessPoint().get(i).getNits().floatValue();
- mBrightnessLevelsLux[i] = autoBrightnessConfig.getDisplayBrightnessMapping()
- .getDisplayBrightnessPoint().get(i).getLux().floatValue();
- }
- }
- }
-
private void loadBrightnessMapFromConfigXml() {
// Use the config.xml mapping
final Resources res = mContext.getResources();
@@ -1337,10 +1248,6 @@ public class DisplayDeviceConfig {
com.android.internal.R.string.config_displayLightSensorType);
}
- private void loadAutoBrightnessConfigsFromConfigXml() {
- loadAutoBrightnessDisplayBrightnessMapping(null /*AutoBrightnessConfig*/);
- }
-
private void loadAmbientLightSensorFromDdc(DisplayConfiguration config) {
final SensorDetails sensorDetails = config.getLightSensor();
if (sensorDetails != null) {
@@ -1483,22 +1390,6 @@ public class DisplayDeviceConfig {
}
}
- /**
- * Extracts a float array from the specified {@link TypedArray}.
- *
- * @param array The array to convert.
- * @return the given array as a float array.
- */
- public static float[] getFloatArray(TypedArray array) {
- final int n = array.length();
- float[] vals = new float[n];
- for (int i = 0; i < n; i++) {
- vals[i] = array.getFloat(i, PowerManager.BRIGHTNESS_OFF_FLOAT);
- }
- array.recycle();
- return vals;
- }
-
static class SensorData {
public String type;
public String name;
diff --git a/services/core/java/com/android/server/logcat/OWNERS b/services/core/java/com/android/server/logcat/OWNERS
index 9588fa9d1f8e..87d30f3dd537 100644
--- a/services/core/java/com/android/server/logcat/OWNERS
+++ b/services/core/java/com/android/server/logcat/OWNERS
@@ -1,5 +1,7 @@
cbrubaker@google.com
eunjeongshin@google.com
+georgechan@google.com
jsharkey@google.com
vishwath@google.com
wenhaowang@google.com
+xiaozhenl@google.com
diff --git a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
index c12dc8e9e92e..a5c762a1df0b 100644
--- a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
+++ b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java
@@ -119,7 +119,7 @@ final class MediaButtonReceiverHolder {
ComponentName componentName = getComponentName(pendingIntent, componentType);
if (componentName != null) {
if (!TextUtils.equals(componentName.getPackageName(), sessionPackageName)) {
- EventLog.writeEvent(0x534e4554, "238177121", -1, ""); // SafetyNet Logging.
+ EventLog.writeEvent(0x534e4554, "238177121", -1, "");
throw new IllegalArgumentException("ComponentName does not belong to "
+ "sessionPackageName. sessionPackageName = " + sessionPackageName
+ ", ComponentName pkg = " + componentName.getPackageName());
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 4f8771a3ddef..1ee9a873fff9 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -914,7 +914,16 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
}
@Override
- public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException {
+ public void setMediaButtonReceiver(PendingIntent pi, String sessionPackageName)
+ throws RemoteException {
+ //mPackageName has been verified in MediaSessionService.enforcePackageName().
+ if (!TextUtils.equals(sessionPackageName, mPackageName)) {
+ EventLog.writeEvent(0x534e4554, "238177121", -1, "");
+ throw new IllegalArgumentException("sessionPackageName name does not match "
+ + "package name provided to MediaSessionRecord. sessionPackageName = "
+ + sessionPackageName + ", pkg = "
+ + mPackageName);
+ }
final long token = Binder.clearCallingIdentity();
try {
if ((mPolicies & MediaSessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER)
@@ -922,7 +931,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
return;
}
mMediaButtonReceiverHolder =
- MediaButtonReceiverHolder.create(mContext, mUserId, pi, mPackageName);
+ MediaButtonReceiverHolder.create(mContext, mUserId, pi, sessionPackageName);
mService.onMediaButtonReceiverChanged(MediaSessionRecord.this);
} finally {
Binder.restoreCallingIdentity(token);
@@ -936,7 +945,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
//mPackageName has been verified in MediaSessionService.enforcePackageName().
if (receiver != null && !TextUtils.equals(
mPackageName, receiver.getPackageName())) {
- EventLog.writeEvent(0x534e4554, "238177121", -1, ""); // SafetyNet Logging.
+ EventLog.writeEvent(0x534e4554, "238177121", -1, "");
throw new IllegalArgumentException("receiver does not belong to "
+ "package name provided to MediaSessionRecord. Pkg = " + mPackageName
+ ", Receiver Pkg = " + receiver.getPackageName());
diff --git a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
index 09035cd1d165..15c9ba923d3a 100644
--- a/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
+++ b/services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewareValidation.java
@@ -37,6 +37,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.util.Log;
+import android.util.SparseArray;
import com.android.internal.util.Preconditions;
@@ -829,17 +830,41 @@ public class SoundTriggerMiddlewareValidation implements ISoundTriggerMiddleware
@Override
public void binderDied() {
// This is called whenever our client process dies.
+ SparseArray<ModelState.Activity> cachedMap =
+ new SparseArray<ModelState.Activity>();
synchronized (SoundTriggerMiddlewareValidation.this) {
- try {
- // Gracefully stop all active recognitions and unload the models.
+ // Copy the relevant state under the lock, so we can call back without
+ // holding a lock. This exposes us to a potential race, but the client is
+ // dead so we don't expect one.
+ // TODO(240613068) A more resilient fix for this.
for (Map.Entry<Integer, ModelState> entry :
mLoadedModels.entrySet()) {
- if (entry.getValue().activityState == ModelState.Activity.ACTIVE) {
- mDelegate.stopRecognition(entry.getKey());
- }
- mDelegate.unloadModel(entry.getKey());
+ cachedMap.put(entry.getKey(), entry.getValue().activityState);
+ }
+ }
+ try {
+ // Gracefully stop all active recognitions and unload the models.
+ for (int i = 0; i < cachedMap.size(); i++) {
+ if (cachedMap.valueAt(i) == ModelState.Activity.ACTIVE) {
+ mDelegate.stopRecognition(cachedMap.keyAt(i));
}
- // Detach.
+ mDelegate.unloadModel(cachedMap.keyAt(i));
+ }
+ } catch (Exception e) {
+ throw handleException(e);
+ }
+ synchronized (SoundTriggerMiddlewareValidation.this) {
+ // Check if state updated unexpectedly to log race conditions.
+ for (Map.Entry<Integer, ModelState> entry : mLoadedModels.entrySet()) {
+ if (cachedMap.get(entry.getKey()) != entry.getValue().activityState) {
+ Log.e(TAG, "Unexpected state update in binderDied. Race occurred!");
+ }
+ }
+ if (mLoadedModels.size() != cachedMap.size()) {
+ Log.e(TAG, "Unexpected state update in binderDied. Race occurred!");
+ }
+ try {
+ // Detach
detachInternal();
} catch (Exception e) {
throw handleException(e);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index f8f94f655a16..58e1d053d433 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1582,13 +1582,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
if (newParent != null && isState(RESUMED)) {
newParent.setResumedActivity(this, "onParentChanged");
- if (mStartingWindow != null && mStartingData != null
- && mStartingData.mAssociatedTask == null && newParent.isEmbedded()) {
- // The starting window should keep covering its task when the activity is
- // reparented to a task fragment that may not fill the task bounds.
- associateStartingDataWithTask();
- attachStartingSurfaceToAssociatedTask();
- }
mImeInsetsFrozenUntilStartInput = false;
}
@@ -2679,14 +2672,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
}
+ /** Called when the starting window is added to this activity. */
void attachStartingWindow(@NonNull WindowState startingWindow) {
startingWindow.mStartingData = mStartingData;
mStartingWindow = startingWindow;
+ // The snapshot type may have called associateStartingDataWithTask().
if (mStartingData != null && mStartingData.mAssociatedTask != null) {
attachStartingSurfaceToAssociatedTask();
}
}
+ /** Makes starting window always fill the associated task. */
private void attachStartingSurfaceToAssociatedTask() {
// Associate the configuration of starting window with the task.
overrideConfigurationPropagation(mStartingWindow, mStartingData.mAssociatedTask);
@@ -2694,6 +2690,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mStartingData.mAssociatedTask.mSurfaceControl);
}
+ /** Called when the starting window is not added yet but its data is known to fill the task. */
private void associateStartingDataWithTask() {
mStartingData.mAssociatedTask = task;
task.forAllActivities(r -> {
@@ -2703,6 +2700,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
});
}
+ /** Associates and attaches an added starting window to the current task. */
+ void associateStartingWindowWithTaskIfNeeded() {
+ if (mStartingWindow == null || mStartingData == null
+ || mStartingData.mAssociatedTask != null) {
+ return;
+ }
+ associateStartingDataWithTask();
+ attachStartingSurfaceToAssociatedTask();
+ }
+
void removeStartingWindow() {
boolean prevEligibleForLetterboxEducation = isEligibleForLetterboxEducation();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 1c90bbae79ec..6ee018606d71 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3188,8 +3188,12 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
mPointerEventDispatcher.dispose();
setRotationAnimation(null);
+ // Unlink death from remote to clear the reference from binder -> mRemoteInsetsDeath
+ // -> this DisplayContent.
+ setRemoteInsetsController(null);
mWmService.mAnimator.removeDisplayLocked(mDisplayId);
mOverlayLayer.release();
+ mWindowingLayer.release();
mInputMonitor.onDisplayRemoved();
mWmService.mDisplayNotificationController.dispatchDisplayRemoved(this);
mWmService.mAccessibilityController.onDisplayRemoved(mDisplayId);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index e38f5fe61888..de135a34c3df 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1436,6 +1436,13 @@ class Task extends TaskFragment {
final TaskFragment childTaskFrag = child.asTaskFragment();
if (childTaskFrag != null && childTaskFrag.asTask() == null) {
childTaskFrag.setMinDimensions(mMinWidth, mMinHeight);
+
+ // The starting window should keep covering its task when a pure TaskFragment is added
+ // because its bounds may not fill the task.
+ final ActivityRecord top = getTopMostActivity();
+ if (top != null) {
+ top.associateStartingWindowWithTaskIfNeeded();
+ }
}
}
diff --git a/services/core/xsd/display-device-config/autobrightness.xsd b/services/core/xsd/display-device-config/autobrightness.xsd
new file mode 100644
index 000000000000..477625a36cbd
--- /dev/null
+++ b/services/core/xsd/display-device-config/autobrightness.xsd
@@ -0,0 +1,33 @@
+<!--
+ 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.
+-->
+<xs:schema version="2.0"
+ elementFormDefault="qualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType name="autoBrightness">
+ <xs:sequence>
+ <!-- Sets the debounce for autoBrightness brightening in millis-->
+ <xs:element name="brighteningLightDebounceMillis" type="xs:nonNegativeInteger"
+ minOccurs="0" maxOccurs="1">
+ <xs:annotation name="final"/>
+ </xs:element>
+ <!-- Sets the debounce for autoBrightness darkening in millis-->
+ <xs:element name="darkeningLightDebounceMillis" type="xs:nonNegativeInteger"
+ minOccurs="0" maxOccurs="1">
+ <xs:annotation name="final"/>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+</xs:schema> \ No newline at end of file
diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd
index 98f83d8c0d09..bea5e2c2de74 100644
--- a/services/core/xsd/display-device-config/display-device-config.xsd
+++ b/services/core/xsd/display-device-config/display-device-config.xsd
@@ -23,6 +23,7 @@
<xs:schema version="2.0"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:include schemaLocation="autobrightness.xsd" />
<xs:element name="displayConfiguration">
<xs:complexType>
<xs:sequence>
@@ -342,74 +343,4 @@
<xs:annotation name="final"/>
</xs:element>
</xs:complexType>
-
- <xs:complexType name="autoBrightness">
- <xs:sequence>
- <!-- Sets the debounce for autoBrightness brightening in millis-->
- <xs:element name="brighteningLightDebounceMillis" type="xs:nonNegativeInteger"
- minOccurs="0" maxOccurs="1">
- <xs:annotation name="final"/>
- </xs:element>
- <!-- Sets the debounce for autoBrightness darkening in millis-->
- <xs:element name="darkeningLightDebounceMillis" type="xs:nonNegativeInteger"
- minOccurs="0" maxOccurs="1">
- <xs:annotation name="final"/>
- </xs:element>
- <!-- Sets the brightness mapping of the desired screen brightness in nits to the
- corresponding lux for the current display -->
- <xs:element name="displayBrightnessMapping" type="displayBrightnessMapping"
- minOccurs="0" maxOccurs="1">
- <xs:annotation name="final"/>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
-
- <!-- Represents the brightness mapping of the desired screen brightness in nits to the
- corresponding lux for the current display -->
- <xs:complexType name="displayBrightnessMapping">
- <xs:sequence>
- <!-- Sets the list of display brightness points, each representing the desired screen
- brightness in nits to the corresponding lux for the current display
-
- The N entries of this array define N + 1 control points as follows:
- (1-based arrays)
-
- Point 1: (0, nits[1]): currentLux <= 0
- Point 2: (lux[1], nits[2]): 0 < currentLux <= lux[1]
- Point 3: (lux[2], nits[3]): lux[2] < currentLux <= lux[3]
- ...
- Point N+1: (lux[N], nits[N+1]): lux[N] < currentLux
-
- The control points must be strictly increasing. Each control point
- corresponds to an entry in the brightness backlight values arrays.
- For example, if currentLux == lux[1] (first element of the levels array)
- then the brightness will be determined by nits[2] (second element
- of the brightness values array).
- -->
- <xs:element name="displayBrightnessPoint" type="displayBrightnessPoint"
- minOccurs="1" maxOccurs="unbounded">
- <xs:annotation name="final"/>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
-
- <!-- Represents a point in the display brightness mapping, representing the lux level from the
- light sensor to the desired screen brightness in nits at this level -->
- <xs:complexType name="displayBrightnessPoint">
- <xs:sequence>
- <!-- The lux level from the light sensor. This must be a non-negative integer -->
- <xs:element name="lux" type="xs:nonNegativeInteger"
- minOccurs="1" maxOccurs="1">
- <xs:annotation name="final"/>
- </xs:element>
-
- <!-- Desired screen brightness in nits corresponding to the suggested lux values.
- The display brightness is defined as the measured brightness of an all-white image.
- This must be a non-negative integer -->
- <xs:element name="nits" type="xs:nonNegativeInteger"
- minOccurs="1" maxOccurs="1">
- <xs:annotation name="final"/>
- </xs:element>
- </xs:sequence>
- </xs:complexType>
</xs:schema>
diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt
index e5d26177b725..e9a926946764 100644
--- a/services/core/xsd/display-device-config/schema/current.txt
+++ b/services/core/xsd/display-device-config/schema/current.txt
@@ -5,10 +5,8 @@ package com.android.server.display.config {
ctor public AutoBrightness();
method public final java.math.BigInteger getBrighteningLightDebounceMillis();
method public final java.math.BigInteger getDarkeningLightDebounceMillis();
- method public final com.android.server.display.config.DisplayBrightnessMapping getDisplayBrightnessMapping();
method public final void setBrighteningLightDebounceMillis(java.math.BigInteger);
method public final void setDarkeningLightDebounceMillis(java.math.BigInteger);
- method public final void setDisplayBrightnessMapping(com.android.server.display.config.DisplayBrightnessMapping);
}
public class BrightnessThresholds {
@@ -45,19 +43,6 @@ package com.android.server.display.config {
method public java.util.List<com.android.server.display.config.Density> getDensity();
}
- public class DisplayBrightnessMapping {
- ctor public DisplayBrightnessMapping();
- method public final java.util.List<com.android.server.display.config.DisplayBrightnessPoint> getDisplayBrightnessPoint();
- }
-
- public class DisplayBrightnessPoint {
- ctor public DisplayBrightnessPoint();
- method public final java.math.BigInteger getLux();
- method public final java.math.BigInteger getNits();
- method public final void setLux(java.math.BigInteger);
- method public final void setNits(java.math.BigInteger);
- }
-
public class DisplayConfiguration {
ctor public DisplayConfiguration();
method @NonNull public final com.android.server.display.config.Thresholds getAmbientBrightnessChangeThresholds();
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java
index 03eff2a1831b..e170e98dd747 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceControllerTest.java
@@ -258,7 +258,7 @@ public final class GameServiceControllerTest {
PROVIDER_A_SERVICE_A,
PROVIDER_A_SERVICE_C));
FakeGameServiceProviderInstance instanceB =
- seedConfigurationForUser(USER_10, configurationA);
+ seedConfigurationForUser(USER_10, configurationB);
Intent intent = new Intent();
intent.setData(Uri.parse("package:" + PROVIDER_A_PACKAGE_NAME));
broadcastReceiverArgumentCaptor.getValue().onReceive(mMockContext, intent);
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
index e4f9eaf091e9..3f16a98c81c9 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameServiceProviderInstanceImplTest.java
@@ -28,7 +28,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -36,7 +35,6 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
-import android.Manifest;
import android.annotation.Nullable;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManagerInternal;
@@ -98,7 +96,6 @@ import org.mockito.quality.Strictness;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Objects;
import java.util.function.Consumer;
@@ -361,7 +358,6 @@ public final class GameServiceProviderInstanceImplTest {
throws Exception {
mGameServiceProviderInstance.start();
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
assertThat(mFakeGameSessionService.getCapturedCreateInvocations()).isEmpty();
@@ -383,7 +379,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSessionService.CapturedCreateInvocation capturedCreateInvocation =
@@ -398,7 +393,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
dispatchTaskCreated(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
assertThat(mFakeGameSessionService.getCapturedCreateInvocations()).isEmpty();
@@ -408,7 +402,6 @@ public final class GameServiceProviderInstanceImplTest {
public void gameTaskStartedAndSessionRequested_createsGameSession() throws Exception {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -426,9 +419,7 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
CreateGameSessionRequest expectedCreateGameSessionRequest = new CreateGameSessionRequest(10,
@@ -442,7 +433,6 @@ public final class GameServiceProviderInstanceImplTest {
public void gameSessionSuccessfullyCreated_createsTaskOverlay() throws Exception {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -462,7 +452,6 @@ public final class GameServiceProviderInstanceImplTest {
startTask(10, GAME_A_MAIN_ACTIVITY);
startProcessForPackage(gameProcessId, GAME_A_PACKAGE);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -488,7 +477,6 @@ public final class GameServiceProviderInstanceImplTest {
startTask(11, GAME_A_MAIN_ACTIVITY);
startProcessForPackage(gameProcessId, GAME_A_PACKAGE);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
mFakeGameService.requestCreateGameSession(11);
@@ -522,7 +510,6 @@ public final class GameServiceProviderInstanceImplTest {
startProcessForPackage(firstGameProcessId, GAME_A_PACKAGE);
startProcessForPackage(secondGameProcessId, GAME_A_PACKAGE);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -551,7 +538,6 @@ public final class GameServiceProviderInstanceImplTest {
startTask(10, GAME_A_MAIN_ACTIVITY);
startProcessForPackage(firstGameProcessId, GAME_A_PACKAGE);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -583,7 +569,6 @@ public final class GameServiceProviderInstanceImplTest {
startTask(11, GAME_A_MAIN_ACTIVITY);
startProcessForPackage(firstGameProcessId, GAME_A_PACKAGE);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
mFakeGameService.requestCreateGameSession(11);
@@ -624,7 +609,6 @@ public final class GameServiceProviderInstanceImplTest {
startTask(10, GAME_A_MAIN_ACTIVITY);
startProcessForPackage(gameProcessId, GAME_A_PACKAGE);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
// No game session should be created.
assertThat(mFakeGameSessionService.getCapturedCreateInvocations()).isEmpty();
@@ -636,7 +620,6 @@ public final class GameServiceProviderInstanceImplTest {
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -677,7 +660,6 @@ public final class GameServiceProviderInstanceImplTest {
public void systemBarsTransientShownDueToGesture_hasGameSession_propagatesToGameSession() {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -699,7 +681,6 @@ public final class GameServiceProviderInstanceImplTest {
public void systemBarsTransientShownButNotGesture_hasGameSession_notPropagatedToGameSession() {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -721,7 +702,6 @@ public final class GameServiceProviderInstanceImplTest {
public void gameTaskFocused_propagatedToGameSession() throws Exception {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -747,7 +727,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -764,7 +743,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
dispatchTaskRemoved(10);
@@ -782,7 +760,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -800,7 +777,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -830,7 +806,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -851,7 +826,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -879,7 +853,6 @@ public final class GameServiceProviderInstanceImplTest {
startTask(10, GAME_A_MAIN_ACTIVITY);
startTask(11, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -897,7 +870,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -925,7 +897,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -955,7 +926,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -989,19 +959,10 @@ public final class GameServiceProviderInstanceImplTest {
}
@Test
- public void createGameSession_failurePermissionDenied() throws Exception {
- mGameServiceProviderInstance.start();
- startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionDenied(Manifest.permission.MANAGE_GAME_ACTIVITY);
- assertThrows(SecurityException.class, () -> mFakeGameService.requestCreateGameSession(10));
- }
-
- @Test
public void gameSessionServiceDies_severalActiveGameSessions_destroysGameSessions() {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -1030,7 +991,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -1058,7 +1018,6 @@ public final class GameServiceProviderInstanceImplTest {
public void takeScreenshot_failureNoBitmapCaptured() throws Exception {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -1093,7 +1052,6 @@ public final class GameServiceProviderInstanceImplTest {
any(), any(), any(), anyInt(), anyInt(), any(), anyInt(), any(), any());
mGameServiceProviderInstance.start();
startTask(taskId, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(taskId);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -1113,7 +1071,6 @@ public final class GameServiceProviderInstanceImplTest {
@Test
public void restartGame_taskIdAssociatedWithGame_restartsTargetGame() throws Exception {
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
Intent launchIntent = new Intent("com.test.ACTION_LAUNCH_GAME_PACKAGE")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
when(mMockPackageManager.getLaunchIntentForPackage(GAME_A_PACKAGE))
@@ -1122,7 +1079,6 @@ public final class GameServiceProviderInstanceImplTest {
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -1148,11 +1104,9 @@ public final class GameServiceProviderInstanceImplTest {
@Test
public void restartGame_taskIdNotAssociatedWithGame_noOp() throws Exception {
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mGameServiceProviderInstance.start();
startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
mFakeGameService.requestCreateGameSession(10);
FakeGameSession gameSession10 = new FakeGameSession();
@@ -1170,21 +1124,6 @@ public final class GameServiceProviderInstanceImplTest {
.restartTaskActivityProcessIfVisible(anyInt(), anyString());
}
- @Test
- public void restartGame_failurePermissionDenied() throws Exception {
- mGameServiceProviderInstance.start();
- startTask(10, GAME_A_MAIN_ACTIVITY);
- mockPermissionGranted(Manifest.permission.MANAGE_GAME_ACTIVITY);
- mFakeGameService.requestCreateGameSession(10);
- IGameSessionController gameSessionController = Objects.requireNonNull(getOnlyElement(
- mFakeGameSessionService.getCapturedCreateInvocations())).mGameSessionController;
- mockPermissionDenied(Manifest.permission.MANAGE_GAME_ACTIVITY);
- assertThrows(SecurityException.class,
- () -> gameSessionController.restartGame(10));
- verify(mActivityTaskManagerInternal, never())
- .restartTaskActivityProcessIfVisible(anyInt(), anyString());
- }
-
private void startTask(int taskId, ComponentName componentName) {
addRunningTaskInfo(taskId, componentName);
@@ -1261,14 +1200,6 @@ public final class GameServiceProviderInstanceImplTest {
}
}
- private void mockPermissionGranted(String permission) {
- mMockContext.setPermission(permission, PackageManager.PERMISSION_GRANTED);
- }
-
- private void mockPermissionDenied(String permission) {
- mMockContext.setPermission(permission, PackageManager.PERMISSION_DENIED);
- }
-
private void dispatchTaskSystemBarsEvent(
ThrowingConsumer<TaskSystemBarsListener> taskSystemBarsListenerConsumer) {
for (TaskSystemBarsListener listener : mTaskSystemBarsListeners) {
@@ -1409,42 +1340,12 @@ public final class GameServiceProviderInstanceImplTest {
}
private final class MockContext extends ContextWrapper {
- // Map of permission name -> PermissionManager.Permission_{GRANTED|DENIED} constant
- private final HashMap<String, Integer> mMockedPermissions = new HashMap<>();
-
MockContext(Context base) {
super(base);
}
-
- /**
- * Mock checks for the specified permission, and have them behave as per {@code granted}.
- *
- * <p>Passing null reverts to default behavior, which does a real permission check on the
- * test package.
- *
- * @param granted One of {@link PackageManager#PERMISSION_GRANTED} or
- * {@link PackageManager#PERMISSION_DENIED}.
- */
- public void setPermission(String permission, Integer granted) {
- mMockedPermissions.put(permission, granted);
- }
-
@Override
public PackageManager getPackageManager() {
return mMockPackageManager;
}
-
- @Override
- public void enforceCallingPermission(String permission, @Nullable String message) {
- final Integer granted = mMockedPermissions.get(permission);
- if (granted == null) {
- super.enforceCallingOrSelfPermission(permission, message);
- return;
- }
-
- if (!granted.equals(PackageManager.PERMISSION_GRANTED)) {
- throw new SecurityException("[Test] permission denied: " + permission);
- }
- }
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 60ddeeb497a8..7755552bcad2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -149,12 +149,6 @@ public class LocalDisplayAdapterTest {
.thenReturn(mockArray);
when(mMockedResources.obtainTypedArray(R.array.config_roundedCornerBottomRadiusArray))
.thenReturn(mockArray);
- when(mMockedResources.obtainTypedArray(
- com.android.internal.R.array.config_autoBrightnessDisplayValuesNits))
- .thenReturn(mockArray);
- when(mMockedResources.obtainTypedArray(
- com.android.internal.R.array.config_autoBrightnessLevels))
- .thenReturn(mockArray);
}
@After
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
index 45e3b4373266..eb1314194aa3 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
@@ -91,8 +91,7 @@ public class BiometricSchedulerTest {
mToken = new Binder();
mScheduler = new BiometricScheduler(TAG, new Handler(TestableLooper.get(this).getLooper()),
BiometricScheduler.SENSOR_TYPE_UNKNOWN, null /* gestureAvailabilityTracker */,
- mBiometricService, LOG_NUM_RECENT_OPERATIONS,
- CoexCoordinator.getInstance());
+ mBiometricService, LOG_NUM_RECENT_OPERATIONS);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
deleted file mode 100644
index abf992b6c637..000000000000
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/CoexCoordinatorTest.java
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Copyright (C) 2021 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.server.biometrics.sensors;
-
-import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FACE;
-import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_FP_OTHER;
-import static com.android.server.biometrics.sensors.BiometricScheduler.SENSOR_TYPE_UDFPS;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.hardware.biometrics.BiometricConstants;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-
-import com.android.server.biometrics.sensors.fingerprint.Udfps;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import java.util.LinkedList;
-
-@Presubmit
-@SmallTest
-public class CoexCoordinatorTest {
-
- @Rule
- public final MockitoRule mockito = MockitoJUnit.rule();
-
- @Mock
- private CoexCoordinator.Callback mCallback;
- @Mock
- private CoexCoordinator.ErrorCallback mErrorCallback;
- @Mock
- private AuthenticationClient mFaceClient;
- @Mock
- private AuthenticationClient mFingerprintClient;
- @Mock(extraInterfaces = {Udfps.class})
- private AuthenticationClient mUdfpsClient;
-
- private CoexCoordinator mCoexCoordinator;
-
- @Before
- public void setUp() {
- mCoexCoordinator = CoexCoordinator.getInstance();
- mCoexCoordinator.setAdvancedLogicEnabled(true);
- mCoexCoordinator.setFaceHapticDisabledWhenNonBypass(true);
- mCoexCoordinator.reset();
- }
-
- @Test
- public void testBiometricPrompt_authSuccess() {
- when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
- mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
- mFaceClient, mCallback);
- verify(mCallback).sendHapticFeedback();
- verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
- verify(mCallback).handleLifecycleAfterAuth();
- }
-
- @Test
- public void testBiometricPrompt_authReject_whenNotLockedOut() {
- when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
- mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
- mFaceClient, LockoutTracker.LOCKOUT_NONE, mCallback);
- verify(mCallback).sendHapticFeedback();
- verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
- verify(mCallback).handleLifecycleAfterAuth();
- }
-
- @Test
- public void testBiometricPrompt_authReject_whenLockedOut() {
- when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
- mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
- mFaceClient, LockoutTracker.LOCKOUT_TIMED, mCallback);
- verify(mCallback).sendHapticFeedback();
- verify(mCallback, never()).sendAuthenticationResult(anyBoolean());
- verify(mCallback).handleLifecycleAfterAuth();
- }
-
- @Test
- public void testBiometricPrompt_coex_success() {
- testBiometricPrompt_coex_success(false /* twice */);
- }
-
- @Test
- public void testBiometricPrompt_coex_successWithoutDouble() {
- testBiometricPrompt_coex_success(true /* twice */);
- }
-
- private void testBiometricPrompt_coex_success(boolean twice) {
- initFaceAndFingerprintForBiometricPrompt();
- when(mFaceClient.wasAuthSuccessful()).thenReturn(true);
- when(mUdfpsClient.wasAuthSuccessful()).thenReturn(twice, true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
- mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
- mFaceClient, mCallback);
- mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
- mUdfpsClient, mCallback);
-
- if (twice) {
- verify(mCallback, never()).sendHapticFeedback();
- } else {
- verify(mCallback).sendHapticFeedback();
- }
- }
-
- @Test
- public void testBiometricPrompt_coex_reject() {
- initFaceAndFingerprintForBiometricPrompt();
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
- mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
- mFaceClient, LockoutTracker.LOCKOUT_NONE, mCallback);
-
- verify(mCallback, never()).sendHapticFeedback();
-
- mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
- mUdfpsClient, LockoutTracker.LOCKOUT_NONE, mCallback);
-
- verify(mCallback).sendHapticFeedback();
- }
-
- @Test
- public void testBiometricPrompt_coex_errorNoHaptics() {
- initFaceAndFingerprintForBiometricPrompt();
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
- mCoexCoordinator.onAuthenticationError(mFaceClient,
- BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
- mCoexCoordinator.onAuthenticationError(mUdfpsClient,
- BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
-
- verify(mErrorCallback, never()).sendHapticFeedback();
- }
-
- private void initFaceAndFingerprintForBiometricPrompt() {
- when(mFaceClient.isKeyguard()).thenReturn(false);
- when(mFaceClient.isBiometricPrompt()).thenReturn(true);
- when(mFaceClient.wasAuthAttempted()).thenReturn(true);
- when(mUdfpsClient.isKeyguard()).thenReturn(false);
- when(mUdfpsClient.isBiometricPrompt()).thenReturn(true);
- when(mUdfpsClient.wasAuthAttempted()).thenReturn(true);
- }
-
- @Test
- public void testKeyguard_faceAuthOnly_success() {
- when(mFaceClient.isKeyguard()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
- mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
- mFaceClient, mCallback);
- verify(mCallback).sendHapticFeedback();
- verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
- verify(mCallback).handleLifecycleAfterAuth();
- }
-
- @Test
- public void testKeyguard_faceAuth_udfpsNotTouching_faceSuccess() {
- when(mFaceClient.isKeyguard()).thenReturn(true);
-
- when(mUdfpsClient.isKeyguard()).thenReturn(true);
- when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(false);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
- mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
- mFaceClient, mCallback);
- // Haptics tested in #testKeyguard_bypass_haptics. Let's leave this commented out (instead
- // of removed) to keep this context.
- // verify(mCallback).sendHapticFeedback();
- verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
- verify(mCallback).handleLifecycleAfterAuth();
- }
-
- @Test
- public void testKeyguard_faceAuthSuccess_nonBypass_udfpsRunning_noHaptics() {
- testKeyguard_bypass_haptics(false /* bypassEnabled */,
- true /* faceAccepted */,
- false /* shouldReceiveHaptics */);
- }
-
- @Test
- public void testKeyguard_faceAuthReject_nonBypass_udfpsRunning_noHaptics() {
- testKeyguard_bypass_haptics(false /* bypassEnabled */,
- false /* faceAccepted */,
- false /* shouldReceiveHaptics */);
- }
-
- @Test
- public void testKeyguard_faceAuthSuccess_bypass_udfpsRunning_haptics() {
- testKeyguard_bypass_haptics(true /* bypassEnabled */,
- true /* faceAccepted */,
- true /* shouldReceiveHaptics */);
- }
-
- @Test
- public void testKeyguard_faceAuthReject_bypass_udfpsRunning_haptics() {
- testKeyguard_bypass_haptics(true /* bypassEnabled */,
- false /* faceAccepted */,
- true /* shouldReceiveHaptics */);
- }
-
- private void testKeyguard_bypass_haptics(boolean bypassEnabled, boolean faceAccepted,
- boolean shouldReceiveHaptics) {
- when(mFaceClient.isKeyguard()).thenReturn(true);
- when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
- when(mUdfpsClient.isKeyguard()).thenReturn(true);
- when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(false);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
- if (faceAccepted) {
- mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mFaceClient,
- mCallback);
- } else {
- mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
- LockoutTracker.LOCKOUT_NONE, mCallback);
- }
-
- if (shouldReceiveHaptics) {
- verify(mCallback).sendHapticFeedback();
- } else {
- verify(mCallback, never()).sendHapticFeedback();
- }
-
- verify(mCallback).sendAuthenticationResult(eq(faceAccepted) /* addAuthTokenIfStrong */);
- verify(mCallback).handleLifecycleAfterAuth();
- }
-
- @Test
- public void testKeyguard_faceAuth_udfpsTouching_faceSuccess_thenUdfpsRejectedWithinBounds() {
- testKeyguard_faceAuth_udfpsTouching_faceSuccess(false /* thenUdfpsAccepted */,
- 0 /* udfpsRejectedAfterMs */);
- }
-
- @Test
- public void testKeyguard_faceAuth_udfpsTouching_faceSuccess_thenUdfpsRejectedAfterBounds() {
- testKeyguard_faceAuth_udfpsTouching_faceSuccess(false /* thenUdfpsAccepted */,
- CoexCoordinator.SUCCESSFUL_AUTH_VALID_DURATION_MS + 1 /* udfpsRejectedAfterMs */);
- }
-
- @Test
- public void testKeyguard_faceAuth_udfpsTouching_faceSuccess_thenUdfpsAccepted() {
- testKeyguard_faceAuth_udfpsTouching_faceSuccess(true /* thenUdfpsAccepted */,
- 0 /* udfpsRejectedAfterMs */);
- }
-
- private void testKeyguard_faceAuth_udfpsTouching_faceSuccess(boolean thenUdfpsAccepted,
- long udfpsRejectedAfterMs) {
- when(mFaceClient.isKeyguard()).thenReturn(true);
- when(mUdfpsClient.isKeyguard()).thenReturn(true);
- when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
- when(mUdfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
- // For easier reading
- final CoexCoordinator.Callback faceCallback = mCallback;
-
- mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mFaceClient,
- faceCallback);
- verify(faceCallback, never()).sendHapticFeedback();
- verify(faceCallback, never()).sendAuthenticationResult(anyBoolean());
- // CoexCoordinator requests the system to hold onto this AuthenticationClient until
- // UDFPS result is known
- verify(faceCallback, never()).handleLifecycleAfterAuth();
-
- // Reset the mock
- CoexCoordinator.Callback udfpsCallback = mock(CoexCoordinator.Callback.class);
- assertEquals(1, mCoexCoordinator.mSuccessfulAuths.size());
- assertEquals(mFaceClient, mCoexCoordinator.mSuccessfulAuths.get(0).mAuthenticationClient);
- if (thenUdfpsAccepted) {
- mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mUdfpsClient,
- udfpsCallback);
- verify(udfpsCallback).sendHapticFeedback();
- verify(udfpsCallback).sendAuthenticationResult(true /* addAuthTokenIfStrong */);
- verify(udfpsCallback).handleLifecycleAfterAuth();
-
- verify(faceCallback).sendAuthenticationCanceled();
-
- assertTrue(mCoexCoordinator.mSuccessfulAuths.isEmpty());
- } else {
- mCoexCoordinator.onAuthenticationRejected(udfpsRejectedAfterMs, mUdfpsClient,
- LockoutTracker.LOCKOUT_NONE, udfpsCallback);
- if (udfpsRejectedAfterMs <= CoexCoordinator.SUCCESSFUL_AUTH_VALID_DURATION_MS) {
- verify(udfpsCallback, never()).sendHapticFeedback();
-
- verify(faceCallback).sendHapticFeedback();
- verify(faceCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
- verify(faceCallback).handleLifecycleAfterAuth();
-
- assertTrue(mCoexCoordinator.mSuccessfulAuths.isEmpty());
- } else {
- assertTrue(mCoexCoordinator.mSuccessfulAuths.isEmpty());
-
- verify(faceCallback, never()).sendHapticFeedback();
- verify(faceCallback, never()).sendAuthenticationResult(anyBoolean());
-
- verify(udfpsCallback).sendHapticFeedback();
- verify(udfpsCallback)
- .sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
- verify(udfpsCallback).handleLifecycleAfterAuth();
- }
- }
- }
-
- @Test
- public void testKeyguard_udfpsAuthSuccess_whileFaceScanning() {
- when(mFaceClient.isKeyguard()).thenReturn(true);
- when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
- when(mUdfpsClient.isKeyguard()).thenReturn(true);
- when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
- mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */, mUdfpsClient,
- mCallback);
- verify(mCallback).sendHapticFeedback();
- verify(mCallback).sendAuthenticationResult(eq(true));
- verify(mFaceClient).cancel();
- verify(mCallback).handleLifecycleAfterAuth();
- }
-
- @Test
- public void testKeyguard_faceRejectedWhenUdfpsTouching_thenUdfpsRejected() {
- when(mFaceClient.isKeyguard()).thenReturn(true);
- when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
- when(mUdfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
- when(mUdfpsClient.isKeyguard()).thenReturn(true);
- when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
- mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
- LockoutTracker.LOCKOUT_NONE, mCallback);
- verify(mCallback, never()).sendHapticFeedback();
- verify(mCallback).handleLifecycleAfterAuth();
-
- // BiometricScheduler removes the face authentication client after rejection
- mCoexCoordinator.removeAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
- // Then UDFPS rejected
- CoexCoordinator.Callback udfpsCallback = mock(CoexCoordinator.Callback.class);
- mCoexCoordinator.onAuthenticationRejected(1 /* currentTimeMillis */, mUdfpsClient,
- LockoutTracker.LOCKOUT_NONE, udfpsCallback);
- verify(udfpsCallback).sendHapticFeedback();
- verify(udfpsCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
- verify(mCallback, never()).sendHapticFeedback();
- }
-
- @Test
- public void testKeyguard_udfpsRejected_thenFaceRejected_noKeyguardBypass() {
- when(mFaceClient.isKeyguard()).thenReturn(true);
- when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
- when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(false); // TODO: also test "true" case
- when(mUdfpsClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
- when(mUdfpsClient.isKeyguard()).thenReturn(true);
- when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
- mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
- mUdfpsClient, LockoutTracker.LOCKOUT_NONE, mCallback);
- // Auth was attempted
- when(mUdfpsClient.getState())
- .thenReturn(AuthenticationClient.STATE_STARTED_PAUSED_ATTEMPTED);
- verify(mCallback).sendHapticFeedback();
- verify(mCallback).handleLifecycleAfterAuth();
-
- // Then face rejected. Note that scheduler leaves UDFPS in the CoexCoordinator since
- // unlike face, its lifecycle becomes "paused" instead of "finished".
- CoexCoordinator.Callback faceCallback = mock(CoexCoordinator.Callback.class);
- mCoexCoordinator.onAuthenticationRejected(1 /* currentTimeMillis */, mFaceClient,
- LockoutTracker.LOCKOUT_NONE, faceCallback);
- verify(faceCallback).sendHapticFeedback();
- verify(faceCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
- verify(mCallback).sendHapticFeedback();
- }
-
- @Test
- public void testKeyguard_capacitiveAccepted_whenFaceScanning() {
- when(mFaceClient.isKeyguard()).thenReturn(true);
- when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
- when(mFingerprintClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
- when(mFingerprintClient.isKeyguard()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, mFingerprintClient);
-
- mCoexCoordinator.onAuthenticationSucceeded(0 /* currentTimeMillis */,
- mFingerprintClient, mCallback);
- verify(mCallback).sendHapticFeedback();
- verify(mCallback).sendAuthenticationResult(eq(true) /* addAuthTokenIfStrong */);
- verify(mCallback).handleLifecycleAfterAuth();
- }
-
- @Test
- public void testKeyguard_capacitiveRejected_whenFaceScanning() {
- when(mFaceClient.isKeyguard()).thenReturn(true);
- when(mFaceClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
- when(mFingerprintClient.getState()).thenReturn(AuthenticationClient.STATE_STARTED);
- when(mFingerprintClient.isKeyguard()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FP_OTHER, mFingerprintClient);
-
- mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */,
- mFingerprintClient, LockoutTracker.LOCKOUT_NONE, mCallback);
- verify(mCallback).sendHapticFeedback();
- verify(mCallback).sendAuthenticationResult(eq(false) /* addAuthTokenIfStrong */);
- verify(mCallback).handleLifecycleAfterAuth();
- }
-
- @Test
- public void testNonKeyguard_rejectAndNotLockedOut() {
- when(mFaceClient.isKeyguard()).thenReturn(false);
- when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
- LockoutTracker.LOCKOUT_NONE, mCallback);
-
- verify(mCallback).sendHapticFeedback();
- verify(mCallback).sendAuthenticationResult(eq(false));
- verify(mCallback).handleLifecycleAfterAuth();
- }
-
- @Test
- public void testNonKeyguard_rejectLockedOut() {
- when(mFaceClient.isKeyguard()).thenReturn(false);
- when(mFaceClient.isBiometricPrompt()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.onAuthenticationRejected(0 /* currentTimeMillis */, mFaceClient,
- LockoutTracker.LOCKOUT_TIMED, mCallback);
-
- verify(mCallback).sendHapticFeedback();
- verify(mCallback, never()).sendAuthenticationResult(anyBoolean());
- verify(mCallback).handleLifecycleAfterAuth();
- }
-
- @Test
- public void testCleanupRunnable() {
- LinkedList<CoexCoordinator.SuccessfulAuth> successfulAuths = mock(LinkedList.class);
- CoexCoordinator.SuccessfulAuth auth = mock(CoexCoordinator.SuccessfulAuth.class);
- CoexCoordinator.Callback callback = mock(CoexCoordinator.Callback.class);
- CoexCoordinator.SuccessfulAuth.CleanupRunnable runnable =
- new CoexCoordinator.SuccessfulAuth.CleanupRunnable(successfulAuths, auth, callback);
- runnable.run();
-
- InstrumentationRegistry.getInstrumentation().waitForIdleSync();
-
- verify(callback).handleLifecycleAfterAuth();
- verify(successfulAuths).remove(eq(auth));
- }
-
- @Test
- public void testBiometricPrompt_FaceError() {
- when(mFaceClient.isBiometricPrompt()).thenReturn(true);
- when(mFaceClient.wasAuthAttempted()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
- mCoexCoordinator.onAuthenticationError(mFaceClient,
- BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
- verify(mErrorCallback).sendHapticFeedback();
- }
-
- @Test
- public void testKeyguard_faceAuthOnly_errorWhenBypassEnabled() {
- testKeyguard_faceAuthOnly(true /* bypassEnabled */);
- }
-
- @Test
- public void testKeyguard_faceAuthOnly_errorWhenBypassDisabled() {
- testKeyguard_faceAuthOnly(false /* bypassEnabled */);
- }
-
- private void testKeyguard_faceAuthOnly(boolean bypassEnabled) {
- when(mFaceClient.isKeyguard()).thenReturn(true);
- when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
- when(mFaceClient.wasAuthAttempted()).thenReturn(true);
- when(mFaceClient.wasUserDetected()).thenReturn(true);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
-
- mCoexCoordinator.onAuthenticationError(mFaceClient,
- BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
- verify(mErrorCallback).sendHapticFeedback();
- }
-
- @Test
- public void testKeyguard_coex_faceErrorWhenBypassEnabled() {
- testKeyguard_coex_faceError(true /* bypassEnabled */);
- }
-
- @Test
- public void testKeyguard_coex_faceErrorWhenBypassDisabled() {
- testKeyguard_coex_faceError(false /* bypassEnabled */);
- }
-
- private void testKeyguard_coex_faceError(boolean bypassEnabled) {
- when(mFaceClient.isKeyguard()).thenReturn(true);
- when(mFaceClient.isKeyguardBypassEnabled()).thenReturn(bypassEnabled);
- when(mFaceClient.wasAuthAttempted()).thenReturn(true);
- when(mFaceClient.wasUserDetected()).thenReturn(true);
- when(mUdfpsClient.isKeyguard()).thenReturn(true);
- when(((Udfps) mUdfpsClient).isPointerDown()).thenReturn(false);
-
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_FACE, mFaceClient);
- mCoexCoordinator.addAuthenticationClient(SENSOR_TYPE_UDFPS, mUdfpsClient);
-
- mCoexCoordinator.onAuthenticationError(mFaceClient,
- BiometricConstants.BIOMETRIC_ERROR_TIMEOUT, mErrorCallback);
-
- if (bypassEnabled) {
- verify(mErrorCallback).sendHapticFeedback();
- } else {
- verify(mErrorCallback, never()).sendHapticFeedback();
- }
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
index 0df3028805d2..0815fe52e262 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java
@@ -118,8 +118,7 @@ public class UserAwareBiometricSchedulerTest {
TEST_SENSOR_ID, mBiometricLogger, mBiometricContext,
mUserStartedCallback, mStartOperationsFinish);
}
- },
- CoexCoordinator.getInstance());
+ });
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
index b60324e88f15..518946aa761a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java
@@ -35,7 +35,6 @@ import androidx.test.filters.SmallTest;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.BiometricScheduler;
-import com.android.server.biometrics.sensors.CoexCoordinator;
import com.android.server.biometrics.sensors.LockoutCache;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.LockoutTracker;
@@ -91,8 +90,7 @@ public class SensorTest {
null /* gestureAvailabilityDispatcher */,
mBiometricService,
() -> USER_ID,
- mUserSwitchCallback,
- CoexCoordinator.getInstance());
+ mUserSwitchCallback);
mHalCallback = new Sensor.HalSessionCallback(mContext, new Handler(mLooper.getLooper()),
TAG, mScheduler, SENSOR_ID,
USER_ID, mLockoutCache, mLockoutResetDispatcher, mHalSessionCallback);
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
index e1a4a2d9f969..ff636c840bad 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java
@@ -35,7 +35,6 @@ import androidx.test.filters.SmallTest;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.sensors.BiometricScheduler;
-import com.android.server.biometrics.sensors.CoexCoordinator;
import com.android.server.biometrics.sensors.LockoutCache;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.LockoutTracker;
@@ -91,8 +90,7 @@ public class SensorTest {
null /* gestureAvailabilityDispatcher */,
mBiometricService,
() -> USER_ID,
- mUserSwitchCallback,
- CoexCoordinator.getInstance());
+ mUserSwitchCallback);
mHalCallback = new Sensor.HalSessionCallback(mContext, new Handler(mLooper.getLooper()),
TAG, mScheduler, SENSOR_ID,
USER_ID, mLockoutCache, mLockoutResetDispatcher, mHalSessionCallback);
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
index 261b882319d8..03ea6137074d 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java
@@ -19,19 +19,16 @@ package com.android.server.display;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyFloat;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.content.res.Resources;
-import android.content.res.TypedArray;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -55,16 +52,22 @@ public final class DisplayDeviceConfigTest {
private Resources mResources;
@Before
- public void setUp() {
+ public void setUp() throws IOException {
MockitoAnnotations.initMocks(this);
when(mContext.getResources()).thenReturn(mResources);
mockDeviceConfigs();
+ try {
+ Path tempFile = Files.createTempFile("display_config", ".tmp");
+ Files.write(tempFile, getContent().getBytes(StandardCharsets.UTF_8));
+ mDisplayDeviceConfig = new DisplayDeviceConfig(mContext);
+ mDisplayDeviceConfig.initFromFile(tempFile.toFile());
+ } catch (IOException e) {
+ throw new IOException("Failed to setup the display device config.", e);
+ }
}
@Test
- public void testConfigValuesFromDisplayConfig() throws IOException {
- setupDisplayDeviceConfigFromDisplayConfigFile();
-
+ public void testConfigValues() {
assertEquals(mDisplayDeviceConfig.getAmbientHorizonLong(), 5000);
assertEquals(mDisplayDeviceConfig.getAmbientHorizonShort(), 50);
assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(), 3000);
@@ -85,24 +88,10 @@ public final class DisplayDeviceConfigTest {
assertEquals(mDisplayDeviceConfig.getScreenDarkeningMinThreshold(), 0.002, 0.000001f);
assertEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLightDebounce(), 2000);
assertEquals(mDisplayDeviceConfig.getAutoBrightnessDarkeningLightDebounce(), 1000);
- assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
- float[]{50.0f, 80.0f}, 0.0f);
- assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new
- float[]{45.0f, 75.0f}, 0.0f);
- // Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
- // HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
- }
- @Test
- public void testConfigValuesFromDeviceConfig() {
- setupDisplayDeviceConfigFromDeviceConfigFile();
- assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new
- float[]{0.0f, 110.0f, 500.0f}, 0.0f);
- assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new
- float[]{2.0f, 200.0f, 600.0f}, 0.0f);
// Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping,
// HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor.
-
+ // Also add test for the case where optional display configs are null
}
private String getContent() {
@@ -125,16 +114,6 @@ public final class DisplayDeviceConfigTest {
+ "<autoBrightness>\n"
+ "<brighteningLightDebounceMillis>2000</brighteningLightDebounceMillis>\n"
+ "<darkeningLightDebounceMillis>1000</darkeningLightDebounceMillis>\n"
- + "<displayBrightnessMapping>\n"
- + "<displayBrightnessPoint>\n"
- + "<lux>50</lux>\n"
- + "<nits>45</nits>\n"
- + "</displayBrightnessPoint>\n"
- + "<displayBrightnessPoint>\n"
- + "<lux>80</lux>\n"
- + "<nits>75</nits>\n"
- + "</displayBrightnessPoint>\n"
- + "</displayBrightnessMapping>\n"
+ "</autoBrightness>\n"
+ "<highBrightnessMode enabled=\"true\">\n"
+ "<transitionPoint>0.62</transitionPoint>\n"
@@ -206,64 +185,4 @@ public final class DisplayDeviceConfigTest {
when(mResources.getFloat(com.android.internal.R.dimen
.config_screenBrightnessSettingMaximumFloat)).thenReturn(1.0f);
}
-
- private void setupDisplayDeviceConfigFromDisplayConfigFile() throws IOException {
- Path tempFile = Files.createTempFile("display_config", ".tmp");
- Files.write(tempFile, getContent().getBytes(StandardCharsets.UTF_8));
- mDisplayDeviceConfig = new DisplayDeviceConfig(mContext);
- mDisplayDeviceConfig.initFromFile(tempFile.toFile());
- }
-
- private void setupDisplayDeviceConfigFromDeviceConfigFile() {
- TypedArray screenBrightnessNits = createFloatTypedArray(new float[]{2.0f, 250.0f, 650.0f});
- when(mResources.obtainTypedArray(
- com.android.internal.R.array.config_screenBrightnessNits))
- .thenReturn(screenBrightnessNits);
- TypedArray screenBrightnessBacklight = createFloatTypedArray(new
- float[]{0.0f, 120.0f, 255.0f});
- when(mResources.obtainTypedArray(
- com.android.internal.R.array.config_screenBrightnessBacklight))
- .thenReturn(screenBrightnessBacklight);
- when(mResources.getIntArray(com.android.internal.R.array
- .config_screenBrightnessBacklight)).thenReturn(new int[]{0, 120, 255});
-
- when(mResources.getIntArray(com.android.internal.R.array
- .config_autoBrightnessLevels)).thenReturn(new int[]{30, 80});
- when(mResources.getIntArray(com.android.internal.R.array
- .config_autoBrightnessDisplayValuesNits)).thenReturn(new int[]{25, 55});
-
- TypedArray screenBrightnessLevelNits = createFloatTypedArray(new
- float[]{2.0f, 200.0f, 600.0f});
- when(mResources.obtainTypedArray(
- com.android.internal.R.array.config_autoBrightnessDisplayValuesNits))
- .thenReturn(screenBrightnessLevelNits);
- TypedArray screenBrightnessLevelLux = createFloatTypedArray(new
- float[]{0.0f, 110.0f, 500.0f});
- when(mResources.obtainTypedArray(
- com.android.internal.R.array.config_autoBrightnessLevels))
- .thenReturn(screenBrightnessLevelLux);
-
- mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true);
-
- }
-
- private TypedArray createFloatTypedArray(float[] vals) {
- TypedArray mockArray = mock(TypedArray.class);
- when(mockArray.length()).thenAnswer(invocation -> {
- return vals.length;
- });
- when(mockArray.getFloat(anyInt(), anyFloat())).thenAnswer(invocation -> {
- final float def = (float) invocation.getArguments()[1];
- if (vals == null) {
- return def;
- }
- int idx = (int) invocation.getArguments()[0];
- if (idx >= 0 && idx < vals.length) {
- return vals[idx];
- } else {
- return def;
- }
- });
- return mockArray;
- }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 44494831eb68..25c8f145bd62 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2869,6 +2869,7 @@ public class ActivityRecordTests extends WindowTestsBase {
mAtm, null /* fragmentToken */, false /* createdByOrganizer */);
fragmentSetup.accept(taskFragment1, new Rect(0, 0, width / 2, height));
task.addChild(taskFragment1, POSITION_TOP);
+ assertEquals(task, activity1.mStartingData.mAssociatedTask);
final TaskFragment taskFragment2 = new TaskFragment(
mAtm, null /* fragmentToken */, false /* createdByOrganizer */);
@@ -2890,7 +2891,6 @@ public class ActivityRecordTests extends WindowTestsBase {
eq(task.mSurfaceControl));
assertEquals(activity1.mStartingData, startingWindow.mStartingData);
assertEquals(task.mSurfaceControl, startingWindow.getAnimationLeashParent());
- assertEquals(task, activity1.mStartingData.mAssociatedTask);
assertEquals(taskFragment1.getBounds(), activity1.getBounds());
// The activity was resized by task fragment, but starting window must still cover the task.
assertEquals(taskBounds, activity1.mStartingWindow.getBounds());
@@ -2898,7 +2898,6 @@ public class ActivityRecordTests extends WindowTestsBase {
// The starting window is only removed when all embedded activities are drawn.
final WindowState activityWindow = mock(WindowState.class);
activity1.onFirstWindowDrawn(activityWindow);
- assertNotNull(activity1.mStartingWindow);
activity2.onFirstWindowDrawn(activityWindow);
assertNull(activity1.mStartingWindow);
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
index 3853af2f609e..1a40f82654ff 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt
@@ -164,7 +164,6 @@ class OpenActivityEmbeddingPlaceholderSplit(
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 1,
supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90),
supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index 9cc1bfe81c8c..ec2b4fa35c41 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -95,7 +95,7 @@ class CloseAppBackButtonTest(testSpec: FlickerTestParameter) : CloseAppTransitio
@JvmStatic
fun getParams(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index 58a80112c85e..55d412927ba6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -103,7 +103,7 @@ class CloseAppHomeButtonTest(testSpec: FlickerTestParameter) : CloseAppTransitio
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
index f6f3f58f29cb..725c10a8ada0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt
@@ -113,8 +113,7 @@ class CloseImeAutoOpenWindowToAppTest(testSpec: FlickerTestParameter) : BaseTest
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- // b/190352379 (IME doesn't show on app launch in 90 degrees)
+ // b/190352379 (IME doesn't show on app launch in 90 degrees)
supportedRotations = listOf(Surface.ROTATION_0),
supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
index 52f561ec4497..8832686b43aa 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt
@@ -123,7 +123,7 @@ class CloseImeAutoOpenWindowToHomeTest(testSpec: FlickerTestParameter) : BaseTes
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3,
+ .getConfigNonRotationTests(
// b/190352379 (IME doesn't show on app launch in 90 degrees)
supportedRotations = listOf(Surface.ROTATION_0),
supportedNavigationModes = listOf(
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
index c6e25d3de4cd..71e0aa1f9628 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt
@@ -141,7 +141,6 @@ class CloseImeEditorPopupDialogTest(testSpec: FlickerTestParameter) : BaseTest(t
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 2,
supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
index 23bd2200397a..0f91fd58abb7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt
@@ -121,7 +121,7 @@ class CloseImeWindowToAppTest(testSpec: FlickerTestParameter) : BaseTest(testSpe
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
index 8ce184072d32..007a4f1835d7 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt
@@ -134,8 +134,7 @@ class CloseImeWindowToHomeTest(testSpec: FlickerTestParameter) : BaseTest(testSp
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- supportedRotations = listOf(Surface.ROTATION_0),
+ supportedRotations = listOf(Surface.ROTATION_0),
supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
index a04a50f02c26..216e0edaf451 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt
@@ -127,14 +127,13 @@ class LaunchAppShowImeAndDialogThemeAppTest(
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(
- repetitions = 3,
- supportedRotations = listOf(Surface.ROTATION_0),
- supportedNavigationModes = listOf(
- WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
- WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
- )
+ .getConfigNonRotationTests(
+ supportedRotations = listOf(Surface.ROTATION_0),
+ supportedNavigationModes = listOf(
+ WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
+ WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
)
+ )
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
index 04e4bc94de9c..868290ec7585 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt
@@ -141,8 +141,7 @@ class LaunchAppShowImeOnStartTest(testSpec: FlickerTestParameter) : BaseTest(tes
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- supportedRotations = listOf(Surface.ROTATION_0),
+ supportedRotations = listOf(Surface.ROTATION_0),
supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
index b10aed30e39e..16c23b93a5de 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt
@@ -82,8 +82,7 @@ class OpenImeWindowAndCloseTest(testSpec: FlickerTestParameter) : BaseTest(testS
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- supportedRotations = listOf(Surface.ROTATION_0),
+ supportedRotations = listOf(Surface.ROTATION_0),
supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
index d9008158ffaf..e5874921ddfa 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt
@@ -117,8 +117,7 @@ class OpenImeWindowFromFixedOrientationAppTest(
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- supportedRotations = listOf(Surface.ROTATION_90),
+ supportedRotations = listOf(Surface.ROTATION_90),
supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
index fdc2193b7eb8..c1f17f3deb2e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt
@@ -95,8 +95,7 @@ class OpenImeWindowTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- supportedRotations = listOf(Surface.ROTATION_0),
+ supportedRotations = listOf(Surface.ROTATION_0),
supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
index 9475734ef3f5..5fd94427dc82 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt
@@ -265,7 +265,6 @@ class OpenImeWindowToOverViewTest(testSpec: FlickerTestParameter) : BaseTest(tes
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 1,
supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90),
supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY,
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
index 2e22e6224813..0281a60bbc3b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt
@@ -192,8 +192,7 @@ open class ReOpenImeWindowTest(testSpec: FlickerTestParameter) : BaseTest(testSp
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- supportedRotations = listOf(Surface.ROTATION_0)
+ supportedRotations = listOf(Surface.ROTATION_0)
)
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
index 4f47ec439da8..85bf6d752bf5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt
@@ -200,8 +200,7 @@ open class SwitchImeWindowsFromGestureNavTest(
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- supportedNavigationModes = listOf(
+ supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
),
supportedRotations = listOf(Surface.ROTATION_0)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
index 33c280ea78bb..eb9acc4b8e4e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt
@@ -142,7 +142,7 @@ class ActivitiesTransitionTest(testSpec: FlickerTestParameter) : BaseTest(testSp
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
index bfc7b39f9d9f..b3db5b70fafa 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt
@@ -171,7 +171,7 @@ open class OpenAppFromLockNotificationCold(testSpec: FlickerTestParameter) :
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
index f93d7a0b09e3..8c1d244b69e0 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt
@@ -221,7 +221,7 @@ open class OpenAppFromLockNotificationWarm(testSpec: FlickerTestParameter) :
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
index 75311eaf5c66..caf2e2dbadc6 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt
@@ -127,7 +127,7 @@ class OpenAppFromLockNotificationWithLockOverlayApp(testSpec: FlickerTestParamet
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
index dbe541882fa8..e744d44bc542 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt
@@ -157,7 +157,7 @@ open class OpenAppFromNotificationCold(
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
index 915b70289055..4ea42433e054 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt
@@ -284,7 +284,7 @@ open class OpenAppFromNotificationWarm(
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index 7c07ace06b82..a3dd0cbcf64f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -130,7 +130,7 @@ open class OpenAppFromOverviewTest(
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
index 53be7d43cce8..82e30accb341 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
@@ -233,8 +233,7 @@ open class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) :
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- supportedNavigationModes =
+ supportedNavigationModes =
listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY),
supportedRotations = listOf(Surface.ROTATION_0)
)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
index fe5e74b87f93..5f342a00bf8c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt
@@ -263,7 +263,7 @@ class TaskTransitionTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) {
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigNonRotationTests(repetitions = 3)
+ .getConfigNonRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
index 181767b3448d..f85bad33c4fd 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt
@@ -278,8 +278,7 @@ open class QuickSwitchBetweenTwoAppsBackTest(
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- supportedNavigationModes = listOf(
+ supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
),
supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
index 0f05622c81bc..f6392cab4a35 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt
@@ -298,8 +298,7 @@ open class QuickSwitchBetweenTwoAppsForwardTest(
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- supportedNavigationModes = listOf(
+ supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
),
supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
index d1f356c830eb..a714111fae21 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt
@@ -324,8 +324,7 @@ class QuickSwitchFromLauncherTest(testSpec: FlickerTestParameter) : BaseTest(tes
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
.getConfigNonRotationTests(
- repetitions = 3,
- supportedNavigationModes = listOf(
+ supportedNavigationModes = listOf(
WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY
),
// TODO: Test with 90 rotation
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
index 4be8963bf7b7..e6c1eaca9380 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt
@@ -146,7 +146,7 @@ class ChangeAppRotationTest(
@JvmStatic
fun getParams(): Collection<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigRotationTests(repetitions = 3)
+ .getConfigRotationTests()
}
}
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
index 0912812afef9..07c213034642 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt
@@ -241,7 +241,7 @@ open class SeamlessAppRotationTest(
@JvmStatic
private fun getConfigurations(): List<FlickerTestParameter> {
return FlickerTestParameterFactory.getInstance()
- .getConfigRotationTests(repetitions = 2)
+ .getConfigRotationTests()
.flatMap { sourceConfig ->
val defaultRun = createConfig(sourceConfig, starveUiThread = false)
val busyUiRun = createConfig(sourceConfig, starveUiThread = true)
diff --git a/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java b/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
index 8b69db707d41..dc34cb6d6a53 100644
--- a/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
+++ b/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java
@@ -15,21 +15,25 @@
*/
package com.google.android.test.handwritingime;
+import android.R;
import android.annotation.Nullable;
import android.graphics.PointF;
import android.graphics.RectF;
import android.inputmethodservice.InputMethodService;
-import android.os.Bundle;
import android.util.Log;
-import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
-import android.view.inputmethod.CursorAnchorInfo;
+import android.view.inputmethod.DeleteGesture;
+import android.view.inputmethod.HandwritingGesture;
+import android.view.inputmethod.InputConnection;
+import android.view.inputmethod.InsertGesture;
+import android.view.inputmethod.SelectGesture;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
+import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.Toast;
@@ -39,19 +43,19 @@ public class HandwritingIme extends InputMethodService {
public static final int HEIGHT_DP = 100;
-
private static final int OP_NONE = 0;
private static final int OP_SELECT = 1;
private static final int OP_DELETE = 2;
- private static final int OP_DELETE_SPACE = 3;
- private static final int OP_INSERT = 4;
+ private static final int OP_INSERT = 3;
private Window mInkWindow;
private InkView mInk;
static final String TAG = "HandwritingIme";
private int mRichGestureMode = OP_NONE;
+ private int mRichGestureGranularity = -1;
private Spinner mRichGestureModeSpinner;
+ private Spinner mRichGestureGranularitySpinner;
private PointF mRichGestureStartPoint;
@@ -86,13 +90,45 @@ public class HandwritingIme extends InputMethodService {
switch (event.getAction()) {
case MotionEvent.ACTION_UP: {
if (areRichGesturesEnabled()) {
- Bundle bundle = new Bundle();
- bundle.putInt("operation", mRichGestureMode);
- bundle.putFloat("left", mRichGestureStartPoint.x);
- bundle.putFloat("top", mRichGestureStartPoint.y);
- bundle.putFloat("right", event.getX());
- bundle.putFloat("bottom", event.getY());
- performPrivateCommand("android.widget.RichGesture", bundle);
+ HandwritingGesture gesture = null;
+ switch(mRichGestureMode) {
+ case OP_SELECT:
+ SelectGesture.Builder builder = new SelectGesture.Builder();
+ builder.setGranularity(mRichGestureGranularity)
+ .setSelectionArea(new RectF(mRichGestureStartPoint.x,
+ mRichGestureStartPoint.y, event.getX(), event.getY()))
+ .setFallbackText("fallback text");
+ gesture = builder.build();
+ break;
+ case OP_DELETE:
+ DeleteGesture.Builder builder1 = new DeleteGesture.Builder();
+ builder1.setGranularity(mRichGestureGranularity)
+ .setDeletionArea(new RectF(mRichGestureStartPoint.x,
+ mRichGestureStartPoint.y, event.getX(), event.getY()))
+ .setFallbackText("fallback text");
+ gesture = builder1.build();
+ break;
+ case OP_INSERT:
+ InsertGesture.Builder builder2 = new InsertGesture.Builder();
+ builder2.setInsertionPoint(
+ new PointF(mRichGestureStartPoint.x, mRichGestureStartPoint.y))
+ .setTextToInsert(" ")
+ .setFallbackText("fallback text");
+ gesture = builder2.build();
+
+ }
+ if (gesture == null) {
+ // This shouldn't happen
+ Log.e(TAG, "Unrecognized gesture mode: " + mRichGestureMode);
+ return;
+ }
+ InputConnection ic = getCurrentInputConnection();
+ if (getCurrentInputStarted() && ic != null) {
+ ic.performHandwritingGesture(gesture, null, null);
+ } else {
+ // This shouldn't happen
+ Log.e(TAG, "No active InputConnection");
+ }
Log.d(TAG, "Sending RichGesture " + mRichGestureMode + " (Screen) Left: "
+ mRichGestureStartPoint.x + ", Top: " + mRichGestureStartPoint.y
@@ -123,8 +159,15 @@ public class HandwritingIme extends InputMethodService {
view.addView(inner, new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, height));
- view.addView(getRichGestureActionsSpinner());
- inner.setBackgroundColor(getColor(R.color.abc_tint_spinner));
+ LinearLayout layout = new LinearLayout(this);
+ layout.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+ layout.setOrientation(LinearLayout.VERTICAL);
+ layout.addView(getRichGestureActionsSpinner());
+ layout.addView(getRichGestureGranularitySpinner());
+
+ view.addView(layout);
+ inner.setBackgroundColor(getColor(R.color.holo_green_light));
return view;
}
@@ -133,14 +176,12 @@ public class HandwritingIme extends InputMethodService {
if (mRichGestureModeSpinner != null) {
return mRichGestureModeSpinner;
}
- //get the spinner from the xml.
mRichGestureModeSpinner = new Spinner(this);
mRichGestureModeSpinner.setPadding(100, 0, 100, 0);
mRichGestureModeSpinner.setTooltipText("Handwriting IME mode");
String[] items =
new String[] { "Handwriting IME - Rich gesture disabled", "Rich gesture SELECT",
- "Rich gesture DELETE", "Rich gesture DELETE SPACE",
- "Rich gesture INSERT" };
+ "Rich gesture DELETE", "Rich gesture INSERT" };
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_dropdown_item, items);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
@@ -149,17 +190,52 @@ public class HandwritingIme extends InputMethodService {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
mRichGestureMode = position;
+ mRichGestureGranularitySpinner.setEnabled(
+ mRichGestureMode != OP_INSERT && mRichGestureMode != OP_NONE);
Log.d(TAG, "Setting RichGesture Mode " + mRichGestureMode);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
mRichGestureMode = OP_NONE;
+ mRichGestureGranularitySpinner.setEnabled(false);
}
});
+ mRichGestureModeSpinner.setSelection(0); // default disabled
return mRichGestureModeSpinner;
}
+ private View getRichGestureGranularitySpinner() {
+ if (mRichGestureGranularitySpinner != null) {
+ return mRichGestureGranularitySpinner;
+ }
+ mRichGestureGranularitySpinner = new Spinner(this);
+ mRichGestureGranularitySpinner.setPadding(100, 0, 100, 0);
+ mRichGestureGranularitySpinner.setTooltipText(" Granularity");
+ String[] items =
+ new String[] { "Granularity - UNDEFINED",
+ "Granularity - WORD", "Granularity - CHARACTER"};
+ ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
+ android.R.layout.simple_spinner_dropdown_item, items);
+ adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mRichGestureGranularitySpinner.setAdapter(adapter);
+ mRichGestureGranularitySpinner.setOnItemSelectedListener(
+ new AdapterView.OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ mRichGestureGranularity = position;
+ Log.d(TAG, "Setting RichGesture Granularity " + mRichGestureGranularity);
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {
+ mRichGestureGranularity = 0;
+ }
+ });
+ mRichGestureGranularitySpinner.setSelection(1);
+ return mRichGestureGranularitySpinner;
+ }
+
public void onPrepareStylusHandwriting() {
Log.d(TAG, "onPrepareStylusHandwriting ");
if (mInk == null) {
@@ -190,15 +266,6 @@ public class HandwritingIme extends InputMethodService {
return false;
}
- boolean performPrivateCommand(String action, Bundle bundle) {
- if (!getCurrentInputStarted()) {
- Log.e(TAG, "Input hasnt started, can't performPrivateCommand");
- return false;
- }
-
- return getCurrentInputConnection().performPrivateCommand(action, bundle);
- }
-
private boolean areRichGesturesEnabled() {
return mRichGestureMode != OP_NONE;
}
diff --git a/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java b/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
index c9e429b6f4c8..94b1f863f197 100644
--- a/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
+++ b/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java
@@ -30,7 +30,7 @@ import android.view.WindowManager;
import android.view.WindowMetrics;
class InkView extends View {
- private static final long FINISH_TIMEOUT = 600;
+ private static final long FINISH_TIMEOUT = 1500;
private final HandwritingIme.HandwritingFinisher mHwCanceller;
private final HandwritingIme.StylusConsumer mConsumer;
private final int mTopInset;
diff --git a/tests/RollbackTest/Android.bp b/tests/RollbackTest/Android.bp
index 9f6ce4e8425b..b7c4c5b28168 100644
--- a/tests/RollbackTest/Android.bp
+++ b/tests/RollbackTest/Android.bp
@@ -61,6 +61,7 @@ java_test_host {
static_libs: ["RollbackTestLib", "frameworks-base-hostutils"],
test_suites: ["general-tests"],
test_config: "NetworkStagedRollbackTest.xml",
+ data: [":RollbackTest"],
}
java_test_host {
diff --git a/tests/StagedInstallTest/Android.bp b/tests/StagedInstallTest/Android.bp
index 1709e1501537..ffde8c7d342c 100644
--- a/tests/StagedInstallTest/Android.bp
+++ b/tests/StagedInstallTest/Android.bp
@@ -58,6 +58,7 @@ java_test_host {
":apex.apexd_test",
":com.android.apex.apkrollback.test_v1",
":com.android.apex.apkrollback.test_v2",
+ ":StagedInstallInternalTestApp",
":StagedInstallTestApexV2",
":StagedInstallTestApexV2_WrongSha",
":TestAppAv1",
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index 46a846bce35f..4fb7ed19ed20 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -369,9 +369,13 @@ class PackageFlattener {
bool sparse_encode = use_sparse_entries_;
- // Only sparse encode if the entries will be read on platforms O+.
- sparse_encode =
- sparse_encode && (context_->GetMinSdkVersion() >= SDK_O || config.sdkVersion >= SDK_O);
+ if (context_->GetMinSdkVersion() == 0 && config.sdkVersion == 0) {
+ // Sparse encode if sdk version is not set in context and config.
+ } else {
+ // Otherwise, only sparse encode if the entries will be read on platforms S_V2+.
+ sparse_encode = sparse_encode &&
+ (context_->GetMinSdkVersion() >= SDK_S_V2 || config.sdkVersion >= SDK_S_V2);
+ }
// Only sparse encode if the offsets are representable in 2 bytes.
sparse_encode =
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index e48fca61fef8..f551bf61dc06 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -330,7 +330,7 @@ TEST_F(TableFlattenerTest, FlattenSparseEntryWithMinSdkO) {
std::unique_ptr<IAaptContext> context = test::ContextBuilder()
.SetCompilationPackage("android")
.SetPackageId(0x01)
- .SetMinSdkVersion(SDK_O)
+ .SetMinSdkVersion(SDK_S_V2)
.Build();
const ConfigDescription sparse_config = test::ParseConfigOrDie("en-rGB");
@@ -376,7 +376,26 @@ TEST_F(TableFlattenerTest, FlattenSparseEntryWithConfigSdkVersionO) {
.SetMinSdkVersion(SDK_LOLLIPOP)
.Build();
- const ConfigDescription sparse_config = test::ParseConfigOrDie("en-rGB-v26");
+ const ConfigDescription sparse_config = test::ParseConfigOrDie("en-rGB-v32");
+ auto table_in = BuildTableWithSparseEntries(context.get(), sparse_config, 0.25f);
+
+ TableFlattenerOptions options;
+ options.use_sparse_entries = true;
+
+ std::string no_sparse_contents;
+ ASSERT_TRUE(Flatten(context.get(), {}, table_in.get(), &no_sparse_contents));
+
+ std::string sparse_contents;
+ ASSERT_TRUE(Flatten(context.get(), options, table_in.get(), &sparse_contents));
+
+ EXPECT_GT(no_sparse_contents.size(), sparse_contents.size());
+}
+
+TEST_F(TableFlattenerTest, FlattenSparseEntryWithSdkVersionNotSet) {
+ std::unique_ptr<IAaptContext> context =
+ test::ContextBuilder().SetCompilationPackage("android").SetPackageId(0x01).Build();
+
+ const ConfigDescription sparse_config = test::ParseConfigOrDie("en-rGB");
auto table_in = BuildTableWithSparseEntries(context.get(), sparse_config, 0.25f);
TableFlattenerOptions options;
@@ -389,6 +408,27 @@ TEST_F(TableFlattenerTest, FlattenSparseEntryWithConfigSdkVersionO) {
ASSERT_TRUE(Flatten(context.get(), options, table_in.get(), &sparse_contents));
EXPECT_GT(no_sparse_contents.size(), sparse_contents.size());
+
+ // Attempt to parse the sparse contents.
+
+ ResourceTable sparse_table;
+ BinaryResourceParser parser(context->GetDiagnostics(), &sparse_table, Source("test.arsc"),
+ sparse_contents.data(), sparse_contents.size());
+ ASSERT_TRUE(parser.Parse());
+
+ auto value = test::GetValueForConfig<BinaryPrimitive>(&sparse_table, "android:string/foo_0",
+ sparse_config);
+ ASSERT_THAT(value, NotNull());
+ EXPECT_EQ(0u, value->value.data);
+
+ ASSERT_THAT(test::GetValueForConfig<BinaryPrimitive>(&sparse_table, "android:string/foo_1",
+ sparse_config),
+ IsNull());
+
+ value = test::GetValueForConfig<BinaryPrimitive>(&sparse_table, "android:string/foo_4",
+ sparse_config);
+ ASSERT_THAT(value, NotNull());
+ EXPECT_EQ(4u, value->value.data);
}
TEST_F(TableFlattenerTest, DoNotUseSparseEntryForDenseConfig) {