summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/windowmanager/Android.bp1
-rw-r--r--apct-tests/perftests/windowmanager/AndroidTest.xml34
-rw-r--r--apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java2
-rw-r--r--api/current.txt2
-rw-r--r--api/module-lib-current.txt7
-rwxr-xr-xapi/system-current.txt1
-rw-r--r--api/test-current.txt1
-rw-r--r--cmds/statsd/src/matchers/SimpleAtomMatchingTracker.cpp2
-rw-r--r--core/java/android/app/ActivityThread.java444
-rw-r--r--core/java/android/app/ClientTransactionHandler.java54
-rw-r--r--core/java/android/app/LocalActivityManager.java31
-rw-r--r--core/java/android/app/PropertyInvalidatedCache.java10
-rw-r--r--core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java12
-rw-r--r--core/java/android/app/servertransaction/ActivityLifecycleItem.java2
-rw-r--r--core/java/android/app/servertransaction/ActivityRelaunchItem.java30
-rw-r--r--core/java/android/app/servertransaction/ActivityResultItem.java11
-rw-r--r--core/java/android/app/servertransaction/ActivityTransactionItem.java69
-rw-r--r--core/java/android/app/servertransaction/DestroyActivityItem.java8
-rw-r--r--core/java/android/app/servertransaction/EnterPipRequestedItem.java8
-rw-r--r--core/java/android/app/servertransaction/LaunchActivityItem.java3
-rw-r--r--core/java/android/app/servertransaction/MoveToDisplayItem.java13
-rw-r--r--core/java/android/app/servertransaction/NewIntentItem.java11
-rw-r--r--core/java/android/app/servertransaction/PauseActivityItem.java9
-rw-r--r--core/java/android/app/servertransaction/ResumeActivityItem.java8
-rw-r--r--core/java/android/app/servertransaction/StartActivityItem.java9
-rw-r--r--core/java/android/app/servertransaction/StopActivityItem.java8
-rw-r--r--core/java/android/app/servertransaction/TopResumedActivityChangeItem.java26
-rw-r--r--core/java/android/app/servertransaction/TransactionExecutor.java12
-rw-r--r--core/java/android/content/res/ApkAssets.java19
-rw-r--r--core/java/android/hardware/face/FaceSensorProperties.java19
-rw-r--r--core/java/android/os/GraphicsEnvironment.java103
-rw-r--r--core/java/android/provider/Settings.java53
-rw-r--r--core/java/android/service/autofill/InlinePresentation.java17
-rw-r--r--core/java/android/view/WindowManager.java4
-rw-r--r--core/java/android/view/inputmethod/InputMethodInfo.java4
-rw-r--r--core/java/android/widget/inline/InlinePresentationSpec.java29
-rw-r--r--core/proto/android/app/settings_enums.proto4
-rw-r--r--core/proto/android/providers/settings/global.proto39
-rw-r--r--core/proto/android/providers/settings/secure.proto3
-rw-r--r--core/res/res/values/config.xml11
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityThreadTest.java56
-rw-r--r--core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java66
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java51
-rw-r--r--core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java10
-rw-r--r--data/etc/car/Android.bp40
-rw-r--r--data/etc/com.android.systemui.xml1
-rw-r--r--graphics/java/android/graphics/Paint.java2
-rw-r--r--libs/hwui/Android.bp7
-rw-r--r--libs/hwui/SkiaCanvas.cpp7
-rw-r--r--libs/hwui/VectorDrawable.cpp7
-rw-r--r--libs/hwui/VectorDrawable.h14
-rw-r--r--libs/hwui/hwui/Canvas.cpp2
-rw-r--r--libs/hwui/hwui/Paint.h9
-rw-r--r--libs/hwui/hwui/PaintImpl.cpp27
-rw-r--r--libs/hwui/jni/Paint.cpp14
-rw-r--r--libs/hwui/jni/Shader.cpp137
-rw-r--r--libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp4
-rw-r--r--libs/hwui/shader/BitmapShader.cpp31
-rw-r--r--libs/hwui/shader/BitmapShader.h39
-rw-r--r--libs/hwui/shader/ComposeShader.cpp51
-rw-r--r--libs/hwui/shader/ComposeShader.h43
-rw-r--r--libs/hwui/shader/LinearGradientShader.cpp39
-rw-r--r--libs/hwui/shader/LinearGradientShader.h42
-rw-r--r--libs/hwui/shader/RadialGradientShader.cpp38
-rw-r--r--libs/hwui/shader/RadialGradientShader.h42
-rw-r--r--libs/hwui/shader/RuntimeShader.cpp36
-rw-r--r--libs/hwui/shader/RuntimeShader.h40
-rw-r--r--libs/hwui/shader/Shader.cpp87
-rw-r--r--libs/hwui/shader/Shader.h82
-rw-r--r--libs/hwui/shader/SweepGradientShader.cpp38
-rw-r--r--libs/hwui/shader/SweepGradientShader.h41
-rw-r--r--libs/hwui/tests/common/scenes/BitmapShaders.cpp22
-rw-r--r--libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp47
-rw-r--r--libs/hwui/tests/common/scenes/ListOfFadedTextAnimation.cpp24
-rw-r--r--libs/hwui/tests/common/scenes/SimpleColorMatrixAnimation.cpp11
-rw-r--r--libs/hwui/tests/common/scenes/SimpleGradientAnimation.cpp22
-rw-r--r--libs/hwui/tests/unit/VectorDrawableTests.cpp21
-rw-r--r--media/java/android/media/session/MediaSessionManager.java12
-rw-r--r--non-updatable-api/current.txt2
-rw-r--r--non-updatable-api/module-lib-current.txt7
-rw-r--r--non-updatable-api/system-current.txt1
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java48
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMShellModule.java54
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java11
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java2
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java35
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java16
-rw-r--r--packages/SystemUI/AndroidManifest.xml3
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java9
-rw-r--r--packages/SystemUI/proguard.flags3
-rw-r--r--packages/SystemUI/res/layout/global_screenshot_action_chip.xml1
-rw-r--r--packages/SystemUI/res/layout/udfps_view.xml4
-rw-r--r--packages/SystemUI/res/values/attrs.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIFactory.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java122
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SuppressedAttachState.kt63
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java205
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnDismissCallbackImpl.java)32
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnDismissCallbackImpl.java)27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/VisualStabilityManager.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java)92
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/PipelineState.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifStabilityManager.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java52
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnUserInteractionCallback.java (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnDismissCallback.java)14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java74
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java93
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java101
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java52
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java (renamed from packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellModule.java)31
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt22
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java136
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java341
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java57
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java93
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java115
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java7
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java16
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java20
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java21
-rw-r--r--services/core/java/com/android/server/SystemServiceManager.java48
-rw-r--r--services/core/java/com/android/server/am/CoreSettingsObserver.java21
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java3
-rwxr-xr-xservices/core/java/com/android/server/audio/AudioService.java83
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/Face10.java6
-rw-r--r--services/core/java/com/android/server/gpu/GpuService.java51
-rw-r--r--services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java7
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java3
-rw-r--r--services/core/java/com/android/server/media/MediaSessionService.java2
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java4
-rw-r--r--services/core/java/com/android/server/pm/StagingManager.java23
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java23
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java8
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java21
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java1
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java3
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java7
-rw-r--r--services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java42
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/TwoFingersDownTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java55
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/utils/TouchEventGenerator.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java4
-rw-r--r--telephony/api/system-current.txt1
-rw-r--r--telephony/java/android/telephony/CellIdentityNr.java8
-rw-r--r--telephony/java/android/telephony/ims/ProvisioningManager.java13
-rw-r--r--telephony/java/com/android/ims/ImsConfig.java3
196 files changed, 3801 insertions, 1671 deletions
diff --git a/apct-tests/perftests/windowmanager/Android.bp b/apct-tests/perftests/windowmanager/Android.bp
index 9fa99853ace3..dbfe6ab3210f 100644
--- a/apct-tests/perftests/windowmanager/Android.bp
+++ b/apct-tests/perftests/windowmanager/Android.bp
@@ -23,6 +23,7 @@ android_test {
"platform-test-annotations",
],
test_suites: ["device-tests"],
+ data: [":perfetto_artifacts"],
platform_apis: true,
certificate: "platform",
}
diff --git a/apct-tests/perftests/windowmanager/AndroidTest.xml b/apct-tests/perftests/windowmanager/AndroidTest.xml
index 0a80cf96fba3..aee02c7ab767 100644
--- a/apct-tests/perftests/windowmanager/AndroidTest.xml
+++ b/apct-tests/perftests/windowmanager/AndroidTest.xml
@@ -28,14 +28,42 @@
<option name="run-command" value="cmd package compile -m speed com.android.perftests.wm" />
</target_preparer>
+ <!-- Needed for pushing the trace config file -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="push-file" key="trace_config_detailed.textproto" value="/data/misc/perfetto-traces/trace_config.textproto" />
+ </target_preparer>
+
+ <!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
+ <option name="isolated-storage" value="false" />
+
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.perftests.wm" />
<option name="hidden-api-checks" value="false"/>
- <option name="device-listeners" value="android.wm.WmPerfRunListener" />
+
+ <!-- Listener related args for collecting the traces and waiting for the device to stabilize. -->
+ <option name="device-listeners" value="android.wm.WmPerfRunListener,android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener" />
+
+ <!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. -->
+ <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
+
+ <!-- ProcLoadListener related arguments -->
+ <!-- Wait for device last minute threshold to reach 3 with 2 minute timeout before starting the test run -->
+ <option name="instrumentation-arg" key="procload-collector:per_run" value="true" />
+ <option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" />
+ <option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" />
+ <option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" />
+
+ <!-- PerfettoListener related arguments -->
+ <option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
+ <option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" />
+
+ <option name="instrumentation-arg" key="newRunListenerMode" value="true" />
</test>
<metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
- <option name="directory-keys" value="/data/local/WmPerfTests" />
- <option name="collect-on-run-ended-only" value="true" />
+ <option name="directory-keys" value="/data/local/tmp/WmPerfTests" />
+ <!-- Needed for pulling the collected trace config on to the host -->
+ <option name="pull-pattern-keys" value="perfetto_file_path" />
</metrics_collector>
</configuration>
diff --git a/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java b/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
index dc6245bf2c09..cc0e939a2a80 100644
--- a/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
+++ b/apct-tests/perftests/windowmanager/src/android/wm/WindowManagerPerfTestBase.java
@@ -55,7 +55,7 @@ public class WindowManagerPerfTestBase {
* is in /data because while enabling method profling of system server, it cannot write the
* trace to external storage.
*/
- static final File BASE_OUT_PATH = new File("/data/local/WmPerfTests");
+ static final File BASE_OUT_PATH = new File("/data/local/tmp/WmPerfTests");
@BeforeClass
public static void setUpOnce() {
diff --git a/api/current.txt b/api/current.txt
index 532c3d938334..9e0d88ecdfd1 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -46987,7 +46987,7 @@ package android.telephony {
method public long getNci();
method @IntRange(from=0, to=3279165) public int getNrarfcn();
method @IntRange(from=0, to=1007) public int getPci();
- method @IntRange(from=0, to=65535) public int getTac();
+ method @IntRange(from=0, to=16777215) public int getTac();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityNr> CREATOR;
}
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
index 7cd8a628c9fc..17545a469cb8 100644
--- a/api/module-lib-current.txt
+++ b/api/module-lib-current.txt
@@ -46,6 +46,13 @@ package android.media.session {
field public static final int FLAG_EXCLUSIVE_GLOBAL_PRIORITY = 65536; // 0x10000
}
+ public final class MediaSessionManager {
+ method public void dispatchMediaKeyEventAsSystemService(@NonNull android.view.KeyEvent);
+ method public boolean dispatchMediaKeyEventAsSystemService(@NonNull android.media.session.MediaSession.Token, @NonNull android.view.KeyEvent);
+ method public void dispatchVolumeKeyEventAsSystemService(@NonNull android.view.KeyEvent, int);
+ method public void dispatchVolumeKeyEventAsSystemService(@NonNull android.media.session.MediaSession.Token, @NonNull android.view.KeyEvent);
+ }
+
}
package android.net {
diff --git a/api/system-current.txt b/api/system-current.txt
index ea16238316ac..3ab164554da6 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -12171,6 +12171,7 @@ package android.telephony.ims {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
+ field public static final int KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID = 67; // 0x43
field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
diff --git a/api/test-current.txt b/api/test-current.txt
index a1d1fa781096..620c5b30b925 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4618,6 +4618,7 @@ package android.telephony.ims {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
+ field public static final int KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID = 67; // 0x43
field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
diff --git a/cmds/statsd/src/matchers/SimpleAtomMatchingTracker.cpp b/cmds/statsd/src/matchers/SimpleAtomMatchingTracker.cpp
index 744ec375efdf..86b148dd8657 100644
--- a/cmds/statsd/src/matchers/SimpleAtomMatchingTracker.cpp
+++ b/cmds/statsd/src/matchers/SimpleAtomMatchingTracker.cpp
@@ -65,7 +65,7 @@ void SimpleAtomMatchingTracker::onLogEvent(
bool matched = matchesSimple(mUidMap, mMatcher, event);
matcherResults[mIndex] = matched ? MatchingState::kMatched : MatchingState::kNotMatched;
- VLOG("Stats SimpleLogMatcher %lld matched? %d", (long long)mId, matched);
+ VLOG("Stats SimpleAtomMatcher %lld matched? %d", (long long)mId, matched);
}
} // namespace statsd
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 267b81823688..d67b98620f37 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -614,7 +614,7 @@ public final class ActivityThread extends ClientTransactionHandler {
throw new IllegalStateException(
"Received config update for non-existing activity");
}
- activity.mMainThread.handleActivityConfigurationChanged(this, overrideConfig,
+ activity.mMainThread.handleActivityConfigurationChanged(token, overrideConfig,
newDisplayId);
};
}
@@ -3475,9 +3475,13 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleStartActivity(ActivityClientRecord r,
- PendingTransactionActions pendingActions) {
+ public void handleStartActivity(IBinder token, PendingTransactionActions pendingActions) {
+ final ActivityClientRecord r = mActivities.get(token);
final Activity activity = r.activity;
+ if (r.activity == null) {
+ // TODO(lifecycler): What do we do in this case?
+ return;
+ }
if (!r.stopped) {
throw new IllegalStateException("Can't start activity that is not stopped.");
}
@@ -3683,7 +3687,12 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleNewIntent(ActivityClientRecord r, List<ReferrerIntent> intents) {
+ public void handleNewIntent(IBinder token, List<ReferrerIntent> intents) {
+ final ActivityClientRecord r = mActivities.get(token);
+ if (r == null) {
+ return;
+ }
+
checkAndBlockForNetworkAccess();
deliverNewIntents(r, intents);
}
@@ -3872,7 +3881,13 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handlePictureInPictureRequested(ActivityClientRecord r) {
+ public void handlePictureInPictureRequested(IBinder token) {
+ final ActivityClientRecord r = mActivities.get(token);
+ if (r == null) {
+ Log.w(TAG, "Activity to request PIP to no longer exists");
+ return;
+ }
+
final boolean receivedByApp = r.activity.onPictureInPictureRequested();
if (!receivedByApp) {
// Previous recommendation was for apps to enter picture-in-picture in
@@ -4402,21 +4417,22 @@ public final class ActivityThread extends ClientTransactionHandler {
/**
* Resume the activity.
- * @param r Target activity record.
+ * @param token Target activity token.
* @param finalStateRequest Flag indicating if this is part of final state resolution for a
* transaction.
* @param reason Reason for performing the action.
*
- * @return {@code true} that was resumed, {@code false} otherwise.
+ * @return The {@link ActivityClientRecord} that was resumed, {@code null} otherwise.
*/
@VisibleForTesting
- public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
+ public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
String reason) {
+ final ActivityClientRecord r = mActivities.get(token);
if (localLOGV) {
Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished);
}
- if (r.activity.mFinished) {
- return false;
+ if (r == null || r.activity.mFinished) {
+ return null;
}
if (r.getLifecycleState() == ON_RESUME) {
if (!finalStateRequest) {
@@ -4430,7 +4446,7 @@ public final class ActivityThread extends ClientTransactionHandler {
// handle two resume requests for the final state. For cases other than this
// one, we don't expect it to happen.
}
- return false;
+ return null;
}
if (finalStateRequest) {
r.hideForNow = false;
@@ -4461,7 +4477,7 @@ public final class ActivityThread extends ClientTransactionHandler {
+ r.intent.getComponent().toShortString() + ": " + e.toString(), e);
}
}
- return true;
+ return r;
}
static final void cleanUpPendingRemoveWindows(ActivityClientRecord r, boolean force) {
@@ -4482,19 +4498,20 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
- boolean isForward, String reason) {
+ public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
+ String reason) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
// TODO Push resumeArgs into the activity for consideration
- // skip below steps for double-resume and r.mFinish = true case.
- if (!performResumeActivity(r, finalStateRequest, reason)) {
+ final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
+ if (r == null) {
+ // We didn't actually resume the activity, so skipping any follow-up actions.
return;
}
- if (mActivitiesToBeDestroyed.containsKey(r.token)) {
+ if (mActivitiesToBeDestroyed.containsKey(token)) {
// Although the activity is resumed, it is going to be destroyed. So the following
// UI operations are unnecessary and also prevents exception because its token may
// be gone that window manager cannot recognize it. All necessary cleanup actions
@@ -4612,8 +4629,13 @@ public final class ActivityThread extends ClientTransactionHandler {
@Override
- public void handleTopResumedActivityChanged(ActivityClientRecord r, boolean onTop,
- String reason) {
+ public void handleTopResumedActivityChanged(IBinder token, boolean onTop, String reason) {
+ ActivityClientRecord r = mActivities.get(token);
+ if (r == null || r.activity == null) {
+ Slog.w(TAG, "Not found target activity to report position change for token: " + token);
+ return;
+ }
+
if (DEBUG_ORDER) {
Slog.d(TAG, "Received position change to top: " + onTop + " for activity: " + r);
}
@@ -4646,20 +4668,23 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handlePauseActivity(ActivityClientRecord r, boolean finished, boolean userLeaving,
+ public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
int configChanges, PendingTransactionActions pendingActions, String reason) {
- if (userLeaving) {
- performUserLeavingActivity(r);
- }
+ ActivityClientRecord r = mActivities.get(token);
+ if (r != null) {
+ if (userLeaving) {
+ performUserLeavingActivity(r);
+ }
- r.activity.mConfigChangeFlags |= configChanges;
- performPauseActivity(r, finished, reason, pendingActions);
+ r.activity.mConfigChangeFlags |= configChanges;
+ performPauseActivity(r, finished, reason, pendingActions);
- // Make sure any pending writes are now committed.
- if (r.isPreHoneycomb()) {
- QueuedWork.waitToFinish();
+ // Make sure any pending writes are now committed.
+ if (r.isPreHoneycomb()) {
+ QueuedWork.waitToFinish();
+ }
+ mSomeActivitiesChanged = true;
}
- mSomeActivitiesChanged = true;
}
final void performUserLeavingActivity(ActivityClientRecord r) {
@@ -4756,11 +4781,8 @@ public final class ActivityThread extends ClientTransactionHandler {
r.setState(ON_PAUSE);
}
- // TODO(b/127877792): Make LocalActivityManager call performStopActivityInner. We cannot do this
- // since it's a high usage hidden API.
/** Called from {@link LocalActivityManager}. */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 127877792,
- publicAlternatives = "{@code N/A}")
+ @UnsupportedAppUsage
final void performStopActivity(IBinder token, boolean saveState, String reason) {
ActivityClientRecord r = mActivities.get(token);
performStopActivityInner(r, null /* stopInfo */, saveState, false /* finalStateRequest */,
@@ -4801,37 +4823,39 @@ public final class ActivityThread extends ClientTransactionHandler {
private void performStopActivityInner(ActivityClientRecord r, StopInfo info,
boolean saveState, boolean finalStateRequest, String reason) {
if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
- if (r.stopped) {
- if (r.activity.mFinished) {
- // If we are finishing, we won't call onResume() in certain
- // cases. So here we likewise don't want to call onStop()
- // if the activity isn't resumed.
- return;
- }
- if (!finalStateRequest) {
- final RuntimeException e = new RuntimeException(
- "Performing stop of activity that is already stopped: "
- + r.intent.getComponent().toShortString());
- Slog.e(TAG, e.getMessage(), e);
- Slog.e(TAG, r.getStateString());
+ if (r != null) {
+ if (r.stopped) {
+ if (r.activity.mFinished) {
+ // If we are finishing, we won't call onResume() in certain
+ // cases. So here we likewise don't want to call onStop()
+ // if the activity isn't resumed.
+ return;
+ }
+ if (!finalStateRequest) {
+ final RuntimeException e = new RuntimeException(
+ "Performing stop of activity that is already stopped: "
+ + r.intent.getComponent().toShortString());
+ Slog.e(TAG, e.getMessage(), e);
+ Slog.e(TAG, r.getStateString());
+ }
}
- }
- // One must first be paused before stopped...
- performPauseActivityIfNeeded(r, reason);
+ // One must first be paused before stopped...
+ performPauseActivityIfNeeded(r, reason);
- if (info != null) {
- try {
- // First create a thumbnail for the activity...
- // For now, don't create the thumbnail here; we are
- // doing that by doing a screen snapshot.
- info.setDescription(r.activity.onCreateDescription());
- } catch (Exception e) {
- if (!mInstrumentation.onException(r.activity, e)) {
- throw new RuntimeException(
- "Unable to save state of activity "
- + r.intent.getComponent().toShortString()
- + ": " + e.toString(), e);
+ if (info != null) {
+ try {
+ // First create a thumbnail for the activity...
+ // For now, don't create the thumbnail here; we are
+ // doing that by doing a screen snapshot.
+ info.setDescription(r.activity.onCreateDescription());
+ } catch (Exception e) {
+ if (!mInstrumentation.onException(r.activity, e)) {
+ throw new RuntimeException(
+ "Unable to save state of activity "
+ + r.intent.getComponent().toShortString()
+ + ": " + e.toString(), e);
+ }
}
}
@@ -4903,8 +4927,9 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleStopActivity(ActivityClientRecord r, int configChanges,
+ public void handleStopActivity(IBinder token, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
+ final ActivityClientRecord r = mActivities.get(token);
r.activity.mConfigChangeFlags |= configChanges;
final StopInfo stopInfo = new StopInfo();
@@ -4940,7 +4965,8 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void performRestartActivity(ActivityClientRecord r, boolean start) {
+ public void performRestartActivity(IBinder token, boolean start) {
+ ActivityClientRecord r = mActivities.get(token);
if (r.stopped) {
r.activity.performRestart(start, "performRestartActivity");
if (start) {
@@ -5027,101 +5053,107 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleSendResult(ActivityClientRecord r, List<ResultInfo> results, String reason) {
+ public void handleSendResult(IBinder token, List<ResultInfo> results, String reason) {
+ ActivityClientRecord r = mActivities.get(token);
if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
- final boolean resumed = !r.paused;
- if (!r.activity.mFinished && r.activity.mDecor != null
- && r.hideForNow && resumed) {
- // We had hidden the activity because it started another
- // one... we have gotten a result back and we are not
- // paused, so make sure our window is visible.
- updateVisibility(r, true);
- }
- if (resumed) {
- try {
- // Now we are idle.
- r.activity.mCalled = false;
- mInstrumentation.callActivityOnPause(r.activity);
- if (!r.activity.mCalled) {
- throw new SuperNotCalledException(
- "Activity " + r.intent.getComponent().toShortString()
- + " did not call through to super.onPause()");
- }
- } catch (SuperNotCalledException e) {
- throw e;
- } catch (Exception e) {
- if (!mInstrumentation.onException(r.activity, e)) {
- throw new RuntimeException(
- "Unable to pause activity "
- + r.intent.getComponent().toShortString()
- + ": " + e.toString(), e);
+ if (r != null) {
+ final boolean resumed = !r.paused;
+ if (!r.activity.mFinished && r.activity.mDecor != null
+ && r.hideForNow && resumed) {
+ // We had hidden the activity because it started another
+ // one... we have gotten a result back and we are not
+ // paused, so make sure our window is visible.
+ updateVisibility(r, true);
+ }
+ if (resumed) {
+ try {
+ // Now we are idle.
+ r.activity.mCalled = false;
+ mInstrumentation.callActivityOnPause(r.activity);
+ if (!r.activity.mCalled) {
+ throw new SuperNotCalledException(
+ "Activity " + r.intent.getComponent().toShortString()
+ + " did not call through to super.onPause()");
+ }
+ } catch (SuperNotCalledException e) {
+ throw e;
+ } catch (Exception e) {
+ if (!mInstrumentation.onException(r.activity, e)) {
+ throw new RuntimeException(
+ "Unable to pause activity "
+ + r.intent.getComponent().toShortString()
+ + ": " + e.toString(), e);
+ }
}
}
- }
- checkAndBlockForNetworkAccess();
- deliverResults(r, results, reason);
- if (resumed) {
- r.activity.performResume(false, reason);
+ checkAndBlockForNetworkAccess();
+ deliverResults(r, results, reason);
+ if (resumed) {
+ r.activity.performResume(false, reason);
+ }
}
}
/** Core implementation of activity destroy call. */
- ActivityClientRecord performDestroyActivity(ActivityClientRecord r, boolean finishing,
+ ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance, String reason) {
+ ActivityClientRecord r = mActivities.get(token);
Class<? extends Activity> activityClass = null;
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
- activityClass = r.activity.getClass();
- r.activity.mConfigChangeFlags |= configChanges;
- if (finishing) {
- r.activity.mFinished = true;
- }
+ if (r != null) {
+ activityClass = r.activity.getClass();
+ r.activity.mConfigChangeFlags |= configChanges;
+ if (finishing) {
+ r.activity.mFinished = true;
+ }
- performPauseActivityIfNeeded(r, "destroy");
+ performPauseActivityIfNeeded(r, "destroy");
- if (!r.stopped) {
- callActivityOnStop(r, false /* saveState */, "destroy");
- }
- if (getNonConfigInstance) {
+ if (!r.stopped) {
+ callActivityOnStop(r, false /* saveState */, "destroy");
+ }
+ if (getNonConfigInstance) {
+ try {
+ r.lastNonConfigurationInstances
+ = r.activity.retainNonConfigurationInstances();
+ } catch (Exception e) {
+ if (!mInstrumentation.onException(r.activity, e)) {
+ throw new RuntimeException(
+ "Unable to retain activity "
+ + r.intent.getComponent().toShortString()
+ + ": " + e.toString(), e);
+ }
+ }
+ }
try {
- r.lastNonConfigurationInstances = r.activity.retainNonConfigurationInstances();
+ r.activity.mCalled = false;
+ mInstrumentation.callActivityOnDestroy(r.activity);
+ if (!r.activity.mCalled) {
+ throw new SuperNotCalledException(
+ "Activity " + safeToComponentShortString(r.intent) +
+ " did not call through to super.onDestroy()");
+ }
+ if (r.window != null) {
+ r.window.closeAllPanels();
+ }
+ } catch (SuperNotCalledException e) {
+ throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(r.activity, e)) {
throw new RuntimeException(
- "Unable to retain activity "
- + r.intent.getComponent().toShortString()
+ "Unable to destroy activity " + safeToComponentShortString(r.intent)
+ ": " + e.toString(), e);
}
}
r.setState(ON_DESTROY);
mLastReportedWindowingMode.remove(r.activity.getActivityToken());
}
- try {
- r.activity.mCalled = false;
- mInstrumentation.callActivityOnDestroy(r.activity);
- if (!r.activity.mCalled) {
- throw new SuperNotCalledException(
- "Activity " + safeToComponentShortString(r.intent)
- + " did not call through to super.onDestroy()");
- }
- if (r.window != null) {
- r.window.closeAllPanels();
- }
- } catch (SuperNotCalledException e) {
- throw e;
- } catch (Exception e) {
- if (!mInstrumentation.onException(r.activity, e)) {
- throw new RuntimeException(
- "Unable to destroy activity " + safeToComponentShortString(r.intent)
- + ": " + e.toString(), e);
- }
- }
- r.setState(ON_DESTROY);
schedulePurgeIdler();
// updatePendingActivityConfiguration() reads from mActivities to update
// ActivityClientRecord which runs in a different thread. Protect modifications to
// mActivities to avoid race.
synchronized (mResourcesManager) {
- mActivities.remove(r.token);
+ mActivities.remove(token);
}
StrictMode.decrementExpectedActivityCount(activityClass);
return r;
@@ -5138,67 +5170,70 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void handleDestroyActivity(ActivityClientRecord r, boolean finishing, int configChanges,
+ public void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
boolean getNonConfigInstance, String reason) {
- r = performDestroyActivity(r, finishing, configChanges, getNonConfigInstance, reason);
- cleanUpPendingRemoveWindows(r, finishing);
- WindowManager wm = r.activity.getWindowManager();
- View v = r.activity.mDecor;
- if (v != null) {
- if (r.activity.mVisibleFromServer) {
- mNumVisibleActivities--;
- }
- IBinder wtoken = v.getWindowToken();
- if (r.activity.mWindowAdded) {
- if (r.mPreserveWindow) {
- // Hold off on removing this until the new activity's
- // window is being added.
- r.mPendingRemoveWindow = r.window;
- r.mPendingRemoveWindowManager = wm;
- // We can only keep the part of the view hierarchy that we control,
- // everything else must be removed, because it might not be able to
- // behave properly when activity is relaunching.
- r.window.clearContentView();
- } else {
- wm.removeViewImmediate(v);
+ ActivityClientRecord r = performDestroyActivity(token, finishing,
+ configChanges, getNonConfigInstance, reason);
+ if (r != null) {
+ cleanUpPendingRemoveWindows(r, finishing);
+ WindowManager wm = r.activity.getWindowManager();
+ View v = r.activity.mDecor;
+ if (v != null) {
+ if (r.activity.mVisibleFromServer) {
+ mNumVisibleActivities--;
}
- }
- if (wtoken != null && r.mPendingRemoveWindow == null) {
- WindowManagerGlobal.getInstance().closeAll(wtoken,
- r.activity.getClass().getName(), "Activity");
- } else if (r.mPendingRemoveWindow != null) {
- // We're preserving only one window, others should be closed so app views
- // will be detached before the final tear down. It should be done now because
- // some components (e.g. WebView) rely on detach callbacks to perform receiver
- // unregister and other cleanup.
- WindowManagerGlobal.getInstance().closeAllExceptView(r.token, v,
+ IBinder wtoken = v.getWindowToken();
+ if (r.activity.mWindowAdded) {
+ if (r.mPreserveWindow) {
+ // Hold off on removing this until the new activity's
+ // window is being added.
+ r.mPendingRemoveWindow = r.window;
+ r.mPendingRemoveWindowManager = wm;
+ // We can only keep the part of the view hierarchy that we control,
+ // everything else must be removed, because it might not be able to
+ // behave properly when activity is relaunching.
+ r.window.clearContentView();
+ } else {
+ wm.removeViewImmediate(v);
+ }
+ }
+ if (wtoken != null && r.mPendingRemoveWindow == null) {
+ WindowManagerGlobal.getInstance().closeAll(wtoken,
+ r.activity.getClass().getName(), "Activity");
+ } else if (r.mPendingRemoveWindow != null) {
+ // We're preserving only one window, others should be closed so app views
+ // will be detached before the final tear down. It should be done now because
+ // some components (e.g. WebView) rely on detach callbacks to perform receiver
+ // unregister and other cleanup.
+ WindowManagerGlobal.getInstance().closeAllExceptView(token, v,
+ r.activity.getClass().getName(), "Activity");
+ }
+ r.activity.mDecor = null;
+ }
+ if (r.mPendingRemoveWindow == null) {
+ // If we are delaying the removal of the activity window, then
+ // we can't clean up all windows here. Note that we can't do
+ // so later either, which means any windows that aren't closed
+ // by the app will leak. Well we try to warning them a lot
+ // about leaking windows, because that is a bug, so if they are
+ // using this recreate facility then they get to live with leaks.
+ WindowManagerGlobal.getInstance().closeAll(token,
r.activity.getClass().getName(), "Activity");
}
- r.activity.mDecor = null;
- }
- if (r.mPendingRemoveWindow == null) {
- // If we are delaying the removal of the activity window, then
- // we can't clean up all windows here. Note that we can't do
- // so later either, which means any windows that aren't closed
- // by the app will leak. Well we try to warning them a lot
- // about leaking windows, because that is a bug, so if they are
- // using this recreate facility then they get to live with leaks.
- WindowManagerGlobal.getInstance().closeAll(r.token,
- r.activity.getClass().getName(), "Activity");
- }
- // Mocked out contexts won't be participating in the normal
- // process lifecycle, but if we're running with a proper
- // ApplicationContext we need to have it tear down things
- // cleanly.
- Context c = r.activity.getBaseContext();
- if (c instanceof ContextImpl) {
- ((ContextImpl) c).scheduleFinalCleanup(
- r.activity.getClass().getName(), "Activity");
+ // Mocked out contexts won't be participating in the normal
+ // process lifecycle, but if we're running with a proper
+ // ApplicationContext we need to have it tear down things
+ // cleanly.
+ Context c = r.activity.getBaseContext();
+ if (c instanceof ContextImpl) {
+ ((ContextImpl) c).scheduleFinalCleanup(
+ r.activity.getClass().getName(), "Activity");
+ }
}
if (finishing) {
try {
- ActivityTaskManager.getService().activityDestroyed(r.token);
+ ActivityTaskManager.getService().activityDestroyed(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
@@ -5421,7 +5456,7 @@ public final class ActivityThread extends ClientTransactionHandler {
callActivityOnStop(r, true /* saveState */, reason);
}
- handleDestroyActivity(r, false, configChanges, true, reason);
+ handleDestroyActivity(r.token, false, configChanges, true, reason);
r.activity = null;
r.window = null;
@@ -5449,10 +5484,12 @@ public final class ActivityThread extends ClientTransactionHandler {
}
@Override
- public void reportRelaunch(ActivityClientRecord r, PendingTransactionActions pendingActions) {
+ public void reportRelaunch(IBinder token, PendingTransactionActions pendingActions) {
try {
- ActivityTaskManager.getService().activityRelaunched(r.token);
- if (pendingActions.shouldReportRelaunchToWindowManager() && r.window != null) {
+ ActivityTaskManager.getService().activityRelaunched(token);
+ final ActivityClientRecord r = mActivities.get(token);
+ if (pendingActions.shouldReportRelaunchToWindowManager() && r != null
+ && r.window != null) {
r.window.reportActivityRelaunched();
}
} catch (RemoteException e) {
@@ -5611,7 +5648,13 @@ public final class ActivityThread extends ClientTransactionHandler {
*/
private Configuration performActivityConfigurationChanged(Activity activity,
Configuration newConfig, Configuration amOverrideConfig, int displayId) {
+ if (activity == null) {
+ throw new IllegalArgumentException("No activity provided.");
+ }
final IBinder activityToken = activity.getActivityToken();
+ if (activityToken == null) {
+ throw new IllegalArgumentException("Activity token not set. Is the activity attached?");
+ }
final boolean movedToDifferentDisplay = isDifferentDisplay(activity, displayId);
boolean shouldReportChange = false;
@@ -5911,8 +5954,20 @@ public final class ActivityThread extends ClientTransactionHandler {
* processing any configurations older than {@code overrideConfig}.
*/
@Override
- public void updatePendingActivityConfiguration(ActivityClientRecord r,
+ public void updatePendingActivityConfiguration(IBinder activityToken,
Configuration overrideConfig) {
+ final ActivityClientRecord r;
+ synchronized (mResourcesManager) {
+ r = mActivities.get(activityToken);
+ }
+
+ if (r == null) {
+ if (DEBUG_CONFIGURATION) {
+ Slog.w(TAG, "Not found target activity to update its pending config.");
+ }
+ return;
+ }
+
synchronized (r) {
if (r.mPendingOverrideConfig != null
&& !r.mPendingOverrideConfig.isOtherSeqNewer(overrideConfig)) {
@@ -5932,14 +5987,21 @@ public final class ActivityThread extends ClientTransactionHandler {
* if {@link #updatePendingActivityConfiguration(IBinder, Configuration)} has been called with
* a newer config than {@code overrideConfig}.
*
- * @param r Target activity record.
+ * @param activityToken Target activity token.
* @param overrideConfig Activity override config.
* @param displayId Id of the display where activity was moved to, -1 if there was no move and
* value didn't change.
*/
@Override
- public void handleActivityConfigurationChanged(ActivityClientRecord r,
+ public void handleActivityConfigurationChanged(IBinder activityToken,
@NonNull Configuration overrideConfig, int displayId) {
+ ActivityClientRecord r = mActivities.get(activityToken);
+ // Check input params.
+ if (r == null || r.activity == null) {
+ if (DEBUG_CONFIGURATION) Slog.w(TAG, "Not found target activity to report to: " + r);
+ return;
+ }
+
synchronized (r) {
if (overrideConfig.isOtherSeqNewer(r.mPendingOverrideConfig)) {
if (DEBUG_CONFIGURATION) {
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index ac50676ff46b..2df756e80fde 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -15,8 +15,6 @@
*/
package android.app;
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.ClientTransactionItem;
import android.app.servertransaction.PendingTransactionActions;
@@ -91,38 +89,37 @@ public abstract class ClientTransactionHandler {
public abstract Map<IBinder, ClientTransactionItem> getActivitiesToBeDestroyed();
/** Destroy the activity. */
- public abstract void handleDestroyActivity(@NonNull ActivityClientRecord r, boolean finishing,
- int configChanges, boolean getNonConfigInstance, String reason);
+ public abstract void handleDestroyActivity(IBinder token, boolean finishing, int configChanges,
+ boolean getNonConfigInstance, String reason);
/** Pause the activity. */
- public abstract void handlePauseActivity(@NonNull ActivityClientRecord r, boolean finished,
- boolean userLeaving, int configChanges, PendingTransactionActions pendingActions,
- String reason);
+ public abstract void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
+ int configChanges, PendingTransactionActions pendingActions, String reason);
/**
* Resume the activity.
- * @param r Target activity record.
+ * @param token Target activity token.
* @param finalStateRequest Flag indicating if this call is handling final lifecycle state
* request for a transaction.
* @param isForward Flag indicating if next transition is forward.
* @param reason Reason for performing this operation.
*/
- public abstract void handleResumeActivity(@NonNull ActivityClientRecord r,
- boolean finalStateRequest, boolean isForward, String reason);
+ public abstract void handleResumeActivity(IBinder token, boolean finalStateRequest,
+ boolean isForward, String reason);
/**
* Notify the activity about top resumed state change.
- * @param r Target activity record.
+ * @param token Target activity token.
* @param isTopResumedActivity Current state of the activity, {@code true} if it's the
* topmost resumed activity in the system, {@code false} otherwise.
* @param reason Reason for performing this operation.
*/
- public abstract void handleTopResumedActivityChanged(@NonNull ActivityClientRecord r,
+ public abstract void handleTopResumedActivityChanged(IBinder token,
boolean isTopResumedActivity, String reason);
/**
* Stop the activity.
- * @param r Target activity record.
+ * @param token Target activity token.
* @param configChanges Activity configuration changes.
* @param pendingActions Pending actions to be used on this or later stages of activity
* transaction.
@@ -130,40 +127,38 @@ public abstract class ClientTransactionHandler {
* request for a transaction.
* @param reason Reason for performing this operation.
*/
- public abstract void handleStopActivity(@NonNull ActivityClientRecord r, int configChanges,
+ public abstract void handleStopActivity(IBinder token, int configChanges,
PendingTransactionActions pendingActions, boolean finalStateRequest, String reason);
/** Report that activity was stopped to server. */
public abstract void reportStop(PendingTransactionActions pendingActions);
/** Restart the activity after it was stopped. */
- public abstract void performRestartActivity(@NonNull ActivityClientRecord r, boolean start);
+ public abstract void performRestartActivity(IBinder token, boolean start);
/** Set pending activity configuration in case it will be updated by other transaction item. */
- public abstract void updatePendingActivityConfiguration(@NonNull ActivityClientRecord r,
+ public abstract void updatePendingActivityConfiguration(IBinder activityToken,
Configuration overrideConfig);
/** Deliver activity (override) configuration change. */
- public abstract void handleActivityConfigurationChanged(@NonNull ActivityClientRecord r,
+ public abstract void handleActivityConfigurationChanged(IBinder activityToken,
Configuration overrideConfig, int displayId);
/** Deliver result from another activity. */
- public abstract void handleSendResult(
- @NonNull ActivityClientRecord r, List<ResultInfo> results, String reason);
+ public abstract void handleSendResult(IBinder token, List<ResultInfo> results, String reason);
/** Deliver new intent. */
- public abstract void handleNewIntent(
- @NonNull ActivityClientRecord r, List<ReferrerIntent> intents);
+ public abstract void handleNewIntent(IBinder token, List<ReferrerIntent> intents);
/** Request that an activity enter picture-in-picture. */
- public abstract void handlePictureInPictureRequested(@NonNull ActivityClientRecord r);
+ public abstract void handlePictureInPictureRequested(IBinder token);
/** Perform activity launch. */
- public abstract Activity handleLaunchActivity(@NonNull ActivityClientRecord r,
+ public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent);
/** Perform activity start. */
- public abstract void handleStartActivity(@NonNull ActivityClientRecord r,
+ public abstract void handleStartActivity(IBinder token,
PendingTransactionActions pendingActions);
/** Get package info. */
@@ -181,7 +176,7 @@ public abstract class ClientTransactionHandler {
* Get {@link android.app.ActivityThread.ActivityClientRecord} instance that corresponds to the
* provided token.
*/
- public abstract ActivityClientRecord getActivityClient(IBinder token);
+ public abstract ActivityThread.ActivityClientRecord getActivityClient(IBinder token);
/**
* Prepare activity relaunch to update internal bookkeeping. This is used to track multiple
@@ -196,7 +191,7 @@ public abstract class ClientTransactionHandler {
* @return An initialized instance of {@link ActivityThread.ActivityClientRecord} to use during
* relaunch, or {@code null} if relaunch cancelled.
*/
- public abstract ActivityClientRecord prepareRelaunchActivity(IBinder token,
+ public abstract ActivityThread.ActivityClientRecord prepareRelaunchActivity(IBinder token,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
int configChanges, MergedConfiguration config, boolean preserveWindow);
@@ -205,15 +200,14 @@ public abstract class ClientTransactionHandler {
* @param r Activity client record prepared for relaunch.
* @param pendingActions Pending actions to be used on later stages of activity transaction.
* */
- public abstract void handleRelaunchActivity(@NonNull ActivityClientRecord r,
+ public abstract void handleRelaunchActivity(ActivityThread.ActivityClientRecord r,
PendingTransactionActions pendingActions);
/**
* Report that relaunch request was handled.
- * @param r Target activity record.
+ * @param token Target activity token.
* @param pendingActions Pending actions initialized on earlier stages of activity transaction.
* Used to check if we should report relaunch to WM.
* */
- public abstract void reportRelaunch(@NonNull ActivityClientRecord r,
- PendingTransactionActions pendingActions);
+ public abstract void reportRelaunch(IBinder token, PendingTransactionActions pendingActions);
}
diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java
index d61c5d5ccd3d..7cdf85e0a6b8 100644
--- a/core/java/android/app/LocalActivityManager.java
+++ b/core/java/android/app/LocalActivityManager.java
@@ -49,7 +49,6 @@ public class LocalActivityManager {
private static final String TAG = "LocalActivityManager";
private static final boolean localLOGV = false;
- // TODO(b/127877792): try to remove this and use {@code ActivityClientRecord} instead.
// Internal token for an Activity being managed by LocalActivityManager.
private static class LocalActivityRecord extends Binder {
LocalActivityRecord(String _id, Intent _intent) {
@@ -137,7 +136,7 @@ public class LocalActivityManager {
// startActivity() has not yet been called, so nothing to do.
return;
}
-
+
if (r.curState == INITIALIZING) {
// Get the lastNonConfigurationInstance for the activity
HashMap<String, Object> lastNonConfigurationInstances =
@@ -178,13 +177,12 @@ public class LocalActivityManager {
pendingActions = null;
}
- mActivityThread.handleStartActivity(clientRecord, pendingActions);
+ mActivityThread.handleStartActivity(r, pendingActions);
r.curState = STARTED;
if (desiredState == RESUMED) {
if (localLOGV) Log.v(TAG, r.id + ": resuming");
- mActivityThread.performResumeActivity(clientRecord, true,
- "moveToState-INITIALIZING");
+ mActivityThread.performResumeActivity(r, true, "moveToState-INITIALIZING");
r.curState = RESUMED;
}
@@ -196,21 +194,18 @@ public class LocalActivityManager {
// group's state catches up.
return;
}
-
- final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
-
+
switch (r.curState) {
case CREATED:
if (desiredState == STARTED) {
if (localLOGV) Log.v(TAG, r.id + ": restarting");
- mActivityThread.performRestartActivity(clientRecord, true /* start */);
+ mActivityThread.performRestartActivity(r, true /* start */);
r.curState = STARTED;
}
if (desiredState == RESUMED) {
if (localLOGV) Log.v(TAG, r.id + ": restarting and resuming");
- mActivityThread.performRestartActivity(clientRecord, true /* start */);
- mActivityThread.performResumeActivity(clientRecord, true,
- "moveToState-CREATED");
+ mActivityThread.performRestartActivity(r, true /* start */);
+ mActivityThread.performResumeActivity(r, true, "moveToState-CREATED");
r.curState = RESUMED;
}
return;
@@ -219,8 +214,7 @@ public class LocalActivityManager {
if (desiredState == RESUMED) {
// Need to resume it...
if (localLOGV) Log.v(TAG, r.id + ": resuming");
- mActivityThread.performResumeActivity(clientRecord, true,
- "moveToState-STARTED");
+ mActivityThread.performResumeActivity(r, true, "moveToState-STARTED");
r.instanceState = null;
r.curState = RESUMED;
}
@@ -358,8 +352,7 @@ public class LocalActivityManager {
ArrayList<ReferrerIntent> intents = new ArrayList<>(1);
intents.add(new ReferrerIntent(intent, mParent.getPackageName()));
if (localLOGV) Log.v(TAG, r.id + ": new intent");
- final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
- mActivityThread.handleNewIntent(clientRecord, intents);
+ mActivityThread.handleNewIntent(r, intents);
r.intent = intent;
moveToState(r, mCurState);
if (mSingleMode) {
@@ -406,8 +399,7 @@ public class LocalActivityManager {
performPause(r, finish);
}
if (localLOGV) Log.v(TAG, r.id + ": destroying");
- final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
- mActivityThread.performDestroyActivity(clientRecord, finish, 0 /* configChanges */,
+ mActivityThread.performDestroyActivity(r, finish, 0 /* configChanges */,
false /* getNonConfigInstance */, "LocalActivityManager::performDestroy");
r.activity = null;
r.window = null;
@@ -672,8 +664,7 @@ public class LocalActivityManager {
for (int i=0; i<N; i++) {
LocalActivityRecord r = mActivityArray.get(i);
if (localLOGV) Log.v(TAG, r.id + ": destroying");
- final ActivityClientRecord clientRecord = mActivityThread.getActivityClient(r);
- mActivityThread.performDestroyActivity(clientRecord, finishing, 0 /* configChanges */,
+ mActivityThread.performDestroyActivity(r, finishing, 0 /* configChanges */,
false /* getNonConfigInstance */, "LocalActivityManager::dispatchDestroy");
}
mActivities.clear();
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 54f3f1026050..6c6c04e4e975 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -413,7 +413,7 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
public final void disableLocal() {
synchronized (mLock) {
mDisabled = true;
- mCache.clear();
+ clear();
}
}
@@ -463,7 +463,7 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
cacheName(), mCache.size(),
mLastSeenNonce, currentNonce));
}
- mCache.clear();
+ clear();
mLastSeenNonce = currentNonce;
cachedResult = null;
}
@@ -728,9 +728,13 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
* It's better to use explicit cork and uncork pairs that tighly surround big batches of
* invalidations, but it's not always practical to tell where these invalidation batches
* might occur. AutoCorker's time-based corking is a decent alternative.
+ *
+ * The auto-cork delay is configurable but it should not be too long. The purpose of
+ * the delay is to minimize the number of times a server writes to the system property
+ * when invalidating the cache. One write every 50ms does not hurt system performance.
*/
public static final class AutoCorker {
- public static final int DEFAULT_AUTO_CORK_DELAY_MS = 2000;
+ public static final int DEFAULT_AUTO_CORK_DELAY_MS = 50;
private final String mPropertyName;
private final int mAutoCorkDelayMs;
diff --git a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
index 8a4bee98ca87..8b52242a6b6c 100644
--- a/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
+++ b/core/java/android/app/servertransaction/ActivityConfigurationChangeItem.java
@@ -20,7 +20,6 @@ import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.Display.INVALID_DISPLAY;
import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.content.res.Configuration;
import android.os.IBinder;
@@ -33,24 +32,23 @@ import java.util.Objects;
* Activity configuration changed callback.
* @hide
*/
-public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
+public class ActivityConfigurationChangeItem extends ClientTransactionItem {
private Configuration mConfiguration;
@Override
public void preExecute(android.app.ClientTransactionHandler client, IBinder token) {
- final ActivityClientRecord r = getActivityClientRecord(client, token);
// Notify the client of an upcoming change in the token configuration. This ensures that
// batches of config change items only process the newest configuration.
- client.updatePendingActivityConfiguration(r, mConfiguration);
+ client.updatePendingActivityConfiguration(token, mConfiguration);
}
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
// TODO(lifecycler): detect if PIP or multi-window mode changed and report it here.
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
- client.handleActivityConfigurationChanged(r, mConfiguration, INVALID_DISPLAY);
+ client.handleActivityConfigurationChanged(token, mConfiguration, INVALID_DISPLAY);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -95,7 +93,7 @@ public class ActivityConfigurationChangeItem extends ActivityTransactionItem {
mConfiguration = in.readTypedObject(Configuration.CREATOR);
}
- public static final @NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
+ public static final @android.annotation.NonNull Creator<ActivityConfigurationChangeItem> CREATOR =
new Creator<ActivityConfigurationChangeItem>() {
public ActivityConfigurationChangeItem createFromParcel(Parcel in) {
return new ActivityConfigurationChangeItem(in);
diff --git a/core/java/android/app/servertransaction/ActivityLifecycleItem.java b/core/java/android/app/servertransaction/ActivityLifecycleItem.java
index cadb6606b1be..c9193a9578e7 100644
--- a/core/java/android/app/servertransaction/ActivityLifecycleItem.java
+++ b/core/java/android/app/servertransaction/ActivityLifecycleItem.java
@@ -25,7 +25,7 @@ import java.lang.annotation.RetentionPolicy;
* Request for lifecycle state that an activity should reach.
* @hide
*/
-public abstract class ActivityLifecycleItem extends ActivityTransactionItem {
+public abstract class ActivityLifecycleItem extends ClientTransactionItem {
@IntDef(prefix = { "UNDEFINED", "PRE_", "ON_" }, value = {
UNDEFINED,
diff --git a/core/java/android/app/servertransaction/ActivityRelaunchItem.java b/core/java/android/app/servertransaction/ActivityRelaunchItem.java
index 87ea3f8db39c..9844de7b6e88 100644
--- a/core/java/android/app/servertransaction/ActivityRelaunchItem.java
+++ b/core/java/android/app/servertransaction/ActivityRelaunchItem.java
@@ -18,8 +18,7 @@ package android.app.servertransaction;
import static android.app.ActivityThread.DEBUG_ORDER;
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
+import android.app.ActivityThread;
import android.app.ClientTransactionHandler;
import android.app.ResultInfo;
import android.os.IBinder;
@@ -37,7 +36,7 @@ import java.util.Objects;
* Activity relaunch callback.
* @hide
*/
-public class ActivityRelaunchItem extends ActivityTransactionItem {
+public class ActivityRelaunchItem extends ClientTransactionItem {
private static final String TAG = "ActivityRelaunchItem";
@@ -51,7 +50,7 @@ public class ActivityRelaunchItem extends ActivityTransactionItem {
* A record that was properly configured for relaunch. Execution will be cancelled if not
* initialized after {@link #preExecute(ClientTransactionHandler, IBinder)}.
*/
- private ActivityClientRecord mActivityClientRecord;
+ private ActivityThread.ActivityClientRecord mActivityClientRecord;
@Override
public void preExecute(ClientTransactionHandler client, IBinder token) {
@@ -60,7 +59,7 @@ public class ActivityRelaunchItem extends ActivityTransactionItem {
}
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
if (mActivityClientRecord == null) {
if (DEBUG_ORDER) Slog.d(TAG, "Activity relaunch cancelled");
@@ -74,8 +73,7 @@ public class ActivityRelaunchItem extends ActivityTransactionItem {
@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
- final ActivityClientRecord r = getActivityClientRecord(client, token);
- client.reportRelaunch(r, pendingActions);
+ client.reportRelaunch(token, pendingActions);
}
// ObjectPoolItem implementation
@@ -132,16 +130,16 @@ public class ActivityRelaunchItem extends ActivityTransactionItem {
mPreserveWindow = in.readBoolean();
}
- public static final @NonNull Creator<ActivityRelaunchItem> CREATOR =
+ public static final @android.annotation.NonNull Creator<ActivityRelaunchItem> CREATOR =
new Creator<ActivityRelaunchItem>() {
- public ActivityRelaunchItem createFromParcel(Parcel in) {
- return new ActivityRelaunchItem(in);
- }
-
- public ActivityRelaunchItem[] newArray(int size) {
- return new ActivityRelaunchItem[size];
- }
- };
+ public ActivityRelaunchItem createFromParcel(Parcel in) {
+ return new ActivityRelaunchItem(in);
+ }
+
+ public ActivityRelaunchItem[] newArray(int size) {
+ return new ActivityRelaunchItem[size];
+ }
+ };
@Override
public boolean equals(Object o) {
diff --git a/core/java/android/app/servertransaction/ActivityResultItem.java b/core/java/android/app/servertransaction/ActivityResultItem.java
index 47096a8257e9..4e743caccad6 100644
--- a/core/java/android/app/servertransaction/ActivityResultItem.java
+++ b/core/java/android/app/servertransaction/ActivityResultItem.java
@@ -18,11 +18,10 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.app.ResultInfo;
import android.compat.annotation.UnsupportedAppUsage;
+import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Trace;
@@ -34,7 +33,7 @@ import java.util.Objects;
* Activity result delivery callback.
* @hide
*/
-public class ActivityResultItem extends ActivityTransactionItem {
+public class ActivityResultItem extends ClientTransactionItem {
@UnsupportedAppUsage
private List<ResultInfo> mResultInfoList;
@@ -46,10 +45,10 @@ public class ActivityResultItem extends ActivityTransactionItem {
}*/
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
- client.handleSendResult(r, mResultInfoList, "ACTIVITY_RESULT");
+ client.handleSendResult(token, mResultInfoList, "ACTIVITY_RESULT");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -89,7 +88,7 @@ public class ActivityResultItem extends ActivityTransactionItem {
mResultInfoList = in.createTypedArrayList(ResultInfo.CREATOR);
}
- public static final @NonNull Parcelable.Creator<ActivityResultItem> CREATOR =
+ public static final @android.annotation.NonNull Parcelable.Creator<ActivityResultItem> CREATOR =
new Parcelable.Creator<ActivityResultItem>() {
public ActivityResultItem createFromParcel(Parcel in) {
return new ActivityResultItem(in);
diff --git a/core/java/android/app/servertransaction/ActivityTransactionItem.java b/core/java/android/app/servertransaction/ActivityTransactionItem.java
deleted file mode 100644
index f7d7e9d20ab9..000000000000
--- a/core/java/android/app/servertransaction/ActivityTransactionItem.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.app.servertransaction;
-
-import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE;
-
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
-import android.app.ClientTransactionHandler;
-import android.os.IBinder;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * An activity-targeting callback message to a client that can be scheduled and executed.
- * It also provides nullity-free version of
- * {@link #execute(ClientTransactionHandler, IBinder, PendingTransactionActions)} for child class
- * to inherit.
- *
- * @see ClientTransaction
- * @see ClientTransactionItem
- * @see com.android.server.wm.ClientLifecycleManager
- * @hide
- */
-public abstract class ActivityTransactionItem extends ClientTransactionItem {
- @Override
- public final void execute(ClientTransactionHandler client, IBinder token,
- PendingTransactionActions pendingActions) {
- final ActivityClientRecord r = getActivityClientRecord(client, token);
-
- execute(client, r, pendingActions);
- }
-
- /**
- * Like {@link #execute(ClientTransactionHandler, IBinder, PendingTransactionActions)},
- * but take non-null {@link ActivityClientRecord} as a parameter.
- */
- @VisibleForTesting(visibility = PACKAGE)
- public abstract void execute(@NonNull ClientTransactionHandler client,
- @NonNull ActivityClientRecord r, PendingTransactionActions pendingActions);
-
- @NonNull ActivityClientRecord getActivityClientRecord(
- @NonNull ClientTransactionHandler client, IBinder token) {
- final ActivityClientRecord r = client.getActivityClient(token);
- if (r == null) {
- throw new IllegalArgumentException("Activity client record must not be null to execute "
- + "transaction item");
- }
- if (client.getActivity(token) == null) {
- throw new IllegalArgumentException("Activity must not be null to execute "
- + "transaction item");
- }
- return r;
- }
-}
diff --git a/core/java/android/app/servertransaction/DestroyActivityItem.java b/core/java/android/app/servertransaction/DestroyActivityItem.java
index 1611369497e9..3ee761477efd 100644
--- a/core/java/android/app/servertransaction/DestroyActivityItem.java
+++ b/core/java/android/app/servertransaction/DestroyActivityItem.java
@@ -18,8 +18,6 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
import android.os.Parcel;
@@ -40,10 +38,10 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
}
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
- client.handleDestroyActivity(r, mFinished, mConfigChanges,
+ client.handleDestroyActivity(token, mFinished, mConfigChanges,
false /* getNonConfigInstance */, "DestroyActivityItem");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -94,7 +92,7 @@ public class DestroyActivityItem extends ActivityLifecycleItem {
mConfigChanges = in.readInt();
}
- public static final @NonNull Creator<DestroyActivityItem> CREATOR =
+ public static final @android.annotation.NonNull Creator<DestroyActivityItem> CREATOR =
new Creator<DestroyActivityItem>() {
public DestroyActivityItem createFromParcel(Parcel in) {
return new DestroyActivityItem(in);
diff --git a/core/java/android/app/servertransaction/EnterPipRequestedItem.java b/core/java/android/app/servertransaction/EnterPipRequestedItem.java
index b7e81a56afad..b2a1276fa178 100644
--- a/core/java/android/app/servertransaction/EnterPipRequestedItem.java
+++ b/core/java/android/app/servertransaction/EnterPipRequestedItem.java
@@ -16,20 +16,20 @@
package android.app.servertransaction;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
+import android.os.IBinder;
import android.os.Parcel;
/**
* Request an activity to enter picture-in-picture mode.
* @hide
*/
-public final class EnterPipRequestedItem extends ActivityTransactionItem {
+public final class EnterPipRequestedItem extends ClientTransactionItem {
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
- client.handlePictureInPictureRequested(r);
+ client.handlePictureInPictureRequested(token);
}
// ObjectPoolItem implementation
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index 77457af77340..2e7b6262c785 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -18,7 +18,6 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import android.annotation.NonNull;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.app.ProfilerInfo;
@@ -164,7 +163,7 @@ public class LaunchActivityItem extends ClientTransactionItem {
in.readTypedObject(FixedRotationAdjustments.CREATOR));
}
- public static final @NonNull Creator<LaunchActivityItem> CREATOR =
+ public static final @android.annotation.NonNull Creator<LaunchActivityItem> CREATOR =
new Creator<LaunchActivityItem>() {
public LaunchActivityItem createFromParcel(Parcel in) {
return new LaunchActivityItem(in);
diff --git a/core/java/android/app/servertransaction/MoveToDisplayItem.java b/core/java/android/app/servertransaction/MoveToDisplayItem.java
index 32de53f189b0..9a457a3aad40 100644
--- a/core/java/android/app/servertransaction/MoveToDisplayItem.java
+++ b/core/java/android/app/servertransaction/MoveToDisplayItem.java
@@ -19,7 +19,6 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.content.res.Configuration;
import android.os.IBinder;
@@ -32,24 +31,23 @@ import java.util.Objects;
* Activity move to a different display message.
* @hide
*/
-public class MoveToDisplayItem extends ActivityTransactionItem {
+public class MoveToDisplayItem extends ClientTransactionItem {
private int mTargetDisplayId;
private Configuration mConfiguration;
@Override
public void preExecute(ClientTransactionHandler client, IBinder token) {
- final ActivityClientRecord r = getActivityClientRecord(client, token);
// Notify the client of an upcoming change in the token configuration. This ensures that
// batches of config change items only process the newest configuration.
- client.updatePendingActivityConfiguration(r, mConfiguration);
+ client.updatePendingActivityConfiguration(token, mConfiguration);
}
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityMovedToDisplay");
- client.handleActivityConfigurationChanged(r, mConfiguration, mTargetDisplayId);
+ client.handleActivityConfigurationChanged(token, mConfiguration, mTargetDisplayId);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -98,8 +96,7 @@ public class MoveToDisplayItem extends ActivityTransactionItem {
mConfiguration = in.readTypedObject(Configuration.CREATOR);
}
- public static final @NonNull Creator<MoveToDisplayItem> CREATOR =
- new Creator<MoveToDisplayItem>() {
+ public static final @android.annotation.NonNull Creator<MoveToDisplayItem> CREATOR = new Creator<MoveToDisplayItem>() {
public MoveToDisplayItem createFromParcel(Parcel in) {
return new MoveToDisplayItem(in);
}
diff --git a/core/java/android/app/servertransaction/NewIntentItem.java b/core/java/android/app/servertransaction/NewIntentItem.java
index b4e2a7bfa10f..6a4996da38ca 100644
--- a/core/java/android/app/servertransaction/NewIntentItem.java
+++ b/core/java/android/app/servertransaction/NewIntentItem.java
@@ -19,10 +19,9 @@ package android.app.servertransaction;
import static android.app.servertransaction.ActivityLifecycleItem.ON_RESUME;
import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.compat.annotation.UnsupportedAppUsage;
+import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Trace;
@@ -36,7 +35,7 @@ import java.util.Objects;
* New intent message.
* @hide
*/
-public class NewIntentItem extends ActivityTransactionItem {
+public class NewIntentItem extends ClientTransactionItem {
@UnsupportedAppUsage
private List<ReferrerIntent> mIntents;
@@ -48,10 +47,10 @@ public class NewIntentItem extends ActivityTransactionItem {
}
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
- client.handleNewIntent(r, mIntents);
+ client.handleNewIntent(token, mIntents);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -95,7 +94,7 @@ public class NewIntentItem extends ActivityTransactionItem {
mIntents = in.createTypedArrayList(ReferrerIntent.CREATOR);
}
- public static final @NonNull Parcelable.Creator<NewIntentItem> CREATOR =
+ public static final @android.annotation.NonNull Parcelable.Creator<NewIntentItem> CREATOR =
new Parcelable.Creator<NewIntentItem>() {
public NewIntentItem createFromParcel(Parcel in) {
return new NewIntentItem(in);
diff --git a/core/java/android/app/servertransaction/PauseActivityItem.java b/core/java/android/app/servertransaction/PauseActivityItem.java
index cb154e9585e6..f65c843ee76f 100644
--- a/core/java/android/app/servertransaction/PauseActivityItem.java
+++ b/core/java/android/app/servertransaction/PauseActivityItem.java
@@ -18,9 +18,8 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import android.annotation.NonNull;
+import android.app.ActivityManager;
import android.app.ActivityTaskManager;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
import android.os.Parcel;
@@ -41,10 +40,10 @@ public class PauseActivityItem extends ActivityLifecycleItem {
private boolean mDontReport;
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
- client.handlePauseActivity(r, mFinished, mUserLeaving, mConfigChanges, pendingActions,
+ client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
"PAUSE_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -131,7 +130,7 @@ public class PauseActivityItem extends ActivityLifecycleItem {
mDontReport = in.readBoolean();
}
- public static final @NonNull Creator<PauseActivityItem> CREATOR =
+ public static final @android.annotation.NonNull Creator<PauseActivityItem> CREATOR =
new Creator<PauseActivityItem>() {
public PauseActivityItem createFromParcel(Parcel in) {
return new PauseActivityItem(in);
diff --git a/core/java/android/app/servertransaction/ResumeActivityItem.java b/core/java/android/app/servertransaction/ResumeActivityItem.java
index d2a156c37c90..905076b08e69 100644
--- a/core/java/android/app/servertransaction/ResumeActivityItem.java
+++ b/core/java/android/app/servertransaction/ResumeActivityItem.java
@@ -18,10 +18,8 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
import android.os.Parcel;
@@ -48,10 +46,10 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
}
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
- client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
+ client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -130,7 +128,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
mIsForward = in.readBoolean();
}
- public static final @NonNull Creator<ResumeActivityItem> CREATOR =
+ public static final @android.annotation.NonNull Creator<ResumeActivityItem> CREATOR =
new Creator<ResumeActivityItem>() {
public ResumeActivityItem createFromParcel(Parcel in) {
return new ResumeActivityItem(in);
diff --git a/core/java/android/app/servertransaction/StartActivityItem.java b/core/java/android/app/servertransaction/StartActivityItem.java
index ae0bd24218fb..4fbe02b9cf76 100644
--- a/core/java/android/app/servertransaction/StartActivityItem.java
+++ b/core/java/android/app/servertransaction/StartActivityItem.java
@@ -18,9 +18,8 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
+import android.os.IBinder;
import android.os.Parcel;
import android.os.Trace;
@@ -33,10 +32,10 @@ public class StartActivityItem extends ActivityLifecycleItem {
private static final String TAG = "StartActivityItem";
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "startActivityItem");
- client.handleStartActivity(r, pendingActions);
+ client.handleStartActivity(token, pendingActions);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -80,7 +79,7 @@ public class StartActivityItem extends ActivityLifecycleItem {
// Empty
}
- public static final @NonNull Creator<StartActivityItem> CREATOR =
+ public static final @android.annotation.NonNull Creator<StartActivityItem> CREATOR =
new Creator<StartActivityItem>() {
public StartActivityItem createFromParcel(Parcel in) {
return new StartActivityItem(in);
diff --git a/core/java/android/app/servertransaction/StopActivityItem.java b/core/java/android/app/servertransaction/StopActivityItem.java
index 7708104da16a..8668bd49c8f5 100644
--- a/core/java/android/app/servertransaction/StopActivityItem.java
+++ b/core/java/android/app/servertransaction/StopActivityItem.java
@@ -18,8 +18,6 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import android.annotation.NonNull;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
import android.os.Parcel;
@@ -36,10 +34,10 @@ public class StopActivityItem extends ActivityLifecycleItem {
private int mConfigChanges;
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
- client.handleStopActivity(r, mConfigChanges, pendingActions,
+ client.handleStopActivity(token, mConfigChanges, pendingActions,
true /* finalStateRequest */, "STOP_ACTIVITY_ITEM");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -95,7 +93,7 @@ public class StopActivityItem extends ActivityLifecycleItem {
mConfigChanges = in.readInt();
}
- public static final @NonNull Creator<StopActivityItem> CREATOR =
+ public static final @android.annotation.NonNull Creator<StopActivityItem> CREATOR =
new Creator<StopActivityItem>() {
public StopActivityItem createFromParcel(Parcel in) {
return new StopActivityItem(in);
diff --git a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
index 345c1dd336ab..c7e4c3641631 100644
--- a/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
+++ b/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java
@@ -17,9 +17,7 @@ package android.app.servertransaction;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
-import android.annotation.NonNull;
import android.app.ActivityTaskManager;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.os.IBinder;
import android.os.Parcel;
@@ -30,15 +28,15 @@ import android.os.Trace;
* Top resumed activity changed callback.
* @hide
*/
-public class TopResumedActivityChangeItem extends ActivityTransactionItem {
+public class TopResumedActivityChangeItem extends ClientTransactionItem {
private boolean mOnTop;
@Override
- public void execute(ClientTransactionHandler client, ActivityClientRecord r,
+ public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "topResumedActivityChangeItem");
- client.handleTopResumedActivityChanged(r, mOnTop, "topResumedActivityChangeItem");
+ client.handleTopResumedActivityChanged(token, mOnTop, "topResumedActivityChangeItem");
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -99,16 +97,16 @@ public class TopResumedActivityChangeItem extends ActivityTransactionItem {
mOnTop = in.readBoolean();
}
- public static final @NonNull Creator<TopResumedActivityChangeItem> CREATOR =
+ public static final @android.annotation.NonNull Creator<TopResumedActivityChangeItem> CREATOR =
new Creator<TopResumedActivityChangeItem>() {
- public TopResumedActivityChangeItem createFromParcel(Parcel in) {
- return new TopResumedActivityChangeItem(in);
- }
-
- public TopResumedActivityChangeItem[] newArray(int size) {
- return new TopResumedActivityChangeItem[size];
- }
- };
+ public TopResumedActivityChangeItem createFromParcel(Parcel in) {
+ return new TopResumedActivityChangeItem(in);
+ }
+
+ public TopResumedActivityChangeItem[] newArray(int size) {
+ return new TopResumedActivityChangeItem[size];
+ }
+ };
@Override
public boolean equals(Object o) {
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index 3dcf2cb5f13e..17fcda587322 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -218,29 +218,29 @@ public class TransactionExecutor {
null /* customIntent */);
break;
case ON_START:
- mTransactionHandler.handleStartActivity(r, mPendingActions);
+ mTransactionHandler.handleStartActivity(r.token, mPendingActions);
break;
case ON_RESUME:
- mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
+ mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
- mTransactionHandler.handlePauseActivity(r, false /* finished */,
+ mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
- mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
+ mTransactionHandler.handleStopActivity(r.token, 0 /* configChanges */,
mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
- mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
+ mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
- mTransactionHandler.performRestartActivity(r, false /* start */);
+ mTransactionHandler.performRestartActivity(r.token, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
index bc418061e1d1..b0437ac7284e 100644
--- a/core/java/android/content/res/ApkAssets.java
+++ b/core/java/android/content/res/ApkAssets.java
@@ -101,14 +101,11 @@ public final class ApkAssets {
public @interface FormatType {}
@GuardedBy("this")
- private final long mNativePtr;
+ private long mNativePtr; // final, except cleared in finalizer.
@Nullable
@GuardedBy("this")
- private final StringBlock mStringBlock;
-
- @GuardedBy("this")
- private boolean mOpen = true;
+ private final StringBlock mStringBlock; // null or closed if mNativePtr = 0.
@PropertyFlags
private final int mFlags;
@@ -380,12 +377,16 @@ public final class ApkAssets {
/** @hide */
@Nullable
public OverlayableInfo getOverlayableInfo(String overlayableName) throws IOException {
- return nativeGetOverlayableInfo(mNativePtr, overlayableName);
+ synchronized (this) {
+ return nativeGetOverlayableInfo(mNativePtr, overlayableName);
+ }
}
/** @hide */
public boolean definesOverlayable() throws IOException {
- return nativeDefinesOverlayable(mNativePtr);
+ synchronized (this) {
+ return nativeDefinesOverlayable(mNativePtr);
+ }
}
/**
@@ -412,12 +413,12 @@ public final class ApkAssets {
*/
public void close() {
synchronized (this) {
- if (mOpen) {
- mOpen = false;
+ if (mNativePtr != 0) {
if (mStringBlock != null) {
mStringBlock.close();
}
nativeDestroy(mNativePtr);
+ mNativePtr = 0;
}
}
}
diff --git a/core/java/android/hardware/face/FaceSensorProperties.java b/core/java/android/hardware/face/FaceSensorProperties.java
index e3b2fbb6c614..1015724a485d 100644
--- a/core/java/android/hardware/face/FaceSensorProperties.java
+++ b/core/java/android/hardware/face/FaceSensorProperties.java
@@ -25,20 +25,36 @@ import android.os.Parcelable;
*/
public class FaceSensorProperties implements Parcelable {
+ /**
+ * A statically configured ID representing this sensor. Sensor IDs must be unique across all
+ * biometrics across the device, starting at 0, and in increments of 1.
+ */
public final int sensorId;
+ /**
+ * True if the sensor is able to perform generic face detection, without running the
+ * matching algorithm, and without affecting the lockout counter.
+ */
public final boolean supportsFaceDetection;
+ /**
+ * True if the sensor is able to provide self illumination in dark scenarios, without support
+ * from above the HAL.
+ */
+ public final boolean supportsSelfIllumination;
/**
* Initializes SensorProperties with specified values
*/
- public FaceSensorProperties(int sensorId, boolean supportsFaceDetection) {
+ public FaceSensorProperties(int sensorId, boolean supportsFaceDetection,
+ boolean supportsSelfIllumination) {
this.sensorId = sensorId;
this.supportsFaceDetection = supportsFaceDetection;
+ this.supportsSelfIllumination = supportsSelfIllumination;
}
protected FaceSensorProperties(Parcel in) {
sensorId = in.readInt();
supportsFaceDetection = in.readBoolean();
+ supportsSelfIllumination = in.readBoolean();
}
public static final Creator<FaceSensorProperties> CREATOR =
@@ -63,5 +79,6 @@ public class FaceSensorProperties implements Parcelable {
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(sensorId);
dest.writeBoolean(supportsFaceDetection);
+ dest.writeBoolean(supportsSelfIllumination);
}
}
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index a6b869d19867..1eb3fc11df7b 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -64,10 +64,11 @@ public class GraphicsEnvironment {
private static final String SYSTEM_DRIVER_NAME = "system";
private static final String SYSTEM_DRIVER_VERSION_NAME = "";
private static final long SYSTEM_DRIVER_VERSION_CODE = 0;
- private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
+ private static final String PROPERTY_GFX_DRIVER_PRODUCTION = "ro.gfx.driver.0";
private static final String PROPERTY_GFX_DRIVER_PRERELEASE = "ro.gfx.driver.1";
private static final String PROPERTY_GFX_DRIVER_BUILD_TIME = "ro.gfx.driver_build_time";
- private static final String METADATA_DRIVER_BUILD_TIME = "com.android.gamedriver.build_time";
+ private static final String METADATA_DRIVER_BUILD_TIME =
+ "com.android.graphics.updatabledriver.build_time";
private static final String METADATA_DEVELOPER_DRIVER_ENABLE =
"com.android.graphics.developerdriver.enable";
private static final String METADATA_INJECT_LAYERS_ENABLE =
@@ -78,20 +79,20 @@ public class GraphicsEnvironment {
private static final String ACTION_ANGLE_FOR_ANDROID_TOAST_MESSAGE =
"android.app.action.ANGLE_FOR_ANDROID_TOAST_MESSAGE";
private static final String INTENT_KEY_A4A_TOAST_MESSAGE = "A4A Toast Message";
- private static final String GAME_DRIVER_ALLOWLIST_ALL = "*";
- private static final String GAME_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt";
+ private static final String UPDATABLE_DRIVER_ALLOWLIST_ALL = "*";
+ private static final String UPDATABLE_DRIVER_SPHAL_LIBRARIES_FILENAME = "sphal_libraries.txt";
private static final int VULKAN_1_0 = 0x00400000;
private static final int VULKAN_1_1 = 0x00401000;
- // GAME_DRIVER_ALL_APPS
+ // UPDATABLE_DRIVER_ALL_APPS
// 0: Default (Invalid values fallback to default as well)
- // 1: All apps use Game Driver
- // 2: All apps use Prerelease Driver
+ // 1: All apps use updatable production driver
+ // 2: All apps use updatable prerelease driver
// 3: All apps use system graphics driver
- private static final int GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT = 0;
- private static final int GAME_DRIVER_GLOBAL_OPT_IN_GAME_DRIVER = 1;
- private static final int GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2;
- private static final int GAME_DRIVER_GLOBAL_OPT_IN_OFF = 3;
+ private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_DEFAULT = 0;
+ private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRODUCTION_DRIVER = 1;
+ private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER = 2;
+ private static final int UPDATABLE_DRIVER_GLOBAL_OPT_IN_OFF = 3;
private ClassLoader mClassLoader;
private String mLibrarySearchPaths;
@@ -722,14 +723,17 @@ public class GraphicsEnvironment {
* Return the driver package name to use. Return null for system driver.
*/
private static String chooseDriverInternal(Bundle coreSettings, ApplicationInfo ai) {
- final String gameDriver = SystemProperties.get(PROPERTY_GFX_DRIVER);
- final boolean hasGameDriver = gameDriver != null && !gameDriver.isEmpty();
+ final String productionDriver = SystemProperties.get(PROPERTY_GFX_DRIVER_PRODUCTION);
+ final boolean hasProductionDriver = productionDriver != null && !productionDriver.isEmpty();
final String prereleaseDriver = SystemProperties.get(PROPERTY_GFX_DRIVER_PRERELEASE);
final boolean hasPrereleaseDriver = prereleaseDriver != null && !prereleaseDriver.isEmpty();
- if (!hasGameDriver && !hasPrereleaseDriver) {
- if (DEBUG) Log.v(TAG, "Neither Game Driver nor prerelease driver is supported.");
+ if (!hasProductionDriver && !hasPrereleaseDriver) {
+ if (DEBUG) {
+ Log.v(TAG,
+ "Neither updatable production driver nor prerelease driver is supported.");
+ }
return null;
}
@@ -745,56 +749,59 @@ public class GraphicsEnvironment {
(ai.metaData != null && ai.metaData.getBoolean(METADATA_DEVELOPER_DRIVER_ENABLE))
|| isDebuggable();
- // Priority for Game Driver settings global on confliction (Higher priority comes first):
- // 1. GAME_DRIVER_ALL_APPS
- // 2. GAME_DRIVER_OPT_OUT_APPS
- // 3. GAME_DRIVER_PRERELEASE_OPT_IN_APPS
- // 4. GAME_DRIVER_OPT_IN_APPS
- // 5. GAME_DRIVER_DENYLIST
- // 6. GAME_DRIVER_ALLOWLIST
- switch (coreSettings.getInt(Settings.Global.GAME_DRIVER_ALL_APPS, 0)) {
- case GAME_DRIVER_GLOBAL_OPT_IN_OFF:
- if (DEBUG) Log.v(TAG, "Game Driver is turned off on this device.");
+ // Priority of updatable driver settings on confliction (Higher priority comes first):
+ // 1. UPDATABLE_DRIVER_ALL_APPS
+ // 2. UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS
+ // 3. UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS
+ // 4. UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS
+ // 5. UPDATABLE_DRIVER_PRODUCTION_DENYLIST
+ // 6. UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST
+ switch (coreSettings.getInt(Settings.Global.UPDATABLE_DRIVER_ALL_APPS, 0)) {
+ case UPDATABLE_DRIVER_GLOBAL_OPT_IN_OFF:
+ if (DEBUG) Log.v(TAG, "updatable driver is turned off on this device.");
return null;
- case GAME_DRIVER_GLOBAL_OPT_IN_GAME_DRIVER:
- if (DEBUG) Log.v(TAG, "All apps opt in to use Game Driver.");
- return hasGameDriver ? gameDriver : null;
- case GAME_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER:
- if (DEBUG) Log.v(TAG, "All apps opt in to use prerelease driver.");
+ case UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRODUCTION_DRIVER:
+ if (DEBUG) Log.v(TAG, "All apps opt in to use updatable production driver.");
+ return hasProductionDriver ? productionDriver : null;
+ case UPDATABLE_DRIVER_GLOBAL_OPT_IN_PRERELEASE_DRIVER:
+ if (DEBUG) Log.v(TAG, "All apps opt in to use updatable prerelease driver.");
return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null;
- case GAME_DRIVER_GLOBAL_OPT_IN_DEFAULT:
+ case UPDATABLE_DRIVER_GLOBAL_OPT_IN_DEFAULT:
default:
break;
}
final String appPackageName = ai.packageName;
- if (getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_OPT_OUT_APPS)
+ if (getGlobalSettingsString(null, coreSettings,
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS)
.contains(appPackageName)) {
- if (DEBUG) Log.v(TAG, "App opts out for Game Driver.");
+ if (DEBUG) Log.v(TAG, "App opts out for updatable production driver.");
return null;
}
if (getGlobalSettingsString(
- null, coreSettings, Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS)
+ null, coreSettings, Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS)
.contains(appPackageName)) {
- if (DEBUG) Log.v(TAG, "App opts in for prerelease Game Driver.");
+ if (DEBUG) Log.v(TAG, "App opts in for updatable prerelease driver.");
return hasPrereleaseDriver && enablePrereleaseDriver ? prereleaseDriver : null;
}
- // Early return here since the rest logic is only for Game Driver.
- if (!hasGameDriver) {
- if (DEBUG) Log.v(TAG, "Game Driver is not supported on the device.");
+ // Early return here since the rest logic is only for updatable production Driver.
+ if (!hasProductionDriver) {
+ if (DEBUG) Log.v(TAG, "Updatable production driver is not supported on the device.");
return null;
}
final boolean isOptIn =
- getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_OPT_IN_APPS)
+ getGlobalSettingsString(null, coreSettings,
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS)
.contains(appPackageName);
final List<String> allowlist =
- getGlobalSettingsString(null, coreSettings, Settings.Global.GAME_DRIVER_ALLOWLIST);
- if (!isOptIn && allowlist.indexOf(GAME_DRIVER_ALLOWLIST_ALL) != 0
+ getGlobalSettingsString(null, coreSettings,
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST);
+ if (!isOptIn && allowlist.indexOf(UPDATABLE_DRIVER_ALLOWLIST_ALL) != 0
&& !allowlist.contains(appPackageName)) {
- if (DEBUG) Log.v(TAG, "App is not on the allowlist for Game Driver.");
+ if (DEBUG) Log.v(TAG, "App is not on the allowlist for updatable production driver.");
return null;
}
@@ -802,13 +809,13 @@ public class GraphicsEnvironment {
// terminate early if it's on the denylist and fallback to system driver.
if (!isOptIn
&& getGlobalSettingsString(
- null, coreSettings, Settings.Global.GAME_DRIVER_DENYLIST)
+ null, coreSettings, Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST)
.contains(appPackageName)) {
- if (DEBUG) Log.v(TAG, "App is on the denylist for Game Driver.");
+ if (DEBUG) Log.v(TAG, "App is on the denylist for updatable production driver.");
return null;
}
- return gameDriver;
+ return productionDriver;
}
/**
@@ -873,7 +880,7 @@ public class GraphicsEnvironment {
final String driverBuildTime = driverAppInfo.metaData.getString(METADATA_DRIVER_BUILD_TIME);
if (driverBuildTime == null || driverBuildTime.isEmpty()) {
- throw new IllegalArgumentException("com.android.gamedriver.build_time is not set");
+ Log.v(TAG, "com.android.graphics.updatabledriver.build_time is not set");
}
// driver_build_time in the meta-data is in "L<Unix epoch timestamp>" format. e.g. L123456.
// Long.parseLong will throw if the meta-data "driver_build_time" is not set properly.
@@ -901,7 +908,7 @@ public class GraphicsEnvironment {
final Context driverContext =
context.createPackageContext(driverPackageName, Context.CONTEXT_RESTRICTED);
final BufferedReader reader = new BufferedReader(new InputStreamReader(
- driverContext.getAssets().open(GAME_DRIVER_SPHAL_LIBRARIES_FILENAME)));
+ driverContext.getAssets().open(UPDATABLE_DRIVER_SPHAL_LIBRARIES_FILENAME)));
final ArrayList<String> assetStrings = new ArrayList<>();
for (String assetString; (assetString = reader.readLine()) != null;) {
assetStrings.add(assetString);
@@ -913,7 +920,7 @@ public class GraphicsEnvironment {
}
} catch (IOException e) {
if (DEBUG) {
- Log.w(TAG, "Failed to load '" + GAME_DRIVER_SPHAL_LIBRARIES_FILENAME + "'");
+ Log.w(TAG, "Failed to load '" + UPDATABLE_DRIVER_SPHAL_LIBRARIES_FILENAME + "'");
}
}
return "";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 857e5dbf4a21..6903a995bf7b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -9037,6 +9037,13 @@ public final class Settings {
"accessibility_magnification_capability";
/**
+ * Whether the Adaptive connectivity option is enabled.
+ *
+ * @hide
+ */
+ public static final String ADAPTIVE_CONNECTIVITY_ENABLED = "adaptive_connectivity_enabled";
+
+ /**
* Keys we no longer back up under the current schema, but want to continue to
* process when restoring historical backup datasets.
*
@@ -12362,63 +12369,71 @@ public final class Settings {
"show_angle_in_use_dialog_box";
/**
- * Game Driver global preference for all Apps.
+ * Updatable driver global preference for all Apps.
* 0 = Default
- * 1 = All Apps use Game Driver
- * 2 = All Apps use system graphics driver
+ * 1 = All Apps use updatable production driver
+ * 2 = All apps use updatable prerelease driver
+ * 3 = All Apps use system graphics driver
* @hide
*/
- public static final String GAME_DRIVER_ALL_APPS = "game_driver_all_apps";
+ public static final String UPDATABLE_DRIVER_ALL_APPS = "updatable_driver_all_apps";
/**
- * List of Apps selected to use Game Driver.
+ * List of Apps selected to use updatable production driver.
* i.e. <pkg1>,<pkg2>,...,<pkgN>
* @hide
*/
- public static final String GAME_DRIVER_OPT_IN_APPS = "game_driver_opt_in_apps";
+ public static final String UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS =
+ "updatable_driver_production_opt_in_apps";
/**
- * List of Apps selected to use prerelease Game Driver.
+ * List of Apps selected to use updatable prerelease driver.
* i.e. <pkg1>,<pkg2>,...,<pkgN>
* @hide
*/
- public static final String GAME_DRIVER_PRERELEASE_OPT_IN_APPS =
- "game_driver_prerelease_opt_in_apps";
+ public static final String UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS =
+ "updatable_driver_prerelease_opt_in_apps";
/**
- * List of Apps selected not to use Game Driver.
+ * List of Apps selected not to use updatable production driver.
* i.e. <pkg1>,<pkg2>,...,<pkgN>
* @hide
*/
- public static final String GAME_DRIVER_OPT_OUT_APPS = "game_driver_opt_out_apps";
+ public static final String UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS =
+ "updatable_driver_production_opt_out_apps";
/**
- * Apps on the denylist that are forbidden to use Game Driver.
+ * Apps on the denylist that are forbidden to use updatable production driver.
* @hide
*/
- public static final String GAME_DRIVER_DENYLIST = "game_driver_denylist";
+ public static final String UPDATABLE_DRIVER_PRODUCTION_DENYLIST =
+ "updatable_driver_production_denylist";
/**
- * List of denylists, each denylist is a denylist for a specific version of Game Driver.
+ * List of denylists, each denylist is a denylist for a specific version of
+ * updatable production driver.
* @hide
*/
- public static final String GAME_DRIVER_DENYLISTS = "game_driver_denylists";
+ public static final String UPDATABLE_DRIVER_PRODUCTION_DENYLISTS =
+ "updatable_driver_production_denylists";
/**
- * Apps on the allowlist that are allowed to use Game Driver.
+ * Apps on the allowlist that are allowed to use updatable production driver.
* The string is a list of application package names, seperated by comma.
* i.e. <apk1>,<apk2>,...,<apkN>
* @hide
*/
- public static final String GAME_DRIVER_ALLOWLIST = "game_driver_allowlist";
+ public static final String UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST =
+ "updatable_driver_production_allowlist";
/**
- * List of libraries in sphal accessible by Game Driver
+ * List of libraries in sphal accessible by updatable driver
* The string is a list of library names, separated by colon.
* i.e. <lib1>:<lib2>:...:<libN>
* @hide
*/
- public static final String GAME_DRIVER_SPHAL_LIBRARIES = "game_driver_sphal_libraries";
+ public static final String UPDATABLE_DRIVER_SPHAL_LIBRARIES =
+ "updatable_driver_sphal_libraries";
/**
* Ordered GPU debug layer list for Vulkan
diff --git a/core/java/android/service/autofill/InlinePresentation.java b/core/java/android/service/autofill/InlinePresentation.java
index 914169485979..6eb2a15eec44 100644
--- a/core/java/android/service/autofill/InlinePresentation.java
+++ b/core/java/android/service/autofill/InlinePresentation.java
@@ -40,6 +40,11 @@ public final class InlinePresentation implements Parcelable {
/**
* Represents the UI content and the action for the inline suggestion.
+ *
+ * <p>The Slice should be constructed using the Content builder provided in the androidx
+ * autofill library e.g. {@code androidx.autofill.inline.v1.InlineSuggestionUi.Content.Builder}
+ * and then converted to a Slice with
+ * {@code androidx.autofill.inline.UiVersions.Content#getSlice()}.</p>
*/
private final @NonNull Slice mSlice;
@@ -90,6 +95,11 @@ public final class InlinePresentation implements Parcelable {
*
* @param slice
* Represents the UI content and the action for the inline suggestion.
+ *
+ * <p>The Slice should be constructed using the Content builder provided in the androidx
+ * autofill library e.g. {@code androidx.autofill.inline.v1.InlineSuggestionUi.Content.Builder}
+ * and then converted to a Slice with
+ * {@code androidx.autofill.inline.UiVersions.Content#getSlice()}.</p>
* @param inlinePresentationSpec
* Specifies the UI specification for the inline suggestion.
* @param pinned
@@ -118,6 +128,11 @@ public final class InlinePresentation implements Parcelable {
/**
* Represents the UI content and the action for the inline suggestion.
+ *
+ * <p>The Slice should be constructed using the Content builder provided in the androidx
+ * autofill library e.g. {@code androidx.autofill.inline.v1.InlineSuggestionUi.Content.Builder}
+ * and then converted to a Slice with
+ * {@code androidx.autofill.inline.UiVersions.Content#getSlice()}.</p>
*/
@DataClass.Generated.Member
public @NonNull Slice getSlice() {
@@ -244,7 +259,7 @@ public final class InlinePresentation implements Parcelable {
};
@DataClass.Generated(
- time = 1593131904745L,
+ time = 1596484869201L,
codegenVersion = "1.0.15",
sourceFile = "frameworks/base/core/java/android/service/autofill/InlinePresentation.java",
inputSignatures = "private final @android.annotation.NonNull android.app.slice.Slice mSlice\nprivate final @android.annotation.NonNull android.widget.inline.InlinePresentationSpec mInlinePresentationSpec\nprivate final boolean mPinned\npublic @android.annotation.NonNull @android.annotation.Size(min=0L) java.lang.String[] getAutofillHints()\nclass InlinePresentation extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genHiddenConstDefs=true, genEqualsHashCode=true)")
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 7923ff0991d8..32ee290a0f47 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -534,7 +534,8 @@ public interface WindowManager extends ViewManager {
ScreenshotSource.SCREENSHOT_KEY_OTHER,
ScreenshotSource.SCREENSHOT_OVERVIEW,
ScreenshotSource.SCREENSHOT_ACCESSIBILITY_ACTIONS,
- ScreenshotSource.SCREENSHOT_OTHER})
+ ScreenshotSource.SCREENSHOT_OTHER,
+ ScreenshotSource.SCREENSHOT_VENDOR_GESTURE})
@interface ScreenshotSource {
int SCREENSHOT_GLOBAL_ACTIONS = 0;
int SCREENSHOT_KEY_CHORD = 1;
@@ -542,6 +543,7 @@ public interface WindowManager extends ViewManager {
int SCREENSHOT_OVERVIEW = 3;
int SCREENSHOT_ACCESSIBILITY_ACTIONS = 4;
int SCREENSHOT_OTHER = 5;
+ int SCREENSHOT_VENDOR_GESTURE = 6;
}
/**
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 28644858377a..7cc347d25458 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -294,7 +294,7 @@ public final class InputMethodInfo implements Parcelable {
*/
public InputMethodInfo(String packageName, String className,
CharSequence label, String settingsActivity) {
- this(buildDummyResolveInfo(packageName, className, label), false /* isAuxIme */,
+ this(buildFakeResolveInfo(packageName, className, label), false /* isAuxIme */,
settingsActivity, null /* subtypes */, 0 /* isDefaultResId */,
false /* forceDefault */, true /* supportsSwitchingToNextInputMethod */,
false /* inlineSuggestionsEnabled */, false /* isVrOnly */);
@@ -344,7 +344,7 @@ public final class InputMethodInfo implements Parcelable {
mIsVrOnly = isVrOnly;
}
- private static ResolveInfo buildDummyResolveInfo(String packageName, String className,
+ private static ResolveInfo buildFakeResolveInfo(String packageName, String className,
CharSequence label) {
ResolveInfo ri = new ResolveInfo();
ServiceInfo si = new ServiceInfo();
diff --git a/core/java/android/widget/inline/InlinePresentationSpec.java b/core/java/android/widget/inline/InlinePresentationSpec.java
index 5f924c6ae194..e7727fd9ff1d 100644
--- a/core/java/android/widget/inline/InlinePresentationSpec.java
+++ b/core/java/android/widget/inline/InlinePresentationSpec.java
@@ -42,8 +42,13 @@ public final class InlinePresentationSpec implements Parcelable {
private final Size mMaxSize;
/**
- * The extras encoding the UI style information. Defaults to {@code Bundle.Empty} in which case
- * the default system UI style will be used.
+ * The extras encoding the UI style information.
+ *
+ * <p>The style bundles can be created using the relevant Style classes and their builders in
+ * the androidx autofill library e.g. {@code androidx.autofill.inline.UiVersions.StylesBuilder}.
+ * </p>
+ *
+ * <p>The style must be set for the suggestion to render properly.</p>
*
* <p>Note: There should be no remote objects in the bundle, all included remote objects will
* be removed from the bundle before transmission.</p>
@@ -123,8 +128,13 @@ public final class InlinePresentationSpec implements Parcelable {
}
/**
- * The extras encoding the UI style information. Defaults to {@code Bundle.Empty} in which case
- * the default system UI style will be used.
+ * The extras encoding the UI style information.
+ *
+ * <p>The style bundles can be created using the relevant Style classes and their builders in
+ * the androidx autofill library e.g. {@code androidx.autofill.inline.UiVersions.StylesBuilder}.
+ * </p>
+ *
+ * <p>The style must be set for the suggestion to render properly.</p>
*
* <p>Note: There should be no remote objects in the bundle, all included remote objects will
* be removed from the bundle before transmission.</p>
@@ -264,8 +274,13 @@ public final class InlinePresentationSpec implements Parcelable {
}
/**
- * The extras encoding the UI style information. Defaults to {@code Bundle.Empty} in which case
- * the default system UI style will be used.
+ * The extras encoding the UI style information.
+ *
+ * <p>The style bundles can be created using the relevant Style classes and their builders in
+ * the androidx autofill library e.g. {@code androidx.autofill.inline.UiVersions.StylesBuilder}.
+ * </p>
+ *
+ * <p>The style must be set for the suggestion to render properly.</p>
*
* <p>Note: There should be no remote objects in the bundle, all included remote objects will
* be removed from the bundle before transmission.</p>
@@ -302,7 +317,7 @@ public final class InlinePresentationSpec implements Parcelable {
}
@DataClass.Generated(
- time = 1588109681295L,
+ time = 1596485189661L,
codegenVersion = "1.0.15",
sourceFile = "frameworks/base/core/java/android/widget/inline/InlinePresentationSpec.java",
inputSignatures = "private final @android.annotation.NonNull android.util.Size mMinSize\nprivate final @android.annotation.NonNull android.util.Size mMaxSize\nprivate final @android.annotation.NonNull android.os.Bundle mStyle\nprivate static @android.annotation.NonNull android.os.Bundle defaultStyle()\nprivate boolean styleEquals(android.os.Bundle)\npublic void filterContentTypes()\nclass InlinePresentationSpec extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nclass BaseBuilder extends java.lang.Object implements []")
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 0d65bd1cf9bb..6eb89040998a 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2345,10 +2345,10 @@ enum PageId {
// OS: Q
ZEN_CUSTOM_SETTINGS_DIALOG = 1612;
- // OPEN: Settings > Developer Options > Game Driver Preferences
+ // OPEN: Settings > Developer Options > Graphics Driver Preferences
// CATEGORY: SETTINGS
// OS: Q
- SETTINGS_GAME_DRIVER_DASHBOARD = 1613;
+ SETTINGS_GRAPHICS_DRIVER_DASHBOARD = 1613;
// OPEN: Settings > Accessibility > Vibration > Ring vibration
// CATEGORY: SETTINGS
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index e4a142b3335b..d5619ca96fbd 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -433,35 +433,36 @@ message GlobalSettingsProto {
// Ordered GPU debug layer list for GLES
// i.e. <layer1>:<layer2>:...:<layerN>
optional SettingProto debug_layers_gles = 7;
- // Game Driver - global preference for all Apps
+ // Updatable Driver - global preference for all Apps
// 0 = Default
- // 1 = All Apps use Game Driver
- // 2 = All Apps use system graphics driver
- optional SettingProto game_driver_all_apps = 8;
- // Game Driver - List of Apps selected to use Game Driver
+ // 1 = All Apps use updatable production driver
+ // 2 = All apps use updatable prerelease driver
+ // 3 = All Apps use system graphics driver
+ optional SettingProto updatable_driver_all_apps = 8;
+ // Updatable Driver - List of Apps selected to use updatable production driver
// i.e. <pkg1>,<pkg2>,...,<pkgN>
- optional SettingProto game_driver_opt_in_apps = 9;
- // Game Driver - List of Apps selected not to use Game Driver
+ optional SettingProto updatable_driver_production_opt_in_apps = 9;
+ // Updatable Driver - List of Apps selected not to use updatable production driver
// i.e. <pkg1>,<pkg2>,...,<pkgN>
- optional SettingProto game_driver_opt_out_apps = 10;
- // Game Driver - List of Apps that are forbidden to use Game Driver
- optional SettingProto game_driver_denylist = 11;
- // Game Driver - List of Apps that are allowed to use Game Driver
- optional SettingProto game_driver_allowlist = 12;
+ optional SettingProto updatable_driver_production_opt_out_apps = 10;
+ // Updatable Driver - List of Apps that are forbidden to use updatable production driver
+ optional SettingProto updatable_driver_production_denylist = 11;
+ // Updatable Driver - List of Apps that are allowed to use updatable production driver
+ optional SettingProto updatable_driver_production_allowlist = 12;
// ANGLE - List of Apps that can check ANGLE rules
optional SettingProto angle_allowlist = 13;
- // Game Driver - List of denylists, each denylist is a denylist for
- // a specific Game Driver version
- optional SettingProto game_driver_denylists = 14;
+ // Updatable Driver - List of denylists, each denylist is a denylist for
+ // a specific updatable production driver version
+ optional SettingProto updatable_driver_production_denylists = 14;
// ANGLE - Show a dialog box when ANGLE is selected for the currently running PKG
optional SettingProto show_angle_in_use_dialog = 15;
- // Game Driver - List of libraries in sphal accessible by Game Driver
- optional SettingProto game_driver_sphal_libraries = 16;
+ // Updatable Driver - List of libraries in sphal accessible by updatable driver
+ optional SettingProto updatable_driver_sphal_libraries = 16;
// ANGLE - External package containing ANGLE libraries
optional SettingProto angle_debug_package = 17;
- // Game Driver - List of Apps selected to use prerelease Game Driver
+ // Updatable Driver - List of Apps selected to use updatable prerelease driver
// i.e. <pkg1>,<pkg2>,...,<pkgN>
- optional SettingProto game_driver_prerelease_opt_in_apps = 18;
+ optional SettingProto updatable_driver_prerelease_opt_in_apps = 18;
}
optional Gpu gpu = 59;
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 541e018d079b..3d12d072eb80 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -181,6 +181,7 @@ message SecureSettingsProto {
optional SettingProto cmas_additional_broadcast_pkg = 14 [ (android.privacy).dest = DEST_AUTOMATIC ];
repeated SettingProto completed_categories = 15;
optional SettingProto connectivity_release_pending_intent_delay_ms = 16 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto adaptive_connectivity_enabled = 84 [ (android.privacy).dest = DEST_AUTOMATIC ];
message Controls {
option (android.msg_privacy).dest = DEST_EXPLICIT;
@@ -614,5 +615,5 @@ message SecureSettingsProto {
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 84;
+ // Next tag = 85;
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 613111d512be..5f2e4f905b1c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -4212,15 +4212,20 @@
</integer-array>
<!-- Messages that should not be shown to the user during face authentication, on
- BiometricPrompt. This should be used to hide messages that may be too chatty or messages that
- the user can't do much about. Entries are defined in
- android.hardware.biometrics.face@1.0 types.hal -->
+ BiometricPrompt. This should be used to hide messages that may be too chatty or messages
+ that the user can't do much about. Entries are defined in
+ android.hardware.biometrics.face@1.0 types.hal -->
<integer-array name="config_face_acquire_biometricprompt_ignorelist" translatable="false" >
</integer-array>
<!-- Same as the above, but are defined by vendorCodes -->
<integer-array name="config_face_acquire_vendor_biometricprompt_ignorelist" translatable="false" >
</integer-array>
+ <!-- True if the sensor is able to provide self illumination in dark secnarios, without support
+ from above the HAL. This configuration is only applicable to IBiometricsFace@1.0 and its
+ minor revisions. -->
+ <bool name="config_faceAuthSupportsSelfIllumination">true</bool>
+
<!-- If face auth sends the user directly to home/last open app, or stays on keyguard -->
<bool name="config_faceAuthDismissesKeyguard">true</bool>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 781e7cff4470..35ce780d3408 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2514,6 +2514,7 @@
<java-symbol type="array" name="config_face_acquire_vendor_keyguard_ignorelist" />
<java-symbol type="array" name="config_face_acquire_biometricprompt_ignorelist" />
<java-symbol type="array" name="config_face_acquire_vendor_biometricprompt_ignorelist" />
+ <java-symbol type="bool" name="config_faceAuthSupportsSelfIllumination" />
<java-symbol type="bool" name="config_faceAuthDismissesKeyguard" />
<!-- Face config -->
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 896a53486311..000e870369db 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -25,14 +25,14 @@ import static android.view.Display.INVALID_DISPLAY;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityThread;
-import android.app.ActivityThread.ActivityClientRecord;
import android.app.IApplicationThread;
import android.app.PictureInPictureParams;
import android.app.ResourcesManager;
@@ -114,12 +114,11 @@ public class ActivityThreadTest {
final ActivityThread activityThread = activity.getActivityThread();
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
activityThread.executeTransaction(newResumeTransaction(activity));
- final ActivityClientRecord r = getActivityClientRecord(activity);
- assertFalse(activityThread.performResumeActivity(r, true /* finalStateRequest */,
- "test"));
+ assertNull(activityThread.performResumeActivity(activity.getActivityToken(),
+ true /* finalStateRequest */, "test"));
- assertFalse(activityThread.performResumeActivity(r, false /* finalStateRequest */,
- "test"));
+ assertNull(activityThread.performResumeActivity(activity.getActivityToken(),
+ false /* finalStateRequest */, "test"));
});
}
@@ -245,18 +244,20 @@ public class ActivityThreadTest {
newerConfig.orientation = orientation == ORIENTATION_LANDSCAPE
? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
newerConfig.seq = seq + 2;
- final ActivityClientRecord r = getActivityClientRecord(activity);
- activityThread.updatePendingActivityConfiguration(r, newerConfig);
+ activityThread.updatePendingActivityConfiguration(activity.getActivityToken(),
+ newerConfig);
final Configuration olderConfig = new Configuration();
olderConfig.orientation = orientation;
olderConfig.seq = seq + 1;
- activityThread.handleActivityConfigurationChanged(r, olderConfig, INVALID_DISPLAY);
+ activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
+ olderConfig, INVALID_DISPLAY);
assertEquals(numOfConfig, activity.mNumOfConfigChanges);
assertEquals(olderConfig.orientation, activity.mConfig.orientation);
- activityThread.handleActivityConfigurationChanged(r, newerConfig, INVALID_DISPLAY);
+ activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
+ newerConfig, INVALID_DISPLAY);
assertEquals(numOfConfig + 1, activity.mNumOfConfigChanges);
assertEquals(newerConfig.orientation, activity.mConfig.orientation);
});
@@ -273,7 +274,7 @@ public class ActivityThreadTest {
config.seq = BASE_SEQ;
config.orientation = ORIENTATION_PORTRAIT;
- activityThread.handleActivityConfigurationChanged(getActivityClientRecord(activity),
+ activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
config, INVALID_DISPLAY);
});
@@ -334,8 +335,8 @@ public class ActivityThreadTest {
config.seq = BASE_SEQ;
config.orientation = ORIENTATION_PORTRAIT;
- final ActivityClientRecord r = getActivityClientRecord(activity);
- activityThread.handleActivityConfigurationChanged(r, config, INVALID_DISPLAY);
+ activityThread.handleActivityConfigurationChanged(activity.getActivityToken(),
+ config, INVALID_DISPLAY);
});
final int numOfConfig = activity.mNumOfConfigChanges;
@@ -512,10 +513,9 @@ public class ActivityThreadTest {
startIntent.putExtra(TestActivity.PIP_REQUESTED_OVERRIDE_ENTER, true);
final TestActivity activity = mActivityTestRule.launchActivity(startIntent);
final ActivityThread activityThread = activity.getActivityThread();
- final ActivityClientRecord r = getActivityClientRecord(activity);
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- activityThread.handlePictureInPictureRequested(r);
+ activityThread.handlePictureInPictureRequested(activity.getActivityToken());
});
assertTrue(activity.pipRequested());
@@ -528,10 +528,9 @@ public class ActivityThreadTest {
startIntent.putExtra(TestActivity.PIP_REQUESTED_OVERRIDE_SKIP, true);
final TestActivity activity = mActivityTestRule.launchActivity(startIntent);
final ActivityThread activityThread = activity.getActivityThread();
- final ActivityClientRecord r = getActivityClientRecord(activity);
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- activityThread.handlePictureInPictureRequested(r);
+ activityThread.handlePictureInPictureRequested(activity.getActivityToken());
});
assertTrue(activity.pipRequested());
@@ -542,10 +541,9 @@ public class ActivityThreadTest {
public void testHandlePictureInPictureRequested_notOverridden() {
final TestActivity activity = mActivityTestRule.launchActivity(new Intent());
final ActivityThread activityThread = activity.getActivityThread();
- final ActivityClientRecord r = getActivityClientRecord(activity);
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
- activityThread.handlePictureInPictureRequested(r);
+ activityThread.handlePictureInPictureRequested(activity.getActivityToken());
});
assertTrue(activity.pipRequested());
@@ -554,9 +552,8 @@ public class ActivityThreadTest {
}
/**
- * Calls {@link ActivityThread#handleActivityConfigurationChanged(ActivityClientRecord,
- * Configuration, int)} to try to push activity configuration to the activity for the given
- * sequence number.
+ * Calls {@link ActivityThread#handleActivityConfigurationChanged(IBinder, Configuration, int)}
+ * to try to push activity configuration to the activity for the given sequence number.
* <p>
* It uses orientation to push the configuration and it tries a different orientation if the
* first attempt doesn't make through, to rule out the possibility that the previous
@@ -569,13 +566,13 @@ public class ActivityThreadTest {
*/
private int applyConfigurationChange(TestActivity activity, int seq) {
final ActivityThread activityThread = activity.getActivityThread();
- final ActivityClientRecord r = getActivityClientRecord(activity);
final int numOfConfig = activity.mNumOfConfigChanges;
Configuration config = new Configuration();
config.orientation = ORIENTATION_PORTRAIT;
config.seq = seq;
- activityThread.handleActivityConfigurationChanged(r, config, INVALID_DISPLAY);
+ activityThread.handleActivityConfigurationChanged(activity.getActivityToken(), config,
+ INVALID_DISPLAY);
if (activity.mNumOfConfigChanges > numOfConfig) {
return config.seq;
@@ -584,17 +581,12 @@ public class ActivityThreadTest {
config = new Configuration();
config.orientation = ORIENTATION_LANDSCAPE;
config.seq = seq + 1;
- activityThread.handleActivityConfigurationChanged(r, config, INVALID_DISPLAY);
+ activityThread.handleActivityConfigurationChanged(activity.getActivityToken(), config,
+ INVALID_DISPLAY);
return config.seq;
}
- private static ActivityClientRecord getActivityClientRecord(Activity activity) {
- final ActivityThread thread = activity.getActivityThread();
- final IBinder token = activity.getActivityToken();
- return thread.getActivityClient(token);
- }
-
private static ClientTransaction newRelaunchResumeTransaction(Activity activity) {
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(null,
null, 0, new MergedConfiguration(), false /* preserveWindow */);
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index 6a0105cf7ff0..3c32c71cf961 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -32,12 +32,11 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.app.Activity;
import android.app.ActivityThread.ActivityClientRecord;
import android.app.ClientTransactionHandler;
import android.app.servertransaction.ActivityLifecycleItem.LifecycleState;
@@ -226,7 +225,6 @@ public class TransactionExecutorTests {
when(callback2.getPostExecutionState()).thenReturn(UNDEFINED);
ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
IBinder token = mock(IBinder.class);
- when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class));
ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
token /* activityToken */);
@@ -238,9 +236,9 @@ public class TransactionExecutorTests {
mExecutor.execute(transaction);
InOrder inOrder = inOrder(mTransactionHandler, callback1, callback2, stateRequest);
- inOrder.verify(callback1).execute(eq(mTransactionHandler), eq(token), any());
- inOrder.verify(callback2).execute(eq(mTransactionHandler), eq(token), any());
- inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
+ inOrder.verify(callback1, times(1)).execute(eq(mTransactionHandler), eq(token), any());
+ inOrder.verify(callback2, times(1)).execute(eq(mTransactionHandler), eq(token), any());
+ inOrder.verify(stateRequest, times(1)).execute(eq(mTransactionHandler), eq(token), any());
}
@Test
@@ -275,7 +273,7 @@ public class TransactionExecutorTests {
// The launch transaction should not be executed because its token is in the
// to-be-destroyed container.
- verify(launchItem, never()).execute(any(), any(), any());
+ verify(launchItem, times(0)).execute(any(), any(), any());
// After the destroy transaction has been executed, the token should be removed.
mExecutor.execute(destroyTransaction);
@@ -284,8 +282,6 @@ public class TransactionExecutorTests {
@Test
public void testActivityResultRequiredStateResolution() {
- when(mTransactionHandler.getActivity(any())).thenReturn(mock(Activity.class));
-
PostExecItem postExecItem = new PostExecItem(ON_RESUME);
IBinder token = mock(IBinder.class);
@@ -296,12 +292,12 @@ public class TransactionExecutorTests {
// Verify resolution that should get to onPause
mClientRecord.setState(ON_RESUME);
mExecutor.executeCallbacks(transaction);
- verify(mExecutor).cycleToPath(eq(mClientRecord), eq(ON_PAUSE), eq(transaction));
+ verify(mExecutor, times(1)).cycleToPath(eq(mClientRecord), eq(ON_PAUSE), eq(transaction));
// Verify resolution that should get to onStart
mClientRecord.setState(ON_STOP);
mExecutor.executeCallbacks(transaction);
- verify(mExecutor).cycleToPath(eq(mClientRecord), eq(ON_START), eq(transaction));
+ verify(mExecutor, times(1)).cycleToPath(eq(mClientRecord), eq(ON_START), eq(transaction));
}
@Test
@@ -437,38 +433,6 @@ public class TransactionExecutorTests {
mExecutorHelper.getClosestPreExecutionState(mClientRecord, ON_RESUME));
}
- @Test(expected = IllegalArgumentException.class)
- public void testActivityItemNullRecordThrowsException() {
- final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
- when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
- final IBinder token = mock(IBinder.class);
- final ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
- token /* activityToken */);
- transaction.addCallback(activityItem);
- when(mTransactionHandler.getActivityClient(token)).thenReturn(null);
-
- mExecutor.executeCallbacks(transaction);
- }
-
- @Test
- public void testActivityItemExecute() {
- final IBinder token = mock(IBinder.class);
- final ClientTransaction transaction = ClientTransaction.obtain(null /* client */,
- token /* activityToken */);
- final ActivityTransactionItem activityItem = mock(ActivityTransactionItem.class);
- when(activityItem.getPostExecutionState()).thenReturn(UNDEFINED);
- transaction.addCallback(activityItem);
- final ActivityLifecycleItem stateRequest = mock(ActivityLifecycleItem.class);
- transaction.setLifecycleStateRequest(stateRequest);
- when(mTransactionHandler.getActivity(token)).thenReturn(mock(Activity.class));
-
- mExecutor.execute(transaction);
-
- final InOrder inOrder = inOrder(activityItem, stateRequest);
- inOrder.verify(activityItem).execute(eq(mTransactionHandler), eq(mClientRecord), any());
- inOrder.verify(stateRequest).execute(eq(mTransactionHandler), eq(mClientRecord), any());
- }
-
private static int[] shuffledArray(int[] inputArray) {
final List<Integer> list = Arrays.stream(inputArray).boxed().collect(Collectors.toList());
Collections.shuffle(list);
@@ -525,13 +489,13 @@ public class TransactionExecutorTests {
public static final Parcelable.Creator<StubItem> CREATOR =
new Parcelable.Creator<StubItem>() {
- public StubItem createFromParcel(Parcel in) {
- return new StubItem(in);
- }
-
- public StubItem[] newArray(int size) {
- return new StubItem[size];
- }
- };
+ public StubItem createFromParcel(Parcel in) {
+ return new StubItem(in);
+ }
+
+ public StubItem[] newArray(int size) {
+ return new StubItem[size];
+ }
+ };
}
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java b/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java
index 01515bd9c6b5..a80f5a03ee4e 100644
--- a/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BstatsCpuTimesValidationTest.java
@@ -52,7 +52,9 @@ import android.os.SystemClock;
import android.provider.Settings;
import android.support.test.uiautomator.UiDevice;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.DebugUtils;
+import android.util.KeyValueListParser;
import android.util.Log;
import androidx.test.InstrumentationRegistry;
@@ -104,8 +106,6 @@ public class BstatsCpuTimesValidationTest {
private static final int WORK_DURATION_MS = 2000;
- private static final String DESIRED_PROC_STATE_CPU_TIMES_DELAY = "0";
-
private static boolean sBatteryStatsConstsUpdated;
private static String sOriginalBatteryStatsConsts;
@@ -124,10 +124,12 @@ public class BstatsCpuTimesValidationTest {
sContext.getPackageManager().setApplicationEnabledSetting(TEST_PKG,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
sTestPkgUid = sContext.getPackageManager().getPackageUid(TEST_PKG, 0);
+
+ final ArrayMap<String, String> desiredConstants = new ArrayMap<>();
+ desiredConstants.put(KEY_TRACK_CPU_TIMES_BY_PROC_STATE, Boolean.toString(true));
+ desiredConstants.put(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS, Integer.toString(0));
+ updateBatteryStatsConstants(desiredConstants);
checkCpuTimesAvailability();
- if (sPerProcStateTimesAvailable && sCpuFreqTimesAvailable) {
- setDesiredReadyDelay();
- }
}
@AfterClass
@@ -139,26 +141,33 @@ public class BstatsCpuTimesValidationTest {
batteryReset();
}
- private static void setDesiredReadyDelay() {
+ private static void updateBatteryStatsConstants(ArrayMap<String, String> desiredConstants) {
sOriginalBatteryStatsConsts = Settings.Global.getString(sContext.getContentResolver(),
Settings.Global.BATTERY_STATS_CONSTANTS);
- String newBatteryStatsConstants;
- final String newConstant = KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS
- + "=" + DESIRED_PROC_STATE_CPU_TIMES_DELAY;
- if (sOriginalBatteryStatsConsts == null || "null".equals(sOriginalBatteryStatsConsts)) {
- // battery_stats_constants is initially empty, so just assign the desired value.
- newBatteryStatsConstants = newConstant;
- } else if (sOriginalBatteryStatsConsts.contains(KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS)) {
- // battery_stats_constants contains delay duration, so replace it
- // with the desired value.
- newBatteryStatsConstants = sOriginalBatteryStatsConsts.replaceAll(
- KEY_PROC_STATE_CPU_TIMES_READ_DELAY_MS + "=\\d+", newConstant);
- } else {
- // battery_stats_constants didn't contain any delay, so append the desired value.
- newBatteryStatsConstants = sOriginalBatteryStatsConsts + "," + newConstant;
+ final char delimiter = ',';
+ final KeyValueListParser parser = new KeyValueListParser(delimiter);
+ parser.setString(sOriginalBatteryStatsConsts);
+ final StringBuilder sb = new StringBuilder();
+ for (int i = 0, size = parser.size(); i < size; ++i) {
+ final String key = parser.keyAt(i);
+ final String value = desiredConstants.getOrDefault(key,
+ parser.getString(key, null));
+ if (sb.length() > 0) {
+ sb.append(delimiter);
+ }
+ sb.append(key + "=" + value);
+ desiredConstants.remove(key);
}
+ desiredConstants.forEach((key, value) -> {
+ if (sb.length() > 0) {
+ sb.append(delimiter);
+ }
+ sb.append(key + '=' + value);
+ });
Settings.Global.putString(sContext.getContentResolver(),
- Settings.Global.BATTERY_STATS_CONSTANTS, newBatteryStatsConstants);
+ Settings.Global.BATTERY_STATS_CONSTANTS, sb.toString());
+ Log.d(TAG, "Updated value of '" + Settings.Global.BATTERY_STATS_CONSTANTS + "': "
+ + sb.toString());
sBatteryStatsConstsUpdated = true;
}
diff --git a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
index 3f2d0f134443..1cdc75aa1f40 100644
--- a/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
+++ b/core/tests/mockingcoretests/src/android/app/activity/ActivityThreadClientTest.java
@@ -176,27 +176,27 @@ public class ActivityThreadClientTest {
}
private void startActivity(ActivityClientRecord r) {
- mThread.handleStartActivity(r, null /* pendingActions */);
+ mThread.handleStartActivity(r.token, null /* pendingActions */);
}
private void resumeActivity(ActivityClientRecord r) {
- mThread.handleResumeActivity(r, true /* finalStateRequest */,
+ mThread.handleResumeActivity(r.token, true /* finalStateRequest */,
true /* isForward */, "test");
}
private void pauseActivity(ActivityClientRecord r) {
- mThread.handlePauseActivity(r, false /* finished */,
+ mThread.handlePauseActivity(r.token, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, null /* pendingActions */,
"test");
}
private void stopActivity(ActivityClientRecord r) {
- mThread.handleStopActivity(r, 0 /* configChanges */,
+ mThread.handleStopActivity(r.token, 0 /* configChanges */,
new PendingTransactionActions(), false /* finalStateRequest */, "test");
}
private void destroyActivity(ActivityClientRecord r) {
- mThread.handleDestroyActivity(r, true /* finishing */, 0 /* configChanges */,
+ mThread.handleDestroyActivity(r.token, true /* finishing */, 0 /* configChanges */,
false /* getNonConfigInstance */, "test");
}
diff --git a/data/etc/car/Android.bp b/data/etc/car/Android.bp
index 04007c91817d..d0e688d3efc1 100644
--- a/data/etc/car/Android.bp
+++ b/data/etc/car/Android.bp
@@ -17,126 +17,126 @@
// Privapp permission whitelist files
prebuilt_etc {
- name: "privapp_whitelist_android.car.cluster.loggingrenderer",
+ name: "allowed_privapp_android.car.cluster.loggingrenderer",
sub_dir: "permissions",
src: "android.car.cluster.loggingrenderer.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_android.car.cluster.sample",
+ name: "allowed_privapp_android.car.cluster.sample",
sub_dir: "permissions",
src: "android.car.cluster.sample.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_android.car.cluster",
+ name: "allowed_privapp_android.car.cluster",
sub_dir: "permissions",
src: "android.car.cluster.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_android.car.usb.handler",
+ name: "allowed_privapp_android.car.usb.handler",
sub_dir: "permissions",
src: "android.car.usb.handler.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.carlauncher",
+ name: "allowed_privapp_com.android.car.carlauncher",
sub_dir: "permissions",
src: "com.android.car.carlauncher.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.dialer",
+ name: "allowed_privapp_com.android.car.dialer",
sub_dir: "permissions",
src: "com.android.car.dialer.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.hvac",
+ name: "allowed_privapp_com.android.car.hvac",
sub_dir: "permissions",
src: "com.android.car.hvac.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.media",
+ name: "allowed_privapp_com.android.car.media",
sub_dir: "permissions",
src: "com.android.car.media.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.notification",
+ name: "allowed_privapp_com.android.car.notification",
sub_dir: "permissions",
src: "com.android.car.notification.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.radio",
+ name: "allowed_privapp_com.android.car.radio",
sub_dir: "permissions",
src: "com.android.car.radio.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.secondaryhome",
+ name: "allowed_privapp_com.android.car.secondaryhome",
sub_dir: "permissions",
src: "com.android.car.secondaryhome.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.settings",
+ name: "allowed_privapp_com.android.car.settings",
sub_dir: "permissions",
src: "com.android.car.settings.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.themeplayground",
+ name: "allowed_privapp_com.android.car.themeplayground",
sub_dir: "permissions",
src: "com.android.car.themeplayground.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car",
+ name: "allowed_privapp_com.android.car",
sub_dir: "permissions",
src: "com.android.car.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.bugreport",
+ name: "allowed_privapp_com.android.car.bugreport",
sub_dir: "permissions",
src: "com.android.car.bugreport.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.companiondevicesupport",
+ name: "allowed_privapp_com.android.car.companiondevicesupport",
sub_dir: "permissions",
src: "com.android.car.companiondevicesupport.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.google.android.car.kitchensink",
+ name: "allowed_privapp_com.google.android.car.kitchensink",
sub_dir: "permissions",
src: "com.google.android.car.kitchensink.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.developeroptions",
+ name: "allowed_privapp_com.android.car.developeroptions",
sub_dir: "permissions",
src: "com.android.car.developeroptions.xml",
filename_from_src: true,
@@ -144,14 +144,14 @@ prebuilt_etc {
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.floatingcardslauncher",
+ name: "allowed_privapp_com.android.car.floatingcardslauncher",
sub_dir: "permissions",
src: "com.android.car.floatingcardslauncher.xml",
filename_from_src: true,
}
prebuilt_etc {
- name: "privapp_whitelist_com.android.car.ui.paintbooth",
+ name: "allowed_privapp_com.android.car.ui.paintbooth",
sub_dir: "permissions",
src: "com.android.car.ui.paintbooth.xml",
filename_from_src: true,
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index ada8b000a26b..06f1dae30cd3 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -35,6 +35,7 @@
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.MASTER_CLEAR"/>
<permission name="android.permission.MEDIA_CONTENT_CONTROL"/>
+ <permission name="android.permission.MODIFY_AUDIO_ROUTING" />
<permission name="android.permission.MODIFY_DAY_NIGHT_MODE"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 28d7911c771f..964640b106b9 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -3111,7 +3111,7 @@ public class Paint {
@CriticalNative
private static native boolean nGetFillPath(long paintPtr, long src, long dst);
@CriticalNative
- private static native long nSetShader(long paintPtr, long shader);
+ private static native void nSetShader(long paintPtr, long shader);
@CriticalNative
private static native long nSetColorFilter(long paintPtr, long filter);
@CriticalNative
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 9ae5ad97ed36..0b13754271b9 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -462,6 +462,13 @@ cc_defaults {
"RenderNode.cpp",
"RenderProperties.cpp",
"RootRenderNode.cpp",
+ "shader/Shader.cpp",
+ "shader/BitmapShader.cpp",
+ "shader/ComposeShader.cpp",
+ "shader/LinearGradientShader.cpp",
+ "shader/RadialGradientShader.cpp",
+ "shader/RuntimeShader.cpp",
+ "shader/SweepGradientShader.cpp",
"SkiaCanvas.cpp",
"VectorDrawable.cpp",
],
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 242b8b0d139e..cfba5d4f6aa2 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -42,6 +42,8 @@
#include <SkTextBlob.h>
#include <SkVertices.h>
+#include <shader/BitmapShader.h>
+
#include <memory>
#include <optional>
#include <utility>
@@ -49,6 +51,7 @@
namespace android {
using uirenderer::PaintUtils;
+using uirenderer::BitmapShader;
Canvas* Canvas::create_canvas(const SkBitmap& bitmap) {
return new SkiaCanvas(bitmap);
@@ -681,7 +684,9 @@ void SkiaCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
if (paint) {
pnt = *paint;
}
- pnt.setShader(bitmap.makeImage()->makeShader());
+
+ pnt.setShader(sk_ref_sp(new BitmapShader(
+ bitmap.makeImage(), SkTileMode::kClamp, SkTileMode::kClamp, nullptr)));
auto v = builder.detach();
apply_looper(&pnt, [&](const SkPaint& p) {
mCanvas->drawVertices(v, SkBlendMode::kModulate, p);
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index cd908354aea5..0f566e4b494a 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -23,7 +23,6 @@
#include "PathParser.h"
#include "SkColorFilter.h"
#include "SkImageInfo.h"
-#include "SkShader.h"
#include "hwui/Paint.h"
#ifdef __ANDROID__
@@ -159,10 +158,10 @@ void FullPath::draw(SkCanvas* outCanvas, bool useStagingData) {
// Draw path's fill, if fill color or gradient is valid
bool needsFill = false;
- SkPaint paint;
+ Paint paint;
if (properties.getFillGradient() != nullptr) {
paint.setColor(applyAlpha(SK_ColorBLACK, properties.getFillAlpha()));
- paint.setShader(sk_sp<SkShader>(SkSafeRef(properties.getFillGradient())));
+ paint.setShader(sk_sp<Shader>(SkSafeRef(properties.getFillGradient())));
needsFill = true;
} else if (properties.getFillColor() != SK_ColorTRANSPARENT) {
paint.setColor(applyAlpha(properties.getFillColor(), properties.getFillAlpha()));
@@ -179,7 +178,7 @@ void FullPath::draw(SkCanvas* outCanvas, bool useStagingData) {
bool needsStroke = false;
if (properties.getStrokeGradient() != nullptr) {
paint.setColor(applyAlpha(SK_ColorBLACK, properties.getStrokeAlpha()));
- paint.setShader(sk_sp<SkShader>(SkSafeRef(properties.getStrokeGradient())));
+ paint.setShader(sk_sp<Shader>(SkSafeRef(properties.getStrokeGradient())));
needsStroke = true;
} else if (properties.getStrokeColor() != SK_ColorTRANSPARENT) {
paint.setColor(applyAlpha(properties.getStrokeColor(), properties.getStrokeAlpha()));
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index ac7d41e0d600..d4086f1aa622 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -31,8 +31,8 @@
#include <SkPath.h>
#include <SkPathMeasure.h>
#include <SkRect.h>
-#include <SkShader.h>
#include <SkSurface.h>
+#include <shader/Shader.h>
#include <cutils/compiler.h>
#include <stddef.h>
@@ -227,20 +227,20 @@ public:
strokeGradient = prop.strokeGradient;
onPropertyChanged();
}
- void setFillGradient(SkShader* gradient) {
+ void setFillGradient(Shader* gradient) {
if (fillGradient.get() != gradient) {
fillGradient = sk_ref_sp(gradient);
onPropertyChanged();
}
}
- void setStrokeGradient(SkShader* gradient) {
+ void setStrokeGradient(Shader* gradient) {
if (strokeGradient.get() != gradient) {
strokeGradient = sk_ref_sp(gradient);
onPropertyChanged();
}
}
- SkShader* getFillGradient() const { return fillGradient.get(); }
- SkShader* getStrokeGradient() const { return strokeGradient.get(); }
+ Shader* getFillGradient() const { return fillGradient.get(); }
+ Shader* getStrokeGradient() const { return strokeGradient.get(); }
float getStrokeWidth() const { return mPrimitiveFields.strokeWidth; }
void setStrokeWidth(float strokeWidth) {
VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(strokeWidth, strokeWidth);
@@ -320,8 +320,8 @@ public:
count,
};
PrimitiveFields mPrimitiveFields;
- sk_sp<SkShader> fillGradient;
- sk_sp<SkShader> strokeGradient;
+ sk_sp<Shader> fillGradient;
+ sk_sp<Shader> strokeGradient;
};
// Called from UI thread
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index c138a32eacc2..2a377bbb83f2 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -73,7 +73,7 @@ void Canvas::drawTextDecorations(float x, float y, float length, const Paint& pa
static void simplifyPaint(int color, Paint* paint) {
paint->setColor(color);
- paint->setShader(nullptr);
+ paint->setShader((sk_sp<uirenderer::Shader>)nullptr);
paint->setColorFilter(nullptr);
paint->setLooper(nullptr);
paint->setStrokeWidth(4 + 0.04 * paint->getSkFont().getSize());
diff --git a/libs/hwui/hwui/Paint.h b/libs/hwui/hwui/Paint.h
index e75e9e7c6933..0bb689c19079 100644
--- a/libs/hwui/hwui/Paint.h
+++ b/libs/hwui/hwui/Paint.h
@@ -30,6 +30,8 @@
#include <minikin/FamilyVariant.h>
#include <minikin/Hyphenator.h>
+#include <shader/Shader.h>
+
namespace android {
class Paint : public SkPaint {
@@ -149,8 +151,14 @@ public:
// The only respected flags are : [ antialias, dither, filterBitmap ]
static uint32_t GetSkPaintJavaFlags(const SkPaint&);
static void SetSkPaintJavaFlags(SkPaint*, uint32_t flags);
+
+ void setShader(sk_sp<uirenderer::Shader> shader);
private:
+
+ using SkPaint::setShader;
+ using SkPaint::setImageFilter;
+
SkFont mFont;
sk_sp<SkDrawLooper> mLooper;
@@ -169,6 +177,7 @@ private:
bool mStrikeThru = false;
bool mUnderline = false;
bool mDevKern = false;
+ sk_sp<uirenderer::Shader> mShader;
};
} // namespace android
diff --git a/libs/hwui/hwui/PaintImpl.cpp b/libs/hwui/hwui/PaintImpl.cpp
index fa2674fc2f5e..21f60fd7b671 100644
--- a/libs/hwui/hwui/PaintImpl.cpp
+++ b/libs/hwui/hwui/PaintImpl.cpp
@@ -24,7 +24,8 @@ Paint::Paint()
, mWordSpacing(0)
, mFontFeatureSettings()
, mMinikinLocaleListId(0)
- , mFamilyVariant(minikin::FamilyVariant::DEFAULT) {
+ , mFamilyVariant(minikin::FamilyVariant::DEFAULT)
+ , mShader(nullptr) {
// SkPaint::antialiasing defaults to false, but
// SkFont::edging defaults to kAntiAlias. To keep them
// insync, we manually set the font to kAilas.
@@ -45,7 +46,8 @@ Paint::Paint(const Paint& paint)
, mAlign(paint.mAlign)
, mStrikeThru(paint.mStrikeThru)
, mUnderline(paint.mUnderline)
- , mDevKern(paint.mDevKern) {}
+ , mDevKern(paint.mDevKern)
+ , mShader(paint.mShader){}
Paint::~Paint() {}
@@ -65,9 +67,30 @@ Paint& Paint::operator=(const Paint& other) {
mStrikeThru = other.mStrikeThru;
mUnderline = other.mUnderline;
mDevKern = other.mDevKern;
+ mShader = other.mShader;
return *this;
}
+void Paint::setShader(sk_sp<uirenderer::Shader> shader) {
+ if (shader) {
+ // If there is an SkShader compatible shader, apply it
+ sk_sp<SkShader> skShader = shader->asSkShader();
+ if (skShader.get()) {
+ SkPaint::setShader(skShader);
+ SkPaint::setImageFilter(nullptr);
+ } else {
+ // ... otherwise the specified shader can only be represented as an ImageFilter
+ SkPaint::setShader(nullptr);
+ SkPaint::setImageFilter(shader->asSkImageFilter());
+ }
+ } else {
+ // No shader is provided at all, clear out both the SkShader and SkImageFilter slots
+ SkPaint::setShader(nullptr);
+ SkPaint::setImageFilter(nullptr);
+ }
+ mShader = shader;
+}
+
bool operator==(const Paint& a, const Paint& b) {
return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b) &&
a.mFont == b.mFont &&
diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp
index df8635a8fe5a..554674a331cd 100644
--- a/libs/hwui/jni/Paint.cpp
+++ b/libs/hwui/jni/Paint.cpp
@@ -47,6 +47,7 @@
#include <minikin/LocaleList.h>
#include <minikin/Measurement.h>
#include <minikin/MinikinPaint.h>
+#include <shader/Shader.h>
#include <unicode/utf16.h>
#include <cassert>
@@ -54,6 +55,8 @@
#include <memory>
#include <vector>
+using namespace android::uirenderer;
+
namespace android {
struct JMetricsID {
@@ -782,11 +785,10 @@ namespace PaintGlue {
return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE;
}
- static jlong setShader(CRITICAL_JNI_PARAMS_COMMA jlong objHandle, jlong shaderHandle) {
- Paint* obj = reinterpret_cast<Paint*>(objHandle);
- SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
- obj->setShader(sk_ref_sp(shader));
- return reinterpret_cast<jlong>(obj->getShader());
+ static void setShader(CRITICAL_JNI_PARAMS_COMMA jlong objHandle, jlong shaderHandle) {
+ auto* paint = reinterpret_cast<Paint*>(objHandle);
+ auto* shader = reinterpret_cast<Shader*>(shaderHandle);
+ paint->setShader(sk_ref_sp(shader));
}
static jlong setColorFilter(CRITICAL_JNI_PARAMS_COMMA jlong objHandle, jlong filterHandle) {
@@ -1097,7 +1099,7 @@ static const JNINativeMethod methods[] = {
{"nGetStrokeJoin","(J)I", (void*) PaintGlue::getStrokeJoin},
{"nSetStrokeJoin","(JI)V", (void*) PaintGlue::setStrokeJoin},
{"nGetFillPath","(JJJ)Z", (void*) PaintGlue::getFillPath},
- {"nSetShader","(JJ)J", (void*) PaintGlue::setShader},
+ {"nSetShader","(JJ)V", (void*) PaintGlue::setShader},
{"nSetColorFilter","(JJ)J", (void*) PaintGlue::setColorFilter},
{"nSetXfermode","(JI)V", (void*) PaintGlue::setXfermode},
{"nSetPathEffect","(JJ)J", (void*) PaintGlue::setPathEffect},
diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp
index e76aace601be..9b1972ed664f 100644
--- a/libs/hwui/jni/Shader.cpp
+++ b/libs/hwui/jni/Shader.cpp
@@ -5,6 +5,13 @@
#include "SkShader.h"
#include "SkBlendMode.h"
#include "include/effects/SkRuntimeEffect.h"
+#include "shader/Shader.h"
+#include "shader/BitmapShader.h"
+#include "shader/ComposeShader.h"
+#include "shader/LinearGradientShader.h"
+#include "shader/RadialGradientShader.h"
+#include "shader/RuntimeShader.h"
+#include "shader/SweepGradientShader.h"
#include <vector>
@@ -50,7 +57,7 @@ static jint Color_HSVToColor(JNIEnv* env, jobject, jint alpha, jfloatArray hsvAr
///////////////////////////////////////////////////////////////////////////////////////////////
-static void Shader_safeUnref(SkShader* shader) {
+static void Shader_safeUnref(Shader* shader) {
SkSafeUnref(shader);
}
@@ -74,15 +81,15 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, j
SkBitmap bitmap;
image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
}
- sk_sp<SkShader> shader = image->makeShader(
- (SkTileMode)tileModeX, (SkTileMode)tileModeY);
- ThrowIAE_IfNull(env, shader.get());
- if (matrix) {
- shader = shader->makeWithLocalMatrix(*matrix);
- }
+ auto* shader = new BitmapShader(
+ image,
+ static_cast<SkTileMode>(tileModeX),
+ static_cast<SkTileMode>(tileModeY),
+ matrix
+ );
- return reinterpret_cast<jlong>(shader.release());
+ return reinterpret_cast<jlong>(shader);
}
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -118,17 +125,18 @@ static jlong LinearGradient_create(JNIEnv* env, jobject, jlong matrixPtr,
#error Need to convert float array to SkScalar array before calling the following function.
#endif
- sk_sp<SkShader> shader(SkGradientShader::MakeLinear(pts, &colors[0],
- GraphicsJNI::getNativeColorSpace(colorSpaceHandle), pos, colors.size(),
- static_cast<SkTileMode>(tileMode), sGradientShaderFlags, nullptr));
- ThrowIAE_IfNull(env, shader);
-
- const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
- if (matrix) {
- shader = shader->makeWithLocalMatrix(*matrix);
- }
+ auto* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
+ auto* shader = new LinearGradientShader(
+ pts,
+ colors,
+ GraphicsJNI::getNativeColorSpace(colorSpaceHandle),
+ pos,
+ static_cast<SkTileMode>(tileMode),
+ sGradientShaderFlags,
+ matrix
+ );
- return reinterpret_cast<jlong>(shader.release());
+ return reinterpret_cast<jlong>(shader);
}
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -148,17 +156,20 @@ static jlong RadialGradient_create(JNIEnv* env, jobject, jlong matrixPtr, jfloat
#error Need to convert float array to SkScalar array before calling the following function.
#endif
- sk_sp<SkShader> shader = SkGradientShader::MakeRadial(center, radius, &colors[0],
- GraphicsJNI::getNativeColorSpace(colorSpaceHandle), pos, colors.size(),
- static_cast<SkTileMode>(tileMode), sGradientShaderFlags, nullptr);
- ThrowIAE_IfNull(env, shader);
+ auto* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
- const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
- if (matrix) {
- shader = shader->makeWithLocalMatrix(*matrix);
- }
+ auto* shader = new RadialGradientShader(
+ center,
+ radius,
+ colors,
+ GraphicsJNI::getNativeColorSpace(colorSpaceHandle),
+ pos,
+ static_cast<SkTileMode>(tileMode),
+ sGradientShaderFlags,
+ matrix
+ );
- return reinterpret_cast<jlong>(shader.release());
+ return reinterpret_cast<jlong>(shader);
}
///////////////////////////////////////////////////////////////////////////////
@@ -174,54 +185,58 @@ static jlong SweepGradient_create(JNIEnv* env, jobject, jlong matrixPtr, jfloat
#error Need to convert float array to SkScalar array before calling the following function.
#endif
- sk_sp<SkShader> shader = SkGradientShader::MakeSweep(x, y, &colors[0],
- GraphicsJNI::getNativeColorSpace(colorSpaceHandle), pos, colors.size(),
- sGradientShaderFlags, nullptr);
- ThrowIAE_IfNull(env, shader);
+ auto* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
- const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
- if (matrix) {
- shader = shader->makeWithLocalMatrix(*matrix);
- }
+ auto* shader = new SweepGradientShader(
+ x,
+ y,
+ colors,
+ GraphicsJNI::getNativeColorSpace(colorSpaceHandle),
+ pos,
+ sGradientShaderFlags,
+ matrix
+ );
- return reinterpret_cast<jlong>(shader.release());
+ return reinterpret_cast<jlong>(shader);
}
///////////////////////////////////////////////////////////////////////////////////////////////
static jlong ComposeShader_create(JNIEnv* env, jobject o, jlong matrixPtr,
jlong shaderAHandle, jlong shaderBHandle, jint xfermodeHandle) {
- const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
- SkShader* shaderA = reinterpret_cast<SkShader *>(shaderAHandle);
- SkShader* shaderB = reinterpret_cast<SkShader *>(shaderBHandle);
- SkBlendMode mode = static_cast<SkBlendMode>(xfermodeHandle);
- sk_sp<SkShader> baseShader(SkShaders::Blend(mode,
- sk_ref_sp(shaderA), sk_ref_sp(shaderB)));
-
- SkShader* shader;
-
- if (matrix) {
- shader = baseShader->makeWithLocalMatrix(*matrix).release();
- } else {
- shader = baseShader.release();
- }
- return reinterpret_cast<jlong>(shader);
+ auto* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
+ auto* shaderA = reinterpret_cast<Shader*>(shaderAHandle);
+ auto* shaderB = reinterpret_cast<Shader*>(shaderBHandle);
+
+ auto mode = static_cast<SkBlendMode>(xfermodeHandle);
+
+ auto* composeShader = new ComposeShader(
+ *shaderA,
+ *shaderB,
+ mode,
+ matrix
+ );
+
+ return reinterpret_cast<jlong>(composeShader);
}
///////////////////////////////////////////////////////////////////////////////////////////////
static jlong RuntimeShader_create(JNIEnv* env, jobject, jlong shaderFactory, jlong matrixPtr,
jbyteArray inputs, jlong colorSpaceHandle, jboolean isOpaque) {
- SkRuntimeEffect* effect = reinterpret_cast<SkRuntimeEffect*>(shaderFactory);
+ auto* effect = reinterpret_cast<SkRuntimeEffect*>(shaderFactory);
AutoJavaByteArray arInputs(env, inputs);
- sk_sp<SkData> fData;
- fData = SkData::MakeWithCopy(arInputs.ptr(), arInputs.length());
- const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
- sk_sp<SkShader> shader = effect->makeShader(fData, nullptr, 0, matrix, isOpaque == JNI_TRUE);
- ThrowIAE_IfNull(env, shader);
+ auto data = SkData::MakeWithCopy(arInputs.ptr(), arInputs.length());
+ auto* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
- return reinterpret_cast<jlong>(shader.release());
+ auto* shader = new RuntimeShader(
+ *effect,
+ std::move(data),
+ isOpaque == JNI_TRUE,
+ matrix
+ );
+ return reinterpret_cast<jlong>(shader);
}
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -239,12 +254,8 @@ static jlong RuntimeShader_createShaderFactory(JNIEnv* env, jobject, jstring sks
///////////////////////////////////////////////////////////////////////////////////////////////
-static void Effect_safeUnref(SkRuntimeEffect* effect) {
- SkSafeUnref(effect);
-}
-
static jlong RuntimeShader_getNativeFinalizer(JNIEnv*, jobject) {
- return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Effect_safeUnref));
+ return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Shader_safeUnref));
}
///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp b/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp
index 9cffceb308c8..a1adcb30e80d 100644
--- a/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp
+++ b/libs/hwui/jni/android_graphics_drawable_VectorDrawable.cpp
@@ -143,13 +143,13 @@ static void updateFullPathPropertiesAndStrokeStyles(JNIEnv*, jobject, jlong full
static void updateFullPathFillGradient(JNIEnv*, jobject, jlong pathPtr, jlong fillGradientPtr) {
VectorDrawable::FullPath* path = reinterpret_cast<VectorDrawable::FullPath*>(pathPtr);
- SkShader* fillShader = reinterpret_cast<SkShader*>(fillGradientPtr);
+ auto* fillShader = reinterpret_cast<Shader*>(fillGradientPtr);
path->mutateStagingProperties()->setFillGradient(fillShader);
}
static void updateFullPathStrokeGradient(JNIEnv*, jobject, jlong pathPtr, jlong strokeGradientPtr) {
VectorDrawable::FullPath* path = reinterpret_cast<VectorDrawable::FullPath*>(pathPtr);
- SkShader* strokeShader = reinterpret_cast<SkShader*>(strokeGradientPtr);
+ auto* strokeShader = reinterpret_cast<Shader*>(strokeGradientPtr);
path->mutateStagingProperties()->setStrokeGradient(strokeShader);
}
diff --git a/libs/hwui/shader/BitmapShader.cpp b/libs/hwui/shader/BitmapShader.cpp
new file mode 100644
index 000000000000..fe653e85a021
--- /dev/null
+++ b/libs/hwui/shader/BitmapShader.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BitmapShader.h"
+
+#include "SkImagePriv.h"
+
+namespace android::uirenderer {
+BitmapShader::BitmapShader(const sk_sp<SkImage>& image, const SkTileMode tileModeX,
+ const SkTileMode tileModeY, const SkMatrix* matrix)
+ : Shader(matrix), skShader(image->makeShader(tileModeX, tileModeY)) {}
+
+sk_sp<SkShader> BitmapShader::makeSkShader() {
+ return skShader;
+}
+
+BitmapShader::~BitmapShader() {}
+} // namespace android::uirenderer \ No newline at end of file
diff --git a/libs/hwui/shader/BitmapShader.h b/libs/hwui/shader/BitmapShader.h
new file mode 100644
index 000000000000..ed6a6e6802d1
--- /dev/null
+++ b/libs/hwui/shader/BitmapShader.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Shader.h"
+#include "SkShader.h"
+
+namespace android::uirenderer {
+
+/**
+ * Shader implementation that renders a Bitmap as either a SkShader or SkImageFilter
+ */
+class BitmapShader : public Shader {
+public:
+ BitmapShader(const sk_sp<SkImage>& image, const SkTileMode tileModeX,
+ const SkTileMode tileModeY, const SkMatrix* matrix);
+ ~BitmapShader() override;
+
+protected:
+ sk_sp<SkShader> makeSkShader() override;
+
+private:
+ sk_sp<SkShader> skShader;
+};
+} // namespace android::uirenderer \ No newline at end of file
diff --git a/libs/hwui/shader/ComposeShader.cpp b/libs/hwui/shader/ComposeShader.cpp
new file mode 100644
index 000000000000..3765489e7431
--- /dev/null
+++ b/libs/hwui/shader/ComposeShader.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ComposeShader.h"
+
+#include "SkImageFilters.h"
+#include "SkShader.h"
+
+namespace android::uirenderer {
+
+ComposeShader::ComposeShader(Shader& shaderA, Shader& shaderB, const SkBlendMode blendMode,
+ const SkMatrix* matrix)
+ : Shader(matrix) {
+ // If both Shaders can be represented as SkShaders then use those, if not
+ // create an SkImageFilter from both Shaders and create the equivalent SkImageFilter
+ sk_sp<SkShader> skShaderA = shaderA.asSkShader();
+ sk_sp<SkShader> skShaderB = shaderB.asSkShader();
+ if (skShaderA.get() && skShaderB.get()) {
+ skShader = SkShaders::Blend(blendMode, skShaderA, skShaderB);
+ skImageFilter = nullptr;
+ } else {
+ sk_sp<SkImageFilter> skImageFilterA = shaderA.asSkImageFilter();
+ sk_sp<SkImageFilter> skImageFilterB = shaderB.asSkImageFilter();
+ skShader = nullptr;
+ skImageFilter = SkImageFilters::Xfermode(blendMode, skImageFilterA, skImageFilterB);
+ }
+}
+
+sk_sp<SkShader> ComposeShader::makeSkShader() {
+ return skShader;
+}
+
+sk_sp<SkImageFilter> ComposeShader::makeSkImageFilter() {
+ return skImageFilter;
+}
+
+ComposeShader::~ComposeShader() {}
+} // namespace android::uirenderer
diff --git a/libs/hwui/shader/ComposeShader.h b/libs/hwui/shader/ComposeShader.h
new file mode 100644
index 000000000000..a246b520d46a
--- /dev/null
+++ b/libs/hwui/shader/ComposeShader.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Shader.h"
+#include "SkShader.h"
+
+namespace android::uirenderer {
+
+/**
+ * Shader implementation that can composite 2 Shaders together with the specified blend mode.
+ * This implementation can appropriately convert the composed result to either an SkShader or
+ * SkImageFilter depending on the inputs
+ */
+class ComposeShader : public Shader {
+public:
+ ComposeShader(Shader& shaderA, Shader& shaderB, const SkBlendMode blendMode,
+ const SkMatrix* matrix);
+ ~ComposeShader() override;
+
+protected:
+ sk_sp<SkShader> makeSkShader() override;
+ sk_sp<SkImageFilter> makeSkImageFilter() override;
+
+private:
+ sk_sp<SkShader> skShader;
+ sk_sp<SkImageFilter> skImageFilter;
+};
+} // namespace android::uirenderer
diff --git a/libs/hwui/shader/LinearGradientShader.cpp b/libs/hwui/shader/LinearGradientShader.cpp
new file mode 100644
index 000000000000..868fa44fb4b7
--- /dev/null
+++ b/libs/hwui/shader/LinearGradientShader.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "LinearGradientShader.h"
+
+#include <vector>
+
+#include "SkGradientShader.h"
+
+namespace android::uirenderer {
+
+LinearGradientShader::LinearGradientShader(const SkPoint pts[2],
+ const std::vector<SkColor4f>& colors,
+ sk_sp<SkColorSpace> colorspace, const SkScalar pos[],
+ const SkTileMode tileMode, const uint32_t shaderFlags,
+ const SkMatrix* matrix)
+ : Shader(matrix)
+ , skShader(SkGradientShader::MakeLinear(pts, colors.data(), colorspace, pos, colors.size(),
+ tileMode, shaderFlags, nullptr)) {}
+
+sk_sp<SkShader> LinearGradientShader::makeSkShader() {
+ return skShader;
+}
+
+LinearGradientShader::~LinearGradientShader() {}
+} // namespace android::uirenderer \ No newline at end of file
diff --git a/libs/hwui/shader/LinearGradientShader.h b/libs/hwui/shader/LinearGradientShader.h
new file mode 100644
index 000000000000..596f4e009448
--- /dev/null
+++ b/libs/hwui/shader/LinearGradientShader.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Shader.h"
+#include "SkShader.h"
+
+namespace android::uirenderer {
+
+/**
+ * Shader implementation that renders a color ramp of colors to either as either SkShader or
+ * SkImageFilter
+ */
+class LinearGradientShader : public Shader {
+public:
+ LinearGradientShader(const SkPoint pts[2], const std::vector<SkColor4f>& colors,
+ sk_sp<SkColorSpace> colorspace, const SkScalar pos[],
+ const SkTileMode tileMode, const uint32_t shaderFlags,
+ const SkMatrix* matrix);
+ ~LinearGradientShader() override;
+
+protected:
+ sk_sp<SkShader> makeSkShader() override;
+
+private:
+ sk_sp<SkShader> skShader;
+};
+} // namespace android::uirenderer
diff --git a/libs/hwui/shader/RadialGradientShader.cpp b/libs/hwui/shader/RadialGradientShader.cpp
new file mode 100644
index 000000000000..21ff56fee2f8
--- /dev/null
+++ b/libs/hwui/shader/RadialGradientShader.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "RadialGradientShader.h"
+
+#include <vector>
+
+#include "SkGradientShader.h"
+
+namespace android::uirenderer {
+
+RadialGradientShader::RadialGradientShader(const SkPoint& center, const float radius,
+ const std::vector<SkColor4f>& colors,
+ sk_sp<SkColorSpace> colorspace, const SkScalar pos[],
+ const SkTileMode tileMode, const uint32_t shaderFlags,
+ const SkMatrix* matrix)
+ : Shader(matrix)
+ , skShader(SkGradientShader::MakeRadial(center, radius, colors.data(), colorspace, pos,
+ colors.size(), tileMode, shaderFlags, nullptr)) {}
+
+sk_sp<SkShader> RadialGradientShader::makeSkShader() {
+ return skShader;
+}
+
+RadialGradientShader::~RadialGradientShader() {}
+} // namespace android::uirenderer \ No newline at end of file
diff --git a/libs/hwui/shader/RadialGradientShader.h b/libs/hwui/shader/RadialGradientShader.h
new file mode 100644
index 000000000000..9a2ff139aedb
--- /dev/null
+++ b/libs/hwui/shader/RadialGradientShader.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Shader.h"
+#include "SkShader.h"
+
+namespace android::uirenderer {
+
+/**
+ * Shader implementation that renders a color ramp from the center outward to either as either
+ * a SkShader or SkImageFilter
+ */
+class RadialGradientShader : public Shader {
+public:
+ RadialGradientShader(const SkPoint& center, const float radius,
+ const std::vector<SkColor4f>& colors, sk_sp<SkColorSpace> colorSpace,
+ const SkScalar pos[], const SkTileMode tileMode, const uint32_t shaderFlags,
+ const SkMatrix* matrix);
+ ~RadialGradientShader() override;
+
+protected:
+ sk_sp<SkShader> makeSkShader() override;
+
+private:
+ sk_sp<SkShader> skShader;
+};
+} // namespace android::uirenderer \ No newline at end of file
diff --git a/libs/hwui/shader/RuntimeShader.cpp b/libs/hwui/shader/RuntimeShader.cpp
new file mode 100644
index 000000000000..dd0b6980841a
--- /dev/null
+++ b/libs/hwui/shader/RuntimeShader.cpp
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "RuntimeShader.h"
+
+#include "SkShader.h"
+#include "include/effects/SkRuntimeEffect.h"
+
+namespace android::uirenderer {
+
+RuntimeShader::RuntimeShader(SkRuntimeEffect& effect, sk_sp<SkData> data, bool isOpaque,
+ const SkMatrix* matrix)
+ : Shader(nullptr)
+ , // Explicitly passing null as RuntimeShader is created with the
+ // matrix directly
+ skShader(effect.makeShader(std::move(data), nullptr, 0, matrix, isOpaque)) {}
+
+sk_sp<SkShader> RuntimeShader::makeSkShader() {
+ return skShader;
+}
+
+RuntimeShader::~RuntimeShader() {}
+} // namespace android::uirenderer \ No newline at end of file
diff --git a/libs/hwui/shader/RuntimeShader.h b/libs/hwui/shader/RuntimeShader.h
new file mode 100644
index 000000000000..7fe0b0206467
--- /dev/null
+++ b/libs/hwui/shader/RuntimeShader.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Shader.h"
+#include "SkShader.h"
+#include "include/effects/SkRuntimeEffect.h"
+
+namespace android::uirenderer {
+
+/**
+ * RuntimeShader implementation that can map to either a SkShader or SkImageFilter
+ */
+class RuntimeShader : public Shader {
+public:
+ RuntimeShader(SkRuntimeEffect& effect, sk_sp<SkData> data, bool isOpaque,
+ const SkMatrix* matrix);
+ ~RuntimeShader() override;
+
+protected:
+ sk_sp<SkShader> makeSkShader() override;
+
+private:
+ sk_sp<SkShader> skShader;
+};
+} // namespace android::uirenderer
diff --git a/libs/hwui/shader/Shader.cpp b/libs/hwui/shader/Shader.cpp
new file mode 100644
index 000000000000..45123dd55002
--- /dev/null
+++ b/libs/hwui/shader/Shader.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Shader.h"
+
+#include "SkImageFilters.h"
+#include "SkPaint.h"
+#include "SkRefCnt.h"
+
+namespace android::uirenderer {
+
+Shader::Shader(const SkMatrix* matrix)
+ : localMatrix(matrix ? *matrix : SkMatrix::I())
+ , skShader(nullptr)
+ , skImageFilter(nullptr) {}
+
+Shader::~Shader() {}
+
+sk_sp<SkShader> Shader::asSkShader() {
+ // If we already have created a shader with these parameters just return the existing
+ // shader we have already created
+ if (!this->skShader.get()) {
+ this->skShader = makeSkShader();
+ if (this->skShader.get()) {
+ if (!localMatrix.isIdentity()) {
+ this->skShader = this->skShader->makeWithLocalMatrix(localMatrix);
+ }
+ }
+ }
+ return this->skShader;
+}
+
+/**
+ * By default return null as we cannot convert all visual effects to SkShader instances
+ */
+sk_sp<SkShader> Shader::makeSkShader() {
+ return nullptr;
+}
+
+sk_sp<SkImageFilter> Shader::asSkImageFilter() {
+ // If we already have created an ImageFilter with these parameters just return the existing
+ // ImageFilter we have already created
+ if (!this->skImageFilter.get()) {
+ // Attempt to create an SkImageFilter from the current Shader implementation
+ this->skImageFilter = makeSkImageFilter();
+ if (this->skImageFilter) {
+ if (!localMatrix.isIdentity()) {
+ // If we have created an SkImageFilter and we have a transformation, wrap
+ // the created SkImageFilter to apply the given matrix
+ this->skImageFilter = SkImageFilters::MatrixTransform(
+ localMatrix, kMedium_SkFilterQuality, this->skImageFilter);
+ }
+ } else {
+ // Otherwise if no SkImageFilter implementation is provided, create one from
+ // the result of asSkShader. Note the matrix is already applied to the shader in
+ // this case so just convert it to an SkImageFilter using SkImageFilters::Paint
+ SkPaint paint;
+ paint.setShader(asSkShader());
+ sk_sp<SkImageFilter> paintFilter = SkImageFilters::Paint(paint);
+ this->skImageFilter = SkImageFilters::Xfermode(SkBlendMode::kDstIn,
+ std::move(paintFilter));
+ }
+ }
+ return this->skImageFilter;
+}
+
+/**
+ * By default return null for subclasses to implement. If there is not a direct SkImageFilter
+ * conversion
+ */
+sk_sp<SkImageFilter> Shader::makeSkImageFilter() {
+ return nullptr;
+}
+} // namespace android::uirenderer \ No newline at end of file
diff --git a/libs/hwui/shader/Shader.h b/libs/hwui/shader/Shader.h
new file mode 100644
index 000000000000..3c0cdaae8253
--- /dev/null
+++ b/libs/hwui/shader/Shader.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "SkImageFilter.h"
+#include "SkShader.h"
+#include "SkPaint.h"
+#include "SkRefCnt.h"
+
+class SkMatrix;
+
+namespace android::uirenderer {
+
+/**
+ * Shader class that can optionally wrap an SkShader or SkImageFilter depending
+ * on the implementation
+ */
+class Shader: public SkRefCnt {
+public:
+ /**
+ * Creates a Shader instance with an optional transformation matrix
+ * @param matrix Optional matrix to transform the underlying SkShader or SkImageFilter
+ */
+ Shader(const SkMatrix* matrix);
+ virtual ~Shader();
+
+ /**
+ * Create an SkShader from the current Shader instance or return a previously
+ * created instance. This can be null if no SkShader could be created from this
+ * Shader instance.
+ */
+ sk_sp<SkShader> asSkShader();
+
+ /**
+ * Create an SkImageFilter from the current Shader instance or return a previously
+ * created instance. Unlike asSkShader, this method cannot return null.
+ */
+ sk_sp<SkImageFilter> asSkImageFilter();
+
+protected:
+ /**
+ * Create a new SkShader instance based on this Shader instance
+ */
+ virtual sk_sp<SkShader> makeSkShader();
+
+ /**
+ * Create a new SkImageFilter instance based on this Shader instance. If no SkImageFilter
+ * can be created then return nullptr
+ */
+ virtual sk_sp<SkImageFilter> makeSkImageFilter();
+
+private:
+ /**
+ * Optional matrix transform
+ */
+ const SkMatrix localMatrix;
+
+ /**
+ * Cached SkShader instance to be returned on subsequent queries
+ */
+ sk_sp<SkShader> skShader;
+
+ /**
+ * Cached SkImageFilter instance to be returned on subsequent queries
+ */
+ sk_sp<SkImageFilter> skImageFilter;
+};
+} // namespace android::uirenderer
diff --git a/libs/hwui/shader/SweepGradientShader.cpp b/libs/hwui/shader/SweepGradientShader.cpp
new file mode 100644
index 000000000000..3b1f37f8b051
--- /dev/null
+++ b/libs/hwui/shader/SweepGradientShader.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "SweepGradientShader.h"
+
+#include <vector>
+
+#include "SkGradientShader.h"
+#include "SkImageFilters.h"
+
+namespace android::uirenderer {
+
+SweepGradientShader::SweepGradientShader(float x, float y, const std::vector<SkColor4f>& colors,
+ const sk_sp<SkColorSpace>& colorspace, const SkScalar pos[],
+ const uint32_t shaderFlags, const SkMatrix* matrix)
+ : Shader(matrix)
+ , skShader(SkGradientShader::MakeSweep(x, y, colors.data(), colorspace, pos, colors.size(),
+ shaderFlags, nullptr)) {}
+
+sk_sp<SkShader> SweepGradientShader::makeSkShader() {
+ return skShader;
+}
+
+SweepGradientShader::~SweepGradientShader() {}
+} // namespace android::uirenderer \ No newline at end of file
diff --git a/libs/hwui/shader/SweepGradientShader.h b/libs/hwui/shader/SweepGradientShader.h
new file mode 100644
index 000000000000..dad3ef0ffad4
--- /dev/null
+++ b/libs/hwui/shader/SweepGradientShader.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Shader.h"
+#include "SkShader.h"
+
+namespace android::uirenderer {
+
+/**
+ * Shader implementation that renders a color ramp clockwise such that the start and end colors
+ * are visible at 3 o'clock. This handles converting to either an SkShader or SkImageFilter
+ */
+class SweepGradientShader : public Shader {
+public:
+ SweepGradientShader(float x, float y, const std::vector<SkColor4f>& colors,
+ const sk_sp<SkColorSpace>& colorspace, const SkScalar pos[],
+ const uint32_t shaderFlags, const SkMatrix* matrix);
+ virtual ~SweepGradientShader() override;
+
+protected:
+ virtual sk_sp<SkShader> makeSkShader() override;
+
+private:
+ sk_sp<SkShader> skShader;
+};
+} // namespace android::uirenderer
diff --git a/libs/hwui/tests/common/scenes/BitmapShaders.cpp b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
index c4067af388e3..e2c1651d823a 100644
--- a/libs/hwui/tests/common/scenes/BitmapShaders.cpp
+++ b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
@@ -18,6 +18,7 @@
#include "hwui/Paint.h"
#include "TestSceneBase.h"
#include "tests/common/BitmapAllocationTestUtils.h"
+#include <shader/BitmapShader.h>
#include "utils/Color.h"
class BitmapShaders;
@@ -45,15 +46,24 @@ public:
});
Paint paint;
+ sk_sp<BitmapShader> bitmapShader = sk_make_sp<BitmapShader>(
+ hwuiBitmap->makeImage(),
+ SkTileMode::kRepeat,
+ SkTileMode::kRepeat,
+ nullptr
+ );
+
sk_sp<SkImage> image = hwuiBitmap->makeImage();
- sk_sp<SkShader> repeatShader =
- image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat);
- paint.setShader(std::move(repeatShader));
+ paint.setShader(std::move(bitmapShader));
canvas.drawRoundRect(0, 0, 500, 500, 50.0f, 50.0f, paint);
- sk_sp<SkShader> mirrorShader =
- image->makeShader(SkTileMode::kMirror, SkTileMode::kMirror);
- paint.setShader(std::move(mirrorShader));
+ sk_sp<BitmapShader> mirrorBitmapShader = sk_make_sp<BitmapShader>(
+ image,
+ SkTileMode::kMirror,
+ SkTileMode::kMirror,
+ nullptr
+ );
+ paint.setShader(std::move(mirrorBitmapShader));
canvas.drawRoundRect(0, 600, 500, 1100, 50.0f, 50.0f, paint);
}
diff --git a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
index 5886ea39acce..d37bc3c7d37c 100644
--- a/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
+++ b/libs/hwui/tests/common/scenes/HwBitmapInCompositeShader.cpp
@@ -20,6 +20,10 @@
#include <SkGradientShader.h>
#include <SkImagePriv.h>
#include <ui/PixelFormat.h>
+#include <shader/BitmapShader.h>
+#include <shader/LinearGradientShader.h>
+#include <shader/RadialGradientShader.h>
+#include <shader/ComposeShader.h>
class HwBitmapInCompositeShader;
@@ -50,20 +54,41 @@ public:
pixels[4000 + 4 * i + 3] = 255;
}
buffer->unlock();
- sk_sp<Bitmap> hardwareBitmap(Bitmap::createFrom(buffer->toAHardwareBuffer(),
- SkColorSpace::MakeSRGB()));
- sk_sp<SkShader> hardwareShader(createBitmapShader(*hardwareBitmap));
+
+ sk_sp<BitmapShader> bitmapShader = sk_make_sp<BitmapShader>(
+ Bitmap::createFrom(
+ buffer->toAHardwareBuffer(),
+ SkColorSpace::MakeSRGB()
+ )->makeImage(),
+ SkTileMode::kClamp,
+ SkTileMode::kClamp,
+ nullptr
+ );
SkPoint center;
center.set(50, 50);
- SkColor colors[2];
- colors[0] = Color::Black;
- colors[1] = Color::White;
- sk_sp<SkShader> gradientShader = SkGradientShader::MakeRadial(
- center, 50, colors, nullptr, 2, SkTileMode::kRepeat);
-
- sk_sp<SkShader> compositeShader(
- SkShaders::Blend(SkBlendMode::kDstATop, hardwareShader, gradientShader));
+
+ std::vector<SkColor4f> vColors(2);
+ vColors[0] = SkColors::kBlack;
+ vColors[1] = SkColors::kWhite;
+
+ sk_sp<RadialGradientShader> radialShader = sk_make_sp<RadialGradientShader>(
+ center,
+ 50,
+ vColors,
+ SkColorSpace::MakeSRGB(),
+ nullptr,
+ SkTileMode::kRepeat,
+ 0,
+ nullptr
+ );
+
+ sk_sp<ComposeShader> compositeShader = sk_make_sp<ComposeShader>(
+ *bitmapShader.get(),
+ *radialShader.get(),
+ SkBlendMode::kDstATop,
+ nullptr
+ );
Paint paint;
paint.setShader(std::move(compositeShader));
diff --git a/libs/hwui/tests/common/scenes/ListOfFadedTextAnimation.cpp b/libs/hwui/tests/common/scenes/ListOfFadedTextAnimation.cpp
index a9449b62a1f8..76e39deedd9a 100644
--- a/libs/hwui/tests/common/scenes/ListOfFadedTextAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ListOfFadedTextAnimation.cpp
@@ -17,7 +17,8 @@
#include "TestSceneBase.h"
#include "tests/common/TestListViewSceneBase.h"
#include "hwui/Paint.h"
-#include <SkGradientShader.h>
+#include "SkColor.h"
+#include <shader/LinearGradientShader.h>
class ListOfFadedTextAnimation;
@@ -42,15 +43,26 @@ class ListOfFadedTextAnimation : public TestListViewSceneBase {
pts[0].set(0, 0);
pts[1].set(0, 1);
- SkColor colors[2] = {Color::Black, Color::Transparent};
- sk_sp<SkShader> s(
- SkGradientShader::MakeLinear(pts, colors, NULL, 2, SkTileMode::kClamp));
-
SkMatrix matrix;
matrix.setScale(1, length);
matrix.postRotate(-90);
+
+ std::vector<SkColor4f> vColors(2);
+ vColors[0] = SkColors::kBlack;
+ vColors[1] = SkColors::kTransparent;
+
+ sk_sp<LinearGradientShader> linearGradientShader = sk_make_sp<LinearGradientShader>(
+ pts,
+ vColors,
+ SkColorSpace::MakeSRGB(),
+ nullptr,
+ SkTileMode::kClamp,
+ 0,
+ &matrix
+ );
+
Paint fadingPaint;
- fadingPaint.setShader(s->makeWithLocalMatrix(matrix));
+ fadingPaint.setShader(linearGradientShader);
fadingPaint.setBlendMode(SkBlendMode::kDstOut);
canvas.drawRect(0, 0, length, itemHeight, fadingPaint);
canvas.restore();
diff --git a/libs/hwui/tests/common/scenes/SimpleColorMatrixAnimation.cpp b/libs/hwui/tests/common/scenes/SimpleColorMatrixAnimation.cpp
index a0bc5aa245d5..bdc157f85264 100644
--- a/libs/hwui/tests/common/scenes/SimpleColorMatrixAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/SimpleColorMatrixAnimation.cpp
@@ -17,7 +17,7 @@
#include "TestSceneBase.h"
#include <SkColorMatrixFilter.h>
-#include <SkGradientShader.h>
+#include <shader/LinearGradientShader.h>
class SimpleColorMatrixAnimation;
@@ -65,9 +65,12 @@ private:
// enough renderer might apply it directly to the paint color)
float pos[] = {0, 1};
SkPoint pts[] = {SkPoint::Make(0, 0), SkPoint::Make(width, height)};
- SkColor colors[2] = {Color::DeepPurple_500, Color::DeepOrange_500};
- paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos, 2,
- SkTileMode::kClamp));
+ std::vector<SkColor4f> colors(2);
+ colors[0] = SkColor4f::FromColor(Color::DeepPurple_500);
+ colors[1] = SkColor4f::FromColor(Color::DeepOrange_500);
+ paint.setShader(sk_make_sp<LinearGradientShader>(
+ pts, colors, SkColorSpace::MakeSRGB(), pos, SkTileMode::kClamp,
+ 0, nullptr));
// overdraw several times to emphasize shader cost
for (int i = 0; i < 10; i++) {
diff --git a/libs/hwui/tests/common/scenes/SimpleGradientAnimation.cpp b/libs/hwui/tests/common/scenes/SimpleGradientAnimation.cpp
index 57a260c8d234..9a15c9d370a4 100644
--- a/libs/hwui/tests/common/scenes/SimpleGradientAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/SimpleGradientAnimation.cpp
@@ -17,6 +17,7 @@
#include "TestSceneBase.h"
#include <SkGradientShader.h>
+#include <shader/LinearGradientShader.h>
class SimpleGradientAnimation;
@@ -55,9 +56,24 @@ private:
// overdraw several times to emphasize shader cost
for (int i = 0; i < 10; i++) {
// use i%2 start position to pick 2 color combo with black in it
- SkColor colors[3] = {Color::Transparent, Color::Black, Color::Cyan_500};
- paint.setShader(SkGradientShader::MakeLinear(pts, colors + (i % 2), pos, 2,
- SkTileMode::kClamp));
+ std::vector<SkColor4f> vColors(2);
+ vColors[0] = ((i % 2) == 0) ?
+ SkColor4f::FromColor(Color::Transparent) :
+ SkColor4f::FromColor(Color::Black);
+ vColors[1] = (((i + 1) % 2) == 0) ?
+ SkColor4f::FromColor(Color::Black) :
+ SkColor4f::FromColor(Color::Cyan_500);
+
+ sk_sp<LinearGradientShader> gradient = sk_make_sp<LinearGradientShader>(
+ pts,
+ vColors,
+ SkColorSpace::MakeSRGB(),
+ pos,
+ SkTileMode::kClamp,
+ 0,
+ nullptr
+ );
+ paint.setShader(gradient);
canvas.drawRect(i, i, width, height, paint);
}
});
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index 6d4c57413f00..5e56b26f46f0 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -17,9 +17,14 @@
#include <gtest/gtest.h>
#include "PathParser.h"
+#include "GraphicsJNI.h"
+#include "SkGradientShader.h"
+#include "SkShader.h"
#include "VectorDrawable.h"
#include "utils/MathUtils.h"
#include "utils/VectorDrawableUtils.h"
+#include <shader/Shader.h>
+#include <shader/LinearGradientShader.h>
#include <functional>
@@ -395,7 +400,21 @@ TEST(VectorDrawable, drawPathWithoutIncrementingShaderRefCount) {
bitmap.allocN32Pixels(5, 5, false);
SkCanvas canvas(bitmap);
- sk_sp<SkShader> shader = SkShaders::Color(SK_ColorBLACK);
+ SkPoint pts[2];
+ pts[0].set(0, 0);
+ pts[1].set(0, 0);
+
+ std::vector<SkColor4f> colors(2);
+ colors[0] = SkColors::kBlack;
+ colors[1] = SkColors::kBlack;
+
+ sk_sp<LinearGradientShader> shader = sk_sp(new LinearGradientShader(pts,
+ colors,
+ SkColorSpace::MakeSRGB(),
+ nullptr,
+ SkTileMode::kClamp,
+ SkGradientShader::kInterpolateColorsInPremul_Flag,
+ nullptr));
// Initial ref count is 1
EXPECT_TRUE(shader->unique());
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 6976a3569655..20006934ee46 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -523,7 +523,8 @@ public final class MediaSessionManager {
* @param keyEvent The KeyEvent to send.
* @hide
*/
- public void dispatchMediaKeyEventAsSystemService(KeyEvent keyEvent) {
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public void dispatchMediaKeyEventAsSystemService(@NonNull KeyEvent keyEvent) {
dispatchMediaKeyEventInternal(true, keyEvent, false);
}
@@ -548,6 +549,7 @@ public final class MediaSessionManager {
* @return {@code true} if the event was sent to the session, {@code false} otherwise
* @hide
*/
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public boolean dispatchMediaKeyEventAsSystemService(@NonNull MediaSession.Token sessionToken,
@NonNull KeyEvent keyEvent) {
if (sessionToken == null) {
@@ -586,10 +588,15 @@ public final class MediaSessionManager {
* Should be only called by the {@link com.android.internal.policy.PhoneWindow} or
* {@link android.view.FallbackEventHandler} when the foreground activity didn't consume the key
* from the hardware devices.
+ * <p>
+ * Valid stream types include {@link AudioManager.PublicStreamTypes} and
+ * {@link AudioManager#USE_DEFAULT_STREAM_TYPE}.
*
- * @param keyEvent The KeyEvent to send.
+ * @param keyEvent volume key event
+ * @param streamType type of stream
* @hide
*/
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public void dispatchVolumeKeyEventAsSystemService(@NonNull KeyEvent keyEvent, int streamType) {
dispatchVolumeKeyEventInternal(true, keyEvent, streamType, false);
}
@@ -614,6 +621,7 @@ public final class MediaSessionManager {
* @param keyEvent volume key event
* @hide
*/
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
public void dispatchVolumeKeyEventAsSystemService(@NonNull MediaSession.Token sessionToken,
@NonNull KeyEvent keyEvent) {
if (sessionToken == null) {
diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt
index f9d0d14c7335..e90fbd4dead8 100644
--- a/non-updatable-api/current.txt
+++ b/non-updatable-api/current.txt
@@ -45137,7 +45137,7 @@ package android.telephony {
method public long getNci();
method @IntRange(from=0, to=3279165) public int getNrarfcn();
method @IntRange(from=0, to=1007) public int getPci();
- method @IntRange(from=0, to=65535) public int getTac();
+ method @IntRange(from=0, to=16777215) public int getTac();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.CellIdentityNr> CREATOR;
}
diff --git a/non-updatable-api/module-lib-current.txt b/non-updatable-api/module-lib-current.txt
index 617a83f05791..8892a2954afb 100644
--- a/non-updatable-api/module-lib-current.txt
+++ b/non-updatable-api/module-lib-current.txt
@@ -46,6 +46,13 @@ package android.media.session {
field public static final int FLAG_EXCLUSIVE_GLOBAL_PRIORITY = 65536; // 0x10000
}
+ public final class MediaSessionManager {
+ method public void dispatchMediaKeyEventAsSystemService(@NonNull android.view.KeyEvent);
+ method public boolean dispatchMediaKeyEventAsSystemService(@NonNull android.media.session.MediaSession.Token, @NonNull android.view.KeyEvent);
+ method public void dispatchVolumeKeyEventAsSystemService(@NonNull android.view.KeyEvent, int);
+ method public void dispatchVolumeKeyEventAsSystemService(@NonNull android.media.session.MediaSession.Token, @NonNull android.view.KeyEvent);
+ }
+
}
package android.os {
diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt
index dbf9e9fb4ae5..3fd0ee1c8011 100644
--- a/non-updatable-api/system-current.txt
+++ b/non-updatable-api/system-current.txt
@@ -11037,6 +11037,7 @@ package android.telephony.ims {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
+ field public static final int KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID = 67; // 0x43
field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index adc8b4d24cd8..290700fad147 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -22,7 +22,6 @@ import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
import android.content.Context;
import android.os.Handler;
import android.os.PowerManager;
-import android.view.IWindowManager;
import com.android.keyguard.KeyguardViewController;
import com.android.systemui.broadcast.BroadcastDispatcher;
@@ -40,8 +39,6 @@ import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
import com.android.systemui.doze.DozeHost;
-import com.android.systemui.pip.phone.PipMenuActivity;
-import com.android.systemui.pip.phone.dagger.PipMenuActivityClass;
import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.EnhancedEstimates;
@@ -68,11 +65,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.volume.VolumeDialogComponent;
-import com.android.systemui.wm.DisplaySystemBarsController;
-import com.android.wm.shell.common.DisplayController;
-import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.SystemWindows;
-import com.android.wm.shell.common.TransactionPool;
+import com.android.systemui.wmshell.CarWMShellModule;
import javax.inject.Named;
@@ -83,7 +76,8 @@ import dagger.Provides;
@Module(
includes = {
DividerModule.class,
- QSModule.class
+ QSModule.class,
+ CarWMShellModule.class
})
abstract class CarSystemUIModule {
@@ -120,42 +114,6 @@ abstract class CarSystemUIModule {
return new Recents(context, recentsImplementation, commandQueue);
}
- @SysUISingleton
- @Provides
- static TransactionPool provideTransactionPool() {
- return new TransactionPool();
- }
-
- @SysUISingleton
- @Provides
- static DisplayController providerDisplayController(Context context, @Main Handler handler,
- IWindowManager wmService) {
- return new DisplayController(context, handler, wmService);
- }
-
- @SysUISingleton
- @Provides
- static SystemWindows provideSystemWindows(DisplayController displayController,
- IWindowManager wmService) {
- return new SystemWindows(displayController, wmService);
- }
-
- @SysUISingleton
- @Provides
- static DisplayImeController provideDisplayImeController(Context context,
- IWindowManager wmService, DisplayController displayController,
- @Main Handler mainHandler, TransactionPool transactionPool) {
- return new DisplaySystemBarsController.Builder(context, wmService, displayController,
- mainHandler, transactionPool).build();
- }
-
- @SysUISingleton
- @PipMenuActivityClass
- @Provides
- static Class<?> providePipMenuActivityClass() {
- return PipMenuActivity.class;
- }
-
@Binds
abstract HeadsUpManager bindHeadsUpManagerPhone(HeadsUpManagerPhone headsUpManagerPhone);
diff --git a/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMShellModule.java b/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMShellModule.java
new file mode 100644
index 000000000000..2324c3d59155
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/wmshell/CarWMShellModule.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.wmshell;
+
+import android.content.Context;
+import android.os.Handler;
+import android.view.IWindowManager;
+
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.pip.phone.PipMenuActivity;
+import com.android.systemui.pip.phone.dagger.PipMenuActivityClass;
+import com.android.systemui.wm.DisplaySystemBarsController;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.DisplayImeController;
+import com.android.wm.shell.common.TransactionPool;
+
+import dagger.Module;
+import dagger.Provides;
+
+/** Provides dependencies from {@link com.android.wm.shell} for CarSystemUI. */
+@Module(includes = WMShellBaseModule.class)
+public class CarWMShellModule {
+ @SysUISingleton
+ @Provides
+ DisplayImeController provideDisplayImeController(Context context,
+ IWindowManager wmService, DisplayController displayController,
+ @Main Handler mainHandler, TransactionPool transactionPool) {
+ return new DisplaySystemBarsController.Builder(context, wmService, displayController,
+ mainHandler, transactionPool).build();
+ }
+
+ /** TODO(b/150319024): PipMenuActivity will move to a Window */
+ @SysUISingleton
+ @PipMenuActivityClass
+ @Provides
+ Class<?> providePipMenuActivityClass() {
+ return PipMenuActivity.class;
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
index 9d06c8467e41..72a6074ff89c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java
@@ -465,7 +465,16 @@ public class LocalMediaManager implements BluetoothCallback {
synchronized (mMediaDevicesLock) {
mMediaDevices.clear();
mMediaDevices.addAll(devices);
- mMediaDevices.addAll(buildDisconnectedBluetoothDevice());
+ // Add disconnected bluetooth devices only when phone output device is available.
+ for (MediaDevice device : devices) {
+ final int type = device.getDeviceType();
+ if (type == MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE
+ || type == MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE
+ || type == MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE) {
+ mMediaDevices.addAll(buildDisconnectedBluetoothDevice());
+ break;
+ }
+ }
}
final MediaDevice infoMediaDevice = mInfoMediaManager.getCurrentConnectedDevice();
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
index a654fd47ea12..8e850b25159c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/LocalMediaManagerTest.java
@@ -585,6 +585,7 @@ public class LocalMediaManagerTest {
when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
when(device3.getId()).thenReturn(TEST_DEVICE_ID_3);
+ when(device1.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE);
when(mLocalMediaManager.mPhoneDevice.getId()).thenReturn("test_phone_id");
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
@@ -683,6 +684,7 @@ public class LocalMediaManagerTest {
when(device1.getId()).thenReturn(TEST_DEVICE_ID_1);
when(device2.getId()).thenReturn(TEST_DEVICE_ID_2);
when(device3.getId()).thenReturn(TEST_DEVICE_ID_3);
+ when(device1.getDeviceType()).thenReturn(MediaDevice.MediaDeviceType.TYPE_PHONE_DEVICE);
when(mLocalMediaManager.mPhoneDevice.getId()).thenReturn("test_phone_id");
assertThat(mLocalMediaManager.mMediaDevices).hasSize(2);
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index bdf00e38ce94..bcd2ff71b57f 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -175,5 +175,6 @@ public class SecureSettings {
Settings.Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED,
Settings.Secure.PANIC_GESTURE_ENABLED,
Settings.Secure.PANIC_SOUND_ENABLED,
+ Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED
};
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 4ea7f3a23c10..3630f257f583 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -263,5 +263,6 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.SWIPE_BOTTOM_TO_NOTIFICATION_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.PANIC_GESTURE_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.PANIC_SOUND_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Secure.ADAPTIVE_CONNECTIVITY_ENABLED, BOOLEAN_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 5c0662e2a8ee..66be8dd68283 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -773,29 +773,29 @@ class SettingsProtoDumpUtil {
Settings.Global.GPU_DEBUG_LAYERS_GLES,
GlobalSettingsProto.Gpu.DEBUG_LAYERS_GLES);
dumpSetting(s, p,
- Settings.Global.GAME_DRIVER_ALL_APPS,
- GlobalSettingsProto.Gpu.GAME_DRIVER_ALL_APPS);
+ Settings.Global.UPDATABLE_DRIVER_ALL_APPS,
+ GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_ALL_APPS);
dumpSetting(s, p,
- Settings.Global.GAME_DRIVER_OPT_IN_APPS,
- GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_IN_APPS);
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS,
+ GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS);
dumpSetting(s, p,
- Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS,
- GlobalSettingsProto.Gpu.GAME_DRIVER_PRERELEASE_OPT_IN_APPS);
+ Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS,
+ GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS);
dumpSetting(s, p,
- Settings.Global.GAME_DRIVER_OPT_OUT_APPS,
- GlobalSettingsProto.Gpu.GAME_DRIVER_OPT_OUT_APPS);
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS,
+ GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS);
dumpSetting(s, p,
- Settings.Global.GAME_DRIVER_DENYLIST,
- GlobalSettingsProto.Gpu.GAME_DRIVER_DENYLIST);
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST,
+ GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRODUCTION_DENYLIST);
dumpSetting(s, p,
- Settings.Global.GAME_DRIVER_ALLOWLIST,
- GlobalSettingsProto.Gpu.GAME_DRIVER_ALLOWLIST);
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST,
+ GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST);
dumpSetting(s, p,
- Settings.Global.GAME_DRIVER_DENYLISTS,
- GlobalSettingsProto.Gpu.GAME_DRIVER_DENYLISTS);
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS,
+ GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS);
dumpSetting(s, p,
- Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES,
- GlobalSettingsProto.Gpu.GAME_DRIVER_SPHAL_LIBRARIES);
+ Settings.Global.UPDATABLE_DRIVER_SPHAL_LIBRARIES,
+ GlobalSettingsProto.Gpu.UPDATABLE_DRIVER_SPHAL_LIBRARIES);
p.end(gpuToken);
final long hdmiToken = p.start(GlobalSettingsProto.HDMI);
@@ -1976,6 +1976,9 @@ class SettingsProtoDumpUtil {
dumpSetting(s, p,
Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS,
SecureSettingsProto.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS);
+ dumpSetting(s, p,
+ Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED,
+ SecureSettingsProto.ADAPTIVE_CONNECTIVITY_ENABLED);
final long controlsToken = p.start(SecureSettingsProto.CONTROLS);
dumpSetting(s, p,
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 4bb8f45f331f..0ac3355c4952 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -504,14 +504,14 @@ public class SettingsBackupTest {
Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_PKGS,
Settings.Global.GLOBAL_SETTINGS_ANGLE_GL_DRIVER_SELECTION_VALUES,
Settings.Global.GLOBAL_SETTINGS_ANGLE_ALLOWLIST,
- Settings.Global.GAME_DRIVER_ALL_APPS,
- Settings.Global.GAME_DRIVER_OPT_IN_APPS,
- Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS,
- Settings.Global.GAME_DRIVER_OPT_OUT_APPS,
- Settings.Global.GAME_DRIVER_DENYLISTS,
- Settings.Global.GAME_DRIVER_DENYLIST,
- Settings.Global.GAME_DRIVER_ALLOWLIST,
- Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES,
+ Settings.Global.UPDATABLE_DRIVER_ALL_APPS,
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS,
+ Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS,
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS,
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS,
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST,
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST,
+ Settings.Global.UPDATABLE_DRIVER_SPHAL_LIBRARIES,
Settings.Global.GLOBAL_SETTINGS_SHOW_ANGLE_IN_USE_DIALOG_BOX,
Settings.Global.GPU_DEBUG_LAYER_APP,
Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING,
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 98d3553287d1..4ce9f5a9edc6 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -240,6 +240,8 @@
<!-- Listen app op changes -->
<uses-permission android:name="android.permission.WATCH_APPOPS" />
<uses-permission android:name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS" />
+ <!-- For handling silent audio recordings -->
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_ROUTING" />
<!-- to read and change hvac values in a car -->
<uses-permission android:name="android.car.permission.CONTROL_CAR_CLIMATE" />
@@ -267,6 +269,7 @@
<!-- Permission to make accessibility service access Bubbles -->
<uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY" />
+
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
<protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
index 0d960f0c21be..6c5c4ef94921 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
@@ -39,6 +39,10 @@ public interface StatusBarStateController {
*/
boolean isDozing();
+ /**
+ * Is the status bar panel expanded.
+ */
+ boolean isExpanded();
/**
* Is device pulsing.
@@ -113,5 +117,10 @@ public interface StatusBarStateController {
* Callback to be notified when the pulsing state changes
*/
default void onPulsingChanged(boolean pulsing) {}
+
+ /**
+ * Callback to be notified when the expanded state of the status bar changes
+ */
+ default void onExpandedChanged(boolean isExpanded) {}
}
}
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 887384d78f29..b42d71abaa6d 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -44,4 +44,5 @@
-keep class com.android.wm.shell.*
-keep class com.android.systemui.dagger.GlobalRootComponent { *; }
--keep class com.android.systemui.dagger.GlobalRootComponent$SysUIComponentImpl { *; } \ No newline at end of file
+-keep class com.android.systemui.dagger.GlobalRootComponent$SysUIComponentImpl { *; }
+-keep class com.android.systemui.dagger.Dagger** { *; } \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
index 46396e3e62b4..4b3534b1cbc8 100644
--- a/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
+++ b/packages/SystemUI/res/layout/global_screenshot_action_chip.xml
@@ -32,6 +32,7 @@
android:gravity="center">
<ImageView
android:id="@+id/screenshot_action_chip_icon"
+ android:tint="@*android:color/accent_device_default"
android:layout_width="@dimen/screenshot_action_chip_icon_size"
android:layout_height="@dimen/screenshot_action_chip_icon_size"
android:layout_marginStart="@dimen/screenshot_action_chip_padding_start"
diff --git a/packages/SystemUI/res/layout/udfps_view.xml b/packages/SystemUI/res/layout/udfps_view.xml
index 732758a2ded2..31a33fbfc308 100644
--- a/packages/SystemUI/res/layout/udfps_view.xml
+++ b/packages/SystemUI/res/layout/udfps_view.xml
@@ -5,6 +5,6 @@
android:id="@+id/udfps_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- systemui:sensorRadius="140px"
- systemui:sensorMarginBottom="630px"
+ systemui:sensorRadius="130px"
+ systemui:sensorCenterY="1636px"
systemui:sensorTouchAreaCoefficient="0.5"/>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 84dbd60b799d..a62502965dd2 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -159,7 +159,7 @@
<declare-styleable name="UdfpsView">
<attr name="sensorRadius" format="dimension"/>
- <attr name="sensorMarginBottom" format="dimension"/>
+ <attr name="sensorCenterY" format="dimension"/>
<attr name="sensorPressureCoefficient" format="float"/>
<attr name="sensorTouchAreaCoefficient" format="float"/>
</declare-styleable>
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index de47c68166ff..748a9c9448c5 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -78,7 +78,7 @@ import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager.KeyguardEnvironment;
import com.android.systemui.statusbar.notification.NotificationFilter;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 7023e477f4ed..f5c364947a2f 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -27,24 +27,15 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.dagger.DaggerGlobalRootComponent;
import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dagger.WMComponent;
-import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.screenshot.ScreenshotNotificationSmartActionsProvider;
-import com.android.systemui.statusbar.NotificationListener;
-import com.android.systemui.statusbar.NotificationMediaManager;
-import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
-import com.android.systemui.statusbar.phone.NotificationIconAreaController;
-import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import java.util.concurrent.Executor;
@@ -151,19 +142,4 @@ public class SystemUIFactory {
Dependency.get(KeyguardUpdateMonitor.class), bypassController,
new Handler(Looper.getMainLooper()));
}
-
- public NotificationIconAreaController createNotificationIconAreaController(Context context,
- StatusBar statusBar,
- NotificationWakeUpCoordinator wakeUpCoordinator,
- KeyguardBypassController keyguardBypassController,
- StatusBarStateController statusBarStateController,
- DemoModeController demoModeController) {
- return new NotificationIconAreaController(context, statusBar, statusBarStateController,
- wakeUpCoordinator, keyguardBypassController,
- Dependency.get(NotificationMediaManager.class),
- Dependency.get(NotificationListener.class),
- Dependency.get(DozeParameters.class),
- Dependency.get(BubbleController.class),
- demoModeController);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
index 36353fa96956..d7e91384f049 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java
@@ -53,12 +53,10 @@ public class UdfpsView extends View implements DozeReceiver,
private final Paint mScrimPaint;
private final Paint mDebugTextPaint;
- private float mSensorX;
- private float mSensorY;
private final RectF mSensorRect;
private final Paint mSensorPaint;
private final float mSensorRadius;
- private final float mSensorMarginBottom;
+ private final float mSensorCenterY;
private final float mSensorTouchAreaCoefficient;
private final int mMaxBurnInOffsetX;
private final int mMaxBurnInOffsetY;
@@ -66,6 +64,10 @@ public class UdfpsView extends View implements DozeReceiver,
private final Rect mTouchableRegion;
private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener;
+ // This is calculated from the screen's dimensions at runtime, as opposed to mSensorCenterY,
+ // which is defined in layout.xml
+ private float mSensorCenterX;
+
// AOD anti-burn-in offsets
private float mInterpolatedDarkAmount;
private float mBurnInOffsetX;
@@ -84,7 +86,7 @@ public class UdfpsView extends View implements DozeReceiver,
if (!a.hasValue(R.styleable.UdfpsView_sensorRadius)) {
throw new IllegalArgumentException("UdfpsView must contain sensorRadius");
}
- if (!a.hasValue(R.styleable.UdfpsView_sensorMarginBottom)) {
+ if (!a.hasValue(R.styleable.UdfpsView_sensorCenterY)) {
throw new IllegalArgumentException("UdfpsView must contain sensorMarginBottom");
}
if (!a.hasValue(R.styleable.UdfpsView_sensorTouchAreaCoefficient)) {
@@ -92,7 +94,7 @@ public class UdfpsView extends View implements DozeReceiver,
"UdfpsView must contain sensorTouchAreaCoefficient");
}
mSensorRadius = a.getDimension(R.styleable.UdfpsView_sensorRadius, 0f);
- mSensorMarginBottom = a.getDimension(R.styleable.UdfpsView_sensorMarginBottom, 0f);
+ mSensorCenterY = a.getDimension(R.styleable.UdfpsView_sensorCenterY, 0f);
mSensorTouchAreaCoefficient = a.getFloat(
R.styleable.UdfpsView_sensorTouchAreaCoefficient, 0f);
} finally {
@@ -163,10 +165,9 @@ public class UdfpsView extends View implements DozeReceiver,
final int h = getLayoutParams().height;
final int w = getLayoutParams().width;
mScrimRect.set(0 /* left */, 0 /* top */, w, h);
- mSensorX = w / 2f;
- mSensorY = h - mSensorMarginBottom - mSensorRadius;
- mSensorRect.set(mSensorX - mSensorRadius, mSensorY - mSensorRadius,
- mSensorX + mSensorRadius, mSensorY + mSensorRadius);
+ mSensorCenterX = w / 2f;
+ mSensorRect.set(mSensorCenterX - mSensorRadius, mSensorCenterY - mSensorRadius,
+ mSensorCenterX + mSensorRadius, mSensorCenterY + mSensorRadius);
// Sets mTouchableRegion with rounded up values from mSensorRect.
mSensorRect.roundOut(mTouchableRegion);
@@ -210,10 +211,10 @@ public class UdfpsView extends View implements DozeReceiver,
}
boolean isValidTouch(float x, float y, float pressure) {
- return x > (mSensorX - mSensorRadius * mSensorTouchAreaCoefficient)
- && x < (mSensorX + mSensorRadius * mSensorTouchAreaCoefficient)
- && y > (mSensorY - mSensorRadius * mSensorTouchAreaCoefficient)
- && y < (mSensorY + mSensorRadius * mSensorTouchAreaCoefficient);
+ return x > (mSensorCenterX - mSensorRadius * mSensorTouchAreaCoefficient)
+ && x < (mSensorCenterX + mSensorRadius * mSensorTouchAreaCoefficient)
+ && y > (mSensorCenterY - mSensorRadius * mSensorTouchAreaCoefficient)
+ && y < (mSensorCenterY + mSensorRadius * mSensorTouchAreaCoefficient);
}
void setScrimAlpha(int alpha) {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index 43d7d7f22e6f..3b225d5313c1 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -62,7 +62,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.wmshell.WindowManagerShellModule;
+import com.android.systemui.wmshell.WMShellModule;
import javax.inject.Named;
@@ -77,7 +77,7 @@ import dagger.Provides;
@Module(includes = {
DividerModule.class,
QSModule.class,
- WindowManagerShellModule.class
+ WMShellModule.class
})
public abstract class SystemUIDefaultModule {
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index b2e8cb04c739..a003d8365810 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -17,7 +17,7 @@ import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.qs.PageIndicator
-import com.android.systemui.statusbar.notification.VisualStabilityManager
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.Utils
import com.android.systemui.util.animation.UniqueObjectHostView
@@ -155,6 +155,7 @@ class MediaCarouselController @Inject constructor(
inflateSettingsButton()
mediaContent = mediaCarousel.requireViewById(R.id.media_carousel)
configurationController.addCallback(configListener)
+ // TODO (b/162832756): remove visual stability manager when migrating to new pipeline
visualStabilityCallback = VisualStabilityManager.Callback {
if (needsReordering) {
needsReordering = false
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index e2aa09c862f3..facb3966f78c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -233,7 +233,10 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio
@Override
public void onAspectRatioChanged(float aspectRatio) {
- mHandler.post(() -> mPipBoundsHandler.onAspectRatioChanged(aspectRatio));
+ mHandler.post(() -> {
+ mPipBoundsHandler.onAspectRatioChanged(aspectRatio);
+ mTouchHandler.onAspectRatioChanged();
+ });
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
index 9c42f8bff378..2800bb938149 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipResizeGestureHandler.java
@@ -364,6 +364,10 @@ public class PipResizeGestureHandler {
mUserResizeBounds.set(bounds);
}
+ void invalidateUserResizeBounds() {
+ mUserResizeBounds.setEmpty();
+ }
+
Rect getUserResizeBounds() {
return mUserResizeBounds;
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index b20ea4e5c836..ecd315b336f2 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -426,8 +426,21 @@ public class PipTouchHandler {
}
}
+ /**
+ * Responds to IPinnedStackListener on resetting aspect ratio for the pinned window.
+ */
+ public void onAspectRatioChanged() {
+ mPipResizeGestureHandler.invalidateUserResizeBounds();
+ }
+
public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect curBounds,
boolean fromImeAdjustment, boolean fromShelfAdjustment, int displayRotation) {
+ // Set the user resized bounds equal to the new normal bounds in case they were
+ // invalidated (e.g. by an aspect ratio change).
+ if (mPipResizeGestureHandler.getUserResizeBounds().isEmpty()) {
+ mPipResizeGestureHandler.setUserResizeBounds(normalBounds);
+ }
+
final int bottomOffset = mIsImeShowing ? mImeHeight : 0;
final boolean fromDisplayRotationChanged = (mDisplayRotation != displayRotation);
if (fromDisplayRotationChanged) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
index b5209bbbdd21..a48870240384 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotActionChip.java
@@ -65,10 +65,10 @@ public class ScreenshotActionChip extends FrameLayout {
}
void setIcon(Icon icon, boolean tint) {
- if (tint) {
- icon.setTint(mIconColor);
- }
mIcon.setImageIcon(icon);
+ if (!tint) {
+ mIcon.setImageTintList(null);
+ }
}
void setText(CharSequence text) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index f272be477f51..1cd1b60ac1ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -21,7 +21,6 @@ import android.content.res.Resources;
import android.os.Handler;
import android.os.Trace;
import android.os.UserHandle;
-import android.service.notification.NotificationListenerService.Ranking;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -35,9 +34,9 @@ import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.DynamicChildBindController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.inflation.LowPriorityInflationHelper;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index e0352671e204..e9442499a8ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -103,6 +103,11 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
private boolean mIsDozing;
/**
+ * If the status bar is currently expanded or not.
+ */
+ private boolean mIsExpanded;
+
+ /**
* Current {@link #mDozeAmount} animator.
*/
private ValueAnimator mDarkAnimator;
@@ -190,6 +195,26 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
}
@Override
+ public boolean isExpanded() {
+ return mIsExpanded;
+ }
+
+ @Override
+ public boolean setPanelExpanded(boolean expanded) {
+ if (mIsExpanded == expanded) {
+ return false;
+ }
+ mIsExpanded = expanded;
+ String tag = getClass().getSimpleName() + "#setIsExpanded";
+ DejankUtils.startDetectingBlockingIpcs(tag);
+ for (RankedListener rl : new ArrayList<>(mListeners)) {
+ rl.mListener.onExpandedChanged(mIsExpanded);
+ }
+ DejankUtils.stopDetectingBlockingIpcs(tag);
+ return true;
+ }
+
+ @Override
public float getInterpolatedDozeAmount() {
return mDozeInterpolator.getInterpolation(mDozeAmount);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
index 07b35502478f..9f8fe35dfbc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
@@ -75,6 +75,14 @@ public interface SysuiStatusBarStateController extends StatusBarStateController
*/
void setDozeAmount(float dozeAmount, boolean animated);
+
+ /**
+ * Update the expanded state from {@link StatusBar}'s perspective
+ * @param expanded are we expanded?
+ * @return {@code true} if the state changed, else {@code false}
+ */
+ boolean setPanelExpanded(boolean expanded);
+
/**
* Sets whether to leave status bar open when hiding keyguard
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
index 5b073cec9764..44550b72e521 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/StatusBarDependenciesModule.java
@@ -41,8 +41,8 @@ import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.DynamicChildBindController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.inflation.LowPriorityInflationHelper;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.stack.ForegroundServiceSectionController;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
index 19637bbd54df..9482c17a8769 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/DynamicPrivacyController.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.notification;
+import android.annotation.Nullable;
import android.util.ArraySet;
import com.android.systemui.dagger.SysUISingleton;
@@ -36,11 +37,11 @@ public class DynamicPrivacyController implements KeyguardStateController.Callbac
private final KeyguardStateController mKeyguardStateController;
private final NotificationLockscreenUserManager mLockscreenUserManager;
private final StatusBarStateController mStateController;
- private ArraySet<Listener> mListeners = new ArraySet<>();
+ private final ArraySet<Listener> mListeners = new ArraySet<>();
private boolean mLastDynamicUnlocked;
private boolean mCacheInvalid;
- private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ @Nullable private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Inject
DynamicPrivacyController(NotificationLockscreenUserManager notificationLockscreenUserManager,
@@ -96,8 +97,7 @@ public class DynamicPrivacyController implements KeyguardStateController.Callbac
* contents aren't revealed yet?
*/
public boolean isInLockedDownShade() {
- if (!mStatusBarKeyguardViewManager.isShowing()
- || !mKeyguardStateController.isMethodSecure()) {
+ if (!isStatusBarKeyguardShowing() || !mKeyguardStateController.isMethodSecure()) {
return false;
}
int state = mStateController.getState();
@@ -110,6 +110,10 @@ public class DynamicPrivacyController implements KeyguardStateController.Callbac
return true;
}
+ private boolean isStatusBarKeyguardShowing() {
+ return mStatusBarKeyguardViewManager != null && mStatusBarKeyguardViewManager.isShowing();
+ }
+
public void setStatusBarKeyguardViewManager(
StatusBarKeyguardViewManager statusBarKeyguardViewManager) {
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index e1ff872456eb..b5f1c7ff9b62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -48,6 +48,7 @@ import com.android.systemui.statusbar.NotificationUiAdjustment;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
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 54e545352e53..1326d920fe42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -27,7 +27,6 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.notification.stack.StackStateAnimator
import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.KeyguardBypassController
-import com.android.systemui.statusbar.phone.NotificationIconAreaController
import com.android.systemui.statusbar.phone.PanelExpansionListener
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
@@ -98,7 +97,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
private var collapsedEnoughToHide: Boolean = false
- lateinit var iconAreaController: NotificationIconAreaController
var pulsing: Boolean = false
set(value) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt
index 57f8a6a3abef..17e62890aadd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt
@@ -46,7 +46,14 @@ data class ListAttachState private constructor(
/**
* The [NotifPromoter] promoting this entry to top-level, if any. Always null for [GroupEntry]s.
*/
- var promoter: NotifPromoter?
+ var promoter: NotifPromoter?,
+
+ /**
+ * If the [VisualStabilityManager] is suppressing group or section changes for this entry,
+ * suppressedChanges will contain the new parent or section that we would have assigned to
+ * the entry had it not been suppressed by the VisualStabilityManager.
+ */
+ var suppressedChanges: SuppressedAttachState
) {
/** Copies the state of another instance. */
@@ -56,6 +63,7 @@ data class ListAttachState private constructor(
sectionIndex = other.sectionIndex
excludingFilter = other.excludingFilter
promoter = other.promoter
+ suppressedChanges.clone(other.suppressedChanges)
}
/** Resets back to a "clean" state (the same as created by the factory method) */
@@ -65,6 +73,7 @@ data class ListAttachState private constructor(
sectionIndex = -1
excludingFilter = null
promoter = null
+ suppressedChanges.reset()
}
companion object {
@@ -75,7 +84,8 @@ data class ListAttachState private constructor(
null,
-1,
null,
- null)
+ null,
+ SuppressedAttachState.create())
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
index 3a0520115d67..786c97d03712 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListDumper.java
@@ -167,6 +167,23 @@ public class ListDumper {
.append(" ");
}
+ if (notifEntry.getAttachState().getSuppressedChanges().getParent() != null) {
+ rksb.append("suppressedParent=")
+ .append(notifEntry.getAttachState().getSuppressedChanges()
+ .getParent().getKey())
+ .append(" ");
+ }
+
+ if (notifEntry.getAttachState().getSuppressedChanges().getSection() != null) {
+ rksb.append("suppressedSectionIndex=")
+ .append(notifEntry.getAttachState().getSuppressedChanges()
+ .getSectionIndex())
+ .append(" sectionName=")
+ .append(notifEntry.getAttachState().getSuppressedChanges()
+ .getSection().getName())
+ .append(" ");
+ }
+
if (hasBeenInteractedWith) {
rksb.append("interacted=yes ");
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.java
index 7d269177a961..05dd4df1f2ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.java
@@ -25,6 +25,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifDismissInterceptor;
@@ -161,6 +162,14 @@ public class NotifPipeline implements CommonNotifCollection {
}
/**
+ * StabilityManager that is used to determine whether to suppress group and section changes.
+ * This should only be set once.
+ */
+ public void setVisualStabilityManager(NotifStabilityManager notifStabilityManager) {
+ mShadeListBuilder.setNotifStabilityManager(notifStabilityManager);
+ }
+
+ /**
* Comparators that are used to sort top-level entries that share the same section. The
* comparators are executed in order until one of them returns a non-zero result. If all return
* zero, the pipeline falls back to sorting by rank (and, failing that, Notification.when).
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index c3ed5b9d77fc..6cbebf803511 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -21,6 +21,7 @@ import static com.android.systemui.statusbar.notification.collection.listbuilder
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_FINALIZE_FILTERING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_FINALIZING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_GROUPING;
+import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_GROUP_STABILIZING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_IDLE;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_PRE_GROUP_FILTERING;
import static com.android.systemui.statusbar.notification.collection.listbuilder.PipelineState.STATE_RESETTING;
@@ -48,6 +49,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.plugga
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
import com.android.systemui.statusbar.notification.collection.notifcollection.CollectionReadyForBuildListener;
import com.android.systemui.util.Assert;
@@ -90,6 +92,7 @@ public class ShadeListBuilder implements Dumpable {
private final List<NotifFilter> mNotifFinalizeFilters = new ArrayList<>();
private final List<NotifComparator> mNotifComparators = new ArrayList<>();
private final List<NotifSection> mNotifSections = new ArrayList<>();
+ @Nullable private NotifStabilityManager mNotifStabilityManager;
private final List<OnBeforeTransformGroupsListener> mOnBeforeTransformGroupsListeners =
new ArrayList<>();
@@ -109,7 +112,8 @@ public class ShadeListBuilder implements Dumpable {
SystemClock systemClock,
ShadeListBuilderLogger logger,
DumpManager dumpManager,
- NotificationInteractionTracker interactionTracker) {
+ NotificationInteractionTracker interactionTracker
+ ) {
Assert.isMainThread();
mSystemClock = systemClock;
mLogger = logger;
@@ -200,6 +204,22 @@ public class ShadeListBuilder implements Dumpable {
}
}
+ void setNotifStabilityManager(NotifStabilityManager notifStabilityManager) {
+ Assert.isMainThread();
+ mPipelineState.requireState(STATE_IDLE);
+
+ if (mNotifStabilityManager != null) {
+ throw new IllegalStateException(
+ "Attempting to set the NotifStabilityManager more than once. There should "
+ + "only be one visual stability manager. Manager is being set by "
+ + mNotifStabilityManager.getName() + " and "
+ + notifStabilityManager.getName());
+ }
+
+ mNotifStabilityManager = notifStabilityManager;
+ mNotifStabilityManager.setInvalidationListener(this::onReorderingAllowedInvalidated);
+ }
+
void setComparators(List<NotifComparator> comparators) {
Assert.isMainThread();
mPipelineState.requireState(STATE_IDLE);
@@ -237,6 +257,16 @@ public class ShadeListBuilder implements Dumpable {
rebuildListIfBefore(STATE_PRE_GROUP_FILTERING);
}
+ private void onReorderingAllowedInvalidated(NotifStabilityManager stabilityManager) {
+ Assert.isMainThread();
+
+ mLogger.logReorderingAllowedInvalidated(
+ stabilityManager.getName(),
+ mPipelineState.getState());
+
+ rebuildListIfBefore(STATE_GROUPING);
+ }
+
private void onPromoterInvalidated(NotifPromoter promoter) {
Assert.isMainThread();
@@ -285,6 +315,7 @@ public class ShadeListBuilder implements Dumpable {
// Step 1: Reset notification states
mPipelineState.incrementTo(STATE_RESETTING);
resetNotifs();
+ onBeginRun();
// Step 2: Filter out any notifications that shouldn't be shown right now
mPipelineState.incrementTo(STATE_PRE_GROUP_FILTERING);
@@ -303,6 +334,10 @@ public class ShadeListBuilder implements Dumpable {
promoteNotifs(mNotifList);
pruneIncompleteGroups(mNotifList);
+ // Step 4.5: Reassign/revert any groups to maintain visual stability
+ mPipelineState.incrementTo(STATE_GROUP_STABILIZING);
+ stabilizeGroupingNotifs(mNotifList);
+
// Step 5: Sort
// Assign each top-level entry a section, then sort the list by section and then within
// section by our list of custom comparators
@@ -472,6 +507,28 @@ public class ShadeListBuilder implements Dumpable {
}
}
+ private void stabilizeGroupingNotifs(List<ListEntry> list) {
+ if (mNotifStabilityManager == null) {
+ return;
+ }
+
+ for (int i = 0; i < list.size(); i++) {
+ final ListEntry tle = list.get(i);
+ if (tle.getPreviousAttachState().getParent() == null) {
+ continue; // new entries are allowed
+ }
+
+ final GroupEntry prevParent = tle.getPreviousAttachState().getParent();
+ final GroupEntry assignedParent = tle.getParent();
+ if (prevParent != assignedParent) {
+ if (!mNotifStabilityManager.isGroupChangeAllowed(tle.getRepresentativeEntry())) {
+ tle.getAttachState().getSuppressedChanges().setParent(assignedParent);
+ tle.setParent(prevParent);
+ }
+ }
+ }
+ }
+
private void promoteNotifs(List<ListEntry> list) {
for (int i = 0; i < list.size(); i++) {
final ListEntry tle = list.get(i);
@@ -650,9 +707,18 @@ public class ShadeListBuilder implements Dumpable {
mLogger.logParentChanged(mIterationCount, prev.getParent(), curr.getParent());
}
+ if (curr.getSuppressedChanges().getParent() != null) {
+ mLogger.logParentChangeSuppressed(
+ mIterationCount,
+ curr.getSuppressedChanges().getParent(),
+ curr.getParent());
+ }
+
if (curr.getExcludingFilter() != prev.getExcludingFilter()) {
mLogger.logFilterChanged(
- mIterationCount, prev.getExcludingFilter(), curr.getExcludingFilter());
+ mIterationCount,
+ prev.getExcludingFilter(),
+ curr.getExcludingFilter());
}
// When something gets detached, its promoter and section are always set to null, so
@@ -661,7 +727,9 @@ public class ShadeListBuilder implements Dumpable {
if (!wasDetached && curr.getPromoter() != prev.getPromoter()) {
mLogger.logPromoterChanged(
- mIterationCount, prev.getPromoter(), curr.getPromoter());
+ mIterationCount,
+ prev.getPromoter(),
+ curr.getPromoter());
}
if (!wasDetached && curr.getSection() != prev.getSection()) {
@@ -672,6 +740,20 @@ public class ShadeListBuilder implements Dumpable {
curr.getSection(),
curr.getSectionIndex());
}
+
+ if (curr.getSuppressedChanges().getSection() != null) {
+ mLogger.logSectionChangeSuppressed(
+ mIterationCount,
+ curr.getSuppressedChanges().getSection(),
+ curr.getSuppressedChanges().getSectionIndex(),
+ curr.getSection());
+ }
+ }
+ }
+
+ private void onBeginRun() {
+ if (mNotifStabilityManager != null) {
+ mNotifStabilityManager.onBeginRun();
}
}
@@ -681,6 +763,10 @@ public class ShadeListBuilder implements Dumpable {
callOnCleanup(mNotifFinalizeFilters);
callOnCleanup(mNotifComparators);
callOnCleanup(mNotifSections);
+
+ if (mNotifStabilityManager != null) {
+ callOnCleanup(List.of(mNotifStabilityManager));
+ }
}
private void callOnCleanup(List<? extends Pluggable<?>> pluggables) {
@@ -770,12 +856,32 @@ public class ShadeListBuilder implements Dumpable {
}
private Pair<NotifSection, Integer> applySections(ListEntry entry) {
- final Pair<NotifSection, Integer> sectionWithIndex = findSection(entry);
- final NotifSection section = sectionWithIndex.first;
- final Integer sectionIndex = sectionWithIndex.second;
+ Pair<NotifSection, Integer> sectionWithIndex = findSection(entry);
+ final ListAttachState prevAttachState = entry.getPreviousAttachState();
+
+ // are we changing sections of this entry?
+ if (mNotifStabilityManager != null
+ && prevAttachState.getParent() != null
+ && (sectionWithIndex.first != prevAttachState.getSection()
+ || sectionWithIndex.second != prevAttachState.getSectionIndex())) {
+
+ // are section changes allowed?
+ if (!mNotifStabilityManager.isSectionChangeAllowed(
+ entry.getRepresentativeEntry())) {
+ entry.getAttachState().getSuppressedChanges().setSection(
+ sectionWithIndex.first);
+ entry.getAttachState().getSuppressedChanges().setSectionIndex(
+ sectionWithIndex.second);
+
+ // keep the previous section
+ sectionWithIndex = new Pair(
+ prevAttachState.getSection(),
+ prevAttachState.getSectionIndex());
+ }
+ }
- entry.getAttachState().setSection(section);
- entry.getAttachState().setSectionIndex(sectionIndex);
+ entry.getAttachState().setSection(sectionWithIndex.first);
+ entry.getAttachState().setSectionIndex(sectionWithIndex.second);
return sectionWithIndex;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SuppressedAttachState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SuppressedAttachState.kt
new file mode 100644
index 000000000000..52612365712e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SuppressedAttachState.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection
+
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSection
+
+/**
+ * Stores the suppressed state that [ShadeListBuilder] assigned to this [ListEntry] before the
+ * VisualStabilityManager suppressed group and section changes.
+ */
+data class SuppressedAttachState private constructor(
+ /**
+ * Null if not attached to the current shade list. If top-level, then the shade list root. If
+ * part of a group, then that group's GroupEntry.
+ */
+ var parent: GroupEntry?,
+
+ /**
+ * The assigned section for this ListEntry. If the child of the group, this will be the
+ * parent's section. Null if not attached to the list.
+ */
+ var section: NotifSection?,
+ var sectionIndex: Int
+) {
+
+ /** Copies the state of another instance. */
+ fun clone(other: SuppressedAttachState) {
+ parent = other.parent
+ section = other.section
+ sectionIndex = other.sectionIndex
+ }
+
+ /** Resets back to a "clean" state (the same as created by the factory method) */
+ fun reset() {
+ parent = null
+ section = null
+ sectionIndex = -1
+ }
+
+ companion object {
+ @JvmStatic
+ fun create(): SuppressedAttachState {
+ return SuppressedAttachState(
+ null,
+ null,
+ -1)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
index f2444d5f1cb3..87ca717982f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.java
@@ -42,6 +42,7 @@ public class NotifCoordinators implements Dumpable {
private static final String TAG = "NotifCoordinators";
private final List<Coordinator> mCoordinators = new ArrayList<>();
private final List<NotifSection> mOrderedSections = new ArrayList<>();
+
/**
* Creates all the coordinators.
*/
@@ -58,7 +59,8 @@ public class NotifCoordinators implements Dumpable {
HeadsUpCoordinator headsUpCoordinator,
ConversationCoordinator conversationCoordinator,
PreparationCoordinator preparationCoordinator,
- MediaCoordinator mediaCoordinator) {
+ MediaCoordinator mediaCoordinator,
+ VisualStabilityCoordinator visualStabilityCoordinator) {
dumpManager.registerDumpable(TAG, this);
mCoordinators.add(new HideLocallyDismissedNotifsCoordinator());
@@ -70,6 +72,7 @@ public class NotifCoordinators implements Dumpable {
mCoordinators.add(bubbleCoordinator);
mCoordinators.add(mediaCoordinator);
mCoordinators.add(conversationCoordinator);
+ mCoordinators.add(visualStabilityCoordinator);
if (featureFlags.isNewNotifPipelineRenderingEnabled()) {
mCoordinators.add(headsUpCoordinator);
mCoordinators.add(preparationCoordinator);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
new file mode 100644
index 000000000000..08030f8201a2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinator.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.coordinator;
+
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
+import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
+
+import android.annotation.NonNull;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.util.concurrency.DelayableExecutor;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+/**
+ * Ensures that notifications are visually stable if the user is looking at the notifications.
+ * Group and section changes are re-allowed when the notification entries are no longer being
+ * viewed.
+ *
+ * Previously this was implemented in the view-layer {@link NotificationViewHierarchyManager} by
+ * {@link com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager}.
+ * This is now integrated in the data-layer via
+ * {@link com.android.systemui.statusbar.notification.collection.ShadeListBuilder}.
+ */
+@SysUISingleton
+public class VisualStabilityCoordinator implements Coordinator {
+ private final DelayableExecutor mDelayableExecutor;
+ private final WakefulnessLifecycle mWakefulnessLifecycle;
+ private final StatusBarStateController mStatusBarStateController;
+ private final HeadsUpManager mHeadsUpManager;
+
+ private boolean mScreenOn;
+ private boolean mPanelExpanded;
+ private boolean mPulsing;
+
+ private boolean mReorderingAllowed;
+ private boolean mIsSuppressingGroupChange = false;
+ private final Set<String> mEntriesWithSuppressedSectionChange = new HashSet<>();
+
+ // key: notification key that can temporarily change its section
+ // value: runnable that when run removes its associated RemoveOverrideSuppressionRunnable
+ // from the DelayableExecutor's queue
+ private Map<String, Runnable> mEntriesThatCanChangeSection = new HashMap<>();
+
+ @VisibleForTesting
+ protected static final long ALLOW_SECTION_CHANGE_TIMEOUT = 500;
+
+ @Inject
+ public VisualStabilityCoordinator(
+ HeadsUpManager headsUpManager,
+ WakefulnessLifecycle wakefulnessLifecycle,
+ StatusBarStateController statusBarStateController,
+ DelayableExecutor delayableExecutor
+ ) {
+ mHeadsUpManager = headsUpManager;
+ mWakefulnessLifecycle = wakefulnessLifecycle;
+ mStatusBarStateController = statusBarStateController;
+ mDelayableExecutor = delayableExecutor;
+ }
+
+ @Override
+ public void attach(NotifPipeline pipeline) {
+ mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
+ mScreenOn = mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_AWAKE
+ || mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_WAKING;
+
+ mStatusBarStateController.addCallback(mStatusBarStateControllerListener);
+ mPulsing = mStatusBarStateController.isPulsing();
+
+ pipeline.setVisualStabilityManager(mNotifStabilityManager);
+ }
+
+ private final NotifStabilityManager mNotifStabilityManager =
+ new NotifStabilityManager("VisualStabilityCoordinator") {
+ @Override
+ public void onBeginRun() {
+ mIsSuppressingGroupChange = false;
+ mEntriesWithSuppressedSectionChange.clear();
+ }
+
+ @Override
+ public boolean isGroupChangeAllowed(NotificationEntry entry) {
+ final boolean isGroupChangeAllowedForEntry =
+ mReorderingAllowed || mHeadsUpManager.isAlerting(entry.getKey());
+ mIsSuppressingGroupChange |= isGroupChangeAllowedForEntry;
+ return isGroupChangeAllowedForEntry;
+ }
+
+ @Override
+ public boolean isSectionChangeAllowed(NotificationEntry entry) {
+ final boolean isSectionChangeAllowedForEntry =
+ mReorderingAllowed
+ || mHeadsUpManager.isAlerting(entry.getKey())
+ || mEntriesThatCanChangeSection.containsKey(entry.getKey());
+ if (isSectionChangeAllowedForEntry) {
+ mEntriesWithSuppressedSectionChange.add(entry.getKey());
+ }
+ return isSectionChangeAllowedForEntry;
+ }
+ };
+
+ private void updateAllowedStates() {
+ mReorderingAllowed = isReorderingAllowed();
+ if (mReorderingAllowed && (mIsSuppressingGroupChange || isSuppressingSectionChange())) {
+ mNotifStabilityManager.invalidateList();
+ }
+ }
+
+ private boolean isSuppressingSectionChange() {
+ return !mEntriesWithSuppressedSectionChange.isEmpty();
+ }
+
+ private boolean isReorderingAllowed() {
+ return (!mScreenOn || !mPanelExpanded) && !mPulsing;
+ }
+
+ /**
+ * Allows this notification entry to be re-ordered in the notification list temporarily until
+ * the timeout has passed.
+ *
+ * Typically this is allowed because the user has directly changed something about the
+ * notification and we are reordering based on the user's change.
+ *
+ * @param entry notification entry that can change sections even if isReorderingAllowed is false
+ * @param now current time SystemClock.uptimeMillis
+ */
+ public void temporarilyAllowSectionChanges(@NonNull NotificationEntry entry, long now) {
+ final String entryKey = entry.getKey();
+ final boolean wasSectionChangeAllowed =
+ mNotifStabilityManager.isSectionChangeAllowed(entry);
+
+ // If it exists, cancel previous timeout
+ if (mEntriesThatCanChangeSection.containsKey(entryKey)) {
+ mEntriesThatCanChangeSection.get(entryKey).run();
+ }
+
+ // Schedule & store new timeout cancellable
+ mEntriesThatCanChangeSection.put(
+ entryKey,
+ mDelayableExecutor.executeAtTime(
+ () -> mEntriesThatCanChangeSection.remove(entryKey),
+ now + ALLOW_SECTION_CHANGE_TIMEOUT));
+
+ if (!wasSectionChangeAllowed) {
+ mNotifStabilityManager.invalidateList();
+ }
+ }
+
+ final StatusBarStateController.StateListener mStatusBarStateControllerListener =
+ new StatusBarStateController.StateListener() {
+ @Override
+ public void onPulsingChanged(boolean pulsing) {
+ mPulsing = pulsing;
+ updateAllowedStates();
+ }
+
+ @Override
+ public void onExpandedChanged(boolean expanded) {
+ mPanelExpanded = expanded;
+ updateAllowedStates();
+ }
+ };
+
+ final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
+ @Override
+ public void onFinishedGoingToSleep() {
+ mScreenOn = false;
+ updateAllowedStates();
+ }
+
+ @Override
+ public void onStartedWakingUp() {
+ mScreenOn = true;
+ updateAllowedStates();
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnDismissCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
index 36adf9b87674..19a356b89f18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnDismissCallbackImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.notification.collection.inflation;
import static android.service.notification.NotificationStats.DISMISS_SENTIMENT_NEUTRAL;
+import android.os.SystemClock;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationStats;
@@ -26,35 +27,43 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
-import com.android.systemui.statusbar.notification.row.OnDismissCallback;
+import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.policy.HeadsUpManager;
/**
- * Callback used when a user:
- * 1. Manually dismisses a notification {@see ExpandableNotificationRow}.
- * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}.
- * {@see StatusBarNotificationActivityStarter}
+ * Callback for when a user interacts with a {@see ExpandableNotificationRow}. Sends relevant
+ * information about the interaction to the notification pipeline.
*/
-public class OnDismissCallbackImpl implements OnDismissCallback {
+public class OnUserInteractionCallbackImpl implements OnUserInteractionCallback {
private final NotifPipeline mNotifPipeline;
private final NotifCollection mNotifCollection;
private final HeadsUpManager mHeadsUpManager;
private final StatusBarStateController mStatusBarStateController;
+ private final VisualStabilityCoordinator mVisualStabilityCoordinator;
- public OnDismissCallbackImpl(
+ public OnUserInteractionCallbackImpl(
NotifPipeline notifPipeline,
NotifCollection notifCollection,
HeadsUpManager headsUpManager,
- StatusBarStateController statusBarStateController
+ StatusBarStateController statusBarStateController,
+ VisualStabilityCoordinator visualStabilityCoordinator
) {
mNotifPipeline = notifPipeline;
mNotifCollection = notifCollection;
mHeadsUpManager = headsUpManager;
mStatusBarStateController = statusBarStateController;
+ mVisualStabilityCoordinator = visualStabilityCoordinator;
}
+ /**
+ * Callback triggered when a user:
+ * 1. Manually dismisses a notification {@see ExpandableNotificationRow}.
+ * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}.
+ * {@see StatusBarNotificationActivityStarter}
+ */
@Override
public void onDismiss(
NotificationEntry entry,
@@ -80,4 +89,11 @@ public class OnDismissCallbackImpl implements OnDismissCallback {
NotificationLogger.getNotificationLocation(entry)))
);
}
+
+ @Override
+ public void onImportanceChanged(NotificationEntry entry) {
+ mVisualStabilityCoordinator.temporarilyAllowSectionChanges(
+ entry,
+ SystemClock.uptimeMillis());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnDismissCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java
index 94ffa8f8c5ed..cce8cdc64d30 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnDismissCallbackImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/OnUserInteractionCallbackImplLegacy.java
@@ -27,30 +27,36 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
-import com.android.systemui.statusbar.notification.row.OnDismissCallback;
+import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.policy.HeadsUpManager;
/**
- * Callback used when a user:
- * 1. Manually dismisses a notification {@see ExpandableNotificationRow}.
- * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}.
- * {@see StatusBarNotificationActivityStarter}
+ * Callback for when a user interacts with a {@see ExpandableNotificationRow}.
*/
-public class OnDismissCallbackImpl implements OnDismissCallback {
+public class OnUserInteractionCallbackImplLegacy implements OnUserInteractionCallback {
private final NotificationEntryManager mNotificationEntryManager;
private final HeadsUpManager mHeadsUpManager;
private final StatusBarStateController mStatusBarStateController;
+ private final VisualStabilityManager mVisualStabilityManager;
- public OnDismissCallbackImpl(
+ public OnUserInteractionCallbackImplLegacy(
NotificationEntryManager notificationEntryManager,
HeadsUpManager headsUpManager,
- StatusBarStateController statusBarStateController
+ StatusBarStateController statusBarStateController,
+ VisualStabilityManager visualStabilityManager
) {
mNotificationEntryManager = notificationEntryManager;
mHeadsUpManager = headsUpManager;
mStatusBarStateController = statusBarStateController;
+ mVisualStabilityManager = visualStabilityManager;
}
+ /**
+ * Callback triggered when a user:
+ * 1. Manually dismisses a notification {@see ExpandableNotificationRow}.
+ * 2. Clicks on a notification with flag {@link android.app.Notification#FLAG_AUTO_CANCEL}.
+ * {@see StatusBarNotificationActivityStarter}
+ */
@Override
public void onDismiss(
NotificationEntry entry,
@@ -77,5 +83,10 @@ public class OnDismissCallbackImpl implements OnDismissCallback {
cancellationReason
);
}
+
+ @Override
+ public void onImportanceChanged(NotificationEntry entry) {
+ mVisualStabilityManager.temporarilyAllowReordering();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/VisualStabilityManager.java
index 8341c02b6b63..165df30b457d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/VisualStabilityManager.java
@@ -11,10 +11,10 @@
* 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
+ * limitations under the License.
*/
-package com.android.systemui.statusbar.notification;
+package com.android.systemui.statusbar.notification.collection.legacy;
import android.os.Handler;
import android.os.SystemClock;
@@ -24,7 +24,11 @@ import androidx.collection.ArraySet;
import com.android.systemui.Dumpable;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.statusbar.NotificationPresenter;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.NotificationEntryListener;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.VisibilityLocationProvider;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -65,24 +69,44 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpabl
*/
public VisualStabilityManager(
NotificationEntryManager notificationEntryManager,
- @Main Handler handler) {
+ @Main Handler handler,
+ StatusBarStateController statusBarStateController,
+ WakefulnessLifecycle wakefulnessLifecycle) {
mHandler = handler;
- notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
- @Override
- public void onPreEntryUpdated(NotificationEntry entry) {
- final boolean ambientStateHasChanged =
- entry.isAmbient() != entry.getRow().isLowPriority();
- if (ambientStateHasChanged) {
- // note: entries are removed in onReorderingFinished
- mLowPriorityReorderingViews.add(entry);
+ if (notificationEntryManager != null) {
+ notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
+ @Override
+ public void onPreEntryUpdated(NotificationEntry entry) {
+ final boolean ambientStateHasChanged =
+ entry.isAmbient() != entry.getRow().isLowPriority();
+ if (ambientStateHasChanged) {
+ // note: entries are removed in onReorderingFinished
+ mLowPriorityReorderingViews.add(entry);
+ }
}
- }
- });
- }
+ });
+ }
+
+ if (statusBarStateController != null) {
+ setPulsing(statusBarStateController.isPulsing());
+ statusBarStateController.addCallback(new StatusBarStateController.StateListener() {
+ @Override
+ public void onPulsingChanged(boolean pulsing) {
+ setPulsing(pulsing);
+ }
+
+ @Override
+ public void onExpandedChanged(boolean expanded) {
+ setPanelExpanded(expanded);
+ }
+ });
+ }
- public void setUpWithPresenter(NotificationPresenter presenter) {
+ if (wakefulnessLifecycle != null) {
+ wakefulnessLifecycle.addObserver(mWakefulnessObserver);
+ }
}
/**
@@ -120,25 +144,25 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpabl
}
/**
- * Set the panel to be expanded.
+ * @param screenOn whether the screen is on
*/
- public void setPanelExpanded(boolean expanded) {
- mPanelExpanded = expanded;
+ private void setScreenOn(boolean screenOn) {
+ mScreenOn = screenOn;
updateAllowedStates();
}
/**
- * @param screenOn whether the screen is on
+ * Set the panel to be expanded.
*/
- public void setScreenOn(boolean screenOn) {
- mScreenOn = screenOn;
+ private void setPanelExpanded(boolean expanded) {
+ mPanelExpanded = expanded;
updateAllowedStates();
}
/**
* @param pulsing whether we are currently pulsing for ambient display.
*/
- public void setPulsing(boolean pulsing) {
+ private void setPulsing(boolean pulsing) {
if (mPulsing == pulsing) {
return;
}
@@ -215,6 +239,10 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpabl
mVisibilityLocationProvider = visibilityLocationProvider;
}
+ /**
+ * Notifications have been reordered, so reset all the allowed list of views that are allowed
+ * to reorder.
+ */
public void onReorderingFinished() {
mAllowedReorderViews.clear();
mAddedChildren.clear();
@@ -271,11 +299,27 @@ public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpabl
pw.println();
}
+ final WakefulnessLifecycle.Observer mWakefulnessObserver = new WakefulnessLifecycle.Observer() {
+ @Override
+ public void onFinishedGoingToSleep() {
+ setScreenOn(false);
+ }
+
+ @Override
+ public void onStartedWakingUp() {
+ setScreenOn(true);
+ }
+ };
+
+
+ /**
+ * See {@link Callback#onChangeAllowed()}
+ */
public interface Callback {
+
/**
* Called when changing is allowed again.
*/
void onChangeAllowed();
}
-
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/PipelineState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/PipelineState.java
index f1f7d632b6f8..798bfe7f39d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/PipelineState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/PipelineState.java
@@ -81,9 +81,10 @@ public class PipelineState {
public static final int STATE_PRE_GROUP_FILTERING = 3;
public static final int STATE_GROUPING = 4;
public static final int STATE_TRANSFORMING = 5;
- public static final int STATE_SORTING = 6;
- public static final int STATE_FINALIZE_FILTERING = 7;
- public static final int STATE_FINALIZING = 8;
+ public static final int STATE_GROUP_STABILIZING = 6;
+ public static final int STATE_SORTING = 7;
+ public static final int STATE_FINALIZE_FILTERING = 8;
+ public static final int STATE_FINALIZING = 9;
@IntDef(prefix = { "STATE_" }, value = {
STATE_IDLE,
@@ -92,6 +93,7 @@ public class PipelineState {
STATE_PRE_GROUP_FILTERING,
STATE_GROUPING,
STATE_TRANSFORMING,
+ STATE_GROUP_STABILIZING,
STATE_SORTING,
STATE_FINALIZE_FILTERING,
STATE_FINALIZING,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
index 67f8bfeaf141..f7bfeb7234f0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
@@ -57,6 +57,15 @@ class ShadeListBuilderLogger @Inject constructor(
})
}
+ fun logReorderingAllowedInvalidated(name: String, pipelineState: Int) {
+ buffer.log(TAG, DEBUG, {
+ str1 = name
+ int1 = pipelineState
+ }, {
+ """ReorderingNowAllowed "$str1" invalidated; pipeline state is $int1"""
+ })
+ }
+
fun logPromoterInvalidated(name: String, pipelineState: Int) {
buffer.log(TAG, DEBUG, {
str1 = name
@@ -156,6 +165,21 @@ class ShadeListBuilderLogger @Inject constructor(
})
}
+ fun logParentChangeSuppressed(
+ buildId: Int,
+ suppressedParent: GroupEntry?,
+ keepingParent: GroupEntry?
+ ) {
+ buffer.log(TAG, INFO, {
+ int1 = buildId
+ str1 = suppressedParent?.key
+ str2 = keepingParent?.key
+ }, {
+ "(Build $long1) Change of parent to '$str1' suppressed; " +
+ "keeping parent '$str2'"
+ })
+ }
+
fun logFilterChanged(
buildId: Int,
prevFilter: NotifFilter?,
@@ -206,6 +230,23 @@ class ShadeListBuilderLogger @Inject constructor(
})
}
+ fun logSectionChangeSuppressed(
+ buildId: Int,
+ suppressedSection: NotifSection?,
+ suppressedSectionIndex: Int,
+ assignedSection: NotifSection?
+ ) {
+ buffer.log(TAG, INFO, {
+ long1 = buildId.toLong()
+ str1 = suppressedSection?.name
+ int1 = suppressedSectionIndex
+ str2 = assignedSection?.name
+ }, {
+ "(Build $long1) Section change suppressed: '$str1' (#$int1). " +
+ "Keeping section: '$str2'"
+ })
+ }
+
fun logFinalList(entries: List<ListEntry>) {
if (entries.isEmpty()) {
buffer.log(TAG, DEBUG, {}, { "(empty list)" })
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifStabilityManager.java
new file mode 100644
index 000000000000..58d4b97f69b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifStabilityManager.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.listbuilder.pluggable;
+
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+
+/**
+ * Pluggable for participating in notif stabilization. In particular, suppressing group and
+ * section changes.
+ *
+ * The stability manager should be invalidated when previously suppressed a group or
+ * section change is now allowed.
+ */
+public abstract class NotifStabilityManager extends Pluggable<NotifStabilityManager> {
+
+ protected NotifStabilityManager(String name) {
+ super(name);
+ }
+
+ /**
+ * Called at the beginning of every pipeline run to perform any necessary cleanup from the
+ * previous run.
+ */
+ public abstract void onBeginRun();
+
+ /**
+ * Returns whether this notification can currently change groups/parents.
+ * Per iteration of the notification pipeline, locally stores this information until the next
+ * run of the pipeline. When this method returns true, it's expected that a group change for
+ * this entry is being suppressed.
+ */
+ public abstract boolean isGroupChangeAllowed(NotificationEntry entry);
+
+ /**
+ * Returns whether this notification entry can currently change sections.
+ * Per iteration of the notification pipeline, locally stores this information until the next
+ * run of the pipeline. When this method returns true, it's expected that a section change is
+ * being suppressed.
+ */
+ public abstract boolean isSectionChangeAllowed(NotificationEntry entry);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
index 201be59d80b4..118ff4a9fbb7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
@@ -21,6 +21,7 @@ import com.android.systemui.statusbar.notification.collection.ListEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.ShadeListBuilder
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
+import com.android.systemui.statusbar.phone.NotificationIconAreaController
import java.lang.RuntimeException
import javax.inject.Inject
@@ -31,7 +32,8 @@ import javax.inject.Inject
class ShadeViewManager constructor(
listContainer: NotificationListContainer,
logger: ShadeViewDifferLogger,
- private val viewBarn: NotifViewBarn
+ private val viewBarn: NotifViewBarn,
+ private val notificationIconAreaController: NotificationIconAreaController
) {
private val rootController = RootNodeController(listContainer)
private val viewDiffer = ShadeViewDiffer(rootController, logger)
@@ -52,6 +54,7 @@ class ShadeViewManager constructor(
root.children.add(buildNotifNode(entry, root))
}
+ notificationIconAreaController.updateNotificationIcons(notifList)
return root
}
@@ -80,9 +83,10 @@ class ShadeViewManager constructor(
class ShadeViewManagerFactory @Inject constructor(
private val logger: ShadeViewDifferLogger,
- private val viewBarn: NotifViewBarn
+ private val viewBarn: NotifViewBarn,
+ private val notificationIconAreaController: NotificationIconAreaController
) {
fun create(listContainer: NotificationListContainer): ShadeViewManager {
- return ShadeViewManager(listContainer, logger, viewBarn)
+ return ShadeViewManager(listContainer, logger, viewBarn, notificationIconAreaController)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 0573156b4804..6d01324f1b7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -32,6 +32,7 @@ import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dagger.qualifiers.UiBackground;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.settings.CurrentUserContextTracker;
import com.android.systemui.statusbar.FeatureFlags;
@@ -41,14 +42,16 @@ import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.ForegroundServiceDismissalFeatureController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifInflaterImpl;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
+import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
import com.android.systemui.statusbar.notification.collection.inflation.NotifInflater;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
-import com.android.systemui.statusbar.notification.collection.inflation.OnDismissCallbackImpl;
+import com.android.systemui.statusbar.notification.collection.inflation.OnUserInteractionCallbackImpl;
+import com.android.systemui.statusbar.notification.collection.legacy.OnUserInteractionCallbackImplLegacy;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.init.NotificationsController;
@@ -62,7 +65,7 @@ import com.android.systemui.statusbar.notification.logging.NotificationPanelLogg
import com.android.systemui.statusbar.notification.row.ChannelEditorDialogController;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
-import com.android.systemui.statusbar.notification.row.OnDismissCallback;
+import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.notification.row.PriorityOnboardingDialogController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -115,7 +118,6 @@ public interface NotificationsModule {
@Provides
static NotificationGutsManager provideNotificationGutsManager(
Context context,
- VisualStabilityManager visualStabilityManager,
Lazy<StatusBar> statusBarLazy,
@Main Handler mainHandler,
@Background Handler bgHandler,
@@ -129,10 +131,10 @@ public interface NotificationsModule {
Provider<PriorityOnboardingDialogController.Builder> builderProvider,
AssistantFeedbackController assistantFeedbackController,
BubbleController bubbleController,
- UiEventLogger uiEventLogger) {
+ UiEventLogger uiEventLogger,
+ OnUserInteractionCallback onUserInteractionCallback) {
return new NotificationGutsManager(
context,
- visualStabilityManager,
statusBarLazy,
mainHandler,
bgHandler,
@@ -146,15 +148,24 @@ public interface NotificationsModule {
builderProvider,
assistantFeedbackController,
bubbleController,
- uiEventLogger);
+ uiEventLogger,
+ onUserInteractionCallback);
}
/** Provides an instance of {@link VisualStabilityManager} */
@SysUISingleton
@Provides
static VisualStabilityManager provideVisualStabilityManager(
- NotificationEntryManager notificationEntryManager, Handler handler) {
- return new VisualStabilityManager(notificationEntryManager, handler);
+ FeatureFlags featureFlags,
+ NotificationEntryManager notificationEntryManager,
+ Handler handler,
+ StatusBarStateController statusBarStateController,
+ WakefulnessLifecycle wakefulnessLifecycle) {
+ return new VisualStabilityManager(
+ notificationEntryManager,
+ handler,
+ statusBarStateController,
+ wakefulnessLifecycle);
}
/** Provides an instance of {@link NotificationLogger} */
@@ -227,20 +238,27 @@ public interface NotificationsModule {
*/
@Provides
@SysUISingleton
- static OnDismissCallback provideOnDismissCallback(
+ static OnUserInteractionCallback provideOnUserInteractionCallback(
FeatureFlags featureFlags,
HeadsUpManager headsUpManager,
StatusBarStateController statusBarStateController,
Lazy<NotifPipeline> pipeline,
Lazy<NotifCollection> notifCollection,
- NotificationEntryManager entryManager) {
+ Lazy<VisualStabilityCoordinator> visualStabilityCoordinator,
+ NotificationEntryManager entryManager,
+ VisualStabilityManager visualStabilityManager) {
return featureFlags.isNewNotifPipelineRenderingEnabled()
- ? new OnDismissCallbackImpl(
- pipeline.get(), notifCollection.get(), headsUpManager,
- statusBarStateController)
- : new com.android.systemui.statusbar.notification.collection
- .legacy.OnDismissCallbackImpl(
- entryManager, headsUpManager, statusBarStateController);
+ ? new OnUserInteractionCallbackImpl(
+ pipeline.get(),
+ notifCollection.get(),
+ headsUpManager,
+ statusBarStateController,
+ visualStabilityCoordinator.get())
+ : new OnUserInteractionCallbackImplLegacy(
+ entryManager,
+ headsUpManager,
+ statusBarStateController,
+ visualStabilityManager);
}
/** */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpController.java
index dbdb42204867..4d56e6013d71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpController.java
@@ -29,8 +29,8 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index d7fa54f0091d..9c09cba5e137 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -84,8 +84,8 @@ import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.NotificationUtils;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.logging.NotificationCounters;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
@@ -323,7 +323,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private View mGroupParentWhenDismissed;
private boolean mShelfIconVisible;
private boolean mAboveShelf;
- private OnDismissCallback mOnDismissCallback;
+ private OnUserInteractionCallback mOnUserInteractionCallback;
private boolean mIsLowPriority;
private boolean mIsColorized;
private boolean mUseIncreasedCollapsedHeight;
@@ -1445,8 +1445,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
dismiss(fromAccessibility);
if (mEntry.isClearable()) {
- if (mOnDismissCallback != null) {
- mOnDismissCallback.onDismiss(mEntry, REASON_CANCEL);
+ if (mOnUserInteractionCallback != null) {
+ mOnUserInteractionCallback.onDismiss(mEntry, REASON_CANCEL);
}
}
}
@@ -1463,10 +1463,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mIsBlockingHelperShowing && mNotificationTranslationFinished;
}
- void setOnDismissCallback(OnDismissCallback onDismissCallback) {
- mOnDismissCallback = onDismissCallback;
- }
-
@Override
public View getShelfTransformationTarget() {
if (mIsSummaryWithChildren && !shouldShowPublic()) {
@@ -1600,7 +1596,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
CoordinateOnClickListener onFeedbackClickListener,
FalsingManager falsingManager,
StatusBarStateController statusBarStateController,
- PeopleNotificationIdentifier peopleNotificationIdentifier) {
+ PeopleNotificationIdentifier peopleNotificationIdentifier,
+ OnUserInteractionCallback onUserInteractionCallback) {
mAppName = appName;
if (mMenuRow == null) {
mMenuRow = new NotificationMenuRow(mContext, peopleNotificationIdentifier);
@@ -1624,6 +1621,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
for (NotificationContentView l : mLayouts) {
l.setPeopleNotificationIdentifier(mPeopleNotificationIdentifier);
}
+ mOnUserInteractionCallback = onUserInteractionCallback;
}
private void initDimens() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index 690dce915cf3..f8bc2bebf93b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -71,7 +71,7 @@ public class ExpandableNotificationRowController implements NodeController {
this::logNotificationExpansion;
private final ExpandableNotificationRow.CoordinateOnClickListener mOnFeedbackClickListener;
private final NotificationGutsManager mNotificationGutsManager;
- private final OnDismissCallback mOnDismissCallback;
+ private final OnUserInteractionCallback mOnUserInteractionCallback;
private final FalsingManager mFalsingManager;
private final boolean mAllowLongPress;
private final PeopleNotificationIdentifier mPeopleNotificationIdentifier;
@@ -90,7 +90,7 @@ public class ExpandableNotificationRowController implements NodeController {
StatusBarStateController statusBarStateController,
NotificationGutsManager notificationGutsManager,
@Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
- OnDismissCallback onDismissCallback, FalsingManager falsingManager,
+ OnUserInteractionCallback onUserInteractionCallback, FalsingManager falsingManager,
PeopleNotificationIdentifier peopleNotificationIdentifier) {
mView = view;
mListContainer = listContainer;
@@ -108,7 +108,7 @@ public class ExpandableNotificationRowController implements NodeController {
mOnExpandClickListener = onExpandClickListener;
mStatusBarStateController = statusBarStateController;
mNotificationGutsManager = notificationGutsManager;
- mOnDismissCallback = onDismissCallback;
+ mOnUserInteractionCallback = onUserInteractionCallback;
mOnFeedbackClickListener = mNotificationGutsManager::openGuts;
mAllowLongPress = allowLongPress;
mFalsingManager = falsingManager;
@@ -133,9 +133,9 @@ public class ExpandableNotificationRowController implements NodeController {
mOnFeedbackClickListener,
mFalsingManager,
mStatusBarStateController,
- mPeopleNotificationIdentifier
+ mPeopleNotificationIdentifier,
+ mOnUserInteractionCallback
);
- mView.setOnDismissCallback(mOnDismissCallback);
mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
if (mAllowLongPress) {
mView.setLongPressListener((v, x, y, item) -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index f543db74d91a..7c7bb5c83762 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -69,7 +69,6 @@ import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.notification.NotificationChannelHelper;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
@@ -89,7 +88,7 @@ public class NotificationConversationInfo extends LinearLayout implements
private ShortcutManager mShortcutManager;
private PackageManager mPm;
private ConversationIconFactory mIconFactory;
- private VisualStabilityManager mVisualStabilityManager;
+ private OnUserInteractionCallback mOnUserInteractionCallback;
private Handler mMainHandler;
private Handler mBgHandler;
private BubbleController mBubbleController;
@@ -207,7 +206,7 @@ public class NotificationConversationInfo extends LinearLayout implements
ShortcutManager shortcutManager,
PackageManager pm,
INotificationManager iNotificationManager,
- VisualStabilityManager visualStabilityManager,
+ OnUserInteractionCallback onUserInteractionCallback,
String pkg,
NotificationChannel notificationChannel,
NotificationEntry entry,
@@ -224,7 +223,7 @@ public class NotificationConversationInfo extends LinearLayout implements
BubbleController bubbleController) {
mSelectedAction = -1;
mINotificationManager = iNotificationManager;
- mVisualStabilityManager = visualStabilityManager;
+ mOnUserInteractionCallback = onUserInteractionCallback;
mPackageName = pkg;
mEntry = entry;
mSbn = entry.getSbn();
@@ -513,7 +512,7 @@ public class NotificationConversationInfo extends LinearLayout implements
mAppUid, mSelectedAction, mNotificationChannel));
mEntry.markForUserTriggeredMovement(true);
mMainHandler.postDelayed(
- mVisualStabilityManager::temporarilyAllowReordering,
+ () -> mOnUserInteractionCallback.onImportanceChanged(mEntry),
StackStateAnimator.ANIMATION_DURATION_STANDARD);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 05d44f6eb406..60074f608969 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -60,7 +60,6 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
@@ -88,10 +87,10 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
private final Context mContext;
- private final VisualStabilityManager mVisualStabilityManager;
private final AccessibilityManager mAccessibilityManager;
private final HighPriorityProvider mHighPriorityProvider;
private final ChannelEditorDialogController mChannelEditorDialogController;
+ private final OnUserInteractionCallback mOnUserInteractionCallback;
// Dependencies:
private final NotificationLockscreenUserManager mLockscreenUserManager =
@@ -129,8 +128,10 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
/**
* Injected constructor. See {@link NotificationsModule}.
*/
- public NotificationGutsManager(Context context, VisualStabilityManager visualStabilityManager,
- Lazy<StatusBar> statusBarLazy, @Main Handler mainHandler, @Background Handler bgHandler,
+ public NotificationGutsManager(Context context,
+ Lazy<StatusBar> statusBarLazy,
+ @Main Handler mainHandler,
+ @Background Handler bgHandler,
AccessibilityManager accessibilityManager,
HighPriorityProvider highPriorityProvider,
INotificationManager notificationManager,
@@ -141,9 +142,9 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
Provider<PriorityOnboardingDialogController.Builder> builderProvider,
AssistantFeedbackController assistantFeedbackController,
BubbleController bubbleController,
- UiEventLogger uiEventLogger) {
+ UiEventLogger uiEventLogger,
+ OnUserInteractionCallback onUserInteractionCallback) {
mContext = context;
- mVisualStabilityManager = visualStabilityManager;
mStatusBarLazy = statusBarLazy;
mMainHandler = mainHandler;
mBgHandler = bgHandler;
@@ -158,6 +159,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
mAssistantFeedbackController = assistantFeedbackController;
mBubbleController = bubbleController;
mUiEventLogger = uiEventLogger;
+ mOnUserInteractionCallback = onUserInteractionCallback;
}
public void setUpWithPresenter(NotificationPresenter presenter,
@@ -363,7 +365,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
notificationInfoView.bindNotification(
pmUser,
mNotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
packageName,
row.getEntry().getChannel(),
@@ -474,7 +476,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
mShortcutManager,
pmUser,
mNotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
packageName,
entry.getChannel(),
entry,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index a6ba85fc8bdf..7a976ac82223 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -60,7 +60,6 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import java.lang.annotation.Retention;
@@ -93,9 +92,9 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
private TextView mAutomaticDescriptionView;
private INotificationManager mINotificationManager;
+ private OnUserInteractionCallback mOnUserInteractionCallback;
private PackageManager mPm;
private MetricsLogger mMetricsLogger;
- private VisualStabilityManager mVisualStabilityManager;
private ChannelEditorDialogController mChannelEditorDialogController;
private String mPackageName;
@@ -119,6 +118,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
private boolean mIsAutomaticChosen;
private boolean mIsSingleDefaultChannel;
private boolean mIsNonblockable;
+ private NotificationEntry mEntry;
private StatusBarNotification mSbn;
private boolean mIsDeviceProvisioned;
@@ -188,7 +188,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
public void bindNotification(
PackageManager pm,
INotificationManager iNotificationManager,
- VisualStabilityManager visualStabilityManager,
+ OnUserInteractionCallback onUserInteractionCallback,
ChannelEditorDialogController channelEditorDialogController,
String pkg,
NotificationChannel notificationChannel,
@@ -204,11 +204,12 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
throws RemoteException {
mINotificationManager = iNotificationManager;
mMetricsLogger = Dependency.get(MetricsLogger.class);
- mVisualStabilityManager = visualStabilityManager;
+ mOnUserInteractionCallback = onUserInteractionCallback;
mChannelEditorDialogController = channelEditorDialogController;
mPackageName = pkg;
mUniqueChannelsInRow = uniqueChannelsInRow;
mNumUniqueChannelsInRow = uniqueChannelsInRow.size();
+ mEntry = entry;
mSbn = entry.getSbn();
mPm = pm;
mAppSettingsClickListener = onAppSettingsClick;
@@ -438,7 +439,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
new UpdateImportanceRunnable(mINotificationManager, mPackageName, mAppUid,
mNumUniqueChannelsInRow == 1 ? mSingleNotificationChannel : null,
mStartingChannelImportance, newImportance, mIsAutomaticChosen));
- mVisualStabilityManager.temporarilyAllowReordering();
+ mOnUserInteractionCallback.onImportanceChanged(mEntry);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnDismissCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnUserInteractionCallback.java
index f1aed899e060..0c3f553825d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnDismissCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/OnUserInteractionCallback.java
@@ -21,15 +21,21 @@ import android.service.notification.NotificationListenerService;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
/**
- * Callback when a user clicks on an auto-cancelled notification or manually swipes to dismiss the
- * notification.
+ * Callbacks for when a user interacts with an {@link ExpandableNotificationRow}.
*/
-public interface OnDismissCallback {
+public interface OnUserInteractionCallback {
/**
- * Handle a user interaction that triggers a notification dismissal.
+ * Handle a user interaction that triggers a notification dismissal. Called when a user clicks
+ * on an auto-cancelled notification or manually swipes to dismiss the notification.
*/
void onDismiss(
NotificationEntry entry,
@NotificationListenerService.NotificationCancelReason int cancellationReason);
+
+ /**
+ * Triggered after a user has changed the importance of the notification via its
+ * {@link NotificationGuts}.
+ */
+ void onImportanceChanged(NotificationEntry entry);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 7e4266c7cd28..a396305a49b6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -22,7 +22,6 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.service.notification.StatusBarNotification;
-import android.util.ArraySet;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.NotificationHeaderView;
@@ -36,7 +35,7 @@ import com.android.systemui.R;
import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.NotificationHeaderUtil;
import com.android.systemui.statusbar.notification.NotificationUtils;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.HybridGroupManager;
import com.android.systemui.statusbar.notification.row.HybridNotificationView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index d2f8a39cc8fb..d4c270f45ceb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -125,10 +125,10 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.ShadeViewRefactor;
import com.android.systemui.statusbar.notification.ShadeViewRefactor.RefactorComponent;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
@@ -150,7 +150,6 @@ import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationGroupManager.OnGroupChangeListener;
-import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -179,8 +178,7 @@ import javax.inject.Named;
/**
* A layout which handles a dynamic amount of notifications and presents them in a scrollable stack.
*/
-public class NotificationStackScrollLayout extends ViewGroup implements ScrollAdapter,
- ConfigurationListener, Dumpable, DynamicPrivacyController.Listener {
+public class NotificationStackScrollLayout extends ViewGroup implements ScrollAdapter, Dumpable {
public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
private static final String TAG = "StackScroller";
@@ -500,7 +498,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
private int mHeadsUpInset;
private HeadsUpAppearanceController mHeadsUpAppearanceController;
- private NotificationIconAreaController mIconAreaController;
private final NotificationLockscreenUserManager mLockscreenUserManager;
private final Rect mTmpRect = new Rect();
private final FeatureFlags mFeatureFlags;
@@ -669,7 +666,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
});
}
- dynamicPrivacyController.addListener(this);
mDynamicPrivacyController = dynamicPrivacyController;
mStatusbarStateController = statusBarStateController;
initializeForegroundServiceSection(fgsFeatureController);
@@ -732,36 +728,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
return 0f;
}
- @Override
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void onDensityOrFontScaleChanged() {
- reinflateViews();
- }
-
- private void reinflateViews() {
+ void reinflateViews() {
inflateFooterView();
inflateEmptyShadeView();
updateFooter();
mSectionsManager.reinflateViews(LayoutInflater.from(mContext));
}
- @Override
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void onThemeChanged() {
- updateFooter();
- }
-
- @Override
- public void onOverlayChanged() {
- int newRadius = mContext.getResources().getDimensionPixelSize(
- Utils.getThemeAttr(mContext, android.R.attr.dialogCornerRadius));
- if (mCornerRadius != newRadius) {
- mCornerRadius = newRadius;
- invalidate();
- }
- reinflateViews();
- }
-
@VisibleForTesting
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void updateFooter() {
@@ -827,7 +800,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
super.onAttachedToWindow();
((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class))
.addCallback(mStateListener, SysuiStatusBarStateController.RANK_STACK_SCROLLER);
- Dependency.get(ConfigurationController.class).addCallback(this);
}
@Override
@@ -835,7 +807,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
- Dependency.get(ConfigurationController.class).removeCallback(this);
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -843,9 +814,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
return mSwipeHelper;
}
- @Override
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void onUiModeChanged() {
+ void updateBgColor() {
mBgColor = mContext.getColor(R.color.notification_shade_background_color);
updateBackgroundDimming();
mShelf.onUiModeChanged();
@@ -1078,6 +1047,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
R.dimen.heads_up_status_bar_padding);
}
+ void updateCornerRadius() {
+ int newRadius = getResources().getDimensionPixelSize(
+ Utils.getThemeAttr(getContext(), android.R.attr.dialogCornerRadius));
+ if (mCornerRadius != newRadius) {
+ mCornerRadius = newRadius;
+ invalidate();
+ }
+ }
+
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
private void notifyHeightChangeListener(ExpandableView view) {
notifyHeightChangeListener(view, false /* needsAnimation */);
@@ -3355,8 +3333,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
void onViewAddedInternal(ExpandableView child) {
- child.setOnHeightChangedListener(mOnChildHeightChangedListener);
updateHideSensitiveForChild(child);
+ child.setOnHeightChangedListener(mOnChildHeightChangedListener);
generateAddAnimation(child, false /* fromMoreCard */);
updateAnimationState(child);
updateChronometerForChild(child);
@@ -4854,7 +4832,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
* @param lightTheme True if light theme should be used.
*/
@ShadeViewRefactor(RefactorComponent.DECORATOR)
- private void updateDecorViews(boolean lightTheme) {
+ void updateDecorViews(boolean lightTheme) {
if (lightTheme == mUsingLightTheme) {
return;
}
@@ -5596,11 +5574,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setIconAreaController(NotificationIconAreaController controller) {
- mIconAreaController = controller;
- }
-
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@VisibleForTesting
void clearNotifications(
@SelectedRows int selection,
@@ -5790,10 +5763,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mNotificationPanelController = notificationPanelViewController;
}
- public void updateIconAreaViews() {
- mIconAreaController.updateNotificationIcons();
- }
-
/**
* Set how far the wake up is when waking up from pulsing. This is a height and will adjust the
* notification positions accordingly.
@@ -5852,17 +5821,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mDimmedNeedsAnimation = true;
}
- @Override
- public void onDynamicPrivacyChanged() {
- if (mIsExpanded) {
- // The bottom might change because we're using the final actual height of the view
- mAnimateBottomOnLayout = true;
- }
- // Let's update the footer once the notifications have been updated (in the next frame)
- post(() -> {
- updateFooter();
- updateSectionBoundaries("dynamic privacy changed");
- });
+ void setAnimateBottomOnLayout(boolean animateBottomOnLayout) {
+ mAnimateBottomOnLayout = animateBottomOnLayout;
}
public void setOnPulseHeightChangedListener(Runnable listener) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index 53d3b7586f7e..7c29ee2b5483 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.notification.stack;
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
-import static com.android.systemui.statusbar.phone.NotificationIconAreaController.HIGH_PRIORITY;
import android.graphics.PointF;
import android.provider.Settings;
@@ -27,10 +26,12 @@ import android.view.ViewGroup;
import android.view.WindowInsets;
import android.widget.FrameLayout;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.statusbar.NotificationShelfController;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
@@ -42,11 +43,12 @@ import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
-import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.NotificationPanelViewController;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.tuner.TunerService;
import java.util.function.BiConsumer;
@@ -64,22 +66,78 @@ public class NotificationStackScrollLayoutController {
private final HeadsUpManagerPhone mHeadsUpManager;
private final NotificationRoundnessManager mNotificationRoundnessManager;
private final TunerService mTunerService;
+ private final DynamicPrivacyController mDynamicPrivacyController;
+ private final ConfigurationController mConfigurationController;
private final NotificationListContainerImpl mNotificationListContainer =
new NotificationListContainerImpl();
private NotificationStackScrollLayout mView;
+ @VisibleForTesting
+ final View.OnAttachStateChangeListener mOnAttachStateChangeListener =
+ new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ mConfigurationController.addCallback(mConfigurationListener);
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ mConfigurationController.removeCallback(mConfigurationListener);
+ }
+ };
+
+ private final DynamicPrivacyController.Listener mDynamicPrivacyControllerListener = () -> {
+ if (mView.isExpanded()) {
+ // The bottom might change because we're using the final actual height of the view
+ mView.setAnimateBottomOnLayout(true);
+ }
+ // Let's update the footer once the notifications have been updated (in the next frame)
+ mView.post(() -> {
+ updateFooter();
+ updateSectionBoundaries("dynamic privacy changed");
+ });
+ };
+
+ @VisibleForTesting
+ final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
+ @Override
+ public void onDensityOrFontScaleChanged() {
+ mView.reinflateViews();
+ }
+
+ @Override
+ public void onOverlayChanged() {
+ mView.updateCornerRadius();
+ mView.reinflateViews();
+ }
+
+ @Override
+ public void onUiModeChanged() {
+ mView.updateBgColor();
+ }
+
+ @Override
+ public void onThemeChanged() {
+ updateFooter();
+ }
+ };
+
@Inject
public NotificationStackScrollLayoutController(
@Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
NotificationGutsManager notificationGutsManager,
HeadsUpManagerPhone headsUpManager,
NotificationRoundnessManager notificationRoundnessManager,
- TunerService tunerService) {
+ TunerService tunerService,
+ DynamicPrivacyController dynamicPrivacyController,
+ ConfigurationController configurationController) {
mAllowLongPress = allowLongPress;
mNotificationGutsManager = notificationGutsManager;
mHeadsUpManager = headsUpManager;
mNotificationRoundnessManager = notificationRoundnessManager;
mTunerService = tunerService;
+ mDynamicPrivacyController = dynamicPrivacyController;
+ mConfigurationController = configurationController;
}
public void attach(NotificationStackScrollLayout view) {
@@ -91,15 +149,26 @@ public class NotificationStackScrollLayoutController {
}
mHeadsUpManager.addListener(mNotificationRoundnessManager); // TODO: why is this here?
+ mDynamicPrivacyController.addListener(mDynamicPrivacyControllerListener);
mNotificationRoundnessManager.setOnRoundingChangedCallback(mView::invalidate);
mView.addOnExpandedHeightChangedListener(mNotificationRoundnessManager::setExpanded);
- mTunerService.addTunable((key, newValue) -> {
- if (key.equals(Settings.Secure.NOTIFICATION_DISMISS_RTL)) {
- mView.updateDismissRtlSetting("1".equals(newValue));
- }
- }, HIGH_PRIORITY, Settings.Secure.NOTIFICATION_DISMISS_RTL);
+ mTunerService.addTunable(
+ (key, newValue) -> {
+ if (key.equals(Settings.Secure.NOTIFICATION_DISMISS_RTL)) {
+ mView.updateDismissRtlSetting("1".equals(newValue));
+ } else if (key.equals(Settings.Secure.NOTIFICATION_HISTORY_ENABLED)) {
+ updateFooter();
+ }
+ },
+ Settings.Secure.NOTIFICATION_DISMISS_RTL,
+ Settings.Secure.NOTIFICATION_HISTORY_ENABLED);
+
+ if (mView.isAttachedToWindow()) {
+ mOnAttachStateChangeListener.onViewAttachedToWindow(mView);
+ }
+ mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
}
public void addOnExpandedHeightChangedListener(BiConsumer<Float, Float> listener) {
@@ -479,10 +548,6 @@ public class NotificationStackScrollLayoutController {
mView.updateFooter();
}
- public void updateIconAreaViews() {
- mView.updateIconAreaViews();
- }
-
public void onUpdateRowStates() {
mView.onUpdateRowStates();
}
@@ -504,10 +569,6 @@ public class NotificationStackScrollLayoutController {
mView.setNotificationPanelController(notificationPanelViewController);
}
- public void setIconAreaController(NotificationIconAreaController controller) {
- mView.setIconAreaController(controller);
- }
-
public void setStatusBar(StatusBar statusBar) {
mView.setStatusBar(statusBar);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
index 952583034ff8..efb24693beff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java
@@ -43,7 +43,6 @@ import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -83,7 +82,6 @@ public final class DozeServiceHost implements DozeHost {
private final Lazy<AssistManager> mAssistManagerLazy;
private final DozeScrimController mDozeScrimController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
- private final VisualStabilityManager mVisualStabilityManager;
private final PulseExpansionHandler mPulseExpansionHandler;
private final NotificationShadeWindowController mNotificationShadeWindowController;
private final NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
@@ -108,12 +106,12 @@ public final class DozeServiceHost implements DozeHost {
KeyguardViewMediator keyguardViewMediator,
Lazy<AssistManager> assistManagerLazy,
DozeScrimController dozeScrimController, KeyguardUpdateMonitor keyguardUpdateMonitor,
- VisualStabilityManager visualStabilityManager,
PulseExpansionHandler pulseExpansionHandler,
NotificationShadeWindowController notificationShadeWindowController,
NotificationWakeUpCoordinator notificationWakeUpCoordinator,
LockscreenLockIconController lockscreenLockIconController,
- AuthController authController) {
+ AuthController authController,
+ NotificationIconAreaController notificationIconAreaController) {
super();
mDozeLog = dozeLog;
mPowerManager = powerManager;
@@ -128,12 +126,12 @@ public final class DozeServiceHost implements DozeHost {
mAssistManagerLazy = assistManagerLazy;
mDozeScrimController = dozeScrimController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
- mVisualStabilityManager = visualStabilityManager;
mPulseExpansionHandler = pulseExpansionHandler;
mNotificationShadeWindowController = notificationShadeWindowController;
mNotificationWakeUpCoordinator = notificationWakeUpCoordinator;
mLockscreenLockIconController = lockscreenLockIconController;
mAuthController = authController;
+ mNotificationIconAreaController = notificationIconAreaController;
}
// TODO: we should try to not pass status bar in here if we can avoid it.
@@ -141,13 +139,13 @@ public final class DozeServiceHost implements DozeHost {
/**
* Initialize instance with objects only available later during execution.
*/
- public void initialize(StatusBar statusBar,
- NotificationIconAreaController notificationIconAreaController,
+ public void initialize(
+ StatusBar statusBar,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
NotificationShadeWindowViewController notificationShadeWindowViewController,
- NotificationPanelViewController notificationPanel, View ambientIndicationContainer) {
+ NotificationPanelViewController notificationPanel,
+ View ambientIndicationContainer) {
mStatusBar = statusBar;
- mNotificationIconAreaController = notificationIconAreaController;
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mNotificationPanel = notificationPanel;
mNotificationShadeWindowViewController = notificationShadeWindowViewController;
@@ -259,11 +257,10 @@ public final class DozeServiceHost implements DozeHost {
}
private void setPulsing(boolean pulsing) {
- mStatusBarStateController.setPulsing(pulsing);
mStatusBarKeyguardViewManager.setPulsing(pulsing);
mKeyguardViewMediator.setPulsing(pulsing);
mNotificationPanel.setPulsing(pulsing);
- mVisualStabilityManager.setPulsing(pulsing);
+ mStatusBarStateController.setPulsing(pulsing);
mIgnoreTouchWhilePulsing = false;
if (mKeyguardUpdateMonitor != null && passiveAuthInterrupt) {
mKeyguardUpdateMonitor.onAuthInterruptDetected(pulsing /* active */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 1d82e0808332..8092cb910b07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -31,8 +31,8 @@ import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -58,6 +58,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
private final NotificationGroupManager mGroupManager;
private final List<OnHeadsUpPhoneListenerChange> mHeadsUpPhoneListeners = new ArrayList<>();
private final int mAutoHeadsUpNotificationDecay;
+ // TODO (b/162832756): remove visual stability manager when migrating to new pipeline
private VisualStabilityManager mVisualStabilityManager;
private boolean mReleaseOnExpandFinish;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 0e413fba0ad5..bda35fb0a48e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -8,7 +8,6 @@ import android.graphics.Rect;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
@@ -21,6 +20,7 @@ import com.android.settingslib.Utils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.demomode.DemoMode;
import com.android.systemui.demomode.DemoModeController;
import com.android.systemui.plugins.DarkIconDispatcher;
@@ -34,19 +34,23 @@ import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
+import javax.inject.Inject;
+
/**
* A controller for the space in the status bar to the left of the system icons. This area is
* normally reserved for notifications.
*/
-public class NotificationIconAreaController implements DarkReceiver,
+@SysUISingleton
+public class NotificationIconAreaController implements
+ DarkReceiver,
StatusBarStateController.StateListener,
NotificationWakeUpCoordinator.WakeUpListener,
DemoMode {
@@ -62,13 +66,14 @@ public class NotificationIconAreaController implements DarkReceiver,
private final KeyguardBypassController mBypassController;
private final DozeParameters mDozeParameters;
private final BubbleController mBubbleController;
+ private final StatusBarWindowController mStatusBarWindowController;
private int mIconSize;
private int mIconHPadding;
private int mIconTint = Color.WHITE;
private int mCenteredIconTint = Color.WHITE;
- private StatusBar mStatusBar;
+ private List<ListEntry> mNotificationEntries = List.of();
protected View mNotificationIconArea;
private NotificationIconContainer mNotificationIcons;
private NotificationIconContainer mShelfIcons;
@@ -77,8 +82,8 @@ public class NotificationIconAreaController implements DarkReceiver,
private NotificationIconContainer mAodIcons;
private StatusBarIconView mCenteredIconView;
private final Rect mTintArea = new Rect();
- private ViewGroup mNotificationScrollLayout;
private Context mContext;
+
private final DemoModeController mDemoModeController;
private int mAodIconAppearTranslation;
@@ -95,16 +100,14 @@ public class NotificationIconAreaController implements DarkReceiver,
new NotificationListener.NotificationSettingsListener() {
@Override
public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) {
- mShowLowPriority = !hideSilentStatusIcons;
- if (mNotificationScrollLayout != null) {
- updateStatusBarIcons();
- }
+ mShowLowPriority = !hideSilentStatusIcons;
+ updateStatusBarIcons();
}
};
+ @Inject
public NotificationIconAreaController(
Context context,
- StatusBar statusBar,
StatusBarStateController statusBarStateController,
NotificationWakeUpCoordinator wakeUpCoordinator,
KeyguardBypassController keyguardBypassController,
@@ -112,8 +115,9 @@ public class NotificationIconAreaController implements DarkReceiver,
NotificationListener notificationListener,
DozeParameters dozeParameters,
BubbleController bubbleController,
- DemoModeController demoModeController) {
- mStatusBar = statusBar;
+ DemoModeController demoModeController,
+ DarkIconDispatcher darkIconDispatcher,
+ StatusBarWindowController statusBarWindowController) {
mContrastColorUtil = ContrastColorUtil.getInstance(context);
mContext = context;
mStatusBarStateController = statusBarStateController;
@@ -124,12 +128,14 @@ public class NotificationIconAreaController implements DarkReceiver,
wakeUpCoordinator.addListener(this);
mBypassController = keyguardBypassController;
mBubbleController = bubbleController;
- notificationListener.addNotificationSettingsListener(mSettingsListener);
mDemoModeController = demoModeController;
mDemoModeController.addCallback(this);
+ mStatusBarWindowController = statusBarWindowController;
+ notificationListener.addNotificationSettingsListener(mSettingsListener);
initializeNotificationAreaViews(context);
reloadAodColor();
+ darkIconDispatcher.addDarkReceiver(this);
}
protected View inflateIconArea(LayoutInflater inflater) {
@@ -146,22 +152,21 @@ public class NotificationIconAreaController implements DarkReceiver,
mNotificationIconArea = inflateIconArea(layoutInflater);
mNotificationIcons = mNotificationIconArea.findViewById(R.id.notificationIcons);
- mNotificationScrollLayout = mStatusBar.getNotificationScrollLayout();
-
mCenteredIconArea = layoutInflater.inflate(R.layout.center_icon_area, null);
mCenteredIcon = mCenteredIconArea.findViewById(R.id.centeredIcon);
-
- initAodIcons();
}
- public void initAodIcons() {
+ /**
+ * Called by the StatusBar. The StatusBar passes the NotificationIconContainer which holds
+ * the aod icons.
+ */
+ void setupAodIcons(@NonNull NotificationIconContainer aodIcons) {
boolean changed = mAodIcons != null;
if (changed) {
mAodIcons.setAnimationsEnabled(false);
mAodIcons.removeAllViews();
}
- mAodIcons = mStatusBar.getNotificationShadeWindowView().findViewById(
- R.id.clock_notification_icon_container);
+ mAodIcons = aodIcons;
mAodIcons.setOnLockScreen(true);
updateAodIconsVisibility(false /* animate */);
updateAnimations();
@@ -199,7 +204,7 @@ public class NotificationIconAreaController implements DarkReceiver,
@NonNull
private FrameLayout.LayoutParams generateIconLayoutParams() {
return new FrameLayout.LayoutParams(
- mIconSize + 2 * mIconHPadding, getHeight());
+ mIconSize + 2 * mIconHPadding, mStatusBarWindowController.getStatusBarHeight());
}
private void reloadDimens(Context context) {
@@ -238,29 +243,17 @@ public class NotificationIconAreaController implements DarkReceiver,
mTintArea.set(tintArea);
}
- if (mNotificationIconArea != null) {
- if (DarkIconDispatcher.isInArea(tintArea, mNotificationIconArea)) {
- mIconTint = iconTint;
- }
- } else {
+ if (DarkIconDispatcher.isInArea(tintArea, mNotificationIconArea)) {
mIconTint = iconTint;
}
- if (mCenteredIconArea != null) {
- if (DarkIconDispatcher.isInArea(tintArea, mCenteredIconArea)) {
- mCenteredIconTint = iconTint;
- }
- } else {
+ if (DarkIconDispatcher.isInArea(tintArea, mCenteredIconArea)) {
mCenteredIconTint = iconTint;
}
applyNotificationIconsTint();
}
- protected int getHeight() {
- return mStatusBar.getStatusBarHeight();
- }
-
protected boolean shouldShowNotificationIcon(NotificationEntry entry,
boolean showAmbient, boolean showLowPriority, boolean hideDismissed,
boolean hideRepliedMessages, boolean hideCurrentMedia, boolean hideCenteredIcon,
@@ -310,11 +303,15 @@ public class NotificationIconAreaController implements DarkReceiver,
}
return true;
}
-
/**
* Updates the notifications with the given list of notifications to display.
*/
- public void updateNotificationIcons() {
+ public void updateNotificationIcons(List<ListEntry> entries) {
+ mNotificationEntries = entries;
+ updateNotificationIcons();
+ }
+
+ private void updateNotificationIcons() {
updateStatusBarIcons();
updateShelfIcons();
updateCenterIcon();
@@ -391,18 +388,15 @@ public class NotificationIconAreaController implements DarkReceiver,
NotificationIconContainer hostLayout, boolean showAmbient, boolean showLowPriority,
boolean hideDismissed, boolean hideRepliedMessages, boolean hideCurrentMedia,
boolean hideCenteredIcon, boolean hidePulsing, boolean onlyShowCenteredIcon) {
- ArrayList<StatusBarIconView> toShow = new ArrayList<>(
- mNotificationScrollLayout.getChildCount());
-
+ ArrayList<StatusBarIconView> toShow = new ArrayList<>(mNotificationEntries.size());
// Filter out ambient notifications and notification children.
- for (int i = 0; i < mNotificationScrollLayout.getChildCount(); i++) {
- View view = mNotificationScrollLayout.getChildAt(i);
- if (view instanceof ExpandableNotificationRow) {
- NotificationEntry ent = ((ExpandableNotificationRow) view).getEntry();
- if (shouldShowNotificationIcon(ent, showAmbient, showLowPriority, hideDismissed,
+ for (int i = 0; i < mNotificationEntries.size(); i++) {
+ NotificationEntry entry = mNotificationEntries.get(i).getRepresentativeEntry();
+ if (entry != null && entry.getRow() != null) {
+ if (shouldShowNotificationIcon(entry, showAmbient, showLowPriority, hideDismissed,
hideRepliedMessages, hideCurrentMedia, hideCenteredIcon, hidePulsing,
onlyShowCenteredIcon)) {
- StatusBarIconView iconView = function.apply(ent);
+ StatusBarIconView iconView = function.apply(entry);
if (iconView != null) {
toShow.add(iconView);
}
@@ -607,13 +601,16 @@ public class NotificationIconAreaController implements DarkReceiver,
mAodIconTint = Utils.getColorAttrDefaultColor(mContext,
R.attr.wallpaperTextColor);
}
+
private void updateAodIconColors() {
- for (int i = 0; i < mAodIcons.getChildCount(); i++) {
- final StatusBarIconView iv = (StatusBarIconView) mAodIcons.getChildAt(i);
- if (iv.getWidth() != 0) {
- updateTintForIcon(iv, mAodIconTint);
- } else {
- iv.executeOnLayout(() -> updateTintForIcon(iv, mAodIconTint));
+ if (mAodIcons != null) {
+ for (int i = 0; i < mAodIcons.getChildCount(); i++) {
+ final StatusBarIconView iv = (StatusBarIconView) mAodIcons.getChildAt(i);
+ if (iv.getWidth() != 0) {
+ updateTintForIcon(iv, mAodIconTint);
+ } else {
+ iv.executeOnLayout(() -> updateTintForIcon(iv, mAodIconTint));
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 42fbe5967d42..5974a53fc86d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -100,6 +100,7 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.PropertyAnimator;
import com.android.systemui.statusbar.notification.ViewGroupFadeHelper;
+import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -177,6 +178,7 @@ public class NotificationPanelViewController extends PanelViewController {
private final ConfigurationController mConfigurationController;
private final FlingAnimationUtils.Builder mFlingAnimationUtilsBuilder;
private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
+ private final NotificationIconAreaController mNotificationIconAreaController;
// Cap and total height of Roboto font. Needs to be adjusted when font for the big clock is
// changed.
@@ -502,7 +504,8 @@ public class NotificationPanelViewController extends PanelViewController {
BiometricUnlockController biometricUnlockController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
Provider<KeyguardClockSwitchController> keyguardClockSwitchControllerProvider,
- NotificationStackScrollLayoutController notificationStackScrollLayoutController) {
+ NotificationStackScrollLayoutController notificationStackScrollLayoutController,
+ NotificationIconAreaController notificationIconAreaController) {
super(view, falsingManager, dozeLog, keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
latencyTracker, flingAnimationUtilsBuilder, statusBarTouchableRegionManager);
@@ -516,6 +519,7 @@ public class NotificationPanelViewController extends PanelViewController {
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardClockSwitchControllerProvider = keyguardClockSwitchControllerProvider;
mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
+ mNotificationIconAreaController = notificationIconAreaController;
mView.setWillNotDraw(!DEBUG);
mInjectionInflationController = injectionInflationController;
mFalsingManager = falsingManager;
@@ -3066,7 +3070,19 @@ public class NotificationPanelViewController extends PanelViewController {
mNotificationStackScrollLayoutController.updateSpeedBumpIndex();
mNotificationStackScrollLayoutController.updateFooter();
updateShowEmptyShadeView();
- mNotificationStackScrollLayoutController.updateIconAreaViews();
+ mNotificationIconAreaController.updateNotificationIcons(createVisibleEntriesList());
+ }
+
+ private List<ListEntry> createVisibleEntriesList() {
+ List<ListEntry> entries = new ArrayList<>(
+ mNotificationStackScrollLayoutController.getChildCount());
+ for (int i = 0; i < mNotificationStackScrollLayoutController.getChildCount(); i++) {
+ View view = mNotificationStackScrollLayoutController.getChildAt(i);
+ if (view instanceof ExpandableNotificationRow) {
+ entries.add(((ExpandableNotificationRow) view).getEntry());
+ }
+ }
+ return entries;
}
public void onUpdateRowStates() {
@@ -3094,15 +3110,17 @@ public class NotificationPanelViewController extends PanelViewController {
mNotificationStackScrollLayoutController.setScrollingEnabled(b);
}
- public void initDependencies(StatusBar statusBar, NotificationGroupManager groupManager,
+ /**
+ * Initialize objects instead of injecting to avoid circular dependencies.
+ */
+ public void initDependencies(
+ StatusBar statusBar,
+ NotificationGroupManager groupManager,
NotificationShelfController notificationShelfController,
- NotificationIconAreaController notificationIconAreaController,
ScrimController scrimController) {
setStatusBar(statusBar);
setGroupManager(mGroupManager);
mNotificationStackScrollLayoutController.setNotificationPanelController(this);
- mNotificationStackScrollLayoutController
- .setIconAreaController(notificationIconAreaController);
mNotificationStackScrollLayoutController.setStatusBar(statusBar);
mNotificationStackScrollLayoutController.setGroupManager(groupManager);
mNotificationStackScrollLayoutController.setShelfController(notificationShelfController);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 5b251befb028..6e37f90f9d94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -144,7 +144,6 @@ import com.android.systemui.InitController;
import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
-import com.android.systemui.SystemUIFactory;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.bubbles.BubbleController;
@@ -204,8 +203,8 @@ import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
@@ -396,7 +395,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
private final LightsOutNotifController mLightsOutNotifController;
private final InitController mInitController;
- private final DarkIconDispatcher mDarkIconDispatcher;
+
private final PluginDependencyProvider mPluginDependencyProvider;
private final KeyguardDismissUtil mKeyguardDismissUtil;
private final ExtensionController mExtensionController;
@@ -609,7 +608,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private UiModeManager mUiModeManager;
protected boolean mIsKeyguard;
private LogMaker mStatusBarStateLog;
- protected NotificationIconAreaController mNotificationIconAreaController;
+ protected final NotificationIconAreaController mNotificationIconAreaController;
@Nullable private View mAmbientIndicationContainer;
private final SysuiColorExtractor mColorExtractor;
private final ScreenLifecycle mScreenLifecycle;
@@ -731,7 +730,6 @@ public class StatusBar extends SystemUI implements DemoMode,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
ViewMediatorCallback viewMediatorCallback,
InitController initController,
- DarkIconDispatcher darkIconDispatcher,
@Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
PluginDependencyProvider pluginDependencyProvider,
KeyguardDismissUtil keyguardDismissUtil,
@@ -742,7 +740,8 @@ public class StatusBar extends SystemUI implements DemoMode,
DismissCallbackRegistry dismissCallbackRegistry,
DemoModeController demoModeController,
Lazy<NotificationShadeDepthController> notificationShadeDepthControllerLazy,
- StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
+ StatusBarTouchableRegionManager statusBarTouchableRegionManager,
+ NotificationIconAreaController notificationIconAreaController) {
super(context);
mNotificationsController = notificationsController;
mLightBarController = lightBarController;
@@ -812,7 +811,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mKeyguardViewMediatorCallback = viewMediatorCallback;
mInitController = initController;
- mDarkIconDispatcher = darkIconDispatcher;
mPluginDependencyProvider = pluginDependencyProvider;
mKeyguardDismissUtil = keyguardDismissUtil;
mExtensionController = extensionController;
@@ -820,6 +818,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mIconPolicy = phoneStatusBarPolicy;
mDismissCallbackRegistry = dismissCallbackRegistry;
mDemoModeController = demoModeController;
+ mNotificationIconAreaController = notificationIconAreaController;
mBubbleExpandListener =
(isExpanding, key) -> {
@@ -953,9 +952,12 @@ public class StatusBar extends SystemUI implements DemoMode,
startKeyguard();
mKeyguardUpdateMonitor.registerCallback(mUpdateCallback);
- mDozeServiceHost.initialize(this, mNotificationIconAreaController,
- mStatusBarKeyguardViewManager, mNotificationShadeWindowViewController,
- mNotificationPanelViewController, mAmbientIndicationContainer);
+ mDozeServiceHost.initialize(
+ this,
+ mStatusBarKeyguardViewManager,
+ mNotificationShadeWindowViewController,
+ mNotificationPanelViewController,
+ mAmbientIndicationContainer);
mConfigurationController.addCallback(this);
@@ -1037,20 +1039,12 @@ public class StatusBar extends SystemUI implements DemoMode,
mStackScrollerController.getNotificationListContainer();
mNotificationLogger.setUpWithContainer(notifListContainer);
- // TODO: make this injectable. Currently that would create a circular dependency between
- // NotificationIconAreaController and StatusBar.
- mNotificationIconAreaController = SystemUIFactory.getInstance()
- .createNotificationIconAreaController(context, this,
- mWakeUpCoordinator, mKeyguardBypassController,
- mStatusBarStateController, mDemoModeController);
- mWakeUpCoordinator.setIconAreaController(mNotificationIconAreaController);
+ updateAodIconArea();
inflateShelf();
mNotificationIconAreaController.setupShelf(mNotificationShelfController);
- mNotificationPanelViewController.setOnReinflationListener(
- mNotificationIconAreaController::initAodIcons);
+ mNotificationPanelViewController.setOnReinflationListener(this::updateAodIconArea);
mNotificationPanelViewController.addExpansionListener(mWakeUpCoordinator);
- mDarkIconDispatcher.addDarkReceiver(mNotificationIconAreaController);
// Allow plugins to reference DarkIconDispatcher and StatusBarStateController
mPluginDependencyProvider.allowPluginDependency(DarkIconDispatcher.class);
mPluginDependencyProvider.allowPluginDependency(StatusBarStateController.class);
@@ -1163,9 +1157,11 @@ public class StatusBar extends SystemUI implements DemoMode,
});
mScrimController.attachViews(scrimBehind, scrimInFront, scrimForBubble);
- mNotificationPanelViewController.initDependencies(this, mGroupManager,
+ mNotificationPanelViewController.initDependencies(
+ this,
+ mGroupManager,
mNotificationShelfController,
- mNotificationIconAreaController, mScrimController);
+ mScrimController);
BackDropView backdrop = mNotificationShadeWindowView.findViewById(R.id.backdrop);
mMediaManager.setup(backdrop, backdrop.findViewById(R.id.backdrop_front),
@@ -1279,6 +1275,12 @@ public class StatusBar extends SystemUI implements DemoMode,
ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
}
+ private void updateAodIconArea() {
+ mNotificationIconAreaController.setupAodIcons(
+ getNotificationShadeWindowView()
+ .findViewById(R.id.clock_notification_icon_container));
+ }
+
@NonNull
@Override
public Lifecycle getLifecycle() {
@@ -1847,7 +1849,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mPanelExpanded = isExpanded;
updateHideIconsForBouncer(false /* animate */);
mNotificationShadeWindowController.setPanelExpanded(isExpanded);
- mVisualStabilityManager.setPanelExpanded(isExpanded);
+ mStatusBarStateController.setPanelExpanded(isExpanded);
if (isExpanded && mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
if (DEBUG) {
Log.v(TAG, "clearing notification effects from setExpandedHeight");
@@ -2068,7 +2070,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
}
mNotificationPanelViewController.expand(true /* animate */);
- ((NotificationListContainer) mStackScroller).setWillExpand(true);
+ mStackScroller.setWillExpand(true);
mHeadsUpManager.unpinAll(true /* userUnpinned */);
mMetricsLogger.count(NotificationPanelView.COUNTER_PANEL_OPEN, 1);
} else if (!mNotificationPanelViewController.isInSettings()
@@ -3785,7 +3787,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mDeviceInteractive = false;
mWakeUpComingFromTouch = false;
mWakeUpTouchLocation = null;
- mVisualStabilityManager.setScreenOn(false);
updateVisibleToUser();
updateNotificationPanelTouchState();
@@ -3822,7 +3823,6 @@ public class StatusBar extends SystemUI implements DemoMode,
if (!mKeyguardBypassController.getBypassEnabled()) {
mHeadsUpManager.releaseAllImmediately();
}
- mVisualStabilityManager.setScreenOn(true);
updateVisibleToUser();
updateIsKeyguard();
mDozeServiceHost.stopDozing();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index f1e2f774a954..de11c9023200 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -73,7 +73,7 @@ import com.android.systemui.statusbar.notification.collection.notifcollection.No
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.OnDismissCallback;
+import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.policy.HeadsUpUtil;
import com.android.systemui.statusbar.policy.KeyguardStateController;
@@ -124,7 +124,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private final NotificationPresenter mPresenter;
private final NotificationPanelViewController mNotificationPanel;
private final ActivityLaunchAnimator mActivityLaunchAnimator;
- private final OnDismissCallback mOnDismissCallback;
+ private final OnUserInteractionCallback mOnUserInteractionCallback;
private boolean mIsCollapsingToShowActivityOverLockscreen;
@@ -158,7 +158,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
FeatureFlags featureFlags,
MetricsLogger metricsLogger,
StatusBarNotificationActivityStarterLogger logger,
- OnDismissCallback onDismissCallback,
+ OnUserInteractionCallback onUserInteractionCallback,
StatusBar statusBar,
NotificationPresenter presenter,
@@ -193,7 +193,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mFeatureFlags = featureFlags;
mMetricsLogger = metricsLogger;
mLogger = logger;
- mOnDismissCallback = onDismissCallback;
+ mOnUserInteractionCallback = onUserInteractionCallback;
// TODO: use KeyguardStateController#isOccluded to remove this dependency
mStatusBar = statusBar;
@@ -575,10 +575,10 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
// To avoid lags we're only performing the remove
// after the shade was collapsed
mShadeController.addPostCollapseAction(
- () -> mOnDismissCallback.onDismiss(entry, REASON_CLICK)
+ () -> mOnUserInteractionCallback.onDismiss(entry, REASON_CLICK)
);
} else {
- mOnDismissCallback.onDismiss(entry, REASON_CLICK);
+ mOnUserInteractionCallback.onDismiss(entry, REASON_CLICK);
}
});
}
@@ -628,7 +628,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
private final FeatureFlags mFeatureFlags;
private final MetricsLogger mMetricsLogger;
private final StatusBarNotificationActivityStarterLogger mLogger;
- private final OnDismissCallback mOnDismissCallback;
+ private final OnUserInteractionCallback mOnUserInteractionCallback;
private StatusBar mStatusBar;
private NotificationPresenter mNotificationPresenter;
@@ -666,7 +666,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
FeatureFlags featureFlags,
MetricsLogger metricsLogger,
StatusBarNotificationActivityStarterLogger logger,
- OnDismissCallback onDismissCallback) {
+ OnUserInteractionCallback onUserInteractionCallback) {
mContext = context;
mCommandQueue = commandQueue;
@@ -697,7 +697,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mFeatureFlags = featureFlags;
mMetricsLogger = metricsLogger;
mLogger = logger;
- mOnDismissCallback = onDismissCallback;
+ mOnUserInteractionCallback = onUserInteractionCallback;
}
/** Sets the status bar to use as {@link StatusBar}. */
@@ -754,7 +754,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
mFeatureFlags,
mMetricsLogger,
mLogger,
- mOnDismissCallback,
+ mOnUserInteractionCallback,
mStatusBar,
mNotificationPresenter,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 0ec22b4a415f..67adaaae402e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -61,9 +61,9 @@ import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
@@ -217,7 +217,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor);
mLockscreenUserManager.setUpWithPresenter(this);
mMediaManager.setUpWithPresenter(this);
- mVisualStabilityManager.setUpWithPresenter(this);
mGutsManager.setUpWithPresenter(this,
stackScrollerController.getNotificationListContainer(), mCheckSaveListener,
mOnSettingsClickListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index bdf63c791d28..2768b826fcfe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -41,7 +41,6 @@ import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.navigationbar.NavigationBarController;
-import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.PluginDependencyProvider;
import com.android.systemui.recents.Recents;
@@ -62,7 +61,7 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
@@ -82,6 +81,7 @@ import com.android.systemui.statusbar.phone.LightsOutNotifController;
import com.android.systemui.statusbar.phone.LockscreenLockIconController;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -189,7 +189,6 @@ public interface StatusBarPhoneModule {
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
ViewMediatorCallback viewMediatorCallback,
InitController initController,
- DarkIconDispatcher darkIconDispatcher,
@Named(TIME_TICK_HANDLER_NAME) Handler timeTickHandler,
PluginDependencyProvider pluginDependencyProvider,
KeyguardDismissUtil keyguardDismissUtil,
@@ -200,7 +199,8 @@ public interface StatusBarPhoneModule {
DemoModeController demoModeController,
Lazy<NotificationShadeDepthController> notificationShadeDepthController,
DismissCallbackRegistry dismissCallbackRegistry,
- StatusBarTouchableRegionManager statusBarTouchableRegionManager) {
+ StatusBarTouchableRegionManager statusBarTouchableRegionManager,
+ NotificationIconAreaController notificationIconAreaController) {
return new StatusBar(
context,
notificationsController,
@@ -268,7 +268,6 @@ public interface StatusBarPhoneModule {
statusBarKeyguardViewManager,
viewMediatorCallback,
initController,
- darkIconDispatcher,
timeTickHandler,
pluginDependencyProvider,
keyguardDismissUtil,
@@ -279,6 +278,7 @@ public interface StatusBarPhoneModule {
dismissCallbackRegistry,
demoModeController,
notificationShadeDepthController,
- statusBarTouchableRegionManager);
+ statusBarTouchableRegionManager,
+ notificationIconAreaController);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
index e10225cedc7e..ca9cb08c0a59 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
@@ -63,7 +63,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.wmshell.WindowManagerShellModule;
+import com.android.systemui.wmshell.WMShellModule;
import javax.inject.Named;
@@ -78,7 +78,7 @@ import dagger.Provides;
@Module(includes = {
DividerModule.class,
QSModule.class,
- WindowManagerShellModule.class
+ WMShellModule.class
},
subcomponents = {
})
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
new file mode 100644
index 000000000000..ac47660f3221
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.wmshell;
+
+import android.content.Context;
+import android.os.Handler;
+import android.view.IWindowManager;
+
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Main;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.common.SystemWindows;
+import com.android.wm.shell.common.TransactionPool;
+
+import dagger.Module;
+import dagger.Provides;
+
+/**
+ * Provides basic dependencies from {@link com.android.wm.shell}, the dependencies declared here
+ * should be shared among different branches of SystemUI.
+ */
+// TODO(b/162923491): Move most of these dependencies into WMSingleton scope.
+@Module
+public class WMShellBaseModule {
+ @SysUISingleton
+ @Provides
+ static TransactionPool provideTransactionPool() {
+ return new TransactionPool();
+ }
+
+ @SysUISingleton
+ @Provides
+ static DisplayController provideDisplayController(Context context, @Main Handler handler,
+ IWindowManager wmService) {
+ return new DisplayController(context, handler, wmService);
+ }
+
+ @SysUISingleton
+ @Provides
+ static SystemWindows provideSystemWindows(DisplayController displayController,
+ IWindowManager wmService) {
+ return new SystemWindows(displayController, wmService);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
index 821150ee7ea6..44bb6ac5a49c 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/WindowManagerShellModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellModule.java
@@ -16,7 +16,6 @@
package com.android.systemui.wmshell;
-import android.content.Context;
import android.os.Handler;
import android.view.IWindowManager;
@@ -26,38 +25,18 @@ import com.android.systemui.pip.phone.PipMenuActivity;
import com.android.systemui.pip.phone.dagger.PipMenuActivityClass;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayImeController;
-import com.android.wm.shell.common.SystemWindows;
import com.android.wm.shell.common.TransactionPool;
import dagger.Module;
import dagger.Provides;
/**
- * Provides dependencies from {@link com.android.wm.shell}.
+ * Provides dependencies from {@link com.android.wm.shell} which could be customized among different
+ * branches of SystemUI.
*/
-@Module
-// TODO(b/161116823) Clean up dependencies after wm shell migration finished.
-public class WindowManagerShellModule {
- @SysUISingleton
- @Provides
- static TransactionPool provideTransactionPool() {
- return new TransactionPool();
- }
-
- @SysUISingleton
- @Provides
- static DisplayController provideDisplayController(Context context, @Main Handler handler,
- IWindowManager wmService) {
- return new DisplayController(context, handler, wmService);
- }
-
- @SysUISingleton
- @Provides
- static SystemWindows provideSystemWindows(DisplayController displayController,
- IWindowManager wmService) {
- return new SystemWindows(displayController, wmService);
- }
-
+// TODO(b/162923491): Move most of these dependencies into WMSingleton scope.
+@Module(includes = WMShellBaseModule.class)
+public class WMShellModule {
@SysUISingleton
@Provides
static DisplayImeController provideDisplayImeController(IWindowManager wmService,
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index a0e5f73b6a4c..11920233e403 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -182,7 +182,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
// IBiometricsFace@1.0 does not support detection, only authentication.
when(mFaceSensorProperties.isEmpty()).thenReturn(false);
when(mFaceSensorProperties.get(anyInt())).thenReturn(new FaceSensorProperties(0 /* id */,
- false /* supportsFaceDetection */));
+ false /* supportsFaceDetection */, true /* supportsSelfIllumination */));
when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
when(mFingerprintManager.hasEnrolledTemplates(anyInt())).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
index 118cffc2d5b8..ca8f79d08ef0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
@@ -44,11 +44,11 @@ public class MediaPlayerDataTest : SysuiTestCase() {
fun addPlayingThenRemote() {
val playerIsPlaying = mock(MediaControlPanel::class.java)
whenever(playerIsPlaying.isPlaying).thenReturn(true)
- val dataIsPlaying = createMediaData(LOCAL, !RESUMPTION)
+ val dataIsPlaying = createMediaData("app1", LOCAL, !RESUMPTION)
val playerIsRemote = mock(MediaControlPanel::class.java)
whenever(playerIsRemote.isPlaying).thenReturn(false)
- val dataIsRemote = createMediaData(!LOCAL, !RESUMPTION)
+ val dataIsRemote = createMediaData("app2", !LOCAL, !RESUMPTION)
MediaPlayerData.addMediaPlayer("1", dataIsPlaying, playerIsPlaying)
MediaPlayerData.addMediaPlayer("2", dataIsRemote, playerIsRemote)
@@ -62,11 +62,11 @@ public class MediaPlayerDataTest : SysuiTestCase() {
fun switchPlayersPlaying() {
val playerIsPlaying1 = mock(MediaControlPanel::class.java)
whenever(playerIsPlaying1.isPlaying).thenReturn(true)
- val dataIsPlaying1 = createMediaData(LOCAL, !RESUMPTION)
+ val dataIsPlaying1 = createMediaData("app1", LOCAL, !RESUMPTION)
val playerIsPlaying2 = mock(MediaControlPanel::class.java)
whenever(playerIsPlaying2.isPlaying).thenReturn(false)
- val dataIsPlaying2 = createMediaData(LOCAL, !RESUMPTION)
+ val dataIsPlaying2 = createMediaData("app2", LOCAL, !RESUMPTION)
MediaPlayerData.addMediaPlayer("1", dataIsPlaying1, playerIsPlaying1)
MediaPlayerData.addMediaPlayer("2", dataIsPlaying2, playerIsPlaying2)
@@ -86,23 +86,23 @@ public class MediaPlayerDataTest : SysuiTestCase() {
fun fullOrderTest() {
val playerIsPlaying = mock(MediaControlPanel::class.java)
whenever(playerIsPlaying.isPlaying).thenReturn(true)
- val dataIsPlaying = createMediaData(LOCAL, !RESUMPTION)
+ val dataIsPlaying = createMediaData("app1", LOCAL, !RESUMPTION)
val playerIsPlayingAndRemote = mock(MediaControlPanel::class.java)
whenever(playerIsPlayingAndRemote.isPlaying).thenReturn(true)
- val dataIsPlayingAndRemote = createMediaData(!LOCAL, !RESUMPTION)
+ val dataIsPlayingAndRemote = createMediaData("app2", !LOCAL, !RESUMPTION)
val playerIsStoppedAndLocal = mock(MediaControlPanel::class.java)
whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false)
- val dataIsStoppedAndLocal = createMediaData(LOCAL, !RESUMPTION)
+ val dataIsStoppedAndLocal = createMediaData("app3", LOCAL, !RESUMPTION)
val playerIsStoppedAndRemote = mock(MediaControlPanel::class.java)
whenever(playerIsStoppedAndLocal.isPlaying).thenReturn(false)
- val dataIsStoppedAndRemote = createMediaData(!LOCAL, !RESUMPTION)
+ val dataIsStoppedAndRemote = createMediaData("app4", !LOCAL, !RESUMPTION)
val playerCanResume = mock(MediaControlPanel::class.java)
whenever(playerCanResume.isPlaying).thenReturn(false)
- val dataCanResume = createMediaData(LOCAL, RESUMPTION)
+ val dataCanResume = createMediaData("app5", LOCAL, RESUMPTION)
MediaPlayerData.addMediaPlayer("3", dataIsStoppedAndLocal, playerIsStoppedAndLocal)
MediaPlayerData.addMediaPlayer("5", dataIsStoppedAndRemote, playerIsStoppedAndRemote)
@@ -116,7 +116,7 @@ public class MediaPlayerDataTest : SysuiTestCase() {
playerIsStoppedAndLocal, playerCanResume, playerIsStoppedAndRemote).inOrder()
}
- private fun createMediaData(isLocalSession: Boolean, resumption: Boolean) =
- MediaData(0, false, 0, null, null, null, null, null, emptyList(), emptyList<Int>(), "",
+ private fun createMediaData(app: String, isLocalSession: Boolean, resumption: Boolean) =
+ MediaData(0, false, 0, app, null, null, null, null, emptyList(), emptyList<Int>(), "",
null, null, null, true, null, isLocalSession, resumption, null, false)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
index c35ada7c3501..1259d28c3400 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -19,12 +19,10 @@ package com.android.systemui.statusbar;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -46,9 +44,9 @@ import com.android.systemui.statusbar.notification.DynamicChildBindController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.inflation.LowPriorityInflationHelper;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
index ea1b498801ec..baeedcfc3fc5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/VisualStabilityManagerTest.java
@@ -32,14 +32,17 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.NotificationPresenter;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -54,109 +57,126 @@ public class VisualStabilityManagerTest extends SysuiTestCase {
private ExpandableNotificationRow mRow = mock(ExpandableNotificationRow.class);
private NotificationEntry mEntry;
+ private StatusBarStateController.StateListener mStatusBarStateListener;
+ private WakefulnessLifecycle.Observer mWakefulnessObserver;
+
@Before
public void setUp() {
+ StatusBarStateController statusBarStateController = mock(StatusBarStateController.class);
+ WakefulnessLifecycle wakefulnessLifecycle = mock(WakefulnessLifecycle.class);
+
mTestableLooper = TestableLooper.get(this);
mVisualStabilityManager = new VisualStabilityManager(
mock(NotificationEntryManager.class),
- new Handler(mTestableLooper.getLooper()));
+ new Handler(mTestableLooper.getLooper()),
+ statusBarStateController,
+ wakefulnessLifecycle);
- mVisualStabilityManager.setUpWithPresenter(mock(NotificationPresenter.class));
mVisualStabilityManager.setVisibilityLocationProvider(mLocationProvider);
mEntry = new NotificationEntryBuilder().build();
mEntry.setRow(mRow);
when(mRow.getEntry()).thenReturn(mEntry);
+
+ ArgumentCaptor<StatusBarStateController.StateListener> stateListenerCaptor =
+ ArgumentCaptor.forClass(StatusBarStateController.StateListener.class);
+ verify(statusBarStateController).addCallback(stateListenerCaptor.capture());
+ mStatusBarStateListener = stateListenerCaptor.getValue();
+
+ ArgumentCaptor<WakefulnessLifecycle.Observer> wakefulnessObserverCaptor =
+ ArgumentCaptor.forClass(WakefulnessLifecycle.Observer.class);
+ verify(wakefulnessLifecycle).addObserver(wakefulnessObserverCaptor.capture());
+ mWakefulnessObserver = wakefulnessObserverCaptor.getValue();
}
@Test
public void testPanelExpansion() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
- mVisualStabilityManager.setPanelExpanded(false);
+ setPanelExpanded(false);
assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
}
@Test
public void testScreenOn() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
- mVisualStabilityManager.setScreenOn(false);
+ setScreenOn(false);
assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
}
@Test
public void testReorderingAllowedChangesScreenOn() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
assertFalse(mVisualStabilityManager.isReorderingAllowed());
- mVisualStabilityManager.setScreenOn(false);
+ setScreenOn(false);
assertTrue(mVisualStabilityManager.isReorderingAllowed());
}
@Test
public void testReorderingAllowedChangesPanel() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
assertFalse(mVisualStabilityManager.isReorderingAllowed());
- mVisualStabilityManager.setPanelExpanded(false);
+ setPanelExpanded(false);
assertTrue(mVisualStabilityManager.isReorderingAllowed());
}
@Test
public void testCallBackCalledScreenOn() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
- mVisualStabilityManager.setScreenOn(false);
+ setScreenOn(false);
verify(mCallback).onChangeAllowed();
}
@Test
public void testCallBackCalledPanelExpanded() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
- mVisualStabilityManager.setPanelExpanded(false);
+ setPanelExpanded(false);
verify(mCallback).onChangeAllowed();
}
@Test
public void testCallBackExactlyOnce() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
- mVisualStabilityManager.setScreenOn(false);
- mVisualStabilityManager.setScreenOn(true);
- mVisualStabilityManager.setScreenOn(false);
+ setScreenOn(false);
+ setScreenOn(true);
+ setScreenOn(false);
verify(mCallback).onChangeAllowed();
}
@Test
public void testCallBackCalledContinuouslyWhenRequested() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
mVisualStabilityManager.addReorderingAllowedCallback(mCallback, true /* persistent */);
- mVisualStabilityManager.setScreenOn(false);
- mVisualStabilityManager.setScreenOn(true);
- mVisualStabilityManager.setScreenOn(false);
+ setScreenOn(false);
+ setScreenOn(true);
+ setScreenOn(false);
verify(mCallback, times(2)).onChangeAllowed();
}
@Test
public void testAddedCanReorder() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
mVisualStabilityManager.notifyViewAddition(mRow);
assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
}
@Test
public void testReorderingVisibleHeadsUpNotAllowed() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(true);
mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
@@ -164,8 +184,8 @@ public class VisualStabilityManagerTest extends SysuiTestCase {
@Test
public void testReorderingVisibleHeadsUpAllowed() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(false);
mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
@@ -173,8 +193,8 @@ public class VisualStabilityManagerTest extends SysuiTestCase {
@Test
public void testReorderingVisibleHeadsUpAllowedOnce() {
- mVisualStabilityManager.setPanelExpanded(true);
- mVisualStabilityManager.setScreenOn(true);
+ setPanelExpanded(true);
+ setScreenOn(true);
when(mLocationProvider.isInVisibleLocation(any(NotificationEntry.class))).thenReturn(false);
mVisualStabilityManager.onHeadsUpStateChanged(mEntry, true);
mVisualStabilityManager.onReorderingFinished();
@@ -183,33 +203,33 @@ public class VisualStabilityManagerTest extends SysuiTestCase {
@Test
public void testPulsing() {
- mVisualStabilityManager.setPulsing(true);
+ setPulsing(true);
assertFalse(mVisualStabilityManager.canReorderNotification(mRow));
- mVisualStabilityManager.setPulsing(false);
+ setPulsing(false);
assertTrue(mVisualStabilityManager.canReorderNotification(mRow));
}
@Test
public void testReorderingAllowedChanges_Pulsing() {
- mVisualStabilityManager.setPulsing(true);
+ setPulsing(true);
assertFalse(mVisualStabilityManager.isReorderingAllowed());
- mVisualStabilityManager.setPulsing(false);
+ setPulsing(false);
assertTrue(mVisualStabilityManager.isReorderingAllowed());
}
@Test
public void testCallBackCalled_Pulsing() {
- mVisualStabilityManager.setPulsing(true);
+ setPulsing(true);
mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
- mVisualStabilityManager.setPulsing(false);
+ setPulsing(false);
verify(mCallback).onChangeAllowed();
}
@Test
public void testTemporarilyAllowReorderingNotifiesCallbacks() {
// GIVEN having the panel open (which would block reordering)
- mVisualStabilityManager.setScreenOn(true);
- mVisualStabilityManager.setPanelExpanded(true);
+ setScreenOn(true);
+ setPanelExpanded(true);
mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
// WHEN we temprarily allow reordering
@@ -223,7 +243,7 @@ public class VisualStabilityManagerTest extends SysuiTestCase {
@Test
public void testTemporarilyAllowReorderingDoesntOverridePulsing() {
// GIVEN we are in a pulsing state
- mVisualStabilityManager.setPulsing(true);
+ setPulsing(true);
mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
// WHEN we temprarily allow reordering
@@ -237,8 +257,8 @@ public class VisualStabilityManagerTest extends SysuiTestCase {
@Test
public void testTemporarilyAllowReorderingExpires() {
// GIVEN having the panel open (which would block reordering)
- mVisualStabilityManager.setScreenOn(true);
- mVisualStabilityManager.setPanelExpanded(true);
+ setScreenOn(true);
+ setPanelExpanded(true);
mVisualStabilityManager.addReorderingAllowedCallback(mCallback, false /* persistent */);
// WHEN we temprarily allow reordering and then wait until the window expires
@@ -249,4 +269,20 @@ public class VisualStabilityManagerTest extends SysuiTestCase {
// THEN reordering is no longer allowed
assertFalse(mVisualStabilityManager.isReorderingAllowed());
}
+
+ private void setPanelExpanded(boolean expanded) {
+ mStatusBarStateListener.onExpandedChanged(expanded);
+ }
+
+ private void setPulsing(boolean pulsing) {
+ mStatusBarStateListener.onPulsingChanged(pulsing);
+ }
+
+ private void setScreenOn(boolean screenOn) {
+ if (screenOn) {
+ mWakefulnessObserver.onStartedWakingUp();
+ } else {
+ mWakefulnessObserver.onFinishedGoingToSleep();
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
new file mode 100644
index 000000000000..605b4d18d2f1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection.coordinator;
+
+import static junit.framework.Assert.assertFalse;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.collection.NotifPipeline;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
+import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable;
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.util.concurrency.FakeExecutor;
+import com.android.systemui.util.time.FakeSystemClock;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class VisualStabilityCoordinatorTest extends SysuiTestCase {
+
+ private VisualStabilityCoordinator mCoordinator;
+
+ // captured listeners and pluggables:
+ private NotifCollectionListener mCollectionListener;
+
+ @Mock private NotifPipeline mNotifPipeline;
+ @Mock private WakefulnessLifecycle mWakefulnessLifecycle;
+ @Mock private StatusBarStateController mStatusBarStateController;
+ @Mock private Pluggable.PluggableListener<NotifStabilityManager> mInvalidateListener;
+ @Mock private HeadsUpManager mHeadsUpManager;
+
+ @Captor private ArgumentCaptor<WakefulnessLifecycle.Observer> mWakefulnessObserverCaptor;
+ @Captor private ArgumentCaptor<StatusBarStateController.StateListener> mSBStateListenerCaptor;
+ @Captor private ArgumentCaptor<NotifStabilityManager> mNotifStabilityManagerCaptor;
+ @Captor private ArgumentCaptor<NotifCollectionListener> mNotifCollectionListenerCaptor;
+
+ private FakeSystemClock mFakeSystemClock = new FakeSystemClock();
+ private FakeExecutor mFakeExecutor = new FakeExecutor(mFakeSystemClock);
+
+ private WakefulnessLifecycle.Observer mWakefulnessObserver;
+ private StatusBarStateController.StateListener mStatusBarStateListener;
+ private NotifStabilityManager mNotifStabilityManager;
+ private NotificationEntry mEntry;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mCoordinator = new VisualStabilityCoordinator(
+ mHeadsUpManager,
+ mWakefulnessLifecycle,
+ mStatusBarStateController,
+ mFakeExecutor);
+
+ mCoordinator.attach(mNotifPipeline);
+
+ // capture arguments:
+ verify(mWakefulnessLifecycle).addObserver(mWakefulnessObserverCaptor.capture());
+ mWakefulnessObserver = mWakefulnessObserverCaptor.getValue();
+
+ verify(mStatusBarStateController).addCallback(mSBStateListenerCaptor.capture());
+ mStatusBarStateListener = mSBStateListenerCaptor.getValue();
+
+ verify(mNotifPipeline).setVisualStabilityManager(mNotifStabilityManagerCaptor.capture());
+ mNotifStabilityManager = mNotifStabilityManagerCaptor.getValue();
+ mNotifStabilityManager.setInvalidationListener(mInvalidateListener);
+
+ mEntry = new NotificationEntryBuilder()
+ .setPkg("testPkg1")
+ .build();
+
+ when(mHeadsUpManager.isAlerting(mEntry.getKey())).thenReturn(false);
+ }
+
+ @Test
+ public void testScreenOff_groupAndSectionChangesAllowed() {
+ // GIVEN screen is off, panel isn't expanded and device isn't pulsing
+ setScreenOn(false);
+ setPanelExpanded(false);
+ setPulsing(false);
+
+ // THEN group changes are allowed
+ assertTrue(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+
+ // THEN section changes are allowed
+ assertTrue(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+ }
+
+ @Test
+ public void testPanelNotExpanded_groupAndSectionChangesAllowed() {
+ // GIVEN screen is on but the panel isn't expanded and device isn't pulsing
+ setScreenOn(true);
+ setPanelExpanded(false);
+ setPulsing(false);
+
+ // THEN group changes are allowed
+ assertTrue(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+
+ // THEN section changes are allowed
+ assertTrue(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+ }
+
+ @Test
+ public void testPanelExpanded_groupAndSectionChangesNotAllowed() {
+ // GIVEN the panel true expanded and device isn't pulsing
+ setScreenOn(true);
+ setPanelExpanded(true);
+ setPulsing(false);
+
+ // THEN group changes are NOT allowed
+ assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+
+ // THEN section changes are NOT allowed
+ assertFalse(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+ }
+
+ @Test
+ public void testPulsing_screenOff_groupAndSectionChangesNotAllowed() {
+ // GIVEN the device is pulsing and screen is off
+ setScreenOn(false);
+ setPulsing(true);
+
+ // THEN group changes are NOT allowed
+ assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+
+ // THEN section changes are NOT allowed
+ assertFalse(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+ }
+
+ @Test
+ public void testPulsing_panelNotExpanded_groupAndSectionChangesNotAllowed() {
+ // GIVEN the device is pulsing and screen is off with the panel not expanded
+ setScreenOn(false);
+ setPanelExpanded(false);
+ setPulsing(true);
+
+ // THEN group changes are NOT allowed
+ assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+
+ // THEN section changes are NOT allowed
+ assertFalse(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+ }
+
+ @Test
+ public void testOverrideReorderingSuppression_onlySectionChangesAllowed() {
+ // GIVEN section changes typically wouldn't be allowed because the panel is expanded and
+ // we're not pulsing
+ setScreenOn(true);
+ setPanelExpanded(true);
+ setPulsing(true);
+
+ // WHEN we temporarily allow section changes for this notification entry
+ mCoordinator.temporarilyAllowSectionChanges(mEntry, mFakeSystemClock.currentTimeMillis());
+
+ // THEN group changes aren't allowed
+ assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+
+ // THEN section changes are allowed for this notification but not other notifications
+ assertTrue(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+ assertFalse(mNotifStabilityManager.isSectionChangeAllowed(
+ new NotificationEntryBuilder()
+ .setPkg("testPkg2")
+ .build()));
+ }
+
+ @Test
+ public void testTemporarilyAllowSectionChanges_callsInvalidate() {
+ // GIVEN section changes typically wouldn't be allowed because the panel is expanded
+ setScreenOn(true);
+ setPanelExpanded(true);
+ setPulsing(false);
+
+ // WHEN we temporarily allow section changes for this notification entry
+ mCoordinator.temporarilyAllowSectionChanges(mEntry, mFakeSystemClock.uptimeMillis());
+
+ // THEN the notification list is invalidated
+ verifyInvalidateCalled(true);
+ }
+
+ @Test
+ public void testTemporarilyAllowSectionChanges_noInvalidationCalled() {
+ // GIVEN section changes typically WOULD be allowed
+ setScreenOn(false);
+ setPanelExpanded(false);
+ setPulsing(false);
+
+ // WHEN we temporarily allow section changes for this notification entry
+ mCoordinator.temporarilyAllowSectionChanges(mEntry, mFakeSystemClock.currentTimeMillis());
+
+ // THEN invalidate is not called because this entry was never suppressed from reordering
+ verifyInvalidateCalled(false);
+ }
+
+ @Test
+ public void testTemporarilyAllowSectionChangesTimeout() {
+ // GIVEN section changes typically WOULD be allowed
+ setScreenOn(false);
+ setPanelExpanded(false);
+ setPulsing(false);
+ assertTrue(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+
+ // WHEN we temporarily allow section changes for this notification entry
+ mCoordinator.temporarilyAllowSectionChanges(mEntry, mFakeSystemClock.currentTimeMillis());
+
+ // THEN invalidate is not called because this entry was never suppressed from reordering;
+ // THEN section changes are allowed for this notification
+ verifyInvalidateCalled(false);
+ assertTrue(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+
+ // WHEN we're pulsing (now disallowing reordering)
+ setPulsing(true);
+
+ // THEN we're still allowed to reorder this section because it's still in the list of
+ // notifications to allow section changes
+ assertTrue(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+
+ // WHEN the timeout for the temporarily allow section reordering runnable is finsihed
+ mFakeExecutor.advanceClockToNext();
+ mFakeExecutor.runNextReady();
+
+ // THEN section changes aren't allowed anymore
+ assertFalse(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+ }
+
+ @Test
+ public void testTemporarilyAllowSectionChanges_isPulsingChangeBeforeTimeout() {
+ // GIVEN section changes typically wouldn't be allowed because the device is pulsing
+ setScreenOn(false);
+ setPanelExpanded(false);
+ setPulsing(true);
+
+ // WHEN we temporarily allow section changes for this notification entry
+ mCoordinator.temporarilyAllowSectionChanges(mEntry, mFakeSystemClock.currentTimeMillis());
+ verifyInvalidateCalled(true); // can now reorder, so invalidates
+
+ // WHEN reordering is now allowed because device isn't pulsing anymore
+ setPulsing(false);
+
+ // THEN invalidate isn't called since reordering was already allowed
+ verifyInvalidateCalled(false);
+ }
+
+ @Test
+ public void testNeverSuppressedChanges_noInvalidationCalled() {
+ // GIVEN no notifications are currently being suppressed from grouping nor being sorted
+
+ // WHEN device isn't pulsing anymore
+ setPulsing(false);
+
+ // WHEN screen isn't on
+ setScreenOn(false);
+
+ // WHEN panel isn't expanded
+ setPanelExpanded(false);
+
+ // THEN we never see any calls to invalidate since there weren't any notifications that
+ // were being suppressed from grouping or section changes
+ verifyInvalidateCalled(false);
+ }
+
+ @Test
+ public void testHeadsUp_allowedToChangeGroupAndSection() {
+ // GIVEN group + section changes disallowed
+ setScreenOn(true);
+ setPanelExpanded(true);
+ setPulsing(true);
+ assertFalse(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+ assertFalse(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+
+ // GIVEN mEntry is a HUN
+ when(mHeadsUpManager.isAlerting(mEntry.getKey())).thenReturn(true);
+
+ // THEN group + section changes are allowed
+ assertTrue(mNotifStabilityManager.isGroupChangeAllowed(mEntry));
+ assertTrue(mNotifStabilityManager.isSectionChangeAllowed(mEntry));
+
+ }
+
+ private void setPulsing(boolean pulsing) {
+ mStatusBarStateListener.onPulsingChanged(pulsing);
+ }
+
+ private void setScreenOn(boolean screenOn) {
+ if (screenOn) {
+ mWakefulnessObserver.onStartedWakingUp();
+ } else {
+ mWakefulnessObserver.onFinishedGoingToSleep();
+ }
+ }
+
+ private void setPanelExpanded(boolean expanded) {
+ mStatusBarStateListener.onExpandedChanged(expanded);
+ }
+
+ private void verifyInvalidateCalled(boolean invalidateCalled) {
+ if (invalidateCalled) {
+ verify(mInvalidateListener).onPluggableInvalidated(mNotifStabilityManager);
+ } else {
+ verify(mInvalidateListener, never()).onPluggableInvalidated(mNotifStabilityManager);
+ }
+
+ reset(mInvalidateListener);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 83fc82634b60..3c5aa1ae9519 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -79,7 +79,6 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.bubbles.BubblesTestActivity;
import com.android.systemui.statusbar.SbnBuilder;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -135,7 +134,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
@Mock
private PackageManager mMockPackageManager;
@Mock
- private VisualStabilityManager mVisualStabilityManager;
+ private OnUserInteractionCallback mOnUserInteractionCallback;
@Mock
private BubbleController mBubbleController;
@Mock
@@ -244,7 +243,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -268,7 +267,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -293,7 +292,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mLauncherApps,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -319,7 +318,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -344,7 +343,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -368,7 +367,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -403,7 +402,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
entry,
@@ -428,7 +427,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -457,7 +456,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -481,7 +480,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -509,7 +508,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -537,7 +536,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -568,7 +567,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -598,7 +597,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -642,7 +641,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -685,7 +684,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -729,7 +728,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -766,7 +765,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -802,7 +801,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -840,7 +839,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -876,7 +875,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -912,7 +911,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -947,7 +946,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -981,7 +980,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -1006,7 +1005,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -1041,7 +1040,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
@@ -1081,7 +1080,7 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
mShortcutManager,
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
TEST_PACKAGE_NAME,
mNotificationChannel,
mEntry,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index 54ccc4d8320d..c2c40cac3d0f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -74,7 +74,6 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.notification.AssistantFeedbackController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
@@ -114,7 +113,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
@Rule public MockitoRule mockito = MockitoJUnit.rule();
@Mock private MetricsLogger mMetricsLogger;
- @Mock private VisualStabilityManager mVisualStabilityManager;
+ @Mock private OnUserInteractionCallback mOnUserInteractionCallback;
@Mock private NotificationPresenter mPresenter;
@Mock private NotificationActivityStarter mNotificationActivityStarter;
@Mock private NotificationListContainer mNotificationListContainer;
@@ -143,19 +142,21 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
mDependency.injectTestDependency(DeviceProvisionedController.class,
mDeviceProvisionedController);
mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
- mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
+ mDependency.injectTestDependency(
+ OnUserInteractionCallback.class,
+ mOnUserInteractionCallback);
mDependency.injectTestDependency(BubbleController.class, mBubbleController);
mDependency.injectMockDependency(NotificationLockscreenUserManager.class);
mHandler = Handler.createAsync(mTestableLooper.getLooper());
mHelper = new NotificationTestHelper(mContext, mDependency, TestableLooper.get(this));
when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
- mGutsManager = new NotificationGutsManager(mContext, mVisualStabilityManager,
+ mGutsManager = new NotificationGutsManager(mContext,
() -> mStatusBar, mHandler, mHandler, mAccessibilityManager, mHighPriorityProvider,
mINotificationManager, mLauncherApps, mShortcutManager,
mChannelEditorDialogController, mContextTracker, mProvider,
mAssistantFeedbackController, mBubbleController,
- new UiEventLoggerFake());
+ new UiEventLoggerFake(), mOnUserInteractionCallback);
mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer,
mCheckSaveListener, mOnSettingsClickListener);
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
@@ -360,7 +361,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
verify(notificationInfoView).bindNotification(
any(PackageManager.class),
any(INotificationManager.class),
- eq(mVisualStabilityManager),
+ eq(mOnUserInteractionCallback),
eq(mChannelEditorDialogController),
eq(statusBarNotification.getPackageName()),
any(NotificationChannel.class),
@@ -394,7 +395,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
verify(notificationInfoView).bindNotification(
any(PackageManager.class),
any(INotificationManager.class),
- eq(mVisualStabilityManager),
+ eq(mOnUserInteractionCallback),
eq(mChannelEditorDialogController),
eq(statusBarNotification.getPackageName()),
any(NotificationChannel.class),
@@ -426,7 +427,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
verify(notificationInfoView).bindNotification(
any(PackageManager.class),
any(INotificationManager.class),
- eq(mVisualStabilityManager),
+ eq(mOnUserInteractionCallback),
eq(mChannelEditorDialogController),
eq(statusBarNotification.getPackageName()),
any(NotificationChannel.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index fd8b72bb15db..02a3e11f312b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -66,7 +66,6 @@ import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
@@ -114,7 +113,7 @@ public class NotificationInfoTest extends SysuiTestCase {
@Mock
private PackageManager mMockPackageManager;
@Mock
- private VisualStabilityManager mVisualStabilityManager;
+ private OnUserInteractionCallback mOnUserInteractionCallback;
@Mock
private ChannelEditorDialogController mChannelEditorDialogController;
@@ -181,7 +180,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -207,7 +206,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -229,7 +228,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -260,7 +259,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -283,7 +282,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -311,7 +310,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -334,7 +333,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -356,7 +355,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mDefaultNotificationChannel,
@@ -382,7 +381,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mDefaultNotificationChannel,
@@ -404,7 +403,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -427,7 +426,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -455,7 +454,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -478,7 +477,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -502,7 +501,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -518,7 +517,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -541,7 +540,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME, mNotificationChannel,
createMultipleChannelSet(MULTIPLE_CHANNEL_COUNT),
@@ -569,7 +568,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -593,7 +592,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -617,7 +616,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -643,7 +642,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -665,7 +664,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -688,7 +687,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -709,7 +708,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -730,7 +729,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -751,7 +750,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -774,7 +773,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -798,7 +797,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -825,7 +824,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -852,7 +851,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -879,7 +878,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -914,7 +913,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -942,7 +941,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -982,7 +981,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -1017,7 +1016,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -1047,7 +1046,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -1082,7 +1081,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -1120,7 +1119,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -1157,7 +1156,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -1175,7 +1174,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.findViewById(R.id.done).performClick();
mNotificationInfo.handleCloseControls(true, false);
- verify(mVisualStabilityManager).temporarilyAllowReordering();
+ verify(mOnUserInteractionCallback).onImportanceChanged(mEntry);
}
@Test
@@ -1185,7 +1184,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -1216,7 +1215,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -1250,7 +1249,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -1283,7 +1282,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -1316,7 +1315,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
@@ -1342,7 +1341,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
- mVisualStabilityManager,
+ mOnUserInteractionCallback,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index fa2fa04abaa3..9a8678f01870 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -424,7 +424,8 @@ public class NotificationTestHelper {
mock(ExpandableNotificationRow.CoordinateOnClickListener.class),
mock(FalsingManager.class),
mStatusBarStateController,
- mPeopleNotificationIdentifier);
+ mPeopleNotificationIdentifier,
+ mock(OnUserInteractionCallback.class));
row.setAboveShelfChangedListener(aboveShelf -> { });
mBindStage.getStageParams(entry).requireContentViews(extraInflationFlags);
inflateAndWait(entry);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index fec467706b7b..9a6674e165e4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -74,13 +74,13 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationEntryManagerLogger;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.NotificationRankingManager;
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinder;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -239,7 +239,6 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mStackScroller.setScrimController(mock(ScrimController.class));
mStackScroller.setGroupManager(mGroupManager);
mStackScroller.setEmptyShadeView(mEmptyShadeView);
- mStackScroller.setIconAreaController(mNotificationIconAreaController);
// Stub out functionality that isn't necessary to test.
doNothing().when(mBar)
@@ -437,9 +436,9 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
}
@Test
- public void testOnDensityOrFontScaleChanged_reInflatesFooterViews() {
+ public void testReInflatesFooterViews() {
clearInvocations(mStackScroller);
- mStackScroller.onDensityOrFontScaleChanged();
+ mStackScroller.reinflateViews();
verify(mStackScroller).setFooterView(any());
verify(mStackScroller).setEmptyShadeView(any());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java
new file mode 100644
index 000000000000..e3acf0213725
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollerControllerTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.stack;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.testing.AndroidTestingRunner;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.tuner.TunerService;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link NotificationStackScrollLayoutController}.
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class NotificationStackScrollerControllerTest extends SysuiTestCase {
+
+ @Mock
+ private NotificationGutsManager mNotificationGutsManager;
+ @Mock
+ private HeadsUpManagerPhone mHeadsUpManager;
+ @Mock
+ private NotificationRoundnessManager mNotificationRoundnessManager;
+ @Mock
+ private TunerService mTunerService;
+ @Mock
+ private AmbientState mAmbientState;
+ @Mock
+ private DynamicPrivacyController mDynamicPrivacyController;
+ @Mock
+ private ConfigurationController mConfigurationController;
+ @Mock
+ private NotificationStackScrollLayout mNotificationStackScrollLayout;
+
+ NotificationStackScrollLayoutController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mController = new NotificationStackScrollLayoutController(
+ true,
+ mNotificationGutsManager,
+ mHeadsUpManager,
+ mNotificationRoundnessManager,
+ mTunerService,
+ mDynamicPrivacyController,
+ mConfigurationController
+ );
+
+ when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(true);
+ }
+
+
+ @Test
+ public void testAttach_viewAlreadyAttached() {
+ mController.attach(mNotificationStackScrollLayout);
+
+ verify(mConfigurationController).addCallback(
+ any(ConfigurationController.ConfigurationListener.class));
+ }
+ @Test
+ public void testAttach_viewAttachedAfterInit() {
+ when(mNotificationStackScrollLayout.isAttachedToWindow()).thenReturn(false);
+
+ mController.attach(mNotificationStackScrollLayout);
+
+ verify(mConfigurationController, never()).addCallback(
+ any(ConfigurationController.ConfigurationListener.class));
+
+ mController.mOnAttachStateChangeListener.onViewAttachedToWindow(
+ mNotificationStackScrollLayout);
+
+ verify(mConfigurationController).addCallback(
+ any(ConfigurationController.ConfigurationListener.class));
+ }
+
+ @Test
+ public void testOnDensityOrFontScaleChanged_reInflatesFooterViews() {
+ mController.attach(mNotificationStackScrollLayout);
+ mController.mConfigurationListener.onDensityOrFontScaleChanged();
+ verify(mNotificationStackScrollLayout).reinflateViews();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
index 713a7c92e1cf..37ccac0b23b3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeServiceHostTest.java
@@ -46,7 +46,6 @@ import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -70,7 +69,6 @@ public class DozeServiceHostTest extends SysuiTestCase {
@Mock private HeadsUpManagerPhone mHeadsUpManager;
@Mock private ScrimController mScrimController;
@Mock private DozeScrimController mDozeScrimController;
- @Mock private VisualStabilityManager mVisualStabilityManager;
@Mock private KeyguardViewMediator mKeyguardViewMediator;
@Mock private StatusBarStateControllerImpl mStatusBarStateController;
@Mock private BatteryController mBatteryController;
@@ -100,13 +98,16 @@ public class DozeServiceHostTest extends SysuiTestCase {
mStatusBarStateController, mDeviceProvisionedController, mHeadsUpManager,
mBatteryController, mScrimController, () -> mBiometricUnlockController,
mKeyguardViewMediator, () -> mAssistManager, mDozeScrimController,
- mKeyguardUpdateMonitor, mVisualStabilityManager, mPulseExpansionHandler,
+ mKeyguardUpdateMonitor, mPulseExpansionHandler,
mNotificationShadeWindowController, mNotificationWakeUpCoordinator,
- mLockscreenLockIconController, mAuthController);
-
- mDozeServiceHost.initialize(mStatusBar, mNotificationIconAreaController,
- mStatusBarKeyguardViewManager, mNotificationShadeWindowViewController,
- mNotificationPanel, mAmbientIndicationContainer);
+ mLockscreenLockIconController, mAuthController, mNotificationIconAreaController);
+
+ mDozeServiceHost.initialize(
+ mStatusBar,
+ mStatusBarKeyguardViewManager,
+ mNotificationShadeWindowViewController,
+ mNotificationPanel,
+ mAmbientIndicationContainer);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index 48bf2db0be6a..2239b1b96ac8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -34,9 +34,9 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.AlertingNotificationManager;
import com.android.systemui.statusbar.AlertingNotificationManagerTest;
import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
import com.android.systemui.statusbar.policy.ConfigurationController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
index 18cb6675f384..5222ffff2637 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
@@ -17,7 +17,6 @@ package com.android.systemui.statusbar.phone;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -29,10 +28,12 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.demomode.DemoModeController;
+import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
import org.junit.Before;
import org.junit.Test;
@@ -48,8 +49,6 @@ public class NotificationIconAreaControllerTest extends SysuiTestCase {
@Mock
private NotificationListener mListener;
@Mock
- StatusBar mStatusBar;
- @Mock
StatusBarStateController mStatusBarStateController;
@Mock
NotificationWakeUpCoordinator mWakeUpCoordinator;
@@ -58,28 +57,37 @@ public class NotificationIconAreaControllerTest extends SysuiTestCase {
@Mock
NotificationMediaManager mNotificationMediaManager;
@Mock
- NotificationIconContainer mNotificationIconContainer;
- @Mock
DozeParameters mDozeParameters;
@Mock
- NotificationShadeWindowView mNotificationShadeWindowView;
+ CommonNotifCollection mNotifCollection;
+ @Mock
+ DarkIconDispatcher mDarkIconDispatcher;
+ @Mock
+ StatusBarWindowController mStatusBarWindowController;
private NotificationIconAreaController mController;
@Mock
private BubbleController mBubbleController;
@Mock private DemoModeController mDemoModeController;
+ @Mock
+ private NotificationIconContainer mAodIcons;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- when(mStatusBar.getNotificationShadeWindowView()).thenReturn(mNotificationShadeWindowView);
- when(mNotificationShadeWindowView.findViewById(anyInt())).thenReturn(
- mNotificationIconContainer);
-
- mController = new NotificationIconAreaController(mContext, mStatusBar,
- mStatusBarStateController, mWakeUpCoordinator, mKeyguardBypassController,
- mNotificationMediaManager, mListener, mDozeParameters, mBubbleController,
- mDemoModeController);
+ mController = new NotificationIconAreaController(
+ mContext,
+ mStatusBarStateController,
+ mWakeUpCoordinator,
+ mKeyguardBypassController,
+ mNotificationMediaManager,
+ mListener,
+ mDozeParameters,
+ mBubbleController,
+ mDemoModeController,
+ mDarkIconDispatcher,
+ mStatusBarWindowController);
+ mController.setupAodIcons(mAodIcons);
}
@Test
@@ -100,7 +108,7 @@ public class NotificationIconAreaControllerTest extends SysuiTestCase {
public void testAppearResetsTranslation() {
when(mDozeParameters.shouldControlScreenOff()).thenReturn(false);
mController.appearAodIcons();
- verify(mNotificationIconContainer).setTranslationY(0);
- verify(mNotificationIconContainer).setAlpha(1.0f);
+ verify(mAodIcons).setTranslationY(0);
+ verify(mAodIcons).setAlpha(1.0f);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index a0c0e7979084..c9e9d94d8a79 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -251,9 +251,13 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mConversationNotificationManager, mMediaHiearchyManager,
mBiometricUnlockController, mStatusBarKeyguardViewManager,
() -> mKeyguardClockSwitchController,
- mNotificationStackScrollLayoutController);
- mNotificationPanelViewController.initDependencies(mStatusBar, mGroupManager,
- mNotificationShelfController, mNotificationAreaController, mScrimController);
+ mNotificationStackScrollLayoutController,
+ mNotificationAreaController);
+ mNotificationPanelViewController.initDependencies(
+ mStatusBar,
+ mGroupManager,
+ mNotificationShelfController,
+ mScrimController);
mNotificationPanelViewController.setHeadsUpManager(mHeadsUpManager);
mNotificationPanelViewController.setBar(mPanelBar);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
index a71b10cf9264..3f631b1f6282 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterTest.java
@@ -73,7 +73,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationTestHelper;
-import com.android.systemui.statusbar.notification.row.OnDismissCallback;
+import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
@@ -132,7 +132,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
@Mock
private Intent mContentIntentInner;
@Mock
- private OnDismissCallback mOnDismissCallback;
+ private OnUserInteractionCallback mOnUserInteractionCallback;
@Mock
private NotificationActivityStarter mNotificationActivityStarter;
private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
@@ -210,7 +210,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
mFeatureFlags,
mock(MetricsLogger.class),
mock(StatusBarNotificationActivityStarterLogger.class),
- mOnDismissCallback)
+ mOnUserInteractionCallback)
.setStatusBar(mStatusBar)
.setNotificationPresenter(mock(NotificationPresenter.class))
.setNotificationPanelViewController(mock(NotificationPanelViewController.class))
@@ -267,7 +267,7 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
eq(sbn.getKey()), any(NotificationVisibility.class));
// Notification calls dismiss callback to remove notification due to FLAG_AUTO_CANCEL
- verify(mOnDismissCallback).onDismiss(mNotificationRow.getEntry(), REASON_CLICK);
+ verify(mOnUserInteractionCallback).onDismiss(mNotificationRow.getEntry(), REASON_CLICK);
}
@Test
@@ -296,7 +296,8 @@ public class StatusBarNotificationActivityStarterTest extends SysuiTestCase {
verifyZeroInteractions(mContentIntent);
// Notification should not be cancelled.
- verify(mOnDismissCallback, never()).onDismiss(eq(mNotificationRow.getEntry()), anyInt());
+ verify(mOnUserInteractionCallback, never()).onDismiss(eq(mNotificationRow.getEntry()),
+ anyInt());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
index e46aa04c4504..c0ebfadf6b57 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -50,9 +50,9 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 8a1d95ea4478..8462386aaf2d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -117,9 +117,9 @@ import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager;
import com.android.systemui.statusbar.notification.init.NotificationsController;
import com.android.systemui.statusbar.notification.interruption.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProviderImpl;
@@ -405,7 +405,6 @@ public class StatusBarTest extends SysuiTestCase {
mStatusBarKeyguardViewManager,
mViewMediatorCallback,
mInitController,
- mDarkIconDispatcher,
new Handler(TestableLooper.get(this).getLooper()),
mPluginDependencyProvider,
mKeyguardDismissUtil,
@@ -416,7 +415,8 @@ public class StatusBarTest extends SysuiTestCase {
mDismissCallbackRegistry,
mDemoModeController,
mNotificationShadeDepthControllerLazy,
- mStatusBarTouchableRegionManager);
+ mStatusBarTouchableRegionManager,
+ mNotificationIconAreaController);
when(mNotificationShadeWindowView.findViewById(R.id.lock_icon_container)).thenReturn(
mLockIconContainer);
@@ -434,7 +434,6 @@ public class StatusBarTest extends SysuiTestCase {
mStatusBar.mNotificationShadeWindowView = mNotificationShadeWindowView;
mStatusBar.mNotificationPanelViewController = mNotificationPanelViewController;
mStatusBar.mDozeScrimController = mDozeScrimController;
- mStatusBar.mNotificationIconAreaController = mNotificationIconAreaController;
mStatusBar.mPresenter = mNotificationPresenter;
mStatusBar.mKeyguardIndicationController = mKeyguardIndicationController;
mStatusBar.mBarService = mBarService;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 833aeecc4c47..c41f4007aa59 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -1530,12 +1530,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
int serviceCount = userState.mBoundServices.size();
for (int i = 0; i < serviceCount; i++) {
AccessibilityServiceConnection service = userState.mBoundServices.get(i);
- relevantEventTypes |= isClientInPackageWhitelist(service.getServiceInfo(), client)
+ relevantEventTypes |= isClientInPackageAllowlist(service.getServiceInfo(), client)
? service.getRelevantEventTypes()
: 0;
}
- relevantEventTypes |= isClientInPackageWhitelist(
+ relevantEventTypes |= isClientInPackageAllowlist(
mUiAutomationManager.getServiceInfo(), client)
? mUiAutomationManager.getRelevantEventTypes()
: 0;
@@ -1571,7 +1571,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
}
- private static boolean isClientInPackageWhitelist(
+ private static boolean isClientInPackageAllowlist(
@Nullable AccessibilityServiceInfo serviceInfo, Client client) {
if (serviceInfo == null) return false;
@@ -1590,7 +1590,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
Slog.d(LOG_TAG, "Dropping events: "
+ Arrays.toString(clientPackages) + " -> "
+ serviceInfo.getComponentName().flattenToShortString()
- + " due to not being in package whitelist "
+ + " due to not being in package allowlist "
+ Arrays.toString(serviceInfo.packageNames));
}
}
@@ -1991,9 +1991,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
private void updateLegacyCapabilitiesLocked(AccessibilityUserState userState) {
- // Up to JB-MR1 we had a white list with services that can enable touch
+ // Up to JB-MR1 we had a allowlist with services that can enable touch
// exploration. When a service is first started we show a dialog to the
- // use to get a permission to white list the service.
+ // use to get a permission to allowlist the service.
final int installedServiceCount = userState.mInstalledServices.size();
for (int i = 0; i < installedServiceCount; i++) {
AccessibilityServiceInfo serviceInfo = userState.mInstalledServices.get(i);
@@ -2261,9 +2261,9 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
}
if (service.getServiceInfo().getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion
<= Build.VERSION_CODES.JELLY_BEAN_MR1) {
- // Up to JB-MR1 we had a white list with services that can enable touch
+ // Up to JB-MR1 we had a allowlist with services that can enable touch
// exploration. When a service is first started we show a dialog to the
- // use to get a permission to white list the service.
+ // use to get a permission to allowlist the service.
if (userState.mTouchExplorationGrantedServices.contains(service.mComponentName)) {
return true;
} else if (mEnableTouchExplorationDialog == null
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 97f3b373f63e..ee794badad88 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -20,14 +20,14 @@ import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
import static android.Manifest.permission.NETWORK_SETTINGS;
import static android.Manifest.permission.OBSERVE_NETWORK_POLICY;
import static android.Manifest.permission.SHUTDOWN;
-import static android.net.INetd.FIREWALL_BLACKLIST;
+import static android.net.INetd.FIREWALL_ALLOWLIST;
import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
import static android.net.INetd.FIREWALL_CHAIN_NONE;
import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
+import static android.net.INetd.FIREWALL_DENYLIST;
import static android.net.INetd.FIREWALL_RULE_ALLOW;
import static android.net.INetd.FIREWALL_RULE_DENY;
-import static android.net.INetd.FIREWALL_WHITELIST;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
@@ -1575,7 +1575,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
enforceSystemUid();
try {
mNetdService.firewallSetFirewallType(
- enabled ? INetd.FIREWALL_WHITELIST : INetd.FIREWALL_BLACKLIST);
+ enabled ? INetd.FIREWALL_ALLOWLIST : INetd.FIREWALL_DENYLIST);
mFirewallEnabled = enabled;
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
@@ -1608,7 +1608,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
int numUids = 0;
if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName);
- if (getFirewallType(chain) == FIREWALL_WHITELIST) {
+ if (getFirewallType(chain) == FIREWALL_ALLOWLIST) {
// Close all sockets on all non-system UIDs...
ranges = new UidRangeParcel[] {
// TODO: is there a better way of finding all existing users? If so, we could
@@ -1714,13 +1714,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
private int getFirewallType(int chain) {
switch (chain) {
case FIREWALL_CHAIN_STANDBY:
- return FIREWALL_BLACKLIST;
+ return FIREWALL_DENYLIST;
case FIREWALL_CHAIN_DOZABLE:
- return FIREWALL_WHITELIST;
+ return FIREWALL_ALLOWLIST;
case FIREWALL_CHAIN_POWERSAVE:
- return FIREWALL_WHITELIST;
+ return FIREWALL_ALLOWLIST;
default:
- return isFirewallEnabled() ? FIREWALL_WHITELIST : FIREWALL_BLACKLIST;
+ return isFirewallEnabled() ? FIREWALL_ALLOWLIST : FIREWALL_DENYLIST;
}
}
@@ -1822,7 +1822,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
private @NonNull String getFirewallRuleName(int chain, int rule) {
String ruleName;
- if (getFirewallType(chain) == FIREWALL_WHITELIST) {
+ if (getFirewallType(chain) == FIREWALL_ALLOWLIST) {
if (rule == FIREWALL_RULE_ALLOW) {
ruleName = "allow";
} else {
@@ -1856,7 +1856,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
private int getFirewallRuleType(int chain, int rule) {
if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) {
- return getFirewallType(chain) == FIREWALL_WHITELIST
+ return getFirewallType(chain) == FIREWALL_ALLOWLIST
? INetd.FIREWALL_RULE_DENY : INetd.FIREWALL_RULE_ALLOW;
}
return rule;
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index d1d9c0e3a285..b72985cc8f2c 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1141,13 +1141,6 @@ class StorageManagerService extends IStorageManager.Stub
}
private void completeUnlockUser(int userId) {
- // If user 0 has completed unlock, perform a one-time migration of legacy obb data
- // to its new location. This may take time depending on the size of the data to be copied
- // so it's done on the StorageManager handler thread.
- if (userId == 0) {
- mPmInternal.migrateLegacyObbData();
- }
-
onKeyguardStateChanged(false);
// Record user as started so newly mounted volumes kick off events
@@ -1540,9 +1533,21 @@ class StorageManagerService extends IStorageManager.Stub
mFuseMountedUser.remove(vol.getMountUserId());
} else if (mVoldAppDataIsolationEnabled){
final int userId = vol.getMountUserId();
- mFuseMountedUser.add(userId);
// Async remount app storage so it won't block the main thread.
new Thread(() -> {
+
+ // If user 0 has completed unlock, perform a one-time migration of legacy
+ // obb data to its new location. This may take time depending on the size of
+ // the data to be copied so it's done on the StorageManager worker thread.
+ // This needs to be finished before start mounting obb directories.
+ if (userId == 0) {
+ mPmInternal.migrateLegacyObbData();
+ }
+
+ // Add fuse mounted user after migration to prevent ProcessList tries to
+ // create obb directory before migration is done.
+ mFuseMountedUser.add(userId);
+
Map<Integer, String> pidPkgMap = null;
// getProcessesWithPendingBindMounts() could fail when a new app process is
// starting and it's not planning to mount storage dirs in zygote, but it's
diff --git a/services/core/java/com/android/server/SystemServiceManager.java b/services/core/java/com/android/server/SystemServiceManager.java
index df966c1ea6ac..34e63705d781 100644
--- a/services/core/java/com/android/server/SystemServiceManager.java
+++ b/services/core/java/com/android/server/SystemServiceManager.java
@@ -47,8 +47,8 @@ import java.util.ArrayList;
*
* {@hide}
*/
-public class SystemServiceManager {
- private static final String TAG = "SystemServiceManager";
+public final class SystemServiceManager {
+ private static final String TAG = SystemServiceManager.class.getSimpleName();
private static final boolean DEBUG = false;
private static final int SERVICE_CALL_WARN_TIME_MS = 50;
@@ -250,76 +250,76 @@ public class SystemServiceManager {
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
}
- private @NonNull TargetUser getTargetUser(@UserIdInt int userHandle) {
+ private @NonNull TargetUser getTargetUser(@UserIdInt int userId) {
final TargetUser targetUser;
synchronized (mTargetUsers) {
- targetUser = mTargetUsers.get(userHandle);
+ targetUser = mTargetUsers.get(userId);
}
- Preconditions.checkState(targetUser != null, "No TargetUser for " + userHandle);
+ Preconditions.checkState(targetUser != null, "No TargetUser for " + userId);
return targetUser;
}
/**
* Starts the given user.
*/
- public void startUser(final @NonNull TimingsTraceAndSlog t, final @UserIdInt int userHandle) {
+ public void startUser(@NonNull TimingsTraceAndSlog t, @UserIdInt int userId) {
// Create cached TargetUser
- final UserInfo userInfo = mUserManagerInternal.getUserInfo(userHandle);
- Preconditions.checkState(userInfo != null, "No UserInfo for " + userHandle);
+ final UserInfo userInfo = mUserManagerInternal.getUserInfo(userId);
+ Preconditions.checkState(userInfo != null, "No UserInfo for " + userId);
synchronized (mTargetUsers) {
- mTargetUsers.put(userHandle, new TargetUser(userInfo));
+ mTargetUsers.put(userId, new TargetUser(userInfo));
}
- onUser(t, START, userHandle);
+ onUser(t, START, userId);
}
/**
* Unlocks the given user.
*/
- public void unlockUser(final @UserIdInt int userHandle) {
- onUser(UNLOCKING, userHandle);
+ public void unlockUser(@UserIdInt int userId) {
+ onUser(UNLOCKING, userId);
}
/**
* Called after the user was unlocked.
*/
- public void onUserUnlocked(final @UserIdInt int userHandle) {
- onUser(UNLOCKED, userHandle);
+ public void onUserUnlocked(@UserIdInt int userId) {
+ onUser(UNLOCKED, userId);
}
/**
* Switches to the given user.
*/
- public void switchUser(final @UserIdInt int from, final @UserIdInt int to) {
+ public void switchUser(@UserIdInt int from, @UserIdInt int to) {
onUser(TimingsTraceAndSlog.newAsyncLog(), SWITCH, to, from);
}
/**
* Stops the given user.
*/
- public void stopUser(final @UserIdInt int userHandle) {
- onUser(STOP, userHandle);
+ public void stopUser(@UserIdInt int userId) {
+ onUser(STOP, userId);
}
/**
* Cleans up the given user.
*/
- public void cleanupUser(final @UserIdInt int userHandle) {
- onUser(CLEANUP, userHandle);
+ public void cleanupUser(@UserIdInt int userId) {
+ onUser(CLEANUP, userId);
// Remove cached TargetUser
synchronized (mTargetUsers) {
- mTargetUsers.remove(userHandle);
+ mTargetUsers.remove(userId);
}
}
- private void onUser(@NonNull String onWhat, @UserIdInt int userHandle) {
- onUser(TimingsTraceAndSlog.newAsyncLog(), onWhat, userHandle);
+ private void onUser(@NonNull String onWhat, @UserIdInt int userId) {
+ onUser(TimingsTraceAndSlog.newAsyncLog(), onWhat, userId);
}
private void onUser(@NonNull TimingsTraceAndSlog t, @NonNull String onWhat,
- @UserIdInt int userHandle) {
- onUser(t, onWhat, userHandle, UserHandle.USER_NULL);
+ @UserIdInt int userId) {
+ onUser(t, onWhat, userId, UserHandle.USER_NULL);
}
private void onUser(@NonNull TimingsTraceAndSlog t, @NonNull String onWhat,
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 0f2dfcc699e2..757b4e83e120 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -100,15 +100,20 @@ final class CoreSettingsObserver extends ContentObserver {
sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYERS, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYERS_GLES, String.class);
sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYER_APP, String.class);
- sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_ALL_APPS, int.class);
- sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_IN_APPS, String.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.UPDATABLE_DRIVER_ALL_APPS, int.class);
sGlobalSettingToTypeMap.put(
- Settings.Global.GAME_DRIVER_PRERELEASE_OPT_IN_APPS, String.class);
- sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_OPT_OUT_APPS, String.class);
- sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_DENYLIST, String.class);
- sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_ALLOWLIST, String.class);
- sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_DENYLISTS, String.class);
- sGlobalSettingToTypeMap.put(Settings.Global.GAME_DRIVER_SPHAL_LIBRARIES, String.class);
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_IN_APPS, String.class);
+ sGlobalSettingToTypeMap.put(
+ Settings.Global.UPDATABLE_DRIVER_PRERELEASE_OPT_IN_APPS, String.class);
+ sGlobalSettingToTypeMap.put(
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_OPT_OUT_APPS, String.class);
+ sGlobalSettingToTypeMap.put(
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST, String.class);
+ sGlobalSettingToTypeMap.put(
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST, String.class);
+ sGlobalSettingToTypeMap.put(
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS, String.class);
+ sGlobalSettingToTypeMap.put(Settings.Global.UPDATABLE_DRIVER_SPHAL_LIBRARIES, String.class);
// add other global settings here...
sDeviceConfigEntries.add(new DeviceConfigEntry<Boolean>(
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 2e8660e1317a..4673ecde7a68 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2222,7 +2222,8 @@ public final class ProcessList {
// access /mnt/user anyway.
&& app.mountMode != Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE
&& app.mountMode != Zygote.MOUNT_EXTERNAL_PASS_THROUGH
- && app.mountMode != Zygote.MOUNT_EXTERNAL_INSTALLER;
+ && app.mountMode != Zygote.MOUNT_EXTERNAL_INSTALLER
+ && app.mountMode != Zygote.MOUNT_EXTERNAL_NONE;
}
private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index bf7c68a845c5..0a179e89f757 100755
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1283,6 +1283,7 @@ public class AudioService extends IAudioService.Stub
}
if (isPlatformTelevision()) {
+ checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI, caller);
synchronized (mHdmiClientLock) {
if (mHdmiManager != null && mHdmiPlaybackClient != null) {
updateHdmiCecSinkLocked(mHdmiCecSink | false);
@@ -1302,54 +1303,22 @@ public class AudioService extends IAudioService.Stub
}
}
- /**
- * Update volume states for the given device.
- *
- * This will initialize the volume index if no volume index is available.
- * If the device is the currently routed device, fixed/full volume policies will be applied.
- *
- * @param device a single audio device, ensure that this is not a devices bitmask
- * @param caller caller of this method
- */
- private void updateVolumeStatesForAudioDevice(int device, String caller) {
+ private void checkAddAllFixedVolumeDevices(int device, String caller) {
final int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = 0; streamType < numStreamTypes; streamType++) {
- updateVolumeStates(device, streamType, caller);
- }
- }
-
- /**
- * Update volume states for the given device and given stream.
- *
- * This will initialize the volume index if no volume index is available.
- * If the device is the currently routed device, fixed/full volume policies will be applied.
- *
- * @param device a single audio device, ensure that this is not a devices bitmask
- * @param streamType streamType to be updated
- * @param caller caller of this method
- */
- private void updateVolumeStates(int device, int streamType, String caller) {
- if (!mStreamStates[streamType].hasIndexForDevice(device)) {
- // set the default value, if device is affected by a full/fix/abs volume rule, it
- // will taken into account in checkFixedVolumeDevices()
- mStreamStates[streamType].setIndex(
- mStreamStates[mStreamVolumeAlias[streamType]]
- .getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
- device, caller, true /*hasModifyAudioSettings*/);
- }
-
- // Check if device to be updated is routed for the given audio stream
- List<AudioDeviceAttributes> devicesForAttributes = getDevicesForAttributesInt(
- new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build());
- for (AudioDeviceAttributes deviceAttributes : devicesForAttributes) {
- if (deviceAttributes.getType() == AudioDeviceInfo.convertInternalDeviceToDeviceType(
- device)) {
- mStreamStates[streamType].checkFixedVolumeDevices();
+ if (!mStreamStates[streamType].hasIndexForDevice(device)) {
+ // set the default value, if device is affected by a full/fix/abs volume rule, it
+ // will taken into account in checkFixedVolumeDevices()
+ mStreamStates[streamType].setIndex(
+ mStreamStates[mStreamVolumeAlias[streamType]]
+ .getIndex(AudioSystem.DEVICE_OUT_DEFAULT),
+ device, caller, true /*hasModifyAudioSettings*/);
+ }
+ mStreamStates[streamType].checkFixedVolumeDevices();
- // Unmute streams if required if device is full volume
- if (isStreamMute(streamType) && mFullVolumeDevices.contains(device)) {
- mStreamStates[streamType].mute(false);
- }
+ // Unmute streams if device is full volume
+ if (mFullVolumeDevices.contains(device)) {
+ mStreamStates[streamType].mute(false);
}
}
}
@@ -1899,13 +1868,8 @@ public class AudioService extends IAudioService.Stub
/** @see AudioManager#getDevicesForAttributes(AudioAttributes) */
public @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
@NonNull AudioAttributes attributes) {
- enforceModifyAudioRoutingPermission();
- return getDevicesForAttributesInt(attributes);
- }
-
- protected @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributesInt(
- @NonNull AudioAttributes attributes) {
Objects.requireNonNull(attributes);
+ enforceModifyAudioRoutingPermission();
return AudioSystem.getDevicesForAttributes(attributes);
}
@@ -4952,15 +4916,7 @@ public class AudioService extends IAudioService.Stub
synchronized (VolumeStreamState.class) {
for (int stream = 0; stream < mStreamStates.length; stream++) {
if (stream != skipStream) {
- int devices = mStreamStates[stream].observeDevicesForStream_syncVSS(
- false /*checkOthers*/);
-
- Set<Integer> devicesSet = AudioSystem.generateAudioDeviceTypesSet(devices);
- for (Integer device : devicesSet) {
- // Update volume states for devices routed for the stream
- updateVolumeStates(device, stream,
- "AudioService#observeDevicesForStreams");
- }
+ mStreamStates[stream].observeDevicesForStream_syncVSS(false /*checkOthers*/);
}
}
}
@@ -5029,7 +4985,7 @@ public class AudioService extends IAudioService.Stub
+ Integer.toHexString(audioSystemDeviceOut) + " from:" + caller));
// make sure we have a volume entry for this device, and that volume is updated according
// to volume behavior
- updateVolumeStatesForAudioDevice(audioSystemDeviceOut, "setDeviceVolumeBehavior:" + caller);
+ checkAddAllFixedVolumeDevices(audioSystemDeviceOut, "setDeviceVolumeBehavior:" + caller);
}
/**
@@ -7251,9 +7207,10 @@ public class AudioService extends IAudioService.Stub
// HDMI output
removeAudioSystemDeviceOutFromFullVolumeDevices(AudioSystem.DEVICE_OUT_HDMI);
}
- updateVolumeStatesForAudioDevice(AudioSystem.DEVICE_OUT_HDMI,
- "HdmiPlaybackClient.DisplayStatusCallback");
}
+
+ checkAddAllFixedVolumeDevices(AudioSystem.DEVICE_OUT_HDMI,
+ "HdmiPlaybackClient.DisplayStatusCallback");
}
private class MyHdmiControlStatusChangeListenerCallback
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
index 7dd6217016eb..32bb2db77ddc 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/Face10.java
@@ -45,6 +45,7 @@ import android.os.UserManager;
import android.provider.Settings;
import android.util.Slog;
+import com.android.internal.R;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.sensors.AcquisitionClient;
@@ -275,7 +276,10 @@ class Face10 implements IHwBinder.DeathRecipient {
Face10(@NonNull Context context, int sensorId,
@NonNull LockoutResetDispatcher lockoutResetDispatcher) {
- mFaceSensorProperties = new FaceSensorProperties(sensorId, false /* supportsFaceDetect */);
+ final boolean supportsSelfIllumination = context.getResources()
+ .getBoolean(R.bool.config_faceAuthSupportsSelfIllumination);
+ mFaceSensorProperties = new FaceSensorProperties(sensorId, false /* supportsFaceDetect */,
+ supportsSelfIllumination);
mContext = context;
mSensorId = sensorId;
mScheduler = new BiometricScheduler(TAG, null /* gestureAvailabilityTracker */);
diff --git a/services/core/java/com/android/server/gpu/GpuService.java b/services/core/java/com/android/server/gpu/GpuService.java
index c0617ca95f9f..54794fecbf5b 100644
--- a/services/core/java/com/android/server/gpu/GpuService.java
+++ b/services/core/java/com/android/server/gpu/GpuService.java
@@ -65,7 +65,7 @@ public class GpuService extends SystemService {
private static final String PROD_DRIVER_PROPERTY = "ro.gfx.driver.0";
private static final String DEV_DRIVER_PROPERTY = "ro.gfx.driver.1";
- private static final String GAME_DRIVER_ALLOWLIST_FILENAME = "allowlist.txt";
+ private static final String UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST_FILENAME = "allowlist.txt";
private static final int BASE64_FLAGS = Base64.NO_PADDING | Base64.NO_WRAP;
private final Context mContext;
@@ -77,7 +77,7 @@ public class GpuService extends SystemService {
private final boolean mHasProdDriver;
private final boolean mHasDevDriver;
private ContentResolver mContentResolver;
- private long mGameDriverVersionCode;
+ private long mProdDriverVersionCode;
private SettingsObserver mSettingsObserver;
private DeviceConfigListener mDeviceConfigListener;
@GuardedBy("mLock")
@@ -88,7 +88,7 @@ public class GpuService extends SystemService {
mContext = context;
mProdDriverPackageName = SystemProperties.get(PROD_DRIVER_PROPERTY);
- mGameDriverVersionCode = -1;
+ mProdDriverVersionCode = -1;
mDevDriverPackageName = SystemProperties.get(DEV_DRIVER_PROPERTY);
mPackageManager = context.getPackageManager();
mHasProdDriver = !TextUtils.isEmpty(mProdDriverPackageName);
@@ -117,20 +117,20 @@ public class GpuService extends SystemService {
}
mSettingsObserver = new SettingsObserver();
mDeviceConfigListener = new DeviceConfigListener();
- fetchGameDriverPackageProperties();
+ fetchProductionDriverPackageProperties();
processDenylists();
setDenylist();
- fetchDeveloperDriverPackageProperties();
+ fetchPrereleaseDriverPackageProperties();
}
}
private final class SettingsObserver extends ContentObserver {
- private final Uri mGameDriverDenylistsUri =
- Settings.Global.getUriFor(Settings.Global.GAME_DRIVER_DENYLISTS);
+ private final Uri mProdDriverDenylistsUri =
+ Settings.Global.getUriFor(Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS);
SettingsObserver() {
super(new Handler());
- mContentResolver.registerContentObserver(mGameDriverDenylistsUri, false, this,
+ mContentResolver.registerContentObserver(mProdDriverDenylistsUri, false, this,
UserHandle.USER_ALL);
}
@@ -140,7 +140,7 @@ public class GpuService extends SystemService {
return;
}
- if (mGameDriverDenylistsUri.equals(uri)) {
+ if (mProdDriverDenylistsUri.equals(uri)) {
processDenylists();
setDenylist();
}
@@ -157,9 +157,11 @@ public class GpuService extends SystemService {
@Override
public void onPropertiesChanged(Properties properties) {
synchronized (mDeviceConfigLock) {
- if (properties.getKeyset().contains(Settings.Global.GAME_DRIVER_DENYLISTS)) {
+ if (properties.getKeyset().contains(
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS)) {
parseDenylists(
- properties.getString(Settings.Global.GAME_DRIVER_DENYLISTS, ""));
+ properties.getString(
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS, ""));
setDenylist();
}
}
@@ -186,10 +188,10 @@ public class GpuService extends SystemService {
case ACTION_PACKAGE_CHANGED:
case ACTION_PACKAGE_REMOVED:
if (isProdDriver) {
- fetchGameDriverPackageProperties();
+ fetchProductionDriverPackageProperties();
setDenylist();
} else if (isDevDriver) {
- fetchDeveloperDriverPackageProperties();
+ fetchPrereleaseDriverPackageProperties();
}
break;
default:
@@ -218,7 +220,7 @@ public class GpuService extends SystemService {
}
}
- private void fetchGameDriverPackageProperties() {
+ private void fetchProductionDriverPackageProperties() {
final ApplicationInfo driverInfo;
try {
driverInfo = mPackageManager.getApplicationInfo(mProdDriverPackageName,
@@ -241,15 +243,16 @@ public class GpuService extends SystemService {
// Reset the allowlist.
Settings.Global.putString(mContentResolver,
- Settings.Global.GAME_DRIVER_ALLOWLIST, "");
- mGameDriverVersionCode = driverInfo.longVersionCode;
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST, "");
+ mProdDriverVersionCode = driverInfo.longVersionCode;
try {
final Context driverContext = mContext.createPackageContext(mProdDriverPackageName,
Context.CONTEXT_RESTRICTED);
- assetToSettingsGlobal(mContext, driverContext, GAME_DRIVER_ALLOWLIST_FILENAME,
- Settings.Global.GAME_DRIVER_ALLOWLIST, ",");
+ assetToSettingsGlobal(mContext, driverContext,
+ UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST_FILENAME,
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_ALLOWLIST, ",");
} catch (PackageManager.NameNotFoundException e) {
if (DEBUG) {
Slog.w(TAG, "driver package '" + mProdDriverPackageName + "' not installed");
@@ -259,11 +262,11 @@ public class GpuService extends SystemService {
private void processDenylists() {
String base64String = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_GAME_DRIVER,
- Settings.Global.GAME_DRIVER_DENYLISTS);
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS);
if (base64String == null) {
base64String =
Settings.Global.getString(mContentResolver,
- Settings.Global.GAME_DRIVER_DENYLISTS);
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLISTS);
}
parseDenylists(base64String != null ? base64String : "");
}
@@ -288,16 +291,16 @@ public class GpuService extends SystemService {
private void setDenylist() {
Settings.Global.putString(mContentResolver,
- Settings.Global.GAME_DRIVER_DENYLIST, "");
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST, "");
synchronized (mLock) {
if (mDenylists == null) {
return;
}
List<Denylist> denylists = mDenylists.getDenylistsList();
for (Denylist denylist : denylists) {
- if (denylist.getVersionCode() == mGameDriverVersionCode) {
+ if (denylist.getVersionCode() == mProdDriverVersionCode) {
Settings.Global.putString(mContentResolver,
- Settings.Global.GAME_DRIVER_DENYLIST,
+ Settings.Global.UPDATABLE_DRIVER_PRODUCTION_DENYLIST,
String.join(",", denylist.getPackageNamesList()));
return;
}
@@ -305,7 +308,7 @@ public class GpuService extends SystemService {
}
}
- private void fetchDeveloperDriverPackageProperties() {
+ private void fetchPrereleaseDriverPackageProperties() {
final ApplicationInfo driverInfo;
try {
driverInfo = mPackageManager.getApplicationInfo(mDevDriverPackageName,
diff --git a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
index 5573eede0d40..e3074dba26ef 100644
--- a/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
+++ b/services/core/java/com/android/server/locksettings/BiometricDeferredQueue.java
@@ -164,9 +164,10 @@ public class BiometricDeferredQueue {
mPendingResetLockouts = new ArrayList<>();
}
- public void systemReady() {
- mFingerprintManager = mContext.getSystemService(FingerprintManager.class);
- mFaceManager = mContext.getSystemService(FaceManager.class);
+ public void systemReady(@Nullable FingerprintManager fingerprintManager,
+ @Nullable FaceManager faceManager) {
+ mFingerprintManager = fingerprintManager;
+ mFaceManager = faceManager;
}
/**
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 6eaa5faac8cb..0044d8936841 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -804,7 +804,8 @@ public class LockSettingsService extends ILockSettings.Stub {
mRebootEscrowManager.loadRebootEscrowDataIfAvailable();
// TODO: maybe skip this for split system user mode.
mStorage.prefetchUser(UserHandle.USER_SYSTEM);
- mBiometricDeferredQueue.systemReady();
+ mBiometricDeferredQueue.systemReady(mInjector.getFingerprintManager(),
+ mInjector.getFaceManager());
}
private void getAuthSecretHal() {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index a8a0e2e937d0..9521611c241d 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -1918,7 +1918,7 @@ public class MediaSessionService extends SystemService implements Monitor {
final int userId = UserHandle.getUserHandleForUid(uid).getIdentifier();
final long token = Binder.clearCallingIdentity();
try {
- // Don't perform sanity check between controllerPackageName and controllerUid.
+ // Don't perform check between controllerPackageName and controllerUid.
// When an (activity|service) runs on the another apps process by specifying
// android:process in the AndroidManifest.xml, then PID and UID would have the
// running process' information instead of the (activity|service) that has created
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index c7e49fbac7a3..32ec052a1fe0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1043,7 +1043,9 @@ class PackageManagerShellCommand extends ShellCommand {
+ "; isStaged = " + session.isStaged()
+ "; isReady = " + session.isStagedSessionReady()
+ "; isApplied = " + session.isStagedSessionApplied()
- + "; isFailed = " + session.isStagedSessionFailed() + ";");
+ + "; isFailed = " + session.isStagedSessionFailed()
+ + "; errorMsg = " + session.getStagedSessionErrorMessage()
+ + ";");
}
private Intent parseIntentAndUser() throws URISyntaxException {
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index ac05aabf998f..6d80f08ecbf6 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -591,13 +591,14 @@ public class StagingManager {
// If checkpoint is supported, then we only resume sessions if we are in checkpointing
// mode. If not, we fail all sessions.
if (supportsCheckpoint() && !needsCheckpoint()) {
- String errorMsg = "Reverting back to safe state. Marking " + session.sessionId
- + " as failed";
- if (!TextUtils.isEmpty(mFailureReason)) {
- errorMsg = errorMsg + ": " + mFailureReason;
+ String revertMsg = "Reverting back to safe state. Marking "
+ + session.sessionId + " as failed.";
+ final String reasonForRevert = getReasonForRevert();
+ if (!TextUtils.isEmpty(reasonForRevert)) {
+ revertMsg += " Reason for revert: " + reasonForRevert;
}
- Slog.d(TAG, errorMsg);
- session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_UNKNOWN, errorMsg);
+ Slog.d(TAG, revertMsg);
+ session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_UNKNOWN, revertMsg);
return;
}
} catch (RemoteException e) {
@@ -702,6 +703,16 @@ public class StagingManager {
}
}
+ private String getReasonForRevert() {
+ if (!TextUtils.isEmpty(mFailureReason)) {
+ return mFailureReason;
+ }
+ if (!TextUtils.isEmpty(mNativeFailureReason)) {
+ return "Session reverted due to crashing native process: " + mNativeFailureReason;
+ }
+ return "";
+ }
+
private List<String> findAPKsInDir(File stageDir) {
List<String> ret = new ArrayList<>();
if (stageDir != null && stageDir.exists()) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 8685be6567c6..1be74154b53a 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -2464,7 +2464,28 @@ public class PermissionManagerService extends IPermissionManager.Stub {
return null;
}
final PermissionsState permissionsState = ps.getPermissionsState();
- return permissionsState.getPermissions(userId);
+ if (!ps.getInstantApp(userId)) {
+ return permissionsState.getPermissions(userId);
+ } else {
+ // Install permission state is shared among all users, but instant app state is
+ // per-user, so we can only filter it here unless we make install permission state
+ // per-user as well.
+ final Set<String> instantPermissions = new ArraySet<>(permissionsState.getPermissions(
+ userId));
+ instantPermissions.removeIf(permissionName -> {
+ BasePermission permission = mSettings.getPermission(permissionName);
+ if (permission == null) {
+ return true;
+ }
+ if (!permission.isInstant()) {
+ EventLog.writeEvent(0x534e4554, "140256621", UserHandle.getUid(userId,
+ ps.getAppId()), permissionName);
+ return true;
+ }
+ return false;
+ });
+ return instantPermissions;
+ }
}
@Nullable
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 4e05a138c543..64fa6ca590d2 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1212,14 +1212,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
return task;
}
- /**
- * Sets the Task on this activity for the purposes of re-use during launch where we will
- * re-use another activity instead of this one for the launch.
- */
- void setTaskForReuse(Task task) {
- this.task = task;
- }
-
Task getStack() {
return task != null ? task.getRootTask() : null;
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 15e88fc44746..f6158383d28a 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1766,8 +1766,8 @@ class ActivityStarter {
} else if (mInTask != null) {
return mInTask;
} else {
- final Task stack = getLaunchStack(mStartActivity, mLaunchFlags,
- null /* task */, mOptions);
+ final Task stack = getLaunchStack(mStartActivity, mLaunchFlags, null /* task */,
+ mOptions);
final ActivityRecord top = stack.getTopNonFinishingActivity();
if (top != null) {
return top.getTask();
@@ -1870,13 +1870,7 @@ class ActivityStarter {
return START_SUCCESS;
}
- boolean clearTaskForReuse = false;
if (reusedTask != null) {
- if (mStartActivity.getTask() == null) {
- mStartActivity.setTaskForReuse(reusedTask);
- clearTaskForReuse = true;
- }
-
if (targetTask.intent == null) {
// This task was started because of movement of the activity based on
// affinity...
@@ -1923,13 +1917,6 @@ class ActivityStarter {
complyActivityFlags(targetTask,
reusedTask != null ? reusedTask.getTopNonFinishingActivity() : null, intentGrants);
- if (clearTaskForReuse) {
- // Clear task for re-use so later code to methods
- // {@link #setTaskFromReuseOrCreateNewTask}, {@link #setTaskFromSourceRecord}, or
- // {@link #setTaskFromInTask} can parent it to the task.
- mStartActivity.setTaskForReuse(null);
- }
-
if (mAddingToTask) {
return START_SUCCESS;
}
@@ -2515,8 +2502,8 @@ class ActivityStarter {
intentActivity.setTaskToAffiliateWith(mSourceRecord.getTask());
}
- final Task launchStack =
- getLaunchStack(mStartActivity, mLaunchFlags, intentTask, mOptions);
+ final Task launchStack = getLaunchStack(mStartActivity, mLaunchFlags, intentTask,
+ mOptions);
if (launchStack == null || launchStack == mTargetStack) {
// Do not set mMovedToFront to true below for split-screen-top stack, or
// START_TASK_TO_FRONT will be returned and trigger unexpected animations when a
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 8204b36bc551..403f225032e9 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -251,6 +251,7 @@ import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.AttributeCache;
import com.android.server.LocalServices;
import com.android.server.SystemService;
+import com.android.server.SystemService.TargetUser;
import com.android.server.SystemServiceManager;
import com.android.server.UiThread;
import com.android.server.Watchdog;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2e879810c085..0215ead7e5de 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -3982,9 +3982,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
- // TODO: Not sure if we really need to set the rotation here since we are updating from
- // the display info above...
- mDisplayFrames.mRotation = getRotation();
mDisplayPolicy.beginLayoutLw(mDisplayFrames, getConfiguration().uiMode);
int seq = mLayoutSeq + 1;
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index fe2d08f6a4c2..aeaffd98f820 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -2816,7 +2816,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
* @param launchParams The resolved launch params to use.
* @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid}
* @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid}
- *
* @return The stack to use for the launch or INVALID_STACK_ID.
*/
Task getLaunchStack(@Nullable ActivityRecord r,
@@ -2965,10 +2964,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// If {@code r} is already in target display area and its task is the same as the candidate
// task, the intention should be getting a launch stack for the reusable activity, so we can
// use the existing stack.
- if (candidateTask != null && (r.getTask() == null || r.getTask() == candidateTask)) {
- // TODO(b/153920825): Fix incorrect evaluation of attached state
- final TaskDisplayArea attachedTaskDisplayArea = r.getTask() != null
- ? r.getTask().getDisplayArea() : r.getDisplayArea();
+ if (candidateTask != null) {
+ final TaskDisplayArea attachedTaskDisplayArea = candidateTask.getDisplayArea();
if (attachedTaskDisplayArea == null || attachedTaskDisplayArea == taskDisplayArea) {
return candidateTask.getRootTask();
}
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index bc75dcd91813..12c69eaa0f8d 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -150,7 +150,8 @@ public final class ProfcollectForwardingService extends SystemService {
}
// Sample for a fraction of app launches.
- int traceFrequency = SystemProperties.getInt("profcollectd.applaunch_trace_freq", 2);
+ int traceFrequency =
+ SystemProperties.getInt("persist.profcollectd.applaunch_trace_freq", 2);
int randomNum = ThreadLocalRandom.current().nextInt(100);
if (randomNum < traceFrequency) {
try {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java
index c29c510b35b5..42ba842f8434 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/MockWindowMagnificationConnection.java
@@ -17,23 +17,33 @@
package com.android.server.accessibility.magnification;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
+import android.view.Display;
import android.view.accessibility.IWindowMagnificationConnection;
import android.view.accessibility.IWindowMagnificationConnectionCallback;
+/**
+ * Mocks the basic logic of window magnification in System UI. We assume the screen size is
+ * unlimited, so source bounds is always on the center of the mirror window bounds.
+ */
class MockWindowMagnificationConnection {
+ public static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY;
private final IWindowMagnificationConnection mConnection;
private final Binder mBinder;
private IBinder.DeathRecipient mDeathRecipient;
private IWindowMagnificationConnectionCallback mIMirrorWindowCallback;
+ private Rect mMirrorWindowFrame = new Rect(0, 0, 500, 500);
MockWindowMagnificationConnection() throws RemoteException {
mConnection = mock(IWindowMagnificationConnection.class);
@@ -50,6 +60,30 @@ class MockWindowMagnificationConnection {
return null;
}).when(mBinder).linkToDeath(
any(IBinder.DeathRecipient.class), eq(0));
+ stubConnection();
+ }
+
+ private void stubConnection() throws RemoteException {
+ doAnswer((invocation) -> {
+ final int displayId = invocation.getArgument(0);
+ if (displayId != TEST_DISPLAY) {
+ throw new IllegalArgumentException("only support default display :" + displayId);
+ }
+ computeMirrorWindowFrame(invocation.getArgument(1), invocation.getArgument(2));
+
+ mIMirrorWindowCallback.onWindowMagnifierBoundsChanged(TEST_DISPLAY,
+ mMirrorWindowFrame);
+ return null;
+ }).when(mConnection).enableWindowMagnification(anyInt(),
+ anyFloat(), anyFloat(), anyFloat());
+ }
+
+ private void computeMirrorWindowFrame(float centerX, float centerY) {
+ final float offsetX = Float.isNaN(centerX) ? 0
+ : centerX - mMirrorWindowFrame.exactCenterX();
+ final float offsetY = Float.isNaN(centerY) ? 0
+ : centerY - mMirrorWindowFrame.exactCenterY();
+ mMirrorWindowFrame.offset((int) offsetX, (int) offsetY);
}
IWindowMagnificationConnection getConnection() {
@@ -60,12 +94,16 @@ class MockWindowMagnificationConnection {
return mBinder;
}
- public IBinder.DeathRecipient getDeathRecipient() {
+ IBinder.DeathRecipient getDeathRecipient() {
return mDeathRecipient;
}
- public IWindowMagnificationConnectionCallback getConnectionCallback() {
+ IWindowMagnificationConnectionCallback getConnectionCallback() {
return mIMirrorWindowCallback;
}
+
+ public Rect getMirrorWindowFrame() {
+ return new Rect(mMirrorWindowFrame);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/TwoFingersDownTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/TwoFingersDownTest.java
index 2b1bdc59d9c8..ed8dc4e470de 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/TwoFingersDownTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/TwoFingersDownTest.java
@@ -87,15 +87,15 @@ public class TwoFingersDownTest {
secondPointerCoords.x = DEFAULT_X + 10;
secondPointerCoords.y = DEFAULT_Y + 10;
- final MotionEvent pointerDownEvent = TouchEventGenerator.pointerDownEvent(
+ final MotionEvent twoPointersDownEvent = TouchEventGenerator.twoPointersDownEvent(
Display.DEFAULT_DISPLAY, defPointerCoords, secondPointerCoords);
mGesturesObserver.onMotionEvent(downEvent, downEvent, 0);
- mGesturesObserver.onMotionEvent(pointerDownEvent, pointerDownEvent, 0);
+ mGesturesObserver.onMotionEvent(twoPointersDownEvent, twoPointersDownEvent, 0);
verify(mListener, timeout(sTimeoutMillis)).onGestureCompleted(
- MagnificationGestureMatcher.GESTURE_TWO_FINGER_DOWN, pointerDownEvent,
- pointerDownEvent, 0);
+ MagnificationGestureMatcher.GESTURE_TWO_FINGER_DOWN, twoPointersDownEvent,
+ twoPointersDownEvent, 0);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
index e580340a29f7..bec9f26672f4 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/WindowMagnificationGestureHandlerTest.java
@@ -16,14 +16,9 @@
package com.android.server.accessibility.magnification;
-import static android.view.MotionEvent.ACTION_POINTER_DOWN;
-
import static com.android.server.testutils.TestUtils.strictMock;
import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.anyFloat;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import android.content.Context;
@@ -63,11 +58,9 @@ public class WindowMagnificationGestureHandlerTest {
public static final int LAST_STATE = STATE_SHOW_MAGNIFIER_TRIPLE_TAP;
// Co-prime x and y, to potentially catch x-y-swapped errors
- public static final float DEFAULT_X = 301;
- public static final float DEFAULT_Y = 299;
- //Assume first pointer position (DEFAULT_X,DEFAULT_Y) is in the window.
- public static Rect DEFAULT_WINDOW_FRAME = new Rect(0, 0, 500, 500);
- private static final int DISPLAY_0 = 0;
+ public static final float DEFAULT_TAP_X = 301;
+ public static final float DEFAULT_TAP_Y = 299;
+ private static final int DISPLAY_0 = MockWindowMagnificationConnection.TEST_DISPLAY;
private Context mContext;
private WindowMagnificationManager mWindowMagnificationManager;
@@ -83,14 +76,6 @@ public class WindowMagnificationGestureHandlerTest {
mContext, mWindowMagnificationManager, mock(ScaleChangedListener.class),
/** detectTripleTap= */true, /** detectShortcutTrigger= */true, DISPLAY_0);
mWindowMagnificationManager.setConnection(mMockConnection.getConnection());
- mMockConnection.getConnectionCallback().onWindowMagnifierBoundsChanged(DISPLAY_0,
- DEFAULT_WINDOW_FRAME);
- doAnswer((invocation) -> {
- mMockConnection.getConnectionCallback().onWindowMagnifierBoundsChanged(DISPLAY_0,
- DEFAULT_WINDOW_FRAME);
- return null;
- }).when(mMockConnection.getConnection()).enableWindowMagnification(eq(DISPLAY_0),
- anyFloat(), anyFloat(), anyFloat());
mWindowMagnificationGestureHandler.setNext(strictMock(EventStreamTransformation.class));
}
@@ -208,10 +193,11 @@ public class WindowMagnificationGestureHandlerTest {
break;
case STATE_TWO_FINGERS_DOWN: {
goFromStateIdleTo(STATE_SHOW_MAGNIFIER);
- send(downEvent());
+ final Rect frame = mMockConnection.getMirrorWindowFrame();
+ send(downEvent(frame.centerX(), frame.centerY()));
//Second finger is outside the window.
- send(pointerEvent(ACTION_POINTER_DOWN, DEFAULT_WINDOW_FRAME.right + 10,
- DEFAULT_WINDOW_FRAME.bottom + 10));
+ send(twoPointerDownEvent(new float[]{frame.centerX(), frame.centerX() + 10},
+ new float[]{frame.centerY(), frame.centerY() + 10}));
}
break;
case STATE_SHOW_MAGNIFIER_TRIPLE_TAP: {
@@ -243,7 +229,8 @@ public class WindowMagnificationGestureHandlerTest {
}
break;
case STATE_TWO_FINGERS_DOWN: {
- send(upEvent());
+ final Rect frame = mMockConnection.getMirrorWindowFrame();
+ send(upEvent(frame.centerX(), frame.centerY()));
returnToNormalFrom(STATE_SHOW_MAGNIFIER);
}
break;
@@ -286,12 +273,8 @@ public class WindowMagnificationGestureHandlerTest {
}
}
- private MotionEvent downEvent() {
- return TouchEventGenerator.downEvent(DISPLAY_0, DEFAULT_X, DEFAULT_Y);
- }
-
- private MotionEvent upEvent() {
- return upEvent(DEFAULT_X, DEFAULT_Y);
+ private MotionEvent downEvent(float x, float y) {
+ return TouchEventGenerator.downEvent(DISPLAY_0, x, y);
}
private MotionEvent upEvent(float x, float y) {
@@ -299,18 +282,18 @@ public class WindowMagnificationGestureHandlerTest {
}
private void tap() {
- send(downEvent());
- send(upEvent());
+ send(downEvent(DEFAULT_TAP_X, DEFAULT_TAP_Y));
+ send(upEvent(DEFAULT_TAP_X, DEFAULT_TAP_Y));
}
- private MotionEvent pointerEvent(int action, float x, float y) {
+ private MotionEvent twoPointerDownEvent(float[] x, float[] y) {
final MotionEvent.PointerCoords defPointerCoords = new MotionEvent.PointerCoords();
- defPointerCoords.x = DEFAULT_X;
- defPointerCoords.y = DEFAULT_Y;
+ defPointerCoords.x = x[0];
+ defPointerCoords.y = y[0];
final MotionEvent.PointerCoords pointerCoords = new MotionEvent.PointerCoords();
- pointerCoords.x = x;
- pointerCoords.y = y;
- return TouchEventGenerator.pointerDownEvent(DISPLAY_0, defPointerCoords, pointerCoords);
+ pointerCoords.x = x[1];
+ pointerCoords.y = y[1];
+ return TouchEventGenerator.twoPointersDownEvent(DISPLAY_0, defPointerCoords, pointerCoords);
}
private String stateDump() {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/utils/TouchEventGenerator.java b/services/tests/servicestests/src/com/android/server/accessibility/utils/TouchEventGenerator.java
index 7cbf3ee46594..a05881f78892 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/utils/TouchEventGenerator.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/utils/TouchEventGenerator.java
@@ -43,9 +43,9 @@ public class TouchEventGenerator {
return generateSingleTouchEvent(displayId, ACTION_UP, x, y);
}
- public static MotionEvent pointerDownEvent(int displayId, PointerCoords defPointerCoords,
+ public static MotionEvent twoPointersDownEvent(int displayId, PointerCoords defPointerCoords,
PointerCoords pointerCoords) {
- return generatePointerEvent(displayId, ACTION_POINTER_DOWN, defPointerCoords,
+ return generateTwoPointersEvent(displayId, ACTION_POINTER_DOWN, defPointerCoords,
pointerCoords);
}
@@ -59,7 +59,7 @@ public class TouchEventGenerator {
return ev;
}
- private static MotionEvent generatePointerEvent(int displayId, int action,
+ private static MotionEvent generateTwoPointersEvent(int displayId, int action,
PointerCoords defPointerCoords, PointerCoords pointerCoords) {
final long downTime = SystemClock.uptimeMillis();
MotionEvent.PointerProperties defPointerProperties = new MotionEvent.PointerProperties();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 1ec9bd24ad59..b89d16807a6e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -890,8 +890,8 @@ public class RootActivityContainerTests extends WindowTestsBase {
// Make sure the root task is valid and can be reused on default display.
final Task stack = mRootWindowContainer.getValidLaunchStackInTaskDisplayArea(
- mRootWindowContainer.getDefaultTaskDisplayArea(), activity, task, null,
- null);
+ mRootWindowContainer.getDefaultTaskDisplayArea(), activity, task,
+ null /* options */, null /* launchParams */);
assertEquals(task, stack);
}
diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt
index 09c16595e2c7..52e0953813a0 100644
--- a/telephony/api/system-current.txt
+++ b/telephony/api/system-current.txt
@@ -1625,6 +1625,7 @@ package android.telephony.ims {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setRcsProvisioningStatusForCapability(int, boolean);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
+ field public static final int KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID = 67; // 0x43
field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
field public static final int PROVISIONING_VALUE_DISABLED = 0; // 0x0
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index e34bbfcde492..06c34dcf290a 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -37,7 +37,7 @@ public final class CellIdentityNr extends CellIdentity {
private static final String TAG = "CellIdentityNr";
private static final int MAX_PCI = 1007;
- private static final int MAX_TAC = 65535;
+ private static final int MAX_TAC = 16777215; // 0xffffff
private static final int MAX_NRARFCN = 3279165;
private static final long MAX_NCI = 68719476735L;
@@ -53,7 +53,7 @@ public final class CellIdentityNr extends CellIdentity {
/**
*
* @param pci Physical Cell Id in range [0, 1007].
- * @param tac 16-bit Tracking Area Code.
+ * @param tac 24-bit Tracking Area Code.
* @param nrArfcn NR Absolute Radio Frequency Channel Number, in range [0, 3279165].
* @param bands Bands used by the cell. Band number defined in 3GPP TS 38.101-1 and TS 38.101-2.
* @param mccStr 3-digit Mobile Country Code in string format.
@@ -199,9 +199,9 @@ public final class CellIdentityNr extends CellIdentity {
/**
* Get the tracking area code.
- * @return a 16 bit integer or {@link CellInfo#UNAVAILABLE} if unknown.
+ * @return a 24 bit integer or {@link CellInfo#UNAVAILABLE} if unknown.
*/
- @IntRange(from = 0, to = 65535)
+ @IntRange(from = 0, to = 16777215)
public int getTac() {
return mTac;
}
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 1a606b7ae6a7..2a073a1f1d81 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -851,6 +851,19 @@ public class ProvisioningManager {
public static final int KEY_RTT_ENABLED = 66;
/**
+ * An obfuscated string defined by the carrier to indicate VoWiFi entitlement status.
+ *
+ * <p>Implementation note: how to generate the value and how it affects VoWiFi service
+ * should follow carrier requirements. For example, set an empty string could result in
+ * VoWiFi being disabled by IMS service, and set to a specific string could enable.
+ *
+ * <p>Value is in String format.
+ * @see #setProvisioningStringValue(int, String)
+ * @see #getProvisioningStringValue(int)
+ */
+ public static final int KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID = 67;
+
+ /**
* Callback for IMS provisioning changes.
*/
public static class Callback {
diff --git a/telephony/java/com/android/ims/ImsConfig.java b/telephony/java/com/android/ims/ImsConfig.java
index d0cec52dfc86..487786045b8e 100644
--- a/telephony/java/com/android/ims/ImsConfig.java
+++ b/telephony/java/com/android/ims/ImsConfig.java
@@ -729,7 +729,8 @@ public class ImsConfig {
// Expand the operator config items as needed here, need to change
// PROVISIONED_CONFIG_END after that.
- public static final int PROVISIONED_CONFIG_END = RTT_SETTING_ENABLED;
+ public static final int PROVISIONED_CONFIG_END =
+ ProvisioningManager.KEY_VOICE_OVER_WIFI_ENTITLEMENT_ID;
// Expand the operator config items as needed here.
}