diff options
Diffstat (limited to 'libs')
108 files changed, 2758 insertions, 6639 deletions
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/SampleExtensionImpl.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/SampleExtensionImpl.java index ce9be6a7bba3..a0d5b004ff1c 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/SampleExtensionImpl.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/SampleExtensionImpl.java @@ -69,21 +69,15 @@ class SampleExtensionImpl extends StubExtension { new ResourceConfigDisplayFeatureProducer(context) )); - mDevicePostureProducer.addDataChangedCallback(this::onDevicePostureChanged); + mDevicePostureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged); mDisplayFeatureProducer.addDataChangedCallback(this::onDisplayFeaturesChanged); } - private void onDevicePostureChanged() { - updateDeviceState(new ExtensionDeviceState(getDevicePosture())); - - // Trigger a change in display features as the posture will be used in place of the feature - // state if the state is left unset by the producer. - onDisplayFeaturesChanged(); - } - - private int getDevicePosture() { + private int getFeatureState(DisplayFeature feature) { + Integer featureState = feature.getState(); Optional<Integer> posture = mDevicePostureProducer.getData(); - return posture.orElse(ExtensionDeviceState.POSTURE_UNKNOWN); + int fallbackPosture = posture.orElse(ExtensionFoldingFeature.STATE_FLAT); + return featureState == null ? fallbackPosture : featureState; } private void onDisplayFeaturesChanged() { @@ -115,17 +109,14 @@ class SampleExtensionImpl extends StubExtension { Optional<List<DisplayFeature>> storedFeatures = mDisplayFeatureProducer.getData(); if (storedFeatures.isPresent()) { - int posture = getDevicePosture(); for (DisplayFeature baseFeature : storedFeatures.get()) { Rect featureRect = baseFeature.getRect(); rotateRectToDisplayRotation(displayId, featureRect); transformToWindowSpaceRect(activity, featureRect); - Integer featureState = baseFeature.getState(); - features.add(new ExtensionFoldingFeature(featureRect, baseFeature.getType(), - featureState == null ? posture : featureState)); + getFeatureState(baseFeature))); } } return features; @@ -141,7 +132,6 @@ class SampleExtensionImpl extends StubExtension { mSettingsDisplayFeatureProducer.unregisterObserversIfNeeded(); } - onDevicePostureChanged(); onDisplayFeaturesChanged(); } } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/StubExtension.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/StubExtension.java index b0895efc75a9..6a53efee0e74 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/StubExtension.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/StubExtension.java @@ -31,7 +31,6 @@ abstract class StubExtension implements ExtensionInterface { private ExtensionCallback mExtensionCallback; private final Set<Activity> mWindowLayoutChangeListenerActivities = new HashSet<>(); - private boolean mDeviceStateChangeListenerRegistered; StubExtension() { } @@ -53,18 +52,6 @@ abstract class StubExtension implements ExtensionInterface { this.onListenersChanged(); } - @Override - public void onDeviceStateListenersChanged(boolean isEmpty) { - this.mDeviceStateChangeListenerRegistered = !isEmpty; - this.onListenersChanged(); - } - - void updateDeviceState(ExtensionDeviceState newState) { - if (this.mExtensionCallback != null) { - mExtensionCallback.onDeviceStateChanged(newState); - } - } - void updateWindowLayout(@NonNull Activity activity, @NonNull ExtensionWindowLayoutInfo newLayout) { if (this.mExtensionCallback != null) { @@ -78,8 +65,7 @@ abstract class StubExtension implements ExtensionInterface { } protected boolean hasListeners() { - return !mWindowLayoutChangeListenerActivities.isEmpty() - || mDeviceStateChangeListenerRegistered; + return !mWindowLayoutChangeListenerActivities.isEmpty(); } protected abstract void onListenersChanged(); diff --git a/libs/WindowManager/Jetpack/window-extensions-release.aar b/libs/WindowManager/Jetpack/window-extensions-release.aar Binary files differindex 7b306b00afd9..be6652d43fb2 100644 --- a/libs/WindowManager/Jetpack/window-extensions-release.aar +++ b/libs/WindowManager/Jetpack/window-extensions-release.aar diff --git a/libs/WindowManager/Jetpack/window-sidecar-release.aar b/libs/WindowManager/Jetpack/window-sidecar-release.aar Binary files differindex 50f101d7d181..9d6baee0993a 100644 --- a/libs/WindowManager/Jetpack/window-sidecar-release.aar +++ b/libs/WindowManager/Jetpack/window-sidecar-release.aar diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp index 18f019dc949b..9aaef3b1f655 100644 --- a/libs/WindowManager/Shell/Android.bp +++ b/libs/WindowManager/Shell/Android.bp @@ -129,6 +129,4 @@ android_library { ], kotlincflags: ["-Xjvm-default=enable"], manifest: "AndroidManifest.xml", - - min_sdk_version: "26", } diff --git a/libs/WindowManager/Shell/lint-baseline.xml b/libs/WindowManager/Shell/lint-baseline.xml deleted file mode 100644 index 06094ffe1930..000000000000 --- a/libs/WindowManager/Shell/lint-baseline.xml +++ /dev/null @@ -1,5471 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<issues format="5" by="lint 4.1.0" client="cli" variant="all" version="4.1.0"> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" return mRootTaskInfo != null ? mRootTaskInfo.taskId : INVALID_TASK_ID;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="73" - column="40"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" return mTaskInfo1 != null ? mTaskInfo1.taskId : INVALID_TASK_ID;" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="77" - column="37"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" return mTaskInfo2 != null ? mTaskInfo2.taskId : INVALID_TASK_ID;" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="81" - column="37"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = task1.taskId; long protoLogParam1 = task2.taskId; String protoLogParam2 = String.valueOf(this); com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -742394458, 5, null, protoLogParam0, protoLogParam1, protoLogParam2); " - errorLine2=" ~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="89" - column="113"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = task1.taskId; long protoLogParam1 = task2.taskId; String protoLogParam2 = String.valueOf(this); com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -742394458, 5, null, protoLogParam0, protoLogParam1, protoLogParam2); " - errorLine2=" ~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="89" - column="149"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b -> b.setParent(mRootTaskLeash), mDisplayImeController);" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="105" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (mRootTaskInfo == null || taskInfo.taskId == mRootTaskInfo.taskId) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="151" - column="38"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (mRootTaskInfo == null || taskInfo.taskId == mRootTaskInfo.taskId) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="151" - column="57"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" } else if (taskInfo.taskId == getTaskId1()) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="154" - column="20"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" } else if (taskInfo.taskId == getTaskId2()) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="157" - column="20"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" throw new IllegalStateException("Unknown task=" + taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="161" - column="63"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(dividerLeash, Integer.MAX_VALUE)" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="172" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (taskInfo.taskId == getRootTaskId()) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="186" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" } else if (taskInfo.taskId == getTaskId1()) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="202" - column="20"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" } else if (taskInfo.taskId == getTaskId2()) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="204" - column="20"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" throw new IllegalStateException("Unknown task=" + taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="207" - column="63"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (taskInfo.taskId == getRootTaskId()) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="213" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mController.unpair(mRootTaskInfo.taskId, false /* releaseToPool */);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="215" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" } else if (taskInfo.taskId == getTaskId1() || taskInfo.taskId == getTaskId2()) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="216" - column="20"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" } else if (taskInfo.taskId == getTaskId1() || taskInfo.taskId == getTaskId2()) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="216" - column="55"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mController.unpair(mRootTaskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="217" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(mRootTaskLeash);" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="224" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(mTaskLeash1);" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="226" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(mTaskLeash2);" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="228" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" pw.println(innerPrefix + "1 taskId=" + mTaskInfo1.taskId" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="242" - column="52"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" pw.println(innerPrefix + "2 taskId=" + mTaskInfo2.taskId" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="246" - column="52"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" .setLayer(dividerLeash, Integer.MAX_VALUE)" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java" - line="291" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.content.LocusId`" - errorLine1=" mLocusId = locus != null ? new LocusId(locus) : null;" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="177" - column="36"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.service.notification.StatusBarNotification#getUid`" - errorLine1=" mAppUid = entry.getStatusBarNotification().getUid();" - errorLine2=" ~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="449" - column="52"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 31 (current min is 26): `android.service.notification.NotificationListenerService.Ranking#getConversationShortcutInfo`" - errorLine1=" mShortcutInfo = entry.getRanking().getConversationShortcutInfo();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="453" - column="48"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.app.NotificationChannel#isImportantConversation`" - errorLine1=" entry.getRanking().getChannel().isImportantConversation();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="457" - column="57"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.app.Notification.BubbleMetadata#getShortcutId`" - errorLine1=" mMetadataShortcutId = entry.getBubbleMetadata().getShortcutId();" - errorLine2=" ~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="461" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getDesiredHeight`" - errorLine1=" mDesiredHeight = entry.getBubbleMetadata().getDesiredHeight();" - errorLine2=" ~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="463" - column="56"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getDesiredHeightResId`" - errorLine1=" mDesiredHeightResId = entry.getBubbleMetadata().getDesiredHeightResId();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="464" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getIcon`" - errorLine1=" mIcon = entry.getBubbleMetadata().getIcon();" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="465" - column="47"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getIntent`" - errorLine1=" mIntent = entry.getBubbleMetadata().getIntent();" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="471" - column="53"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getIntent`" - errorLine1=" } else if (mIntent != null && entry.getBubbleMetadata().getIntent() == null) {" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="475" - column="69"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getDeleteIntent`" - errorLine1=" mDeleteIntent = entry.getBubbleMetadata().getDeleteIntent();" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="481" - column="55"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.app.Notification.MessagingStyle.Message#getMessagesFromBundleArray`" - errorLine1=" Notification.MessagingStyle.Message.getMessagesFromBundleArray(" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="856" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.app.Notification.MessagingStyle.Message#getSenderPerson`" - errorLine1=" Person sender = latestMessage.getSenderPerson();" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="864" - column="51"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.app.Person#getName`" - errorLine1=" bubbleMessage.senderName = sender != null ? sender.getName() : null;" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="865" - column="72"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.app.Person#getIcon`" - errorLine1=" bubbleMessage.senderIcon = sender != null ? sender.getIcon() : null;" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java" - line="867" - column="72"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (task.taskId == b.getTaskId()) {" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java" - line="357" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsTypes`" - errorLine1=" mWmLayoutParams.setFitInsetsTypes(0);" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java" - line="553" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`" - errorLine1=" mWmLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java" - line="558" - column="9"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getAutoExpandBubble`" - errorLine1=" && !notif.getBubbleMetadata().getAutoExpandBubble())" - errorLine2=" ~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java" - line="842" - column="51"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.service.notification.NotificationListenerService.Ranking#canBubble`" - errorLine1=" if (isActiveBubble && !mTmpRanking.canBubble()) {" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java" - line="919" - column="48"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.app.Notification.BubbleMetadata#getIntent`" - errorLine1=" ? entry.getBubbleMetadata().getIntent()" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java" - line="1217" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.app.Notification.BubbleMetadata#getShortcutId`" - errorLine1=" && entry.getBubbleMetadata().getShortcutId() != null) {" - errorLine2=" ~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java" - line="1220" - column="46"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.content.LocusId#getId`" - errorLine1=" b.locusId?.id" - errorLine2=" ~~"> - <location - file="frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt" - line="85" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.app.Notification#getLocusId`" - errorLine1=" return mSbn.getNotification().getLocusId();" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEntry.java" - line="81" - column="39"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.app.Notification#getBubbleMetadata`" - errorLine1=" return getStatusBarNotification().getNotification().getBubbleMetadata();" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEntry.java" - line="87" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.service.notification.NotificationListenerService.Ranking#canBubble`" - errorLine1=" return mRanking.canBubble();" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleEntry.java" - line="115" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.graphics.Bitmap#createBitmap`" - errorLine1=" Bitmap snapshot = Bitmap.createBitmap(p);" - errorLine2=" ~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java" - line="428" - column="38"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 31 (current min is 26): `android.graphics.Bitmap#getHardwareBuffer`" - errorLine1=" return new SurfaceControl.ScreenshotHardwareBuffer(snapshot.getHardwareBuffer()," - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java" - line="429" - column="73"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceView#getSurfaceControl`" - errorLine1=" if (mTaskView == null || mTaskView.getSurfaceControl() == null) {" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java" - line="432" - column="44"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceView#getSurfaceControl`" - errorLine1=" mTaskView.getSurfaceControl()," - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java" - line="436" - column="27"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`" - errorLine1=" ? mExpandedViewContainerLocation[1] - mPositioner.getInsets().top" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java" - line="636" - column="55"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.graphics.Outline#setPath`" - errorLine1=" outline.setPath(rectPath);" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java" - line="504" - column="21"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getType`" - errorLine1=" if (ic.getType() == Icon.TYPE_URI" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java" - line="65" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getType`" - errorLine1=" || ic.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) {" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java" - line="66" - column="31"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getUri`" - errorLine1=" ic.getUri()," - errorLine2=" ~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java" - line="68" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`" - errorLine1=" getContext().getDisplay().getMetrics(displayMetrics);" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java" - line="143" - column="22"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager#getCurrentWindowMetrics`" - errorLine1=" WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="93" - column="54"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getWindowInsets`" - errorLine1=" WindowInsets metricInsets = windowMetrics.getWindowInsets();" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="97" - column="51"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets#getInsetsIgnoringVisibility`" - errorLine1=" Insets insets = metricInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="99" - column="38"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#navigationBars`" - errorLine1=" Insets insets = metricInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()" - errorLine2=" ~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="99" - column="84"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#statusBars`" - errorLine1=" | WindowInsets.Type.statusBars()" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="100" - column="37"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#displayCutout`" - errorLine1=" | WindowInsets.Type.displayCutout());" - errorLine2=" ~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="101" - column="37"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getBounds`" - errorLine1=" + " bounds: " + windowMetrics.getBounds()" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="107" - column="51"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getBounds`" - errorLine1=" updateInternal(orientation, insets, windowMetrics.getBounds());" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="110" - column="59"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`" - errorLine1=" mPositionRect.left += mInsets.left;" - errorLine2=" ~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="134" - column="31"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`" - errorLine1=" mPositionRect.top += mInsets.top;" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="135" - column="30"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`" - errorLine1=" mPositionRect.right -= mInsets.right;" - errorLine2=" ~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="136" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#bottom`" - errorLine1=" mPositionRect.bottom -= mInsets.bottom;" - errorLine2=" ~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="137" - column="33"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager#getCurrentWindowMetrics`" - errorLine1=" WindowInsets metricInsets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="156" - column="56"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getWindowInsets`" - errorLine1=" WindowInsets metricInsets = mWindowManager.getCurrentWindowMetrics().getWindowInsets();" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="156" - column="82"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets#getInsetsIgnoringVisibility`" - errorLine1=" Insets navBarInsets = metricInsets.getInsetsIgnoringVisibility(" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="157" - column="48"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#navigationBars`" - errorLine1=" WindowInsets.Type.navigationBars());" - errorLine2=" ~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="158" - column="39"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`" - errorLine1=" int newInsetLeft = mInsets.left;" - errorLine2=" ~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="159" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`" - errorLine1=" int newInsetRight = mInsets.right;" - errorLine2=" ~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="160" - column="33"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`" - errorLine1=" mPositionRect.left -= navBarInsets.left;" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="162" - column="39"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`" - errorLine1=" newInsetLeft -= navBarInsets.left;" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="163" - column="33"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`" - errorLine1=" mPositionRect.right += navBarInsets.right;" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="165" - column="40"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`" - errorLine1=" newInsetRight -= navBarInsets.right;" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="166" - column="34"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.graphics.Insets#of`" - errorLine1=" mInsets = Insets.of(newInsetLeft, mInsets.top, newInsetRight, mInsets.bottom);" - errorLine2=" ~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="168" - column="30"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#bottom`" - errorLine1=" mInsets = Insets.of(newInsetLeft, mInsets.top, newInsetRight, mInsets.bottom);" - errorLine2=" ~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="168" - column="75"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`" - errorLine1=" mInsets = Insets.of(newInsetLeft, mInsets.top, newInsetRight, mInsets.bottom);" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="168" - column="47"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `new android.graphics.PointF`" - errorLine1=" mRestingStackPosition = new PointF(position);" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java" - line="229" - column="37"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.View#getAnimationMatrix`" - errorLine1=" pw.println(mExpandedViewContainer.getAnimationMatrix());" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="295" - column="43"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.View#setSystemGestureExclusionRects`" - errorLine1=" mBubbleContainer.setSystemGestureExclusionRects(mSystemGestureExclusionRects);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="1427" - column="30"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.View#setSystemGestureExclusionRects`" - errorLine1=" mBubbleContainer.setSystemGestureExclusionRects(Collections.emptyList());" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="1430" - column="30"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`" - errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix))" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="1750" - column="48"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`" - errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix))" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="1775" - column="48"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`" - errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="1863" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`" - errorLine1=" mExpandedViewContainer.setAnimationMatrix(" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="1894" - column="48"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`" - errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="1986" - column="44"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`" - errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="2074" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`" - errorLine1=" mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix);" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="2091" - column="48"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.View#setAnimationMatrix`" - errorLine1=" mExpandedViewContainer.setAnimationMatrix(null);" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="2118" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`" - errorLine1=" int leftPadding = insets.left + mExpandedViewPadding;" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="2696" - column="27"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`" - errorLine1=" int rightPadding = insets.right + mExpandedViewPadding;" - errorLine2=" ~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java" - line="2697" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getType`" - errorLine1=" if (icon.getType() == Icon.TYPE_URI || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) {" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java" - line="220" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getType`" - errorLine1=" if (icon.getType() == Icon.TYPE_URI || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) {" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java" - line="220" - column="53"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.graphics.drawable.Icon#getUri`" - errorLine1=" icon.getUri(), Intent.FLAG_GRANT_READ_URI_PERMISSION);" - errorLine2=" ~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java" - line="222" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java" - line="119" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, transformation.getAlpha());" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java" - line="237" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java" - line="239" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java" - line="279" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#ime`" - errorLine1=" if ((types & WindowInsets.Type.ime()) == 0) {" - errorLine2=" ~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java" - line="285" - column="44"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#ime`" - errorLine1=" if ((types & WindowInsets.Type.ime()) == 0) {" - errorLine2=" ~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java" - line="294" - column="44"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(mImeSourceControl.getLeash(), alpha);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java" - line="396" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java" - line="398" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(mImeSourceControl.getLeash(), alpha);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java" - line="420" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java" - line="424" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(mImeSourceControl.getLeash(), 1.f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java" - line="439" - column="27"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayImeController.java" - line="446" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.view.DisplayCutout#getSafeInsetLeft`" - errorLine1=" outInsets.left += displayCutout.getSafeInsetLeft();" - errorLine2=" ~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="313" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.view.DisplayCutout#getSafeInsetTop`" - errorLine1=" outInsets.top += displayCutout.getSafeInsetTop();" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="314" - column="44"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.view.DisplayCutout#getSafeInsetRight`" - errorLine1=" outInsets.right += displayCutout.getSafeInsetRight();" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="315" - column="46"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 28 (current min is 26): `android.view.DisplayCutout#getSafeInsetBottom`" - errorLine1=" outInsets.bottom += displayCutout.getSafeInsetBottom();" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="316" - column="47"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.DisplayCutout#getWaterfallInsets`" - errorLine1=" final Insets waterfallInsets = rotateInsets(cutout.getWaterfallInsets(), rotation);" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="358" - column="60"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.DisplayCutout#getWaterfallInsets`" - errorLine1=" int leftInset = Math.max(cutout.getWaterfallInsets().left," - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="405" - column="41"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`" - errorLine1=" int leftInset = Math.max(cutout.getWaterfallInsets().left," - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="405" - column="34"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.DisplayCutout#getBoundingRectLeft`" - errorLine1=" findCutoutInsetForSide(displaySize, cutout.getBoundingRectLeft(), Gravity.LEFT));" - errorLine2=" ~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="406" - column="60"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.DisplayCutout#getWaterfallInsets`" - errorLine1=" int topInset = Math.max(cutout.getWaterfallInsets().top," - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="407" - column="40"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`" - errorLine1=" int topInset = Math.max(cutout.getWaterfallInsets().top," - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="407" - column="33"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.DisplayCutout#getBoundingRectTop`" - errorLine1=" findCutoutInsetForSide(displaySize, cutout.getBoundingRectTop(), Gravity.TOP));" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="408" - column="60"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.DisplayCutout#getWaterfallInsets`" - errorLine1=" int rightInset = Math.max(cutout.getWaterfallInsets().right," - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="409" - column="42"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`" - errorLine1=" int rightInset = Math.max(cutout.getWaterfallInsets().right," - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="409" - column="35"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.DisplayCutout#getBoundingRectRight`" - errorLine1=" findCutoutInsetForSide(displaySize, cutout.getBoundingRectRight(), Gravity.RIGHT));" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="410" - column="60"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.DisplayCutout#getWaterfallInsets`" - errorLine1=" int bottomInset = Math.max(cutout.getWaterfallInsets().bottom," - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="411" - column="43"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#bottom`" - errorLine1=" int bottomInset = Math.max(cutout.getWaterfallInsets().bottom," - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="411" - column="36"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.DisplayCutout#getBoundingRectBottom`" - errorLine1=" findCutoutInsetForSide(displaySize, cutout.getBoundingRectBottom()," - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java" - line="412" - column="60"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java" - line="343" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java" - line="359" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java" - line="406" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java" - line="731" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java" - line="800" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java" - line="878" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(dim, alpha);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java" - line="1065" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java" - line="1106" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java" - line="1171" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`" - errorLine1=" mLp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerWindowManager.java" - line="64" - column="9"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java" - line="73" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#createWindowContext`" - errorLine1=" .createWindowContext(TYPE_APPLICATION_OVERLAY, null);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java" - line="89" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`" - errorLine1=" layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java" - line="101" - column="9"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsTypes`" - errorLine1=" layoutParams.setFitInsetsTypes(0);" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java" - line="102" - column="22"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`" - errorLine1=" mTransaction.reparent(dragSurface, null);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java" - line="229" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" mTransaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java" - line="230" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`" - errorLine1=" final int iw = w - insets.left - insets.right;" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java" - line="126" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#right`" - errorLine1=" final int iw = w - insets.left - insets.right;" - errorLine2=" ~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java" - line="126" - column="42"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#bottom`" - errorLine1=" final int ih = h - insets.top - insets.bottom;" - errorLine2=" ~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java" - line="127" - column="41"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`" - errorLine1=" final int ih = h - insets.top - insets.bottom;" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java" - line="127" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#left`" - errorLine1=" final int l = insets.left;" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java" - line="128" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`" - errorLine1=" final int t = insets.top;" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java" - line="129" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" runningTaskId = task.taskId;" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropPolicy.java" - line="279" - column="33"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#NONE`" - errorLine1=" private Insets mInsets = Insets.NONE;" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java" - line="59" - column="30"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets#getInsets`" - errorLine1=" mInsets = insets.getInsets(Type.systemBars() | Type.displayCutout());" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java" - line="76" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#displayCutout`" - errorLine1=" mInsets = insets.getInsets(Type.systemBars() | Type.displayCutout());" - errorLine2=" ~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java" - line="76" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#systemBars`" - errorLine1=" mInsets = insets.getInsets(Type.systemBars() | Type.displayCutout());" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragLayout.java" - line="76" - column="41"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 31 (current min is 26): `com.google.android.collect.Sets#newHashSet`" - errorLine1=" return Sets.newHashSet(" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java" - line="498" - column="21"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (mLeashByTaskId.get(taskInfo.taskId) != null) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="53" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" throw new IllegalStateException("Task appeared more than once: #" + taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="54" - column="81"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, -1501874464, 1, null, protoLogParam0); " - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="56" - column="113"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mLeashByTaskId.put(taskInfo.taskId, leash);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="58" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, 1f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="66" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="75" - column="57"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (mLeashByTaskId.get(taskInfo.taskId) == null) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="88" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" Slog.e(TAG, "Task already vanished: #" + taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="89" - column="54"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mLeashByTaskId.remove(taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="92" - column="31"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, 564235578, 1, null, protoLogParam0); " - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="93" - column="113"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`" - errorLine1=" if (!mLeashByTaskId.contains(taskId)) {" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="99" - column="29"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(mLeashByTaskId.get(taskId));" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/FullscreenTaskListener.java" - line="102" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.os.Handler#hasCallbacks`" - errorLine1=" return mHandler.hasCallbacks(r);" - errorLine2=" ~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/HandlerExecutor.java" - line="55" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" final SurfaceControl.Transaction t = new SurfaceControl.Transaction();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="86" - column="54"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="90" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" final SurfaceControl.Transaction tx = new SurfaceControl.Transaction();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="107" - column="47"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" final SurfaceControl.Transaction t = new SurfaceControl.Transaction();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="121" - column="50"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" final SurfaceControl.Transaction t = new SurfaceControl.Transaction();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="167" - column="46"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#NONE`" - errorLine1=" return Insets.NONE;" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="185" - column="20"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.Display#getCutout`" - errorLine1=" DisplayCutout cutout = display.getCutout();" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="187" - column="40"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.graphics.Insets#of`" - errorLine1=" Insets insets = cutout != null ? Insets.of(cutout.getSafeInsets()) : Insets.NONE;" - errorLine2=" ~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="188" - column="49"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#NONE`" - errorLine1=" Insets insets = cutout != null ? Insets.of(cutout.getSafeInsets()) : Insets.NONE;" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="188" - column="78"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 31 (current min is 26): `android.graphics.Rect#inset`" - errorLine1=" mCurrentDisplayBounds.inset(mCurrentCutoutInsets);" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="239" - column="35"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`" - errorLine1=" if (mCurrentCutoutInsets.top != 0) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="244" - column="17"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.Insets#top`" - errorLine1=" mCurrentDisplayBounds.top = Math.max(mStatusBarHeight, mCurrentCutoutInsets.top);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="245" - column="72"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/hidedisplaycutout/HideDisplayCutoutOrganizer.java" - line="287" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`" - errorLine1=" mContext.getResources().getFloat(" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenController.java" - line="465" - column="41"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { String protoLogParam0 = String.valueOf(TAG); long protoLogParam1 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -1362429294, 4, null, protoLogParam0, protoLogParam1); " - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="129" - column="166"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { String protoLogParam0 = String.valueOf(TAG); long protoLogParam1 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, 982027396, 4, null, protoLogParam0, protoLogParam1); " - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="134" - column="166"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { String protoLogParam0 = String.valueOf(TAG); long protoLogParam1 = taskInfo.taskId; long protoLogParam2 = winMode; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -298656957, 20, null, protoLogParam0, protoLogParam1, protoLogParam2); " - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="139" - column="166"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" .setParent(mPrimarySurface).setColorLayer()" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="150" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`" - errorLine1=" .setName("Primary Divider Dim")" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="151" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`" - errorLine1=" .build();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="153" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" .setParent(mSecondarySurface).setColorLayer()" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="155" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`" - errorLine1=" .setName("Secondary Divider Dim")" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="156" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`" - errorLine1=" .build();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="158" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(mPrimaryDim, Integer.MAX_VALUE);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="160" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(mSecondaryDim, Integer.MAX_VALUE);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="162" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="164" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mPositionByTaskId.remove(taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="173" - column="38"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mLeashByTaskId.remove(taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="175" - column="39"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="192" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (taskInfo.positionInParent.equals(mPositionByTaskId.get(taskInfo.taskId))) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="211" - column="76"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mPositionByTaskId.put(taskInfo.taskId, new Point(taskInfo.positionInParent));" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="218" - column="35"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mLeashByTaskId.put(taskInfo.taskId, leash);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="223" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mPositionByTaskId.put(taskInfo.taskId, new Point(taskInfo.positionInParent));" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="224" - column="31"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="231" - column="57"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, 1f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="242" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final SurfaceControl leash = mLeashByTaskId.get(taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="322" - column="65"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`" - errorLine1=" if (!mLeashByTaskId.contains(taskId)) {" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="339" - column="29"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(mLeashByTaskId.get(taskId));" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="342" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (mPrimary != null) pw.println(innerPrefix + "mPrimary.taskId=" + mPrimary.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="351" - column="77"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (mSecondary != null) pw.println(innerPrefix + "mSecondary.taskId=" + mSecondary.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTaskListener.java" - line="352" - column="81"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" && triggerTask.parentTaskId == mListener.mPrimary.taskId)" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="94" - column="64"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" transaction.setAlpha(leash, start * (1.f - fraction) + end * fraction);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="132" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" transaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="133" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" transaction.setAlpha(leash, end);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="136" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" transaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="137" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" transaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="180" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" transaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="185" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(parentChange.getLeash(), 1.f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="245" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`" - errorLine1=" t.reparent(leash, info.getRootLeash());" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="248" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(leash, info.getChanges().size() - i);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="249" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`" - errorLine1=" mFinishTransaction.reparent(leash, parentChange.getLeash());" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="251" - column="40"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(leash, info.getChanges().size() + 1);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="281" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, 0.f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="294" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="316" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" mFinishTransaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java" - line="334" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.os.VibrationEffect#createPredefined`" - errorLine1=" vibrator.vibrate(VibrationEffect.createPredefined(effectId))" - errorLine2=" ~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/magnetictarget/MagnetizedObject.kt" - line="465" - column="46"/> - </issue> - - <issue - id="NewApi" - message="Method reference requires API level 29 (current min is 26): `SurfaceControl.Transaction::new`" - errorLine1=" mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java" - line="141" - column="49"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java" - line="286" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAnimationController.java" - line="295" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Method reference requires API level 29 (current min is 26): `SurfaceControl.Transaction::new`" - errorLine1=" mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java" - line="101" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" .setParent(mParentLeash)" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java" - line="152" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setBufferSize`" - errorLine1=" .setBufferSize(mBkgBounds.width(), mBkgBounds.height())" - errorLine2=" ~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java" - line="153" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setFormat`" - errorLine1=" .setFormat(PixelFormat.RGB_888)" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java" - line="155" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setOpaque`" - errorLine1=" .setOpaque(true)" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java" - line="156" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`" - errorLine1=" .setName("one-handed-background-panel")" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java" - line="157" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`" - errorLine1=" .build();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java" - line="159" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" transaction.setLayer(mBackgroundSurface, -1 /* at bottom-most layer */)" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java" - line="179" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" .apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java" - line="182" - column="22"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" transaction.remove(mBackgroundSurface).apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java" - line="197" - column="52"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.accessibility.AccessibilityManager#getRecommendedTimeoutMillis`" - errorLine1=" .getRecommendedTimeoutMillis(mOneHandedTimeout * 1000" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java" - line="150" - column="34"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.os.RemoteException#rethrowFromSystemServer`" - errorLine1=" throw e.rethrowFromSystemServer();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java" - line="574" - column="21"/> - </issue> - - <issue - id="NewApi" - message="Method reference requires API level 29 (current min is 26): `SurfaceControl.Transaction::new`" - errorLine1=" mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java" - line="130" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java" - line="241" - column="12"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" tx.setAlpha(leash, alpha);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSurfaceTransactionHelper.java" - line="57" - column="12"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager#getCurrentWindowMetrics`" - errorLine1=" mDisplaySize = windowManager.getCurrentWindowMetrics().getBounds();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java" - line="101" - column="38"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getBounds`" - errorLine1=" mDisplaySize = windowManager.getCurrentWindowMetrics().getBounds();" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java" - line="101" - column="64"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsTypes`" - errorLine1=" lp.setFitInsetsTypes(0 /* types */);" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java" - line="200" - column="12"/> - </issue> - - <issue - id="NewApi" - message="Method reference requires API level 29 (current min is 26): `SurfaceControl.Transaction::new`" - errorLine1=" mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java" - line="244" - column="49"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java" - line="399" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java" - line="413" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java" - line="499" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java" - line="518" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java" - line="532" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`" - errorLine1=" mDefaultAspectRatio = res.getFloat(" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java" - line="77" - column="35"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`" - errorLine1=" mMinAspectRatio = res.getFloat(" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java" - line="93" - column="31"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`" - errorLine1=" mMaxAspectRatio = res.getFloat(" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java" - line="95" - column="31"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`" - errorLine1=" mDefaultSizePercent = res.getFloat(" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java" - line="97" - column="35"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`" - errorLine1=" mMaxAspectRatioForMinSize = res.getFloat(" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsAlgorithm.java" - line="99" - column="41"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`" - errorLine1=" mPipBoundsState.setDisplayLayout(new DisplayLayout(mContext, mContext.getDisplay()));" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java" - line="337" - column="79"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`" - errorLine1=" onDisplayChanged(new DisplayLayout(mContext, mContext.getDisplay())," - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java" - line="428" - column="63"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`" - errorLine1=" lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java" - line="247" - column="9"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsTypes`" - errorLine1=" lp.setFitInsetsTypes(0 /* types */);" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipDismissTargetHandler.java" - line="248" - column="12"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.accessibility.AccessibilityManager#getRecommendedTimeoutMillis`" - errorLine1=" int recommendedTimeout = mAccessibilityManager.getRecommendedTimeoutMillis(delay," - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java" - line="506" - column="56"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`" - errorLine1=" mContext.getDisplay().getRealSize(mMaxSize);" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java" - line="142" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`" - errorLine1=" mDownPoint.set(ev.getRawX(mFirstIndex), ev.getRawY(mFirstIndex));" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java" - line="388" - column="35"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`" - errorLine1=" mDownPoint.set(ev.getRawX(mFirstIndex), ev.getRawY(mFirstIndex));" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java" - line="388" - column="60"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`" - errorLine1=" mDownSecondPoint.set(ev.getRawX(mSecondIndex), ev.getRawY(mSecondIndex));" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java" - line="389" - column="41"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`" - errorLine1=" mDownSecondPoint.set(ev.getRawX(mSecondIndex), ev.getRawY(mSecondIndex));" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java" - line="389" - column="67"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`" - errorLine1=" float x0 = ev.getRawX(mFirstIndex);" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java" - line="403" - column="27"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`" - errorLine1=" float y0 = ev.getRawY(mFirstIndex);" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java" - line="404" - column="27"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`" - errorLine1=" float x1 = ev.getRawX(mSecondIndex);" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java" - line="405" - column="27"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`" - errorLine1=" float y1 = ev.getRawY(mSecondIndex);" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java" - line="406" - column="27"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" tx.setAlpha(leash, alpha);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java" - line="66" - column="12"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 31 (current min is 26): `android.graphics.Matrix#IDENTITY_MATRIX`" - errorLine1=" tx.setMatrix(leash, Matrix.IDENTITY_MATRIX, mTmpFloat9)" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java" - line="166" - column="29"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`" - errorLine1=" t.reparent(snapshot, parent);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java" - line="188" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(snapshot, Integer.MAX_VALUE);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java" - line="189" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java" - line="191" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Method reference requires API level 29 (current min is 26): `SurfaceControl.Transaction::new`" - errorLine1=" mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="238" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)" - errorLine1=" .getAnimator(mTaskInfo, mLeash, mPipBoundsState.getBounds(), 1f, 0f)" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="397" - column="30"/> - </issue> - - <issue - id="NewApi" - message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)" - errorLine1=" mPipUiEventLoggerLogger.setTaskInfo(mTaskInfo);" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="431" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" tx.setAlpha(mLeash, 0f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="462" - column="16"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="464" - column="16"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" tx.setAlpha(mLeash, 0f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="502" - column="12"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="503" - column="12"/> - </issue> - - <issue - id="NewApi" - message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)" - errorLine1=" .getAnimator(mTaskInfo, mLeash, destinationBounds, 0f, 1f)" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="506" - column="34"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="820" - column="16"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="858" - column="16"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" transaction.setAlpha(snapshotSurface, alpha);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="991" - column="33"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" transaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="992" - column="33"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="1000" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)" - errorLine1=" .getAnimator(mTaskInfo, mLeash, baseBounds, currentBounds, destinationBounds," - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java" - line="1082" - column="30"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`" - errorLine1=" mContext.getDisplay().getRealSize(displaySize);" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java" - line="380" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`" - errorLine1=" int displayRotation = mContext.getDisplay().getRotation();" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java" - line="674" - column="52"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`" - errorLine1=" float x = ev.getRawX(pointerIndex);" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java" - line="138" - column="30"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`" - errorLine1=" float y = ev.getRawY(pointerIndex);" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java" - line="139" - column="30"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`" - errorLine1=" mLastTouch.set(ev.getRawX(newPointerIndex), ev.getRawY(newPointerIndex));" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java" - line="174" - column="39"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`" - errorLine1=" mLastTouch.set(ev.getRawX(newPointerIndex), ev.getRawY(newPointerIndex));" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java" - line="174" - column="68"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawX`" - errorLine1=" mLastTouch.set(ev.getRawX(pointerIndex), ev.getRawY(pointerIndex));" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java" - line="197" - column="35"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.MotionEvent#getRawY`" - errorLine1=" mLastTouch.set(ev.getRawX(pointerIndex), ev.getRawY(pointerIndex));" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java" - line="197" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)" - errorLine1=" return startEnterAnimation(change.getTaskInfo(), change.getLeash(), t);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java" - line="79" - column="44"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`" - errorLine1=" setBoundsStateForEntry(taskInfo.topActivity, taskInfo.pictureInPictureParams," - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java" - line="105" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, 0f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java" - line="118" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java" - line="119" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`" - errorLine1=" if (taskInfo != null && taskInfo.topActivity != null) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java" - line="44" - column="33"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`" - errorLine1=" mPackageName = taskInfo.topActivity.getPackageName();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java" - line="45" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(sc);" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/RootTaskDisplayAreaOrganizer.java" - line="97" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#baseIntent`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = info.getTaskInfo().taskId; String protoLogParam1 = String.valueOf(info.getTaskInfo().baseIntent); com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -1683614271, 1, null, protoLogParam0, protoLogParam1); " - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="168" - column="187"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = info.getTaskInfo().taskId; String protoLogParam1 = String.valueOf(info.getTaskInfo().baseIntent); com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -1683614271, 1, null, protoLogParam0, protoLogParam1); " - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="168" - column="121"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = info.getTaskInfo().taskId;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="333" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)" - errorLine1=" notifyLocusVisibilityIfNeeded(info.getTaskInfo());" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="341" - column="39"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, 157713005, 1, null, protoLogParam0); }" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="348" - column="117"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final TaskAppearedInfo data = mTasks.get(taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="349" - column="54"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mTasks.put(taskInfo.taskId, new TaskAppearedInfo(taskInfo, data.getLeash()));" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="352" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)" - errorLine1=" notifyLocusVisibilityIfNeeded(taskInfo);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="358" - column="43"/> - </issue> - - <issue - id="NewApi" - message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)" - errorLine1=" if (updated || !taskInfo.equalsForSizeCompat(data.getTaskInfo())) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="359" - column="58"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, 980952660, 1, null, protoLogParam0); }" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="369" - column="117"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TASK_ORG_enabled) { long protoLogParam0 = taskInfo.taskId; com.android.wm.shell.protolog.ShellProtoLogImpl.v(WM_SHELL_TASK_ORG, -880817403, 1, null, protoLogParam0); }" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="380" - column="117"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = taskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="381" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Cast from `RunningTaskInfo` to `TaskInfo` requires API level 29 (current min is 26)" - errorLine1=" notifyLocusVisibilityIfNeeded(taskInfo);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="387" - column="43"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskId`" - errorLine1=" final int taskId = taskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="417" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskId`" - errorLine1=" mVisibleTasksWithLocusId.remove(taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="437" - column="49"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mSizeCompatUI.onSizeCompatInfoChanged(taskInfo.displayId, taskInfo.taskId," - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="466" - column="71"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mSizeCompatUI.onSizeCompatInfoChanged(taskInfo.displayId, taskInfo.taskId," - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="472" - column="67"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = runningTaskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java" - line="483" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`" - errorLine1=" } else if (mActiveLayouts.contains(taskId)) {" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIController.java" - line="96" - column="35"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(leash, Integer.MAX_VALUE);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUILayout.java" - line="314" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`" - errorLine1=" .setName("SizeCompatUILeash")" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java" - line="63" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`" - errorLine1=" mLeash = builder.build();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java" - line="67" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(mLeash);" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java" - line="68" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`" - errorLine1=" mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java" - line="78" - column="67"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`" - errorLine1=" mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java" - line="94" - column="67"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#release`" - errorLine1=" mViewHost.release();" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java" - line="108" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" new SurfaceControl.Transaction().remove(mLeash).apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java" - line="113" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" new SurfaceControl.Transaction().remove(mLeash).apply();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUIWindowManager.java" - line="113" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 31 (current min is 26): `android.window.SplashScreenView#getIconView`" - errorLine1=" final View iconView = mSplashScreenView.getIconView();" - errorLine2=" ~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java" - line="158" - column="49"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.graphics.Paint#setBlendMode`" - errorLine1=" mVanishPaint.setBlendMode(BlendMode.MODULATE);" - errorLine2=" ~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java" - line="247" - column="30"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.graphics.BlendMode#MODULATE`" - errorLine1=" mVanishPaint.setBlendMode(BlendMode.MODULATE);" - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java" - line="247" - column="43"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java" - line="284" - column="16"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" tx.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java" - line="303" - column="16"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#release`" - errorLine1=" mFirstWindowSurface.release();" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashScreenExitAnimation.java" - line="304" - column="33"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager#getMaximumWindowMetrics`" - errorLine1=" .getMaximumWindowMetrics()" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java" - line="256" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowMetrics#getWindowInsets`" - errorLine1=" .getWindowInsets()" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java" - line="257" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets#getInsets`" - errorLine1=" .getInsets(WindowInsets.Type.navigationBars()" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java" - line="258" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#navigationBars`" - errorLine1=" .getInsets(WindowInsets.Type.navigationBars()" - errorLine2=" ~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java" - line="258" - column="46"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#statusBars`" - errorLine1=" | WindowInsets.Type.statusBars()" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java" - line="259" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#displayCutout`" - errorLine1=" | WindowInsets.Type.displayCutout()).toRect();" - errorLine2=" ~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java" - line="260" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(parentChange.getLeash(), 1.f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="116" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`" - errorLine1=" t.reparent(leash, info.getRootLeash());" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="119" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(leash, info.getChanges().size() - i);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="120" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`" - errorLine1=" mFinishTransaction.reparent(leash, parentChange.getLeash());" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="122" - column="40"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, 0.f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="158" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="164" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" mFinishTransaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="198" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" transaction.setAlpha(leash, start * (1.f - fraction) + end * fraction);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="222" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" transaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="223" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" transaction.setAlpha(leash, end);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="226" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" transaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="227" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" transaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="270" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" transaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenTransitions.java" - line="275" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`" - errorLine1=" .setName(TAG)" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java" - line="101" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`" - errorLine1=" mLeash = builder.build();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java" - line="105" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(mLeash);" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java" - line="106" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`" - errorLine1=" mViewHost = new SurfaceControlViewHost(mContext, mContext.getDisplay(), this);" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java" - line="116" - column="67"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#release`" - errorLine1=" mViewHost.release();" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java" - line="145" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" new SurfaceControl.Transaction().remove(mLeash).apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java" - line="150" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" new SurfaceControl.Transaction().remove(mLeash).apply();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitWindowManager.java" - line="150" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 31 (current min is 26): `com.google.android.collect.Sets#newHashSet`" - errorLine1=" return Sets.newHashSet(" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java" - line="692" - column="21"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" .setLayer(dividerLeash, Integer.MAX_VALUE)" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="399" - column="30"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" .setLayer(dividerLeash, Integer.MAX_VALUE)" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="515" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" && taskInfo.parentTaskId == mMainStage.mRootTaskInfo.taskId) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="570" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" && taskInfo.parentTaskId == mSideStage.mRootTaskInfo.taskId) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="573" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (com.android.wm.shell.protolog.ShellProtoLogCache.WM_SHELL_TRANSITIONS_enabled) { long protoLogParam0 = triggerTask.taskId; String protoLogParam1 = String.valueOf(transitTypeToString(type)); long protoLogParam2 = mMainStage.getChildCount(); long protoLogParam3 = mSideStage.getChildCount(); com.android.wm.shell.protolog.ShellProtoLogImpl.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, 165317020, 81, " split is active so using split" + "Transition to handle request. triggerTask=%d type=%s mainChildren=%d" + " sideChildren=%d", protoLogParam0, protoLogParam1, protoLogParam2, protoLogParam3); " - errorLine2=" ~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="597" - column="120"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (!stage.containsTask(taskInfo.taskId)) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="655" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" + " with " + taskInfo.taskId + " before startAnimation().");" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="657" - column="46"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (stage.containsTask(taskInfo.taskId)) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="660" - column="44"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" + " with " + taskInfo.taskId + " before startAnimation().");" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="662" - column="46"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (!mMainStage.containsTask(mainChild.getTaskInfo().taskId)) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="732" - column="42"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" + " to have been called with " + mainChild.getTaskInfo().taskId" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="734" - column="58"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (!mSideStage.containsTask(sideChild.getTaskInfo().taskId)) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="737" - column="42"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" + " to have been called with " + sideChild.getTaskInfo().taskId" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="739" - column="58"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, 1.f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="820" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(leash, Integer.MAX_VALUE);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java" - line="821" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`" - errorLine1=" return mChildrenTaskInfo.contains(taskId);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="85" - column="34"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" } else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="96" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = taskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="97" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (mRootTaskInfo.taskId == taskInfo.taskId) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="116" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (mRootTaskInfo.taskId == taskInfo.taskId) {" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="116" - column="37"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" } else if (taskInfo.parentTaskId == mRootTaskInfo.taskId) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="118" - column="45"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mChildrenTaskInfo.put(taskInfo.taskId, taskInfo);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="119" - column="35"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mCallbacks.onChildTaskStatusChanged(taskInfo.taskId, true /* present */," - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="120" - column="49"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" taskInfo, mChildrenLeashes.get(taskInfo.taskId), false /* firstAppeared */);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="124" - column="56"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = taskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="140" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (mRootTaskInfo.taskId == taskId) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="141" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`" - errorLine1=" } else if (mChildrenTaskInfo.contains(taskId)) {" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="144" - column="38"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (mRootTaskInfo.taskId == taskId) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="161" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(mRootLeash);" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="162" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.util.SparseArray#contains`" - errorLine1=" } else if (mChildrenLeashes.contains(taskId)) {" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="163" - column="37"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(mChildrenLeashes.get(taskId));" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="164" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, 1f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java" - line="194" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = taskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java" - line="131" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" + Integer.toHexString(theme) + " task= " + taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java" - line="141" - column="64"/> - </issue> - - <issue - id="NewApi" - message="Cast from `SplashScreenView` to `View` requires API level 31 (current min is 26)" - errorLine1=" win.setContentView(sView);" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java" - line="280" - column="40"/> - </issue> - - <issue - id="NewApi" - message="Cast from `SplashScreenView` to `View` requires API level 31 (current min is 26)" - errorLine1=" win.setContentView(sView);" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java" - line="284" - column="40"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = startingWindowInfo.taskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java" - line="309" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final TaskSnapshot snapshot = getTaskSnapshot(windowInfo.taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java" - line="162" - column="63"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" Slog.d(TAG, "isSnapshotCompatible no snapshot " + windowInfo.taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java" - line="180" - column="71"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" mTaskLaunchingCallback.accept(runningTaskInfo.taskId, suggestionType);" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java" - line="238" - column="47"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" mInFlight.onTransactionReady(mInFlight.mId, new SurfaceControl.Transaction());" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java" - line="55" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java" - line="114" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java" - line="125" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.SurfaceControlViewHost#release`" - errorLine1=" root.release();" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java" - line="121" - column="14"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`" - errorLine1=" .setName("SystemWindowLeash")" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java" - line="278" - column="20"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" .setParent(mRootSurface)" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java" - line="280" - column="20"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`" - errorLine1=" .setCallsite("SysUiWIndowManager#attachToParentSurface").build();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java" - line="281" - column="76"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(leash);" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java" - line="285" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" new SurfaceControl.Transaction().remove(mLeashForWindow.get(token))" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java" - line="293" - column="17"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" .apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/SystemWindows.java" - line="294" - column="22"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = runningTaskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="151" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`" - errorLine1=" layoutParams.layoutInDisplayCutoutMode = attrs.layoutInDisplayCutoutMode;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="186" - column="9"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 28 (current min is 26): `android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode`" - errorLine1=" layoutParams.layoutInDisplayCutoutMode = attrs.layoutInDisplayCutoutMode;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="186" - column="50"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#getFitInsetsTypes`" - errorLine1=" layoutParams.setFitInsetsTypes(attrs.getFitInsetsTypes());" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="187" - column="46"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsTypes`" - errorLine1=" layoutParams.setFitInsetsTypes(attrs.getFitInsetsTypes());" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="187" - column="22"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#getFitInsetsSides`" - errorLine1=" layoutParams.setFitInsetsSides(attrs.getFitInsetsSides());" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="188" - column="46"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsSides`" - errorLine1=" layoutParams.setFitInsetsSides(attrs.getFitInsetsSides());" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="188" - column="22"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#isFitInsetsIgnoringVisibility`" - errorLine1=" layoutParams.setFitInsetsIgnoringVisibility(attrs.isFitInsetsIgnoringVisibility());" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="189" - column="59"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowManager.LayoutParams#setFitInsetsIgnoringVisibility`" - errorLine1=" layoutParams.setFitInsetsIgnoringVisibility(attrs.isFitInsetsIgnoringVisibility());" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="189" - column="22"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`" - errorLine1=" if (runningTaskInfo.taskDescription != null) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="208" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`" - errorLine1=" taskDescription = runningTaskInfo.taskDescription;" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="209" - column="31"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" mTransaction = new SurfaceControl.Transaction();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="271" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.view.WindowInsets.Type#systemBars`" - errorLine1=" return state.calculateInsets(frame, WindowInsets.Type.systemBars()," - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="328" - column="63"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setName`" - errorLine1=" .setName(mTitle + " - task-snapshot-surface")" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="374" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setBufferSize`" - errorLine1=" .setBufferSize(buffer.getWidth(), buffer.getHeight())" - errorLine2=" ~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="375" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setFormat`" - errorLine1=" .setFormat(buffer.getFormat())" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="376" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" .setParent(mSurfaceControl)" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="377" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#build`" - errorLine1=" .build();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="379" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" mTransaction.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="406" - column="22"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 31 (current min is 26): `android.graphics.Rect#inset`" - errorLine1=" rect.inset((int) (insets.left * scaleX)," - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java" - line="435" - column="14"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" onTaskMovedToFront(taskInfo.taskId);" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/TaskStackListenerCallback.java" - line="52" - column="28"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `new android.util.CloseGuard`" - errorLine1=" private final CloseGuard mGuard = new CloseGuard();" - errorLine2=" ~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="73" - column="39"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" private final SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="81" - column="61"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.util.CloseGuard#open`" - errorLine1=" mGuard.open("release");" - errorLine2=" ~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="99" - column="16"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.util.CloseGuard#warnIfOpen`" - errorLine1=" mGuard.warnIfOpen();" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="204" - column="24"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.util.CloseGuard#close`" - errorLine1=" mGuard.close();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="218" - column="16"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = mTaskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="239" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`" - errorLine1=" mTransaction.reparent(mTaskLeash, getSurfaceControl())" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="255" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceView#getSurfaceControl`" - errorLine1=" mTransaction.reparent(mTaskLeash, getSurfaceControl())" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="255" - column="47"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" .apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="257" - column="22"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`" - errorLine1=" if (taskInfo.taskDescription != null) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="266" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`" - errorLine1=" setResizeBackgroundColor(taskInfo.taskDescription.getBackgroundColor());" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="267" - column="38"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = taskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="271" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = taskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="284" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" mTransaction.reparent(mTaskLeash, null).apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="292" - column="49"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`" - errorLine1=" mTransaction.reparent(mTaskLeash, null).apply();" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="292" - column="22"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`" - errorLine1=" if (taskInfo.taskDescription != null) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="298" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskDescription`" - errorLine1=" setResizeBackgroundColor(taskInfo.taskDescription.getBackgroundColor());" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="299" - column="38"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" final int taskId = taskInfo.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="307" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" if (mTaskInfo.taskId != taskId) {" - errorLine2=" ~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="316" - column="13"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Builder#setParent`" - errorLine1=" b.setParent(mTaskLeash);" - errorLine2=" ~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="319" - column="11"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.ActivityManager.RunningTaskInfo#taskId`" - errorLine1=" return "TaskView" + ":" + (mTaskInfo != null ? mTaskInfo.taskId : "null");" - errorLine2=" ~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="331" - column="56"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`" - errorLine1=" mTransaction.reparent(mTaskLeash, getSurfaceControl())" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="349" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceView#getSurfaceControl`" - errorLine1=" mTransaction.reparent(mTaskLeash, getSurfaceControl())" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="349" - column="47"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" .apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="351" - column="22"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" mTransaction.reparent(mTaskLeash, null).apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="374" - column="53"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`" - errorLine1=" mTransaction.reparent(mTaskLeash, null).apply();" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java" - line="374" - column="26"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" return new SurfaceControl.Transaction();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/TransactionPool.java" - line="36" - column="20"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.content.res.Resources#getFloat`" - errorLine1=" context.getResources().getFloat(" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="117" - column="40"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`" - errorLine1=" if (info.getRootLeash().isValid()) {" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="231" - column="33"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, 1.f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="247" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#reparent`" - errorLine1=" t.reparent(leash, info.getRootLeash());" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="256" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(leash, zSplitLine + info.getChanges().size() - i);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="266" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, 1.f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="270" - column="27"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, 0.f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="272" - column="27"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(leash, zSplitLine - i);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="276" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setAlpha`" - errorLine1=" t.setAlpha(leash, 1.f);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="277" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(leash, zSplitLine - i);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="282" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(leash, zSplitLine + info.getChanges().size() - i);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="285" - column="23"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#setLayer`" - errorLine1=" t.setLayer(leash, zSplitLine + info.getChanges().size() - i);" - errorLine2=" ~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="288" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`" - errorLine1=" if (!info.getRootLeash().isValid()) {" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="304" - column="34"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java" - line="309" - column="15"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.graphics.Outline#setPath`" - errorLine1=" outline.setPath(mTriangularPath);" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/common/TriangleShape.java" - line="75" - column="17"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`" - errorLine1=" mPipBoundsState.setDisplayLayout(new DisplayLayout(context, context.getDisplay()));" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java" - line="147" - column="77"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#taskId`" - errorLine1=" mPinnedTaskId = pinnedTask.taskId;" - errorLine2=" ~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java" - line="283" - column="25"/> - </issue> - - <issue - id="NewApi" - message="Field requires API level 29 (current min is 26): `android.app.TaskInfo#topActivity`" - errorLine1=" mPipNotificationController.show(pinnedTask.topActivity.getPackageName());" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java" - line="287" - column="41"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level R (current min is 26): `android.content.Context#getDisplay`" - errorLine1=" mContext.getDisplay().getDisplayInfo(displayInfo);" - errorLine2=" ~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipController.java" - line="348" - column="18"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" SurfaceControl.Transaction t = new SurfaceControl.Transaction();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java" - line="134" - column="48"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl.Transaction#apply`" - errorLine1=" t.apply();" - errorLine2=" ~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuController.java" - line="136" - column="19"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `android.view.SurfaceControl#isValid`" - errorLine1=" if (out != null && out.isValid()) {" - errorLine2=" ~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/TvPipMenuView.java" - line="188" - column="32"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 29 (current min is 26): `new android.view.SurfaceControl.Transaction`" - errorLine1=" final SurfaceControl.Transaction sft = new SurfaceControl.Transaction();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="out/.intermediates/frameworks/base/libs/WindowManager/Shell/wm_shell_protolog_src/gen/wm_shell_protolog.srcjar!/frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/WindowManagerProxy.java" - line="326" - column="56"/> - </issue> - - <issue - id="NewApi" - message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)" - errorLine1=" android:bottomLeftRadius="?android:attr/dialogCornerRadius"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/libs/WindowManager/Shell/res/drawable/rounded_bg_full.xml" - line="21" - column="9"/> - </issue> - - <issue - id="NewApi" - message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)" - errorLine1=" android:topLeftRadius="?android:attr/dialogCornerRadius"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/libs/WindowManager/Shell/res/drawable/rounded_bg_full.xml" - line="22" - column="9"/> - </issue> - - <issue - id="NewApi" - message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)" - errorLine1=" android:bottomRightRadius="?android:attr/dialogCornerRadius"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/libs/WindowManager/Shell/res/drawable/rounded_bg_full.xml" - line="23" - column="9"/> - </issue> - - <issue - id="NewApi" - message="`?android:attr/dialogCornerRadius` requires API level 28 (current min is 26)" - errorLine1=" android:topRightRadius="?android:attr/dialogCornerRadius"" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="frameworks/base/libs/WindowManager/Shell/res/drawable/rounded_bg_full.xml" - line="24" - column="9"/> - </issue> - -</issues> diff --git a/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml b/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml index 8224d95fd9ad..270186a199bb 100644 --- a/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml +++ b/libs/WindowManager/Shell/res/layout/bubble_overflow_container.xml @@ -27,24 +27,26 @@ <androidx.recyclerview.widget.RecyclerView android:id="@+id/bubble_overflow_recycler" - android:layout_gravity="center_horizontal" android:nestedScrollingEnabled="false" - android:layout_width="wrap_content" - android:layout_height="wrap_content"/> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center_horizontal" + android:gravity="center"/> <LinearLayout android:id="@+id/bubble_overflow_empty_state" - android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:visibility="gone" + android:layout_width="match_parent" + android:layout_height="match_parent" android:paddingLeft="@dimen/bubble_overflow_empty_state_padding" android:paddingRight="@dimen/bubble_overflow_empty_state_padding" android:orientation="vertical" android:gravity="center"> <ImageView + android:id="@+id/bubble_overflow_empty_state_image" android:layout_width="@dimen/bubble_empty_overflow_image_height" android:layout_height="@dimen/bubble_empty_overflow_image_height" - android:id="@+id/bubble_overflow_empty_state_image" android:scaleType="fitCenter" android:layout_gravity="center"/> @@ -60,12 +62,12 @@ <TextView android:id="@+id/bubble_overflow_empty_subtitle" + android:layout_width="match_parent" + android:layout_height="wrap_content" android:fontFamily="@*android:string/config_bodyFontFamily" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2" android:textColor="?android:attr/textColorSecondary" android:text="@string/bubble_overflow_empty_subtitle" - android:layout_width="match_parent" - android:layout_height="wrap_content" android:paddingBottom="@dimen/bubble_empty_overflow_subtitle_padding" android:gravity="center"/> </LinearLayout> diff --git a/libs/WindowManager/Shell/res/layout/bubble_overflow_view.xml b/libs/WindowManager/Shell/res/layout/bubble_overflow_view.xml index c1f67bd27d93..d07107c8f0a0 100644 --- a/libs/WindowManager/Shell/res/layout/bubble_overflow_view.xml +++ b/libs/WindowManager/Shell/res/layout/bubble_overflow_view.xml @@ -32,12 +32,14 @@ android:id="@+id/bubble_view_name" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.ListItem" android:textSize="13sp" - android:layout_width="fill_parent" + android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxLines="1" android:lines="2" android:ellipsize="end" android:layout_gravity="center" android:paddingTop="@dimen/bubble_overflow_text_padding" + android:paddingEnd="@dimen/bubble_overflow_text_padding" + android:paddingStart="@dimen/bubble_overflow_text_padding" android:gravity="center"/> </LinearLayout> diff --git a/libs/WindowManager/Shell/res/layout/bubble_stack_user_education.xml b/libs/WindowManager/Shell/res/layout/bubble_stack_user_education.xml index fe1ed4b6f726..fe6a8bd7643d 100644 --- a/libs/WindowManager/Shell/res/layout/bubble_stack_user_education.xml +++ b/libs/WindowManager/Shell/res/layout/bubble_stack_user_education.xml @@ -38,6 +38,7 @@ android:gravity="start" android:textAlignment="viewStart" android:text="@string/bubbles_user_education_title" + android:textColor="?android:attr/textColorPrimaryInverse" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Headline"/> <TextView @@ -48,6 +49,7 @@ android:gravity="start" android:textAlignment="viewStart" android:text="@string/bubbles_user_education_description" + android:textColor="?android:attr/textColorPrimaryInverse" android:fontFamily="@*android:string/config_bodyFontFamily" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/> </LinearLayout> diff --git a/libs/WindowManager/Shell/res/layout/bubbles_manage_button_education.xml b/libs/WindowManager/Shell/res/layout/bubbles_manage_button_education.xml index 8de06c7732d4..3d48e403b059 100644 --- a/libs/WindowManager/Shell/res/layout/bubbles_manage_button_education.xml +++ b/libs/WindowManager/Shell/res/layout/bubbles_manage_button_education.xml @@ -41,6 +41,7 @@ android:ellipsize="end" android:gravity="start" android:textAlignment="viewStart" + android:textColor="?android:attr/textColorPrimaryInverse" android:text="@string/bubbles_user_education_manage_title" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Headline"/> @@ -55,6 +56,7 @@ android:ellipsize="end" android:gravity="start" android:textAlignment="viewStart" + android:textColor="?android:attr/textColorPrimaryInverse" android:fontFamily="@*android:string/config_bodyFontFamily" android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Body2"/> diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml index a138fee32550..e8757b5d96f4 100644 --- a/libs/WindowManager/Shell/res/values/config.xml +++ b/libs/WindowManager/Shell/res/values/config.xml @@ -52,9 +52,6 @@ when the PIP menu is shown in center. --> <string translatable="false" name="pip_menu_bounds">"596 280 1324 690"</string> - <!-- maximum animation duration for the icon when entering the starting window --> - <integer name="max_starting_window_intro_icon_anim_duration">1000</integer> - <!-- Animation duration when exit starting window: icon going away --> <integer name="starting_window_icon_exit_anim_duration">166</integer> diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml index 3ced8d3ec6e7..d94030dba652 100644 --- a/libs/WindowManager/Shell/res/values/dimen.xml +++ b/libs/WindowManager/Shell/res/values/dimen.xml @@ -125,7 +125,9 @@ <dimen name="bubble_expanded_view_slop">8dp</dimen> <!-- Default (and minimum) height of the expanded view shown when the bubble is expanded --> <dimen name="bubble_expanded_default_height">180dp</dimen> - <!-- Default height of bubble overflow --> + <!-- On large screens the width of the expanded view is restricted to this size. --> + <dimen name="bubble_expanded_view_tablet_width">412dp</dimen> + <!-- Default (and minimum) height of bubble overflow --> <dimen name="bubble_overflow_height">480dp</dimen> <!-- Bubble overflow padding when there are no bubbles --> <dimen name="bubble_overflow_empty_state_padding">16dp</dimen> @@ -178,7 +180,9 @@ <dimen name="bubble_stack_user_education_side_inset">72dp</dimen> <!-- The width/height of the icon view on staring surface. --> - <dimen name="starting_surface_icon_size">108dp</dimen> + <dimen name="starting_surface_icon_size">160dp</dimen> + <!-- The default width/height of the icon on the spec of adaptive icon drawable. --> + <dimen name="default_icon_size">108dp</dimen> <!-- The width/height of the size compat restart button. --> <dimen name="size_compat_button_size">48dp</dimen> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java index b6d408afd703..eb82c6d597d4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/apppairs/AppPair.java @@ -23,7 +23,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TASK_ORG; import android.app.ActivityManager; -import android.app.ActivityTaskManager; import android.graphics.Rect; import android.view.SurfaceControl; import android.window.WindowContainerToken; @@ -89,11 +88,11 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.LayoutChan ProtoLog.v(WM_SHELL_TASK_ORG, "pair task1=%d task2=%d in AppPair=%s", task1.taskId, task2.taskId, this); - if ((!task1.isResizeable || !task2.isResizeable) - && !ActivityTaskManager.supportsNonResizableMultiWindow()) { + if (!task1.supportsMultiWindow || !task2.supportsMultiWindow) { ProtoLog.e(WM_SHELL_TASK_ORG, - "Can't pair unresizeable tasks task1.isResizeable=%b task1.isResizeable=%b", - task1.isResizeable, task2.isResizeable); + "Can't pair tasks that doesn't support multi window, " + + "task1.supportsMultiWindow=%b, task2.supportsMultiWindow=%b", + task1.supportsMultiWindow, task2.supportsMultiWindow); return false; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java index 0a15d8468983..f6e92ef0e8ea 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java @@ -165,7 +165,8 @@ public class Bubble implements BubbleViewProvider { * Create a bubble with limited information based on given {@link ShortcutInfo}. * Note: Currently this is only being used when the bubble is persisted to disk. */ - Bubble(@NonNull final String key, @NonNull final ShortcutInfo shortcutInfo, + @VisibleForTesting(visibility = PRIVATE) + public Bubble(@NonNull final String key, @NonNull final ShortcutInfo shortcutInfo, final int desiredHeight, final int desiredHeightResId, @Nullable final String title, int taskId, @Nullable final String locus, Executor mainExecutor) { Objects.requireNonNull(key); @@ -188,7 +189,7 @@ public class Bubble implements BubbleViewProvider { } @VisibleForTesting(visibility = PRIVATE) - Bubble(@NonNull final BubbleEntry entry, + public Bubble(@NonNull final BubbleEntry entry, @Nullable final Bubbles.SuppressionChangedListener listener, final Bubbles.PendingIntentCanceledListener intentCancelListener, Executor mainExecutor) { @@ -718,7 +719,8 @@ public class Bubble implements BubbleViewProvider { private int getUid(final Context context) { if (mAppUid != -1) return mAppUid; - final PackageManager pm = context.getPackageManager(); + final PackageManager pm = BubbleController.getPackageManagerForUser(context, + mUser.getIdentifier()); if (pm == null) return -1; try { final ApplicationInfo info = pm.getApplicationInfo(mShortcutInfo.getPackage(), 0); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java index dca598518432..6a0f06192359 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java @@ -48,9 +48,11 @@ import android.content.pm.ActivityInfo; import android.content.pm.LauncherApps; import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; +import android.content.pm.UserInfo; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.PointF; +import android.graphics.Rect; import android.os.Binder; import android.os.Bundle; import android.os.Handler; @@ -64,10 +66,12 @@ import android.util.ArraySet; import android.util.Log; import android.util.Pair; import android.util.Slog; +import android.util.SparseArray; import android.util.SparseSetArray; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; +import android.window.WindowContainerTransaction; import androidx.annotation.MainThread; import androidx.annotation.Nullable; @@ -77,6 +81,8 @@ import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.wm.shell.ShellTaskOrganizer; import com.android.wm.shell.WindowManagerShellWrapper; +import com.android.wm.shell.common.DisplayChangeController; +import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.FloatingContentCoordinator; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.common.TaskStackListenerCallback; @@ -129,6 +135,7 @@ public class BubbleController { private final WindowManager mWindowManager; private final TaskStackListenerImpl mTaskStackListener; private final ShellTaskOrganizer mTaskOrganizer; + private final DisplayController mDisplayController; // Used to post to main UI thread private final ShellExecutor mMainExecutor; @@ -144,6 +151,8 @@ public class BubbleController { // Tracks the id of the current (foreground) user. private int mCurrentUserId; + // Current profiles of the user (e.g. user with a workprofile) + private SparseArray<UserInfo> mCurrentProfiles; // Saves notification keys of active bubbles when users are switched. private final SparseSetArray<String> mSavedBubbleKeysPerUser; @@ -153,8 +162,8 @@ public class BubbleController { // Callback that updates BubbleOverflowActivity on data change. @Nullable private BubbleData.Listener mOverflowListener = null; - // Only load overflow data from disk once - private boolean mOverflowDataLoaded = false; + // Typically only load once & after user switches + private boolean mOverflowDataLoadNeeded = true; /** * When the shade status changes to SHADE (from anything but SHADE, like LOCKED) we'll select @@ -167,25 +176,21 @@ public class BubbleController { /** Whether or not the BubbleStackView has been added to the WindowManager. */ private boolean mAddedToWindowManager = false; - /** Last known orientation, used to detect orientation changes in {@link #onConfigChanged}. */ - private int mOrientation = Configuration.ORIENTATION_UNDEFINED; - - /** - * Last known screen density, used to detect display size changes in {@link #onConfigChanged}. - */ + /** Saved screen density, used to detect display size changes in {@link #onConfigChanged}. */ private int mDensityDpi = Configuration.DENSITY_DPI_UNDEFINED; - /** - * Last known font scale, used to detect font size changes in {@link #onConfigChanged}. - */ + /** Saved screen bounds, used to detect screen size changes in {@link #onConfigChanged}. **/ + private Rect mScreenBounds = new Rect(); + + /** Saved font scale, used to detect font size changes in {@link #onConfigChanged}. */ private float mFontScale = 0; - /** Last known direction, used to detect layout direction changes @link #onConfigChanged}. */ + /** Saved direction, used to detect layout direction changes @link #onConfigChanged}. */ private int mLayoutDirection = View.LAYOUT_DIRECTION_UNDEFINED; private boolean mInflateSynchronously; - /** true when user is in status bar unlock shade. */ + /** True when user is in status bar unlock shade. */ private boolean mIsStatusBarShade = true; /** @@ -201,6 +206,7 @@ public class BubbleController { TaskStackListenerImpl taskStackListener, UiEventLogger uiEventLogger, ShellTaskOrganizer organizer, + DisplayController displayController, ShellExecutor mainExecutor, Handler mainHandler) { BubbleLogger logger = new BubbleLogger(uiEventLogger); @@ -209,7 +215,8 @@ public class BubbleController { return new BubbleController(context, data, synchronizer, floatingContentCoordinator, new BubbleDataRepository(context, launcherApps, mainExecutor), statusBarService, windowManager, windowManagerShellWrapper, launcherApps, - logger, taskStackListener, organizer, positioner, mainExecutor, mainHandler); + logger, taskStackListener, organizer, positioner, displayController, mainExecutor, + mainHandler); } /** @@ -229,6 +236,7 @@ public class BubbleController { TaskStackListenerImpl taskStackListener, ShellTaskOrganizer organizer, BubblePositioner positioner, + DisplayController displayController, ShellExecutor mainExecutor, Handler mainHandler) { mContext = context; @@ -252,6 +260,7 @@ public class BubbleController { mBubbleData = data; mSavedBubbleKeysPerUser = new SparseSetArray<>(); mBubbleIconFactory = new BubbleIconFactory(context); + mDisplayController = displayController; } public void initialize() { @@ -283,7 +292,6 @@ public class BubbleController { e.printStackTrace(); } - mBubbleData.setCurrentUserId(mCurrentUserId); mTaskOrganizer.addLocusIdListener((taskId, locus, visible) -> @@ -362,6 +370,23 @@ public class BubbleController { } } }); + + mDisplayController.addDisplayChangingController( + new DisplayChangeController.OnDisplayChangingListener() { + @Override + public void onRotateDisplay(int displayId, int fromRotation, int toRotation, + WindowContainerTransaction t) { + // This is triggered right before the rotation is applied + if (fromRotation != toRotation) { + mBubblePositioner.setRotation(toRotation); + if (mStackView != null) { + // Layout listener set on stackView will update the positioner + // once the rotation is applied + mStackView.onOrientationChanged(); + } + } + } + }); } @VisibleForTesting @@ -468,14 +493,31 @@ public class BubbleController { updateStack(); } - private void onUserChanged(int newUserId) { + /** Called when the current user changes. */ + @VisibleForTesting + public void onUserChanged(int newUserId) { saveBubbles(mCurrentUserId); + mCurrentUserId = newUserId; + mBubbleData.dismissAll(DISMISS_USER_CHANGED); + mBubbleData.clearOverflow(); + mOverflowDataLoadNeeded = true; + restoreBubbles(newUserId); - mCurrentUserId = newUserId; mBubbleData.setCurrentUserId(newUserId); } + /** Called when the profiles for the current user change. **/ + public void onCurrentProfilesChanged(SparseArray<UserInfo> currentProfiles) { + mCurrentProfiles = currentProfiles; + } + + /** Whether this userId belongs to the current user. */ + private boolean isCurrentProfile(int userId) { + return userId == UserHandle.USER_ALL + || (mCurrentProfiles != null && mCurrentProfiles.get(userId) != null); + } + /** * Sets whether to perform inflation on the same thread as the caller. This method should only * be used in tests, not in production. @@ -556,6 +598,7 @@ public class BubbleController { mWmLayoutParams.setTitle("Bubbles!"); mWmLayoutParams.packageName = mContext.getPackageName(); mWmLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; + mWmLayoutParams.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS; try { mAddedToWindowManager = true; @@ -563,7 +606,7 @@ public class BubbleController { mStackView.addView(mBubbleScrim); mWindowManager.addView(mStackView, mWmLayoutParams); // Position info is dependent on us being attached to a window - mBubblePositioner.update(mOrientation); + mBubblePositioner.update(); } catch (IllegalStateException e) { // This means the stack has already been added. This shouldn't happen... e.printStackTrace(); @@ -639,7 +682,7 @@ public class BubbleController { }); }); // Finally, remove the entries for this user now that bubbles are restored. - mSavedBubbleKeysPerUser.remove(mCurrentUserId); + mSavedBubbleKeysPerUser.remove(userId); } private void updateForThemeChanges() { @@ -660,16 +703,13 @@ public class BubbleController { private void onConfigChanged(Configuration newConfig) { if (mBubblePositioner != null) { - // This doesn't trigger any changes, always update it - mBubblePositioner.update(newConfig.orientation); + mBubblePositioner.update(); } if (mStackView != null && newConfig != null) { - if (newConfig.orientation != mOrientation) { - mOrientation = newConfig.orientation; - mStackView.onOrientationChanged(); - } - if (newConfig.densityDpi != mDensityDpi) { + if (newConfig.densityDpi != mDensityDpi + || !newConfig.windowConfiguration.getBounds().equals(mScreenBounds)) { mDensityDpi = newConfig.densityDpi; + mScreenBounds.set(newConfig.windowConfiguration.getBounds()); mBubbleIconFactory = new BubbleIconFactory(mContext); mStackView.onDisplaySizeChanged(); } @@ -804,12 +844,12 @@ public class BubbleController { * Fills the overflow bubbles by loading them from disk. */ void loadOverflowBubblesFromDisk() { - if (!mBubbleData.getOverflowBubbles().isEmpty() || mOverflowDataLoaded) { + if (!mBubbleData.getOverflowBubbles().isEmpty() && !mOverflowDataLoadNeeded) { // we don't need to load overflow bubbles from disk if it is already in memory return; } - mOverflowDataLoaded = true; - mDataRepository.loadBubbles((bubbles) -> { + mOverflowDataLoadNeeded = false; + mDataRepository.loadBubbles(mCurrentUserId, (bubbles) -> { bubbles.forEach(bubble -> { if (mBubbleData.hasAnyBubbleWithKey(bubble.getKey())) { // if the bubble is already active, there's no need to push it to overflow @@ -911,6 +951,12 @@ public class BubbleController { Pair<BubbleEntry, Boolean> entryData = entryDataByKey.get(key); BubbleEntry entry = entryData.first; boolean shouldBubbleUp = entryData.second; + + if (entry != null && !isCurrentProfile( + entry.getStatusBarNotification().getUser().getIdentifier())) { + return; + } + rankingMap.getRanking(key, mTmpRanking); boolean isActiveBubble = mBubbleData.hasAnyBubbleWithKey(key); if (isActiveBubble && !mTmpRanking.canBubble()) { @@ -1428,6 +1474,13 @@ public class BubbleController { } @Override + public void onCurrentProfilesChanged(SparseArray<UserInfo> currentProfiles) { + mMainExecutor.execute(() -> { + BubbleController.this.onCurrentProfilesChanged(currentProfiles); + }); + } + + @Override public void onConfigChanged(Configuration newConfig) { mMainExecutor.execute(() -> { BubbleController.this.onConfigChanged(newConfig); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java index f6e6b8f3b700..6f526ecf2b62 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleData.java @@ -510,7 +510,8 @@ public class BubbleData { || reason == Bubbles.DISMISS_NO_LONGER_BUBBLE || reason == Bubbles.DISMISS_BLOCKED || reason == Bubbles.DISMISS_SHORTCUT_REMOVED - || reason == Bubbles.DISMISS_PACKAGE_REMOVED)) { + || reason == Bubbles.DISMISS_PACKAGE_REMOVED + || reason == Bubbles.DISMISS_USER_CHANGED)) { Bubble b = getOverflowBubbleWithKey(key); if (DEBUG_BUBBLE_DATA) { @@ -574,6 +575,7 @@ public class BubbleData { Log.d(TAG, "Overflowing: " + bubble); } mLogger.logOverflowAdd(bubble, reason); + mOverflowBubbles.remove(bubble); mOverflowBubbles.add(0, bubble); mStateChange.addedOverflowBubble = bubble; bubble.stopInflation(); @@ -642,6 +644,16 @@ public class BubbleData { } } + /** + * Removes all bubbles from the overflow, called when the user changes. + */ + public void clearOverflow() { + while (!mOverflowBubbles.isEmpty()) { + doRemove(mOverflowBubbles.get(0).getKey(), Bubbles.DISMISS_USER_CHANGED); + } + dispatchPendingChanges(); + } + private void dispatchPendingChanges() { if (mListener != null && mStateChange.anythingChanged()) { mListener.applyUpdate(mStateChange); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt index bfacd1cfe90e..9d9e442affd3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleDataRepository.kt @@ -58,7 +58,8 @@ internal class BubbleDataRepository( */ fun addBubbles(@UserIdInt userId: Int, bubbles: List<Bubble>) { if (DEBUG) Log.d(TAG, "adding ${bubbles.size} bubbles") - val entities = transform(userId, bubbles).also(volatileRepository::addBubbles) + val entities = transform(bubbles).also { + b -> volatileRepository.addBubbles(userId, b) } if (entities.isNotEmpty()) persistToDisk() } @@ -67,14 +68,15 @@ internal class BubbleDataRepository( */ fun removeBubbles(@UserIdInt userId: Int, bubbles: List<Bubble>) { if (DEBUG) Log.d(TAG, "removing ${bubbles.size} bubbles") - val entities = transform(userId, bubbles).also(volatileRepository::removeBubbles) + val entities = transform(bubbles).also { + b -> volatileRepository.removeBubbles(userId, b) } if (entities.isNotEmpty()) persistToDisk() } - private fun transform(userId: Int, bubbles: List<Bubble>): List<BubbleEntity> { + private fun transform(bubbles: List<Bubble>): List<BubbleEntity> { return bubbles.mapNotNull { b -> BubbleEntity( - userId, + b.user.identifier, b.packageName, b.metadataShortcutId ?: return@mapNotNull null, b.key, @@ -116,10 +118,11 @@ internal class BubbleDataRepository( /** * Load bubbles from disk. * @param cb The callback to be run after the bubbles are loaded. This callback is always made - * on the main thread of the hosting process. + * on the main thread of the hosting process. The callback is only run if there are + * bubbles. */ @SuppressLint("WrongConstant") - fun loadBubbles(cb: (List<Bubble>) -> Unit) = ioScope.launch { + fun loadBubbles(userId: Int, cb: (List<Bubble>) -> Unit) = ioScope.launch { /** * Load BubbleEntity from disk. * e.g. @@ -129,8 +132,9 @@ internal class BubbleDataRepository( * BubbleEntity(0, "com.example.messenger", "id-1") * ] */ - val entities = persistentRepository.readFromDisk() - volatileRepository.addBubbles(entities) + val entitiesByUser = persistentRepository.readFromDisk() + val entities = entitiesByUser.get(userId) ?: return@launch + volatileRepository.addBubbles(userId, entities) /** * Extract userId/packageName from these entities. * e.g. @@ -139,9 +143,10 @@ internal class BubbleDataRepository( * ] */ val shortcutKeys = entities.map { ShortcutKey(it.userId, it.packageName) }.toSet() + /** - * Retrieve shortcuts with given userId/packageName combination, then construct a mapping - * from the userId/packageName pair to a list of associated ShortcutInfo. + * Retrieve shortcuts with given userId/packageName combination, then construct a + * mapping from the userId/packageName pair to a list of associated ShortcutInfo. * e.g. * { * ShortcutKey(0, "com.example.messenger") -> [ @@ -161,21 +166,23 @@ internal class BubbleDataRepository( .setQueryFlags(SHORTCUT_QUERY_FLAG), UserHandle.of(key.userId)) ?: emptyList() }.groupBy { ShortcutKey(it.userId, it.`package`) } - // For each entity loaded from xml, find the corresponding ShortcutInfo then convert them - // into Bubble. + // For each entity loaded from xml, find the corresponding ShortcutInfo then convert + // them into Bubble. val bubbles = entities.mapNotNull { entity -> shortcutMap[ShortcutKey(entity.userId, entity.packageName)] ?.firstOrNull { shortcutInfo -> entity.shortcutId == shortcutInfo.id } - ?.let { shortcutInfo -> Bubble( - entity.key, - shortcutInfo, - entity.desiredHeight, - entity.desiredHeightResId, - entity.title, - entity.taskId, - entity.locus, - mainExecutor - ) } + ?.let { shortcutInfo -> + Bubble( + entity.key, + shortcutInfo, + entity.desiredHeight, + entity.desiredHeightResId, + entity.title, + entity.taskId, + entity.locus, + mainExecutor + ) + } } mainExecutor.execute { cb(bubbles) } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java index abe1f7179dda..696f705782c0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java @@ -19,6 +19,7 @@ package com.android.wm.shell.bubbles; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static com.android.wm.shell.bubbles.BubbleDebugConfig.DEBUG_BUBBLE_EXPANDED_VIEW; @@ -335,7 +336,10 @@ public class BubbleExpandedView extends LinearLayout { mOverflowView = (BubbleOverflowContainerView) LayoutInflater.from(getContext()).inflate( R.layout.bubble_overflow_container, null /* root */); mOverflowView.setBubbleController(mController); - mExpandedViewContainer.addView(mOverflowView); + FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT); + mExpandedViewContainer.addView(mOverflowView, lp); + mExpandedViewContainer.setLayoutParams( + new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)); bringChildToFront(mOverflowView); mSettingsIcon.setVisibility(GONE); } else { @@ -600,9 +604,9 @@ public class BubbleExpandedView extends LinearLayout { return; } - if (mBubble != null || mIsOverflow) { + if ((mBubble != null && mTaskView != null) || mIsOverflow) { float desiredHeight = mIsOverflow - ? mOverflowHeight + ? mPositioner.isLargeScreen() ? getMaxExpandedHeight() : mOverflowHeight : mBubble.getDesiredHeight(mContext); desiredHeight = Math.max(desiredHeight, mMinHeight); float height = Math.min(desiredHeight, getMaxExpandedHeight()); @@ -657,10 +661,10 @@ public class BubbleExpandedView extends LinearLayout { + getBubbleKey()); } mExpandedViewContainerLocation = containerLocationOnScreen; + updateHeight(); if (mTaskView != null && mTaskView.getVisibility() == VISIBLE && mTaskView.isAttachedToWindow()) { - updateHeight(); mTaskView.onLocationChanged(); } if (mIsOverflow) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java index fe3f9ef6aa5f..e64ed6a0836c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java @@ -29,6 +29,8 @@ import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; +import androidx.annotation.VisibleForTesting; + import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.ShadowGenerator; @@ -39,11 +41,12 @@ import com.android.wm.shell.R; * We are not using Launcher's IconFactory because bubbles only runs on the UI thread, * so there is no need to manage a pool across multiple threads. */ +@VisibleForTesting public class BubbleIconFactory extends BaseIconFactory { private int mBadgeSize; - protected BubbleIconFactory(Context context) { + public BubbleIconFactory(Context context) { super(context, context.getResources().getConfiguration().densityDpi, context.getResources().getDimensionPixelSize(R.dimen.individual_bubble_size)); mBadgeSize = mContext.getResources().getDimensionPixelSize( diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java index 8ee2b40d5985..af5b3a61f393 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java @@ -26,7 +26,6 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Color; import android.util.AttributeSet; -import android.util.DisplayMetrics; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -51,8 +50,6 @@ import java.util.function.Consumer; * Container view for showing aged out bubbles. */ public class BubbleOverflowContainerView extends LinearLayout { - static final String EXTRA_BUBBLE_CONTROLLER = "bubble_controller"; - private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleOverflowActivity" : TAG_BUBBLES; private LinearLayout mEmptyState; @@ -64,18 +61,16 @@ public class BubbleOverflowContainerView extends LinearLayout { private RecyclerView mRecyclerView; private List<Bubble> mOverflowBubbles = new ArrayList<>(); - private class NoScrollGridLayoutManager extends GridLayoutManager { - NoScrollGridLayoutManager(Context context, int columns) { + private class OverflowGridLayoutManager extends GridLayoutManager { + OverflowGridLayoutManager(Context context, int columns) { super(context, columns); } - @Override - public boolean canScrollVertically() { - if (getResources().getConfiguration().orientation - == Configuration.ORIENTATION_LANDSCAPE) { - return super.canScrollVertically(); - } - return false; - } + +// @Override +// public boolean canScrollVertically() { +// // TODO (b/162006693): this should be based on items in the list & available height +// return true; +// } @Override public int getColumnCountForAccessibility(RecyclerView.Recycler recycler, @@ -137,47 +132,24 @@ public class BubbleOverflowContainerView extends LinearLayout { Resources res = getResources(); final int columns = res.getInteger(R.integer.bubbles_overflow_columns); mRecyclerView.setLayoutManager( - new NoScrollGridLayoutManager(getContext(), columns)); - - DisplayMetrics displayMetrics = new DisplayMetrics(); - getContext().getDisplay().getMetrics(displayMetrics); - - final int overflowPadding = res.getDimensionPixelSize(R.dimen.bubble_overflow_padding); - final int recyclerViewWidth = displayMetrics.widthPixels - (overflowPadding * 2); - final int viewWidth = recyclerViewWidth / columns; - - final int maxOverflowBubbles = res.getInteger(R.integer.bubbles_max_overflow); - final int rows = (int) Math.ceil((double) maxOverflowBubbles / columns); - final int recyclerViewHeight = res.getDimensionPixelSize(R.dimen.bubble_overflow_height) - - res.getDimensionPixelSize(R.dimen.bubble_overflow_padding); - final int viewHeight = recyclerViewHeight / rows; - + new OverflowGridLayoutManager(getContext(), columns)); mAdapter = new BubbleOverflowAdapter(getContext(), mOverflowBubbles, mController::promoteBubbleFromOverflow, - mController.getPositioner(), - viewWidth, viewHeight); + mController.getPositioner()); mRecyclerView.setAdapter(mAdapter); mOverflowBubbles.clear(); mOverflowBubbles.addAll(mController.getOverflowBubbles()); mAdapter.notifyDataSetChanged(); - // Currently BubbleExpandedView.mExpandedViewContainer is WRAP_CONTENT so use the same - // width we would use for the recycler view - LayoutParams lp = (LayoutParams) mEmptyState.getLayoutParams(); - lp.width = recyclerViewWidth; - updateEmptyStateVisibility(); - mController.setOverflowListener(mDataListener); + updateEmptyStateVisibility(); updateTheme(); } void updateEmptyStateVisibility() { - if (mOverflowBubbles.isEmpty()) { - mEmptyState.setVisibility(View.VISIBLE); - } else { - mEmptyState.setVisibility(View.GONE); - } + mEmptyState.setVisibility(mOverflowBubbles.isEmpty() ? View.VISIBLE : View.GONE); + mRecyclerView.setVisibility(mOverflowBubbles.isEmpty() ? View.GONE : View.VISIBLE); } /** @@ -220,18 +192,25 @@ public class BubbleOverflowContainerView extends LinearLayout { Log.d(TAG, "remove: " + toRemove); } toRemove.cleanupViews(); - final int i = mOverflowBubbles.indexOf(toRemove); + final int indexToRemove = mOverflowBubbles.indexOf(toRemove); mOverflowBubbles.remove(toRemove); - mAdapter.notifyItemRemoved(i); + mAdapter.notifyItemRemoved(indexToRemove); } Bubble toAdd = update.addedOverflowBubble; if (toAdd != null) { + final int indexToAdd = mOverflowBubbles.indexOf(toAdd); if (DEBUG_OVERFLOW) { - Log.d(TAG, "add: " + toAdd); + Log.d(TAG, "add: " + toAdd + " prevIndex: " + indexToAdd); + } + if (indexToAdd > 0) { + mOverflowBubbles.remove(toAdd); + mOverflowBubbles.add(0, toAdd); + mAdapter.notifyItemMoved(indexToAdd, 0); + } else { + mOverflowBubbles.add(0, toAdd); + mAdapter.notifyItemInserted(0); } - mOverflowBubbles.add(0, toAdd); - mAdapter.notifyItemInserted(0); } updateEmptyStateVisibility(); @@ -251,20 +230,15 @@ class BubbleOverflowAdapter extends RecyclerView.Adapter<BubbleOverflowAdapter.V private Consumer<Bubble> mPromoteBubbleFromOverflow; private BubblePositioner mPositioner; private List<Bubble> mBubbles; - private int mWidth; - private int mHeight; BubbleOverflowAdapter(Context context, List<Bubble> list, Consumer<Bubble> promoteBubble, - BubblePositioner positioner, - int width, int height) { + BubblePositioner positioner) { mContext = context; mBubbles = list; mPromoteBubbleFromOverflow = promoteBubble; mPositioner = positioner; - mWidth = width; - mHeight = height; } @Override @@ -277,8 +251,6 @@ class BubbleOverflowAdapter extends RecyclerView.Adapter<BubbleOverflowAdapter.V LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT); - params.width = mWidth; - params.height = mHeight; overflowView.setLayoutParams(params); // Ensure name has enough contrast. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java index 1562e4bf6fcc..ae1a053ae19e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java @@ -20,13 +20,13 @@ import static java.lang.annotation.RetentionPolicy.SOURCE; import android.annotation.IntDef; import android.content.Context; -import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.util.Log; +import android.view.Surface; import android.view.View; import android.view.WindowInsets; import android.view.WindowManager; @@ -65,15 +65,21 @@ public class BubblePositioner { private Context mContext; private WindowManager mWindowManager; private Rect mPositionRect; - private int mOrientation; + private @Surface.Rotation int mRotation = Surface.ROTATION_0; private Insets mInsets; private int mBubbleSize; private int mBubbleBitmapSize; + private int mExpandedViewLargeScreenWidth; + private int mExpandedViewPadding; + private int mPointerHeight; + private int mBubblePaddingTop; private PointF mPinLocation; private PointF mRestingStackPosition; + private int[] mLeftRightPadding = new int[2]; + private boolean mIsLargeScreen; private boolean mShowingInTaskbar; private @TaskbarPosition int mTaskbarPosition = TASKBAR_POSITION_NONE; private int mTaskbarIconSize; @@ -82,32 +88,38 @@ public class BubblePositioner { public BubblePositioner(Context context, WindowManager windowManager) { mContext = context; mWindowManager = windowManager; - update(Configuration.ORIENTATION_UNDEFINED); + update(); + } + + public void setRotation(int rotation) { + mRotation = rotation; } /** - * Updates orientation, available space, and inset information. Call this when config changes + * Available space and inset information. Call this when config changes * occur or when added to a window. */ - public void update(int orientation) { + public void update() { WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics(); if (windowMetrics == null) { return; } WindowInsets metricInsets = windowMetrics.getWindowInsets(); - Insets insets = metricInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars() | WindowInsets.Type.statusBars() | WindowInsets.Type.displayCutout()); + mIsLargeScreen = mContext.getResources().getConfiguration().smallestScreenWidthDp >= 600; + if (BubbleDebugConfig.DEBUG_POSITIONER) { Log.w(TAG, "update positioner:" - + " landscape= " + (orientation == Configuration.ORIENTATION_LANDSCAPE) + + " rotation: " + mRotation + " insets: " + insets + + " isLargeScreen: " + mIsLargeScreen + " bounds: " + windowMetrics.getBounds() + " showingInTaskbar: " + mShowingInTaskbar); } - updateInternal(orientation, insets, windowMetrics.getBounds()); + updateInternal(mRotation, insets, windowMetrics.getBounds()); } /** @@ -122,12 +134,12 @@ public class BubblePositioner { mTaskbarIconSize = iconSize; mTaskbarPosition = taskbarPosition; mTaskbarSize = taskbarSize; - update(mOrientation); + update(); } @VisibleForTesting - public void updateInternal(int orientation, Insets insets, Rect bounds) { - mOrientation = orientation; + public void updateInternal(int rotation, Insets insets, Rect bounds) { + mRotation = rotation; mInsets = insets; mPositionRect = new Rect(bounds); @@ -139,6 +151,11 @@ public class BubblePositioner { Resources res = mContext.getResources(); mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size); mBubbleBitmapSize = res.getDimensionPixelSize(R.dimen.bubble_bitmap_size); + mExpandedViewLargeScreenWidth = res.getDimensionPixelSize( + R.dimen.bubble_expanded_view_tablet_width); + mExpandedViewPadding = res.getDimensionPixelSize(R.dimen.bubble_expanded_view_padding); + mPointerHeight = res.getDimensionPixelSize(R.dimen.bubble_pointer_height); + mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top); if (mShowingInTaskbar) { adjustForTaskbar(); } @@ -185,11 +202,14 @@ public class BubblePositioner { return mInsets; } - /** - * @return whether the device is in landscape orientation. - */ + /** @return whether the device is in landscape orientation. */ public boolean isLandscape() { - return mOrientation == Configuration.ORIENTATION_LANDSCAPE; + return mRotation == Surface.ROTATION_90 || mRotation == Surface.ROTATION_270; + } + + /** @return whether the screen is considered large. */ + public boolean isLargeScreen() { + return mIsLargeScreen; } /** @@ -200,8 +220,7 @@ public class BubblePositioner { * to the left or right side. */ public boolean showBubblesVertically() { - return mOrientation == Configuration.ORIENTATION_LANDSCAPE - || mShowingInTaskbar; + return isLandscape() || mShowingInTaskbar || mIsLargeScreen; } /** Size of the bubble account for badge & dot. */ @@ -221,6 +240,45 @@ public class BubblePositioner { } /** + * Calculates the left & right padding for the bubble expanded view. + * + * On larger screens the width of the expanded view is restricted via this padding. + * On landscape the bubble overflow expanded view is also restricted via this padding. + */ + public int[] getExpandedViewPadding(boolean onLeft, boolean isOverflow) { + int leftPadding = mInsets.left + mExpandedViewPadding; + int rightPadding = mInsets.right + mExpandedViewPadding; + final boolean isLargeOrOverflow = mIsLargeScreen || isOverflow; + if (showBubblesVertically()) { + if (!onLeft) { + rightPadding += mPointerHeight + mBubbleSize; + leftPadding += isLargeOrOverflow + ? (mPositionRect.width() - rightPadding - mExpandedViewLargeScreenWidth) + : 0; + } else { + //TODO: pointer height should be padding between pointer & bubbles here & above + leftPadding += mPointerHeight + mBubbleSize; + rightPadding += isLargeOrOverflow + ? (mPositionRect.width() - leftPadding - mExpandedViewLargeScreenWidth) + : 0; + } + } + mLeftRightPadding[0] = leftPadding; + mLeftRightPadding[1] = rightPadding; + return mLeftRightPadding; + } + + /** Calculates the y position of the expanded view when it is expanded. */ + public float getExpandedViewY() { + final int top = getAvailableRect().top; + if (showBubblesVertically()) { + return top + mExpandedViewPadding; + } else { + return top + mBubbleSize + mBubblePaddingTop; + } + } + + /** * Sets the stack's most recent position along the edge of the screen. This is saved when the * last bubble is removed, so that the stack can be restored in its previous position. */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index 64bd245cb2ee..c4d33877f17d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -35,7 +35,6 @@ import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; -import android.graphics.Insets; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.PointF; @@ -246,7 +245,6 @@ public class BubbleStackView extends FrameLayout private int mMaxBubbles; private int mBubbleSize; private int mBubbleElevation; - private int mBubblePaddingTop; private int mBubbleTouchPadding; private int mExpandedViewPadding; private int mPointerHeight; @@ -768,7 +766,6 @@ public class BubbleStackView extends FrameLayout mMaxBubbles = res.getInteger(R.integer.bubbles_max_rendered); mBubbleSize = res.getDimensionPixelSize(R.dimen.individual_bubble_size); mBubbleElevation = res.getDimensionPixelSize(R.dimen.bubble_elevation); - mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top); mBubbleTouchPadding = res.getDimensionPixelSize(R.dimen.bubble_touch_padding); mPointerHeight = res.getDimensionPixelSize(R.dimen.bubble_pointer_height); mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset); @@ -884,6 +881,7 @@ public class BubbleStackView extends FrameLayout mOrientationChangedListener = (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { + mPositioner.update(); onDisplaySizeChanged(); mExpandedAnimationController.updateResources(); mStackAnimationController.updateResources(); @@ -904,7 +902,7 @@ public class BubbleStackView extends FrameLayout afterExpandedViewAnimation(); } /* after */); mExpandedViewContainer.setTranslationX(0f); - mExpandedViewContainer.setTranslationY(getExpandedViewY()); + mExpandedViewContainer.setTranslationY(mPositioner.getExpandedViewY()); mExpandedViewContainer.setAlpha(1f); } removeOnLayoutChangeListener(mOrientationChangedListener); @@ -1214,11 +1212,12 @@ public class BubbleStackView extends FrameLayout updateExpandedViewTheme(); } - /** Respond to the phone being rotated by repositioning the stack and hiding any flyouts. */ + /** + * Respond to the phone being rotated by repositioning the stack and hiding any flyouts. + * This is called prior to the rotation occurring, any values that should be updated + * based on the new rotation should occur in {@link #mOrientationChangedListener}. + */ public void onOrientationChanged() { - Resources res = getContext().getResources(); - mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top); - mRelativeStackPositionBeforeRotation = new RelativeStackPosition( mPositioner.getRestingPosition(), mStackAnimationController.getAllowableStackPositionRegion()); @@ -1245,9 +1244,6 @@ public class BubbleStackView extends FrameLayout /** Respond to the display size change by recalculating view size and location. */ public void onDisplaySizeChanged() { updateOverflow(); - - Resources res = getContext().getResources(); - mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top); mBubbleSize = mPositioner.getBubbleSize(); for (Bubble b : mBubbleData.getBubbles()) { if (b.getIconView() == null) { @@ -1261,6 +1257,13 @@ public class BubbleStackView extends FrameLayout mStackAnimationController.updateResources(); mDismissView.updateResources(); mMagneticTarget.setMagneticFieldRadiusPx(mBubbleSize * 2); + mStackAnimationController.setStackPosition( + new RelativeStackPosition( + mPositioner.getRestingPosition(), + mStackAnimationController.getAllowableStackPositionRegion())); + if (mIsExpanded) { + updateExpandedView(); + } } @Override @@ -1598,6 +1601,7 @@ public class BubbleStackView extends FrameLayout // can start fresh. cancelAllExpandCollapseSwitchAnimations(); } + showManageMenu(false /* show */); // If we're expanded, screenshot the currently expanded bubble (before expanding the newly // selected bubble) so we can animate it out. @@ -1809,7 +1813,7 @@ public class BubbleStackView extends FrameLayout } mExpandedViewContainer.setTranslationX(0f); - mExpandedViewContainer.setTranslationY(getExpandedViewY()); + mExpandedViewContainer.setTranslationY(mPositioner.getExpandedViewY()); mExpandedViewContainer.setAlpha(1f); int index; @@ -1858,7 +1862,7 @@ public class BubbleStackView extends FrameLayout 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, bubbleWillBeAt + mBubbleSize / 2f, - getExpandedViewY()); + mPositioner.getExpandedViewY()); } mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix); @@ -1962,7 +1966,7 @@ public class BubbleStackView extends FrameLayout mExpandedViewContainerMatrix.setScale( 1f, 1f, expandingFromBubbleAt + mBubbleSize / 2f, - getExpandedViewY()); + mPositioner.getExpandedViewY()); } mExpandedViewAlphaAnimator.reverse(); @@ -2068,7 +2072,7 @@ public class BubbleStackView extends FrameLayout 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, 1f - EXPANDED_VIEW_ANIMATE_SCALE_AMOUNT, expandingFromBubbleDestination + mBubbleSize / 2f, - getExpandedViewY()); + mPositioner.getExpandedViewY()); } mExpandedViewContainer.setAnimationMatrix(mExpandedViewContainerMatrix); @@ -2306,18 +2310,6 @@ public class BubbleStackView extends FrameLayout : 0f); } - /** - * Calculates the y position of the expanded view when it is expanded. - */ - float getExpandedViewY() { - final int top = mPositioner.getAvailableRect().top; - if (mPositioner.showBubblesVertically()) { - return top + mExpandedViewPadding; - } else { - return top + mBubbleSize + mBubblePaddingTop; - } - } - private boolean shouldShowFlyout(Bubble bubble) { Bubble.FlyoutMessage flyoutMessage = bubble.getFlyoutMessage(); final BadgedImageView bubbleView = bubble.getIconView(); @@ -2690,24 +2682,16 @@ public class BubbleStackView extends FrameLayout if (DEBUG_BUBBLE_STACK_VIEW) { Log.d(TAG, "updateExpandedView: mIsExpanded=" + mIsExpanded); } - - // Need to update the padding around the view for any insets - Insets insets = mPositioner.getInsets(); - int leftPadding = insets.left + mExpandedViewPadding; - int rightPadding = insets.right + mExpandedViewPadding; - if (mPositioner.showBubblesVertically()) { - if (!mStackAnimationController.isStackOnLeftSide()) { - rightPadding += mPointerHeight + mBubbleSize; - } else { - leftPadding += mPointerHeight + mBubbleSize; - } - } - mExpandedViewContainer.setPadding(leftPadding, 0, rightPadding, 0); + boolean isOverflowExpanded = mExpandedBubble != null + && mBubbleOverflow.KEY.equals(mExpandedBubble.getKey()); + int[] paddings = mPositioner.getExpandedViewPadding( + mStackAnimationController.isStackOnLeftSide(), isOverflowExpanded); + mExpandedViewContainer.setPadding(paddings[0], 0, paddings[1], 0); if (mIsExpansionAnimating) { mExpandedViewContainer.setVisibility(mIsExpanded ? VISIBLE : GONE); } if (mExpandedBubble != null && mExpandedBubble.getExpandedView() != null) { - mExpandedViewContainer.setTranslationY(getExpandedViewY()); + mExpandedViewContainer.setTranslationY(mPositioner.getExpandedViewY()); mExpandedViewContainer.setTranslationX(0f); mExpandedBubble.getExpandedView().updateView( mExpandedViewContainer.getLocationOnScreen()); @@ -2748,13 +2732,14 @@ public class BubbleStackView extends FrameLayout return; } float bubblePosition = mExpandedAnimationController.getBubbleXOrYForOrientation(index); + float expandedViewY = mPositioner.getExpandedViewY(); if (mPositioner.showBubblesVertically()) { float x = mStackOnLeftOrWillBe ? mPositioner.getAvailableRect().left : mPositioner.getAvailableRect().right - mExpandedViewContainer.getPaddingRight() - mPointerHeight; - float bubbleCenter = bubblePosition - getExpandedViewY() + (mBubbleSize / 2f); + float bubbleCenter = bubblePosition - expandedViewY + (mBubbleSize / 2f); mExpandedBubble.getExpandedView().setPointerPosition( x, bubbleCenter, @@ -2764,7 +2749,7 @@ public class BubbleStackView extends FrameLayout float bubbleCenter = bubblePosition + (mBubbleSize / 2f); mExpandedBubble.getExpandedView().setPointerPosition( bubbleCenter, - getExpandedViewY(), + expandedViewY, false, mStackOnLeftOrWillBe); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java index c5a712e271e4..fc53ef26dbd9 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java @@ -39,6 +39,7 @@ import android.util.PathParser; import android.view.LayoutInflater; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import com.android.internal.graphics.ColorUtils; import com.android.launcher3.icons.BitmapInfo; @@ -118,7 +119,8 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask /** * Info necessary to render a bubble. */ - static class BubbleViewInfo { + @VisibleForTesting + public static class BubbleViewInfo { BadgedImageView imageView; BubbleExpandedView expandedView; ShortcutInfo shortcutInfo; @@ -129,8 +131,9 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask Path dotPath; Bubble.FlyoutMessage flyoutMessage; + @VisibleForTesting @Nullable - static BubbleViewInfo populate(Context c, BubbleController controller, + public static BubbleViewInfo populate(Context c, BubbleController controller, BubbleStackView stackView, BubbleIconFactory iconFactory, Bubble b, boolean skipInflation) { BubbleViewInfo info = new BubbleViewInfo(); @@ -152,7 +155,8 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask } // App name & app icon - PackageManager pm = c.getPackageManager(); + PackageManager pm = BubbleController.getPackageManagerForUser(c, + b.getUser().getIdentifier()); ApplicationInfo appInfo; Drawable badgedIcon; Drawable appIcon; @@ -217,10 +221,16 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask static Drawable loadSenderAvatar(@NonNull final Context context, @Nullable final Icon icon) { Objects.requireNonNull(context); if (icon == null) return null; - if (icon.getType() == Icon.TYPE_URI || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) { - context.grantUriPermission(context.getPackageName(), - icon.getUri(), Intent.FLAG_GRANT_READ_URI_PERMISSION); + try { + if (icon.getType() == Icon.TYPE_URI + || icon.getType() == Icon.TYPE_URI_ADAPTIVE_BITMAP) { + context.grantUriPermission(context.getPackageName(), + icon.getUri(), Intent.FLAG_GRANT_READ_URI_PERMISSION); + } + return icon.loadDrawable(context); + } catch (Exception e) { + Log.w(TAG, "loadSenderAvatar failed: " + e.getMessage()); + return null; } - return icon.loadDrawable(context); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java index 1bfb61929297..a93ce01dfc7b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java @@ -21,12 +21,14 @@ import static java.lang.annotation.ElementType.LOCAL_VARIABLE; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.SOURCE; +import android.content.pm.UserInfo; import android.content.res.Configuration; import android.os.Bundle; import android.os.Looper; import android.service.notification.NotificationListenerService.RankingMap; import android.util.ArraySet; import android.util.Pair; +import android.util.SparseArray; import android.view.View; import androidx.annotation.IntDef; @@ -214,6 +216,13 @@ public interface Bubbles { void onUserChanged(int newUserId); /** + * Called when the current user profiles change. + * + * @param currentProfiles the user infos for the current profile. + */ + void onCurrentProfilesChanged(SparseArray<UserInfo> currentProfiles); + + /** * Called when config changed. * * @param newConfig the new config. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java index 18aaa9677be6..48bd8943b25a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/ExpandedAnimationController.java @@ -16,7 +16,6 @@ package com.android.wm.shell.bubbles.animation; -import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Path; import android.graphics.PointF; @@ -142,6 +141,7 @@ public class ExpandedAnimationController updateResources(); mExpandedViewPadding = expandedViewPadding; mOnBubbleAnimatedOutAction = onBubbleAnimatedOutAction; + mCollapsePoint = mPositioner.getDefaultStartPosition(); } /** @@ -528,17 +528,34 @@ public class ExpandedAnimationController startOrUpdatePathAnimation(true /* expanding */); } else if (mAnimatingCollapse) { startOrUpdatePathAnimation(false /* expanding */); + } else if (mPositioner.showBubblesVertically()) { + child.setTranslationY(getBubbleXOrYForOrientation(index)); + if (!mPreparingToCollapse) { + // Only animate if we're not collapsing as that animation will handle placing the + // new bubble in the stacked position. + Rect availableRect = mPositioner.getAvailableRect(); + boolean onLeft = mCollapsePoint != null + && mCollapsePoint.x < (availableRect.width() / 2f); + float fromX = onLeft + ? -mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR + : availableRect.right + mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR; + float toX = onLeft + ? availableRect.left + mExpandedViewPadding + : availableRect.right - mBubbleSizePx - mExpandedViewPadding; + animationForChild(child) + .translationX(fromX, toX) + .start(); + updateBubblePositions(); + } } else { child.setTranslationX(getBubbleXOrYForOrientation(index)); - - // If we're preparing to collapse, don't start animations since the collapse animation - // will take over and animate the new bubble into the correct (stacked) position. if (!mPreparingToCollapse) { + // Only animate if we're not collapsing as that animation will handle placing the + // new bubble in the stacked position. + float toY = getExpandedY(); + float fromY = getExpandedY() - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR; animationForChild(child) - .translationY( - getExpandedY() - - mBubbleSizePx * ANIMATE_TRANSLATION_FACTOR, /* from */ - getExpandedY() /* to */) + .translationY(fromY, toY) .start(); updateBubblePositions(); } @@ -617,15 +634,16 @@ public class ExpandedAnimationController } } + // TODO - could move to method on bubblePositioner if mSpaceBetweenBubbles gets moved /** * When bubbles are expanded in portrait, they display at the top of the screen in a horizontal - * row. When in landscape, they show at the left or right side in a vertical row. This method - * accounts for screen orientation and will return an x or y value for the position of the - * bubble in the row. + * row. When in landscape or on a large screen, they show at the left or right side in a + * vertical row. This method accounts for screen orientation and will return an x or y value + * for the position of the bubble in the row. * * @param index Bubble index in row. - * @return the y position of the bubble if {@link Configuration#ORIENTATION_LANDSCAPE} and the - * x position if {@link Configuration#ORIENTATION_PORTRAIT}. + * @return the y position of the bubble if showing vertically and the x position if showing + * horizontally. */ public float getBubbleXOrYForOrientation(int index) { if (mLayout == null) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java index 56fe126f507e..578f87fbfbf8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/animation/StackAnimationController.java @@ -958,17 +958,26 @@ public class StackAnimationController extends if (!isActiveController()) { return; } - v.setTranslationX(mStackPosition.x); + final float yOffset = getOffsetForChainedPropertyAnimation(DynamicAnimation.TRANSLATION_Y); - final float endY = mStackPosition.y + yOffset * index; - final float startY = endY + NEW_BUBBLE_START_Y; - v.setTranslationY(startY); + float endY = mStackPosition.y + yOffset * index; + float endX = mStackPosition.x; + if (mPositioner.showBubblesVertically()) { + v.setTranslationY(endY); + final float startX = isStackOnLeftSide() + ? endX - NEW_BUBBLE_START_Y + : endX + NEW_BUBBLE_START_Y; + v.setTranslationX(startX); + } else { + v.setTranslationX(mStackPosition.x); + final float startY = endY + NEW_BUBBLE_START_Y; + v.setTranslationY(startY); + } v.setScaleX(NEW_BUBBLE_START_SCALE); v.setScaleY(NEW_BUBBLE_START_SCALE); v.setAlpha(0f); final ViewPropertyAnimator animator = v.animate() - .translationY(endY) .scaleX(1f) .scaleY(1f) .alpha(1f) @@ -977,6 +986,11 @@ public class StackAnimationController extends v.setTag(R.id.reorder_animator_tag, null); }); v.setTag(R.id.reorder_animator_tag, animator); + if (mPositioner.showBubblesVertically()) { + animator.translationX(endX); + } else { + animator.translationY(endY); + } } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepository.kt index 66a75af7d64c..130790a04160 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepository.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepository.kt @@ -18,6 +18,7 @@ package com.android.wm.shell.bubbles.storage import android.content.Context import android.util.AtomicFile import android.util.Log +import android.util.SparseArray import java.io.File import java.io.FileOutputStream import java.io.IOException @@ -27,8 +28,8 @@ class BubblePersistentRepository(context: Context) { private val bubbleFile: AtomicFile = AtomicFile(File(context.filesDir, "overflow_bubbles.xml"), "overflow-bubbles") - fun persistsToDisk(bubbles: List<BubbleEntity>): Boolean { - if (DEBUG) Log.d(TAG, "persisting ${bubbles.size} bubbles") + fun persistsToDisk(bubbles: SparseArray<List<BubbleEntity>>): Boolean { + if (DEBUG) Log.d(TAG, "persisting ${bubbles.size()} bubbles") synchronized(bubbleFile) { val stream: FileOutputStream = try { bubbleFile.startWrite() } catch (e: IOException) { Log.e(TAG, "Failed to save bubble file", e) @@ -37,7 +38,7 @@ class BubblePersistentRepository(context: Context) { try { writeXml(stream, bubbles) bubbleFile.finishWrite(stream) - if (DEBUG) Log.d(TAG, "persisted ${bubbles.size} bubbles") + if (DEBUG) Log.d(TAG, "persisted ${bubbles.size()} bubbles") return true } catch (e: Exception) { Log.e(TAG, "Failed to save bubble file, restoring backup", e) @@ -47,13 +48,13 @@ class BubblePersistentRepository(context: Context) { return false } - fun readFromDisk(): List<BubbleEntity> { + fun readFromDisk(): SparseArray<List<BubbleEntity>> { synchronized(bubbleFile) { - if (!bubbleFile.exists()) return emptyList() + if (!bubbleFile.exists()) return SparseArray() try { return bubbleFile.openRead().use(::readXml) } catch (e: Throwable) { Log.e(TAG, "Failed to open bubble file", e) } - return emptyList() + return SparseArray() } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepository.kt index 7f0b165bdc25..a5267d8be9fe 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepository.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepository.kt @@ -17,6 +17,7 @@ package com.android.wm.shell.bubbles.storage import android.content.pm.LauncherApps import android.os.UserHandle +import android.util.SparseArray import com.android.internal.annotations.VisibleForTesting import com.android.wm.shell.bubbles.ShortcutKey @@ -27,10 +28,11 @@ private const val CAPACITY = 16 * manipulation. */ class BubbleVolatileRepository(private val launcherApps: LauncherApps) { + /** - * An ordered set of bubbles based on their natural ordering. + * Set of bubbles per user. Each set of bubbles is ordered by recency. */ - private var entities = mutableSetOf<BubbleEntity>() + private var entitiesByUser = SparseArray<MutableList<BubbleEntity>>() /** * The capacity of the cache. @@ -39,19 +41,43 @@ class BubbleVolatileRepository(private val launcherApps: LauncherApps) { var capacity = CAPACITY /** - * Returns a snapshot of all the bubbles. + * Returns a snapshot of all the bubbles, a map of the userId to bubble list. */ - val bubbles: List<BubbleEntity> + val bubbles: SparseArray<List<BubbleEntity>> @Synchronized - get() = entities.toList() + get() { + val map = SparseArray<List<BubbleEntity>>() + for (i in 0 until entitiesByUser.size()) { + val k = entitiesByUser.keyAt(i) + val v = entitiesByUser.valueAt(i) + map.put(k, v.toList()) + } + return map + } + + /** + * Returns the entity list of the provided user's bubbles or creates one if it doesn't exist. + */ + @Synchronized + fun getEntities(userId: Int): MutableList<BubbleEntity> { + val entities = entitiesByUser.get(userId) + return when (entities) { + null -> mutableListOf<BubbleEntity>().also { + entitiesByUser.put(userId, it) + } + else -> entities + } + } /** * Add the bubbles to memory and perform a de-duplication. In case a bubble already exists, * it will be moved to the last. */ @Synchronized - fun addBubbles(bubbles: List<BubbleEntity>) { + fun addBubbles(userId: Int, bubbles: List<BubbleEntity>) { if (bubbles.isEmpty()) return + // Get the list for this user + var entities = getEntities(userId) // Verify the size of given bubbles is within capacity, otherwise trim down to capacity val bubblesInRange = bubbles.takeLast(capacity) // To ensure natural ordering of the bubbles, removes bubbles which already exist @@ -61,16 +87,17 @@ class BubbleVolatileRepository(private val launcherApps: LauncherApps) { if (overflowCount > 0) { // Uncache ShortcutInfo of bubbles that will be removed due to capacity uncache(entities.take(overflowCount)) - entities = entities.drop(overflowCount).toMutableSet() + entities = entities.drop(overflowCount).toMutableList() } entities.addAll(bubblesInRange) + entitiesByUser.put(userId, entities) cache(uniqueBubbles) } @Synchronized - fun removeBubbles(bubbles: List<BubbleEntity>) = + fun removeBubbles(userId: Int, bubbles: List<BubbleEntity>) = uncache(bubbles.filter { b: BubbleEntity -> - entities.removeIf { e: BubbleEntity -> b.key == e.key } }) + getEntities(userId).removeIf { e: BubbleEntity -> b.key == e.key } }) private fun cache(bubbles: List<BubbleEntity>) { bubbles.groupBy { ShortcutKey(it.userId, it.packageName) }.forEach { (key, bubbles) -> diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelper.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelper.kt index a74445bba1ab..f4fa1835b7a5 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelper.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelper.kt @@ -16,6 +16,8 @@ package com.android.wm.shell.bubbles.storage import android.app.ActivityTaskManager.INVALID_TASK_ID +import android.os.UserHandle +import android.util.SparseArray import android.util.Xml import com.android.internal.util.FastXmlSerializer import com.android.internal.util.XmlUtils @@ -26,8 +28,8 @@ import java.io.InputStream import java.io.OutputStream import java.nio.charset.StandardCharsets -// TODO: handle version changes gracefully -private const val CURRENT_VERSION = 1 +// If this number increases, consider bubbles might be restored even with differences in XML. +private const val CURRENT_VERSION = 2 private const val TAG_BUBBLES = "bs" private const val ATTR_VERSION = "v" @@ -46,13 +48,20 @@ private const val ATTR_LOCUS = "l" * Writes the bubbles in xml format into given output stream. */ @Throws(IOException::class) -fun writeXml(stream: OutputStream, bubbles: List<BubbleEntity>) { +fun writeXml(stream: OutputStream, bubbles: SparseArray<List<BubbleEntity>>) { val serializer: XmlSerializer = FastXmlSerializer() serializer.setOutput(stream, StandardCharsets.UTF_8.name()) serializer.startDocument(null, true) serializer.startTag(null, TAG_BUBBLES) serializer.attribute(null, ATTR_VERSION, CURRENT_VERSION.toString()) - bubbles.forEach { b -> writeXmlEntry(serializer, b) } + for (i in 0 until bubbles.size()) { + val k = bubbles.keyAt(i) + val v = bubbles.valueAt(i) + serializer.startTag(null, TAG_BUBBLES) + serializer.attribute(null, ATTR_USER_ID, k.toString()) + v.forEach { b -> writeXmlEntry(serializer, b) } + serializer.endTag(null, TAG_BUBBLES) + } serializer.endTag(null, TAG_BUBBLES) serializer.endDocument() } @@ -84,16 +93,39 @@ private fun writeXmlEntry(serializer: XmlSerializer, bubble: BubbleEntity) { /** * Reads the bubbles from xml file. */ -fun readXml(stream: InputStream): List<BubbleEntity> { - val bubbles = mutableListOf<BubbleEntity>() +fun readXml(stream: InputStream): SparseArray<List<BubbleEntity>> { + val bubbles = SparseArray<List<BubbleEntity>>() val parser: XmlPullParser = Xml.newPullParser() parser.setInput(stream, StandardCharsets.UTF_8.name()) XmlUtils.beginDocument(parser, TAG_BUBBLES) - val version = parser.getAttributeWithName(ATTR_VERSION)?.toInt() - if (version != null && version == CURRENT_VERSION) { + val veryOuterDepth = parser.depth + val version = parser.getAttributeWithName(ATTR_VERSION)?.toInt() ?: return bubbles + if (version == CURRENT_VERSION) { + while (XmlUtils.nextElementWithin(parser, veryOuterDepth)) { + val uid = parser.getAttributeWithName(ATTR_USER_ID) ?: continue + val outerDepth = parser.depth + val userBubbles = mutableListOf<BubbleEntity>() + while (XmlUtils.nextElementWithin(parser, outerDepth)) { + userBubbles.add(readXmlEntry(parser) ?: continue) + } + if (!userBubbles.isEmpty()) { + bubbles.put(uid.toInt(), userBubbles.toList()) + } + } + } else if (version == 1) { + // upgrade v1 to v2 format val outerDepth = parser.depth + val userBubbles = mutableListOf<BubbleEntity>() while (XmlUtils.nextElementWithin(parser, outerDepth)) { - bubbles.add(readXmlEntry(parser) ?: continue) + // We can't tell which profile the bubble was for, so we'll only copy the main users' + // bubbles on upgrade. + val b = readXmlEntry(parser) + if (b != null && b.userId == UserHandle.USER_SYSTEM) { + userBubbles.add(b) + } + } + if (!userBubbles.isEmpty()) { + bubbles.put(UserHandle.USER_SYSTEM, userBubbles.toList()) } } return bubbles diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java index b9fdaa1ab1af..442e7a4c6796 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java @@ -110,6 +110,10 @@ public class DividerView extends FrameLayout implements View.OnTouchListener, return false; } + if (mDoubleTapDetector.onTouchEvent(event)) { + return true; + } + final int action = event.getAction() & MotionEvent.ACTION_MASK; final boolean isLandscape = isLandscape(); // Using raw xy to prevent lost track of motion events while moving divider bar. @@ -136,21 +140,22 @@ public class DividerView extends FrameLayout implements View.OnTouchListener, case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: mVelocityTracker.addMovement(event); + releaseTouching(); + + if (!mMoving) break; + mVelocityTracker.computeCurrentVelocity(1000 /* units */); final float velocity = isLandscape ? mVelocityTracker.getXVelocity() : mVelocityTracker.getYVelocity(); - releaseTouching(); - mMoving = false; - final int position = mSplitLayout.getDividePosition() + touchPos - mStartPos; final DividerSnapAlgorithm.SnapTarget snapTarget = mSplitLayout.findSnapTarget(position, velocity, false /* hardDismiss */); mSplitLayout.snapToTarget(position, snapTarget); + mMoving = false; break; } - mDoubleTapDetector.onTouchEvent(event); return true; } @@ -229,7 +234,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener, if (mSplitLayout != null) { mSplitLayout.onDoubleTappedDivider(); } - return false; + return true; } } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index b64c796a1a43..d318a5aaef5c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -231,6 +231,7 @@ public class SplitLayout { } private void flingDividePosition(int from, int to) { + if (from == to) return; ValueAnimator animator = ValueAnimator .ofInt(from, to) .setDuration(250); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java index 57a9dd2ec6cc..23171bb9575c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerImeController.java @@ -109,8 +109,9 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor return mSplits.mSplitScreenController.getSplitLayout(); } - private boolean isDividerVisible() { - return mSplits.mSplitScreenController.isDividerVisible(); + private boolean isDividerHidden() { + final DividerView view = mSplits.mSplitScreenController.getDividerView(); + return view == null || view.isHidden(); } private boolean getSecondaryHasFocus(int displayId) { @@ -143,7 +144,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor @ImeAnimationFlags public int onImeStartPositioning(int displayId, int hiddenTop, int shownTop, boolean imeShouldShow, boolean imeIsFloating, SurfaceControl.Transaction t) { - if (!isDividerVisible()) { + if (isDividerHidden()) { return 0; } mHiddenTop = hiddenTop; @@ -263,7 +264,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor @Override public void onImePositionChanged(int displayId, int imeTop, SurfaceControl.Transaction t) { - if (mAnimation != null || !isDividerVisible() || mPaused) { + if (mAnimation != null || isDividerHidden() || mPaused) { // Not synchronized with IME anymore, so return. return; } @@ -275,7 +276,7 @@ class DividerImeController implements DisplayImeController.ImePositionProcessor @Override public void onImeEndPositioning(int displayId, boolean cancelled, SurfaceControl.Transaction t) { - if (mAnimation != null || !isDividerVisible() || mPaused) { + if (mAnimation != null || isDividerHidden() || mPaused) { // Not synchronized with IME anymore, so return. return; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java index a18d106abea4..60f7ee2941e2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/DividerView.java @@ -49,7 +49,6 @@ import android.view.VelocityTracker; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewConfiguration; -import android.view.ViewRootImpl; import android.view.ViewTreeObserver.InternalInsetsInfo; import android.view.ViewTreeObserver.OnComputeInternalInsetsListener; import android.view.WindowManager; @@ -524,9 +523,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, case MotionEvent.ACTION_CANCEL: mVelocityTracker.addMovement(event); + if (!mMoving) break; + x = (int) event.getRawX(); y = (int) event.getRawY(); - mVelocityTracker.computeCurrentVelocity(1000); int position = calculatePosition(x, y); stopDragging(position, isHorizontalDivision() ? mVelocityTracker.getYVelocity() diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java index 27c56fd55e40..d9409ec2dc17 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/LegacySplitScreenTransitions.java @@ -30,7 +30,6 @@ import android.animation.ValueAnimator; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; -import android.app.ActivityTaskManager; import android.app.WindowConfiguration; import android.graphics.Rect; import android.os.IBinder; @@ -92,11 +91,10 @@ public class LegacySplitScreenTransitions implements Transitions.TransitionHandl // is nothing behind it. ((type == TRANSIT_CLOSE || type == TRANSIT_TO_BACK) && triggerTask.parentTaskId == mListener.mPrimary.taskId) - // if a non-resizable is launched when it is not supported in multi window, + // if an activity that is not supported in multi window mode is launched, // we also need to leave split-screen. || ((type == TRANSIT_OPEN || type == TRANSIT_TO_FRONT) - && !triggerTask.isResizeable - && !ActivityTaskManager.supportsNonResizableMultiWindow()); + && !triggerTask.supportsMultiWindow); // In both cases, dismiss the primary if (shouldDismiss) { WindowManagerProxy.buildDismissSplit(out, mListener, diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/WindowManagerProxy.java b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/WindowManagerProxy.java index 5a2ef568d82a..1072845b35dd 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/WindowManagerProxy.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/legacysplitscreen/WindowManagerProxy.java @@ -46,7 +46,6 @@ import com.android.wm.shell.transition.Transitions; import java.util.ArrayList; import java.util.List; -import java.util.function.BooleanSupplier; /** * Proxy to simplify calls into window manager/activity manager @@ -209,17 +208,10 @@ class WindowManagerProxy { return false; } ActivityManager.RunningTaskInfo topHomeTask = null; - // One-time lazy wrapper to avoid duplicated IPC in loop. Not store as class variable - // because the value can be changed at runtime. - final BooleanSupplier supportsNonResizableMultiWindow = - createSupportsNonResizableMultiWindowSupplier(); for (int i = rootTasks.size() - 1; i >= 0; --i) { final ActivityManager.RunningTaskInfo rootTask = rootTasks.get(i); - // Check whether to move resizeable task to split secondary. - // Also, we have an exception for non-resizable home because we will minimize to show - // it. - if (!rootTask.isResizeable && rootTask.topActivityType != ACTIVITY_TYPE_HOME - && !supportsNonResizableMultiWindow.getAsBoolean()) { + // Check whether the task can be moved to split secondary. + if (!rootTask.supportsMultiWindow && rootTask.topActivityType != ACTIVITY_TYPE_HOME) { continue; } // Only move fullscreen tasks to split secondary. @@ -364,21 +356,6 @@ class WindowManagerProxy { outWct.setFocusable(tiles.mPrimary.token, true /* focusable */); } - /** Creates a lazy wrapper to get whether it supports non-resizable in multi window. */ - private static BooleanSupplier createSupportsNonResizableMultiWindowSupplier() { - return new BooleanSupplier() { - private Boolean mSupportsNonResizableMultiWindow; - @Override - public boolean getAsBoolean() { - if (mSupportsNonResizableMultiWindow == null) { - mSupportsNonResizableMultiWindow = - ActivityTaskManager.supportsNonResizableMultiWindow(); - } - return mSupportsNonResizableMultiWindow; - } - }; - } - /** * Utility to apply a sync transaction serially with other sync transactions. * diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java index 625f4b85c946..04ec3917428e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java @@ -21,6 +21,10 @@ import static android.os.UserHandle.myUserId; import static android.view.Display.DEFAULT_DISPLAY; import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; +import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE; +import static com.android.wm.shell.onehanded.OneHandedState.STATE_ENTERING; +import static com.android.wm.shell.onehanded.OneHandedState.STATE_EXITING; +import static com.android.wm.shell.onehanded.OneHandedState.STATE_NONE; import android.annotation.BinderThread; import android.content.ComponentName; @@ -62,8 +66,7 @@ import java.io.PrintWriter; /** * Manages and manipulates the one handed states, transitions, and gesture for phones. */ -public class OneHandedController implements RemoteCallable<OneHandedController>, - OneHandedTransitionCallback { +public class OneHandedController implements RemoteCallable<OneHandedController> { private static final String TAG = "OneHandedController"; private static final String ONE_HANDED_MODE_OFFSET_PERCENTAGE = @@ -75,7 +78,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, private volatile boolean mIsOneHandedEnabled; private volatile boolean mIsSwipeToNotificationEnabled; - private volatile boolean mIsTransitioning; private boolean mTaskChangeToExit; private boolean mLockedDisabled; private int mUserId; @@ -89,6 +91,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, private final OneHandedAccessibilityUtil mOneHandedAccessibilityUtil; private final OneHandedTimeoutHandler mTimeoutHandler; private final OneHandedTouchHandler mTouchHandler; + private final OneHandedState mState; private final OneHandedTutorialHandler mTutorialHandler; private final OneHandedUiEventLogger mOneHandedUiEventLogger; private final TaskStackListenerImpl mTaskStackListener; @@ -162,6 +165,19 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, } }; + private final OneHandedTransitionCallback mTransitionCallBack = + new OneHandedTransitionCallback() { + @Override + public void onStartFinished(Rect bounds) { + mState.setState(STATE_ACTIVE); + } + + @Override + public void onStopFinished(Rect bounds) { + mState.setState(STATE_NONE); + } + }; + private final TaskStackListenerCallback mTaskStackListenerCallback = new TaskStackListenerCallback() { @Override @@ -200,8 +216,9 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, OneHandedSettingsUtil settingsUtil = new OneHandedSettingsUtil(); OneHandedAccessibilityUtil accessibilityUtil = new OneHandedAccessibilityUtil(context); OneHandedTimeoutHandler timeoutHandler = new OneHandedTimeoutHandler(mainExecutor); + OneHandedState transitionState = new OneHandedState(); OneHandedTutorialHandler tutorialHandler = new OneHandedTutorialHandler(context, - windowManager, mainExecutor); + displayLayout, windowManager, mainExecutor); OneHandedAnimationController animationController = new OneHandedAnimationController(context); OneHandedTouchHandler touchHandler = new OneHandedTouchHandler(timeoutHandler, @@ -218,7 +235,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, ServiceManager.getService(Context.OVERLAY_SERVICE)); return new OneHandedController(context, displayController, oneHandedBackgroundPanelOrganizer, organizer, touchHandler, tutorialHandler, - gestureHandler, settingsUtil, accessibilityUtil, timeoutHandler, + gestureHandler, settingsUtil, accessibilityUtil, timeoutHandler, transitionState, oneHandedUiEventsLogger, overlayManager, taskStackListener, mainExecutor, mainHandler); } @@ -234,6 +251,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, OneHandedSettingsUtil settingsUtil, OneHandedAccessibilityUtil oneHandedAccessibilityUtil, OneHandedTimeoutHandler timeoutHandler, + OneHandedState state, OneHandedUiEventLogger uiEventsLogger, IOverlayManager overlayManager, TaskStackListenerImpl taskStackListener, @@ -246,6 +264,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, mDisplayAreaOrganizer = displayAreaOrganizer; mDisplayController = displayController; mTouchHandler = touchHandler; + mState = state; mTutorialHandler = tutorialHandler; mGestureHandler = gestureHandler; mOverlayManager = overlayManager; @@ -330,26 +349,27 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, @VisibleForTesting void startOneHanded() { - if (isLockedDisabled() || mIsTransitioning) { + if (isLockedDisabled()) { Slog.d(TAG, "Temporary lock disabled"); return; } + if (mState.isTransitioning() || mState.isInOneHanded()) { + return; + } final int currentRotation = mDisplayAreaOrganizer.getDisplayLayout().rotation(); if (currentRotation != Surface.ROTATION_0 && currentRotation != Surface.ROTATION_180) { Slog.w(TAG, "One handed mode only support portrait mode"); return; } - if (!mDisplayAreaOrganizer.isInOneHanded()) { - mIsTransitioning = true; - final int yOffSet = Math.round( - mDisplayAreaOrganizer.getDisplayLayout().height() * mOffSetFraction); - mOneHandedAccessibilityUtil.announcementForScreenReader( - mOneHandedAccessibilityUtil.getOneHandedStartDescription()); - mDisplayAreaOrganizer.scheduleOffset(0, yOffSet); - mTimeoutHandler.resetTimer(); - mOneHandedUiEventLogger.writeEvent( - OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_GESTURE_IN); - } + mState.setState(STATE_ENTERING); + final int yOffSet = Math.round( + mDisplayAreaOrganizer.getDisplayLayout().height() * mOffSetFraction); + mOneHandedAccessibilityUtil.announcementForScreenReader( + mOneHandedAccessibilityUtil.getOneHandedStartDescription()); + mDisplayAreaOrganizer.scheduleOffset(0, yOffSet); + mTimeoutHandler.resetTimer(); + mOneHandedUiEventLogger.writeEvent( + OneHandedUiEventLogger.EVENT_ONE_HANDED_TRIGGER_GESTURE_IN); } @VisibleForTesting @@ -358,14 +378,15 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, } private void stopOneHanded(int uiEvent) { - if (mDisplayAreaOrganizer.isInOneHanded() && !mIsTransitioning) { - mIsTransitioning = true; - mOneHandedAccessibilityUtil.announcementForScreenReader( - mOneHandedAccessibilityUtil.getOneHandedStopDescription()); - mDisplayAreaOrganizer.scheduleOffset(0, 0); - mTimeoutHandler.removeTimer(); - mOneHandedUiEventLogger.writeEvent(uiEvent); + if (mState.isTransitioning() || mState.getState() == STATE_NONE) { + return; } + mState.setState(STATE_EXITING); + mOneHandedAccessibilityUtil.announcementForScreenReader( + mOneHandedAccessibilityUtil.getOneHandedStopDescription()); + mDisplayAreaOrganizer.scheduleOffset(0, 0); + mTimeoutHandler.removeTimer(); + mOneHandedUiEventLogger.writeEvent(uiEvent); } private void setThreeButtonModeEnabled(boolean enabled) { @@ -388,7 +409,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, mDisplayAreaOrganizer.registerTransitionCallback(mGestureHandler); mDisplayAreaOrganizer.registerTransitionCallback(mTutorialHandler); mDisplayAreaOrganizer.registerTransitionCallback(mBackgroundPanelOrganizer); - mDisplayAreaOrganizer.registerTransitionCallback(this); + mDisplayAreaOrganizer.registerTransitionCallback(mTransitionCallBack); if (mTaskChangeToExit) { mTaskStackListener.addListener(mTaskStackListenerCallback); } @@ -432,6 +453,7 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, final DisplayLayout newDisplayLayout = mDisplayController.getDisplayLayout(displayId); mDisplayAreaOrganizer.setDisplayLayout(newDisplayLayout); mGestureHandler.onDisplayChanged(newDisplayLayout); + mTutorialHandler.onDisplayChanged(newDisplayLayout); } private ContentObserver getObserver(Runnable onChangeRunnable) { @@ -523,8 +545,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, } private void updateOneHandedEnabled() { - if (mDisplayAreaOrganizer.isInOneHanded()) { - stopOneHanded(); + if (mState.getState() == STATE_ENTERING || mState.getState() == STATE_ACTIVE) { + mMainExecutor.execute(() -> stopOneHanded()); } mTouchHandler.onOneHandedEnabled(mIsOneHandedEnabled); @@ -615,8 +637,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, pw.println(mLockedDisabled); pw.print(innerPrefix + "mUserId="); pw.println(mUserId); - pw.print(innerPrefix + "mIsTransitioning="); - pw.println(mIsTransitioning); if (mBackgroundPanelOrganizer != null) { mBackgroundPanelOrganizer.dump(pw); @@ -638,6 +658,10 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, mTimeoutHandler.dump(pw); } + if (mState != null) { + mState.dump(pw); + } + if (mTutorialHandler != null) { mTutorialHandler.dump(pw); } @@ -663,26 +687,6 @@ public class OneHandedController implements RemoteCallable<OneHandedController>, } /** - * TODO(b/185558765) To implement a state machine for One-Handed transition state machine. - * ONE_HANDDE_STATE_TRANSITION { - * STATE_DEFAULT, - * STATE_TRANSITIONING, - * STATE_ENTER_ONE_HANED, - * STATE_EXIT_ONE_HANDED - * } - * and we need to align the state to launcher3 quick steps through SysuiProxy. - */ - @Override - public void onStartFinished(Rect bounds) { - mIsTransitioning = false; - } - - @Override - public void onStopFinished(Rect bounds) { - mIsTransitioning = false; - } - - /** * The interface for calls from outside the Shell, within the host process. */ @ExternalThread diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java index d1b3f1a2e8a5..4b4d934bef43 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java @@ -65,7 +65,6 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { private final Rect mDefaultDisplayBounds = new Rect(); private final OneHandedSettingsUtil mOneHandedSettingsUtil; - private boolean mIsInOneHanded; private int mEnterExitAnimationDurationMs; private ArrayMap<WindowContainerToken, SurfaceControl> mDisplayAreaTokenMap = new ArrayMap(); @@ -82,6 +81,14 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { @Override public void onOneHandedAnimationStart( OneHandedAnimationController.OneHandedTransitionAnimator animator) { + final boolean isEntering = animator.getTransitionDirection() + == TRANSITION_DIRECTION_TRIGGER; + if (!mTransitionCallbacks.isEmpty()) { + for (int i = mTransitionCallbacks.size() - 1; i >= 0; i--) { + final OneHandedTransitionCallback cb = mTransitionCallbacks.get(i); + cb.onStartTransition(isEntering); + } + } } @Override @@ -260,31 +267,20 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { @VisibleForTesting void finishOffset(int offset, @OneHandedAnimationController.TransitionDirection int direction) { - // Only finishOffset() can update mIsInOneHanded to ensure the state is handle in sequence, - // the flag *MUST* be updated before dispatch mTransitionCallbacks - mIsInOneHanded = (offset > 0 || direction == TRANSITION_DIRECTION_TRIGGER); mLastVisualDisplayBounds.offsetTo(0, direction == TRANSITION_DIRECTION_TRIGGER ? offset : 0); for (int i = mTransitionCallbacks.size() - 1; i >= 0; i--) { - final OneHandedTransitionCallback callback = mTransitionCallbacks.get(i); + final OneHandedTransitionCallback cb = mTransitionCallbacks.get(i); + cb.onStartTransition(false /* isTransitioning */); if (direction == TRANSITION_DIRECTION_TRIGGER) { - callback.onStartFinished(getLastVisualDisplayBounds()); + cb.onStartFinished(getLastVisualDisplayBounds()); } else { - callback.onStopFinished(getLastVisualDisplayBounds()); + cb.onStopFinished(getLastVisualDisplayBounds()); } } } /** - * The latest state of one handed mode - * - * @return true Currently is in one handed mode, otherwise is not in one handed mode - */ - public boolean isInOneHanded() { - return mIsInOneHanded; - } - - /** * The latest visual bounds of displayArea translated * * @return Rect latest finish_offset @@ -328,8 +324,6 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer { void dump(@NonNull PrintWriter pw) { final String innerPrefix = " "; pw.println(TAG + "states: "); - pw.print(innerPrefix + "mIsInOneHanded="); - pw.println(mIsInOneHanded); pw.print(innerPrefix + "mDisplayLayout.rotation()="); pw.println(mDisplayLayout.rotation()); pw.print(innerPrefix + "mDisplayAreaTokenMap="); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java new file mode 100644 index 000000000000..cc874432be87 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.onehanded; + +import android.annotation.IntDef; + +import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + Represents current OHM state by following steps, a generic CUJ is + STATE_NONE -> STATE_ENTERING -> STATE_ACTIVE -> STATE_EXITING -> STATE_NONE + */ +public class OneHandedState { + /** DEFAULT STATE after OHM feature initialized. */ + public static final int STATE_NONE = 0x00000000; + /** The state flag set when user trigger OHM. */ + public static final int STATE_ENTERING = 0x00000001; + /** The state flag set when transitioning */ + public static final int STATE_ACTIVE = 0x00000002; + /** The state flag set when user stop OHM feature. */ + public static final int STATE_EXITING = 0x00000004; + + @IntDef(prefix = { "STATE_" }, value = { + STATE_NONE, + STATE_ENTERING, + STATE_ACTIVE, + STATE_EXITING + }) + @Retention(RetentionPolicy.SOURCE) + @interface State {} + + public OneHandedState() { + sCurrentState = STATE_NONE; + } + + @State + private static int sCurrentState = STATE_NONE; + + private static final String TAG = OneHandedState.class.getSimpleName(); + + /** + * Gets current transition state of One handed mode. + * + * @return The bitwise flags representing current states. + */ + public @State int getState() { + return sCurrentState; + } + + /** + * Is the One handed mode is in transitioning state. + * @return true if One handed mode is in transitioning states. + */ + public boolean isTransitioning() { + return sCurrentState == STATE_ENTERING || sCurrentState == STATE_EXITING; + } + + /** + * Is the One handed mode active state. + * @return true if One handed mode is active state. + */ + public boolean isInOneHanded() { + return sCurrentState == STATE_ACTIVE; + } + + /** + * Sets new state for One handed mode feature. + * @param newState The bitwise value to represent current transition states. + */ + public void setState(@State int newState) { + sCurrentState = newState; + } + + /** Dumps internal state. */ + public void dump(PrintWriter pw) { + final String innerPrefix = " "; + pw.println(TAG + "states: "); + pw.println(innerPrefix + "sCurrentState=" + sCurrentState); + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTransitionCallback.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTransitionCallback.java index 3af7c4b71d0a..e8291862947b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTransitionCallback.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTransitionCallback.java @@ -24,6 +24,12 @@ import android.graphics.Rect; */ public interface OneHandedTransitionCallback { /** + * Called when one handed mode entering or exiting transition starting + */ + default void onStartTransition(boolean isEntering) { + } + + /** * Called when start one handed transition finished */ default void onStartFinished(Rect bounds) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java index b445917fb90c..7a3f34d0e5a5 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java @@ -33,6 +33,7 @@ import android.widget.FrameLayout; import androidx.annotation.NonNull; import com.android.wm.shell.R; +import com.android.wm.shell.common.DisplayLayout; import com.android.wm.shell.common.ShellExecutor; import java.io.PrintWriter; @@ -50,9 +51,10 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback { private static final int MAX_TUTORIAL_SHOW_COUNT = 2; private final WindowManager mWindowManager; private final String mPackageName; - private final Rect mDisplaySize; + private final float mTutorialHeightRatio; private Context mContext; + private Rect mDisplayBounds; private View mTutorialView; private ContentResolver mContentResolver; private boolean mCanShowTutorial; @@ -94,23 +96,22 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback { } }; - public OneHandedTutorialHandler(Context context, WindowManager windowManager, - ShellExecutor mainExecutor) { + public OneHandedTutorialHandler(Context context, DisplayLayout displayLayout, + WindowManager windowManager, ShellExecutor mainExecutor) { mContext = context; mWindowManager = windowManager; - mDisplaySize = windowManager.getCurrentWindowMetrics().getBounds(); mPackageName = context.getPackageName(); mContentResolver = context.getContentResolver(); - mCanShowTutorial = (Settings.Secure.getInt(mContentResolver, - Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0) >= MAX_TUTORIAL_SHOW_COUNT) - ? false : true; - mIsOneHandedMode = false; final float offsetPercentageConfig = context.getResources().getFraction( R.fraction.config_one_handed_offset, 1, 1); final int sysPropPercentageConfig = SystemProperties.getInt( ONE_HANDED_MODE_OFFSET_PERCENTAGE, Math.round(offsetPercentageConfig * 100.0f)); - mTutorialAreaHeight = Math.round( - mDisplaySize.height() * (sysPropPercentageConfig / 100.0f)); + mTutorialHeightRatio = sysPropPercentageConfig / 100.0f; + onDisplayChanged(displayLayout); + mCanShowTutorial = (Settings.Secure.getInt(mContentResolver, + Settings.Secure.ONE_HANDED_TUTORIAL_SHOW_COUNT, 0) >= MAX_TUTORIAL_SHOW_COUNT) + ? false : true; + mIsOneHandedMode = false; mainExecutor.execute(() -> { recreateTutorialView(mContext); @@ -131,6 +132,20 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback { mTriggerState = ONE_HANDED_TRIGGER_STATE.UNSET; } + /** + * Called when onDisplayAdded() or onDisplayRemoved() callback + * @param displayLayout The latest {@link DisplayLayout} representing current displayId + */ + public void onDisplayChanged(DisplayLayout displayLayout) { + // Ensure the mDisplayBounds is portrait, due to OHM only support on portrait + if (displayLayout.height() > displayLayout.width()) { + mDisplayBounds = new Rect(0, 0, displayLayout.width(), displayLayout.height()); + } else { + mDisplayBounds = new Rect(0, 0, displayLayout.height(), displayLayout.width()); + } + mTutorialAreaHeight = Math.round(mDisplayBounds.height() * mTutorialHeightRatio); + } + private void recreateTutorialView(Context context) { mTutorialView = LayoutInflater.from(context).inflate(R.layout.one_handed_tutorial, null); @@ -190,7 +205,7 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback { */ private WindowManager.LayoutParams getTutorialTargetLayoutParams() { final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - mDisplaySize.width(), mTutorialAreaHeight, 0, 0, + mDisplayBounds.width(), mTutorialAreaHeight, 0, 0, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, @@ -207,8 +222,8 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback { pw.println(TAG + " states: "); pw.print(innerPrefix + "mTriggerState="); pw.println(mTriggerState); - pw.print(innerPrefix + "mDisplaySize="); - pw.println(mDisplaySize); + pw.print(innerPrefix + "mDisplayBounds="); + pw.println(mDisplayBounds); pw.print(innerPrefix + "mTutorialAreaHeight="); pw.println(mTutorialAreaHeight); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java index 8ac9a7a479db..ca05ff47d507 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java @@ -427,36 +427,44 @@ public class PipAnimationController { Rect baseValue, Rect startValue, Rect endValue, Rect sourceHintRect, @PipAnimationController.TransitionDirection int direction, float startingAngle, @Surface.Rotation int rotationDelta) { + final boolean isOutPipDirection = isOutPipDirection(direction); + // Just for simplicity we'll interpolate between the source rect hint insets and empty // insets to calculate the window crop final Rect initialSourceValue; - if (isOutPipDirection(direction)) { + if (isOutPipDirection) { initialSourceValue = new Rect(endValue); } else { initialSourceValue = new Rect(baseValue); } - final Rect sourceHintRectInsets; - if (sourceHintRect == null) { - sourceHintRectInsets = null; - } else { - sourceHintRectInsets = new Rect(sourceHintRect.left - initialSourceValue.left, - sourceHintRect.top - initialSourceValue.top, - initialSourceValue.right - sourceHintRect.right, - initialSourceValue.bottom - sourceHintRect.bottom); - } - final Rect sourceInsets = new Rect(0, 0, 0, 0); - final Rect rotatedEndRect; + final Rect lastEndRect; + final Rect initialContainerRect; if (rotationDelta == ROTATION_90 || rotationDelta == ROTATION_270) { + lastEndRect = new Rect(endValue); + rotatedEndRect = new Rect(endValue); // Rotate the end bounds according to the rotation delta because the display will // be rotated to the same orientation. - rotatedEndRect = new Rect(endValue); - rotateBounds(rotatedEndRect, endValue, rotationDelta); + rotateBounds(rotatedEndRect, initialSourceValue, rotationDelta); + // Use the rect that has the same orientation as the hint rect. + initialContainerRect = isOutPipDirection ? rotatedEndRect : initialSourceValue; } else { - rotatedEndRect = null; + rotatedEndRect = lastEndRect = null; + initialContainerRect = initialSourceValue; } + final Rect sourceHintRectInsets; + if (sourceHintRect == null) { + sourceHintRectInsets = null; + } else { + sourceHintRectInsets = new Rect(sourceHintRect.left - initialContainerRect.left, + sourceHintRect.top - initialContainerRect.top, + initialContainerRect.right - sourceHintRect.right, + initialContainerRect.bottom - sourceHintRect.bottom); + } + final Rect zeroInsets = new Rect(0, 0, 0, 0); + // construct new Rect instances in case they are recycled return new PipTransitionAnimator<Rect>(taskInfo, leash, ANIM_TYPE_BOUNDS, endValue, new Rect(baseValue), new Rect(startValue), new Rect(endValue), @@ -472,8 +480,8 @@ public class PipAnimationController { final Rect end = getEndValue(); if (rotatedEndRect != null) { // Animate the bounds in a different orientation. It only happens when - // leaving PiP to fullscreen. - applyRotation(tx, leash, fraction, start, end, rotatedEndRect); + // switching between PiP and fullscreen. + applyRotation(tx, leash, fraction, start, end); return; } Rect bounds = mRectEvaluator.evaluate(fraction, start, end); @@ -481,20 +489,13 @@ public class PipAnimationController { setCurrentValue(bounds); if (inScaleTransition() || sourceHintRect == null) { - if (isOutPipDirection(direction)) { + if (isOutPipDirection) { getSurfaceTransactionHelper().scale(tx, leash, end, bounds); } else { getSurfaceTransactionHelper().scale(tx, leash, base, bounds, angle); } } else { - final Rect insets; - if (isOutPipDirection(direction)) { - insets = mInsetsEvaluator.evaluate(fraction, sourceHintRectInsets, - sourceInsets); - } else { - insets = mInsetsEvaluator.evaluate(fraction, sourceInsets, - sourceHintRectInsets); - } + final Rect insets = computeInsets(fraction); getSurfaceTransactionHelper().scaleAndCrop(tx, leash, initialSourceValue, bounds, insets); } @@ -502,9 +503,17 @@ public class PipAnimationController { } private void applyRotation(SurfaceControl.Transaction tx, SurfaceControl leash, - float fraction, Rect start, Rect end, Rect rotatedEndRect) { + float fraction, Rect start, Rect end) { + if (!end.equals(lastEndRect)) { + // If the end bounds are changed during animating (e.g. shelf height), the + // rotated end bounds also need to be updated. + rotatedEndRect.set(endValue); + rotateBounds(rotatedEndRect, initialSourceValue, rotationDelta); + lastEndRect.set(end); + } final Rect bounds = mRectEvaluator.evaluate(fraction, start, rotatedEndRect); setCurrentValue(bounds); + final Rect insets = computeInsets(fraction); final float degree, x, y; if (rotationDelta == ROTATION_90) { degree = 90 * fraction; @@ -515,11 +524,21 @@ public class PipAnimationController { x = fraction * (end.left - start.left) + start.left; y = fraction * (end.bottom - start.top) + start.top; } - getSurfaceTransactionHelper().rotateAndScaleWithCrop(tx, leash, bounds, - rotatedEndRect, degree, x, y); + getSurfaceTransactionHelper().rotateAndScaleWithCrop(tx, leash, + initialContainerRect, bounds, insets, degree, x, y, isOutPipDirection, + rotationDelta == ROTATION_270 /* clockwise */); tx.apply(); } + private Rect computeInsets(float fraction) { + if (sourceHintRectInsets == null) { + return zeroInsets; + } + final Rect startRect = isOutPipDirection ? sourceHintRectInsets : zeroInsets; + final Rect endRect = isOutPipDirection ? zeroInsets : sourceHintRectInsets; + return mInsetsEvaluator.evaluate(fraction, startRect, endRect); + } + @Override void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) { getSurfaceTransactionHelper() diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java index e3594d0cd367..561dff0da6ca 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java @@ -19,10 +19,14 @@ package com.android.wm.shell.pip; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.ActivityTaskManager; +import android.app.PictureInPictureUiState; import android.content.ComponentName; import android.content.Context; import android.graphics.Point; import android.graphics.Rect; +import android.os.RemoteException; +import android.util.Log; import android.util.Size; import android.view.Display; @@ -185,7 +189,18 @@ public final class PipBoundsState { /** Dictate where PiP currently should be stashed, if at all. */ public void setStashed(@StashType int stashedState) { + if (mStashedState == stashedState) { + return; + } + mStashedState = stashedState; + try { + ActivityTaskManager.getService().onPictureInPictureStateChanged( + new PictureInPictureUiState(stashedState != STASH_TYPE_NONE /* isStashed */) + ); + } catch (RemoteException e) { + Log.e(TAG, "Unable to set alert PiP state change."); + } } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java index 3af0ff0dfb36..97139626a3d2 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipMediaController.java @@ -21,6 +21,7 @@ import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; import android.annotation.DrawableRes; import android.annotation.StringRes; +import android.annotation.SuppressLint; import android.app.PendingIntent; import android.app.RemoteAction; import android.content.BroadcastReceiver; @@ -210,13 +211,16 @@ public class PipMediaController { /** * Gets the set of media actions currently available. */ + // This is due to using PlaybackState#isActive, which is added in API 31. + // It can be removed when min_sdk of the app is set to 31 or greater. + @SuppressLint("NewApi") private List<RemoteAction> getMediaActions() { if (mMediaController == null || mMediaController.getPlaybackState() == null) { return Collections.emptyList(); } ArrayList<RemoteAction> mediaActions = new ArrayList<>(); - boolean isPlaying = mMediaController.getPlaybackState().isActiveState(); + boolean isPlaying = mMediaController.getPlaybackState().isActive(); long actions = mMediaController.getPlaybackState().getActions(); // Prev action diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSnapAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSnapAlgorithm.java index 0528e4d88374..dd30137813e5 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSnapAlgorithm.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSnapAlgorithm.java @@ -109,13 +109,14 @@ public class PipSnapAlgorithm { * consideration. */ public void applySnapFraction(Rect stackBounds, Rect movementBounds, float snapFraction, - @PipBoundsState.StashType int stashType, int stashOffset, Rect displayBounds) { + @PipBoundsState.StashType int stashType, int stashOffset, Rect displayBounds, + Rect insetBounds) { applySnapFraction(stackBounds, movementBounds, snapFraction); if (stashType != STASH_TYPE_NONE) { stackBounds.offsetTo(stashType == STASH_TYPE_LEFT - ? stashOffset - stackBounds.width() - : displayBounds.right - stashOffset, + ? stashOffset - stackBounds.width() + insetBounds.left + : displayBounds.right - stashOffset - insetBounds.right, stackBounds.top); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java index 582ff2180c83..2b795390adda 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java @@ -21,6 +21,7 @@ import android.content.res.Resources; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.RectF; +import android.os.SystemProperties; import android.view.SurfaceControl; import com.android.wm.shell.R; @@ -42,7 +43,8 @@ public class PipSurfaceTransactionHelper { public PipSurfaceTransactionHelper(Context context) { final Resources res = context.getResources(); - mEnableCornerRadius = res.getBoolean(R.bool.config_pipEnableRoundCorner); + mEnableCornerRadius = res.getBoolean(R.bool.config_pipEnableRoundCorner) + || SystemProperties.getBoolean("debug.sf.enable_hole_punch_pip", false); } /** @@ -135,23 +137,41 @@ public class PipSurfaceTransactionHelper { * @return same {@link PipSurfaceTransactionHelper} instance for method chaining */ public PipSurfaceTransactionHelper rotateAndScaleWithCrop(SurfaceControl.Transaction tx, - SurfaceControl leash, Rect sourceBounds, Rect destinationBounds, float degrees, - float positionX, float positionY) { + SurfaceControl leash, Rect sourceBounds, Rect destinationBounds, Rect insets, + float degrees, float positionX, float positionY, boolean isExpanding, + boolean clockwise) { mTmpDestinationRect.set(sourceBounds); - final int dw = destinationBounds.width(); - final int dh = destinationBounds.height(); + mTmpDestinationRect.inset(insets); + final int srcW = mTmpDestinationRect.width(); + final int srcH = mTmpDestinationRect.height(); + final int destW = destinationBounds.width(); + final int destH = destinationBounds.height(); // Scale by the short side so there won't be empty area if the aspect ratio of source and // destination are different. - final float scale = dw <= dh - ? (float) sourceBounds.width() / dw - : (float) sourceBounds.height() / dh; + final float scale = srcW <= srcH ? (float) destW / srcW : (float) destH / srcH; + final Rect crop = mTmpDestinationRect; + crop.set(0, 0, destW, destH); // Inverse scale for crop to fit in screen coordinates. - mTmpDestinationRect.scale(1 / scale); - mTmpTransform.setRotate(degrees); - mTmpTransform.postScale(scale, scale); + crop.scale(1 / scale); + crop.offset(insets.left, insets.top); + if (isExpanding) { + // Expand bounds (shrink insets) in source orientation. + positionX -= insets.left * scale; + positionY -= insets.top * scale; + } else { + // Shrink bounds (expand insets) in destination orientation. + if (clockwise) { + positionX -= insets.top * scale; + positionY -= insets.left * scale; + } else { + positionX += insets.top * scale; + positionY += insets.left * scale; + } + } + mTmpTransform.setScale(scale, scale); + mTmpTransform.postRotate(degrees); mTmpTransform.postTranslate(positionX, positionY); - tx.setMatrix(leash, mTmpTransform, mTmpFloat9) - .setWindowCrop(leash, mTmpDestinationRect.width(), mTmpDestinationRect.height()); + tx.setMatrix(leash, mTmpTransform, mTmpFloat9).setWindowCrop(leash, crop); return this; } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index e66be66c8ef4..4ce6c9e35e9e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -20,6 +20,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static android.util.RotationUtils.deltaRotation; +import static android.util.RotationUtils.rotateBounds; import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_PIP; import static com.android.wm.shell.ShellTaskOrganizer.taskListenerTypeToString; @@ -50,8 +52,10 @@ import android.app.TaskInfo; import android.content.ComponentName; import android.content.Context; import android.content.pm.ActivityInfo; +import android.content.res.Configuration; import android.graphics.Rect; import android.os.RemoteException; +import android.os.SystemClock; import android.util.Log; import android.util.Rational; import android.view.Display; @@ -94,6 +98,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, DisplayController.OnDisplaysChangedListener { private static final String TAG = PipTaskOrganizer.class.getSimpleName(); private static final boolean DEBUG = false; + /** + * The alpha type is set for swiping to home. But the swiped task may not enter PiP. And if + * another task enters PiP by non-swipe ways, e.g. call API in foreground or switch to 3-button + * navigation, then the alpha type is unexpected. + */ + private static final int ONE_SHOT_ALPHA_ANIMATION_TIMEOUT_MS = 1000; // Not a complete set of states but serves what we want right now. private enum State { @@ -127,6 +137,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } } + private final Context mContext; private final SyncTransactionQueue mSyncTransactionQueue; private final PipBoundsState mPipBoundsState; private final PipBoundsAlgorithm mPipBoundsAlgorithm; @@ -160,8 +171,20 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, public void onPipAnimationEnd(TaskInfo taskInfo, SurfaceControl.Transaction tx, PipAnimationController.PipTransitionAnimator animator) { final int direction = animator.getTransitionDirection(); - finishResize(tx, animator.getDestinationBounds(), direction, - animator.getAnimationType()); + final int animationType = animator.getAnimationType(); + final Rect destinationBounds = animator.getDestinationBounds(); + if (mWaitForFixedRotation && animationType == ANIM_TYPE_BOUNDS + && direction == TRANSITION_DIRECTION_TO_PIP) { + // Notify the display to continue the deferred orientation change. + final WindowContainerTransaction wct = new WindowContainerTransaction(); + wct.scheduleFinishEnterPip(mToken, destinationBounds); + mTaskOrganizer.applyTransaction(wct); + // The final task bounds will be applied by onFixedRotationFinished so that all + // coordinates are in new rotation. + mDeferredAnimEndTransaction = tx; + return; + } + finishResize(tx, destinationBounds, direction, animationType); sendOnPipTransitionFinished(direction); if (direction == TRANSITION_DIRECTION_TO_PIP) { // TODO (b//169221267): Add jank listener for transactions without buffer updates. @@ -186,10 +209,18 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, private SurfaceControl mLeash; private State mState = State.UNDEFINED; private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS; + private long mLastOneShotAlphaAnimationTime; private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory mSurfaceControlTransactionFactory; private PictureInPictureParams mPictureInPictureParams; private IntConsumer mOnDisplayIdChangeCallback; + /** + * The end transaction of PiP animation for switching between PiP and fullscreen with + * orientation change. The transaction should be applied after the display is rotated. + */ + private SurfaceControl.Transaction mDeferredAnimEndTransaction; + /** Whether the existing PiP is hidden by alpha. */ + private boolean mHasFadeOut; /** * If set to {@code true}, the entering animation will be skipped and we will wait for @@ -203,6 +234,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, */ private @Surface.Rotation int mNextRotation; + private @Surface.Rotation int mCurrentRotation; + /** * If set to {@code true}, no entering PiP transition would be kicked off and most likely * it's due to the fact that Launcher is handling the transition directly when swiping @@ -224,6 +257,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, @NonNull PipUiEventLogger pipUiEventLogger, @NonNull ShellTaskOrganizer shellTaskOrganizer, @ShellMainThread ShellExecutor mainExecutor) { + mContext = context; mSyncTransactionQueue = syncTransactionQueue; mPipBoundsState = pipBoundsState; mPipBoundsAlgorithm = boundsHandler; @@ -261,10 +295,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, return mState.isInPip(); } - public boolean isDeferringEnterPipAnimation() { - return mState.isInPip() && mWaitForFixedRotation; - } - /** * Returns whether the entry animation is waiting to be started. */ @@ -286,6 +316,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, */ public void setOneShotAnimationType(@PipAnimationController.AnimationType int animationType) { mOneShotAnimationType = animationType; + if (animationType == ANIM_TYPE_ALPHA) { + mLastOneShotAlphaAnimationTime = SystemClock.uptimeMillis(); + } } /** @@ -297,9 +330,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mInSwipePipToHomeTransition = true; sendOnPipTransitionStarted(TRANSITION_DIRECTION_TO_PIP); setBoundsStateForEntry(componentName, pictureInPictureParams, activityInfo); - // disable the conflicting transaction from fixed rotation, see also - // onFixedRotationStarted and onFixedRotationFinished - mWaitForFixedRotation = false; return mPipBoundsAlgorithm.getEntryDestinationBounds(); } @@ -355,6 +385,9 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, : WINDOWING_MODE_FULLSCREEN); wct.setBounds(mToken, destinationBounds); wct.setBoundsChangeTransaction(mToken, tx); + // Set the exiting state first so if there is fixed rotation later, the running animation + // won't be interrupted by alpha animation for existing PiP. + mState = State.EXITING_PIP; mSyncTransactionQueue.queue(wct); mSyncTransactionQueue.runInSync(t -> { // Make sure to grab the latest source hint rect as it could have been @@ -362,9 +395,8 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, final Rect sourceHintRect = PipBoundsAlgorithm.getValidSourceHintRect( mPictureInPictureParams, destinationBounds); final PipAnimationController.PipTransitionAnimator<?> animator = - scheduleAnimateResizePip(mPipBoundsState.getBounds(), destinationBounds, - 0 /* startingAngle */, sourceHintRect, direction, - animationDurationMs, null /* updateBoundsCallback */); + animateResizePip(mPipBoundsState.getBounds(), destinationBounds, sourceHintRect, + direction, animationDurationMs, 0 /* startingAngle */); if (animator != null) { // Even though the animation was started above, re-apply the transaction for the // first frame using the SurfaceControl.Transaction supplied by the @@ -374,7 +406,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, // hint during expansion that causes a visible jank/flash. See b/184166183. animator.applySurfaceControlTransaction(mLeash, t, FRACTION_START); } - mState = State.EXITING_PIP; }); } @@ -447,29 +478,22 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } if (mInSwipePipToHomeTransition) { - final Rect destinationBounds = mPipBoundsState.getBounds(); - final SurfaceControl.Transaction tx = - mSurfaceControlTransactionFactory.getTransaction(); - mSurfaceTransactionHelper.resetScale(tx, mLeash, destinationBounds); - mSurfaceTransactionHelper.crop(tx, mLeash, destinationBounds); - // animation is finished in the Launcher and here we directly apply the final touch. - applyEnterPipSyncTransaction(destinationBounds, () -> { - // ensure menu's settled in its final bounds first - finishResizeForMenu(destinationBounds); - sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); - }, tx); - mInSwipePipToHomeTransition = false; + if (!mWaitForFixedRotation) { + onEndOfSwipePipToHomeTransition(); + } else { + Log.d(TAG, "Defer onTaskAppeared-SwipePipToHome until end of fixed rotation."); + } return; } + if (mOneShotAnimationType == ANIM_TYPE_ALPHA + && SystemClock.uptimeMillis() - mLastOneShotAlphaAnimationTime + > ONE_SHOT_ALPHA_ANIMATION_TIMEOUT_MS) { + Log.d(TAG, "Alpha animation is expired. Use bounds animation."); + mOneShotAnimationType = ANIM_TYPE_BOUNDS; + } if (mWaitForFixedRotation) { - if (DEBUG) Log.d(TAG, "Defer entering PiP animation, fixed rotation is ongoing"); - // if deferred, hide the surface till fixed rotation is completed - final SurfaceControl.Transaction tx = - mSurfaceControlTransactionFactory.getTransaction(); - tx.setAlpha(mLeash, 0f); - tx.show(mLeash); - tx.apply(); + onTaskAppearedWithFixedRotation(); return; } @@ -500,6 +524,27 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, } } + private void onTaskAppearedWithFixedRotation() { + if (mOneShotAnimationType == ANIM_TYPE_ALPHA) { + Log.d(TAG, "Defer entering PiP alpha animation, fixed rotation is ongoing"); + // If deferred, hide the surface till fixed rotation is completed. + final SurfaceControl.Transaction tx = + mSurfaceControlTransactionFactory.getTransaction(); + tx.setAlpha(mLeash, 0f); + tx.show(mLeash); + tx.apply(); + mOneShotAnimationType = ANIM_TYPE_BOUNDS; + return; + } + final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds(); + final Rect sourceHintRect = PipBoundsAlgorithm.getValidSourceHintRect( + mPictureInPictureParams, currentBounds); + final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); + animateResizePip(currentBounds, destinationBounds, sourceHintRect, + TRANSITION_DIRECTION_TO_PIP, mEnterAnimationDuration, 0 /* startingAngle */); + mState = State.ENTERING_PIP; + } + /** * Called when the display rotation handling is skipped (e.g. when rotation happens while in * the middle of an entry transition). @@ -536,6 +581,20 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, }, null /* boundsChangeTransaction */); } + private void onEndOfSwipePipToHomeTransition() { + final Rect destinationBounds = mPipBoundsState.getBounds(); + final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction(); + mSurfaceTransactionHelper.resetScale(tx, mLeash, destinationBounds); + mSurfaceTransactionHelper.crop(tx, mLeash, destinationBounds); + // The animation is finished in the Launcher and here we directly apply the final touch. + applyEnterPipSyncTransaction(destinationBounds, () -> { + // Ensure menu's settled in its final bounds first. + finishResizeForMenu(destinationBounds); + sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); + }, tx); + mInSwipePipToHomeTransition = false; + } + private void applyEnterPipSyncTransaction(Rect destinationBounds, Runnable runnable, @Nullable SurfaceControl.Transaction boundsChangeTransaction) { // PiP menu is attached late in the process here to avoid any artifacts on the leash @@ -547,7 +606,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, if (boundsChangeTransaction != null) { wct.setBoundsChangeTransaction(mToken, boundsChangeTransaction); } - wct.scheduleFinishEnterPip(mToken, destinationBounds); mSyncTransactionQueue.queue(wct); if (runnable != null) { mSyncTransactionQueue.runInSync(t -> runnable.run()); @@ -600,7 +658,7 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, Log.wtf(TAG, "Unrecognized token: " + token); return; } - mWaitForFixedRotation = false; + clearWaitForFixedRotation(); mInSwipePipToHomeTransition = false; mPictureInPictureParams = null; mState = State.UNDEFINED; @@ -617,8 +675,10 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, @Override public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) { Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken"); - if (mState != State.ENTERED_PIP) { + if (mState != State.ENTERED_PIP && mState != State.EXITING_PIP) { Log.d(TAG, "Defer onTaskInfoChange in current state: " + mState); + // Defer applying PiP parameters if the task is entering PiP to avoid disturbing + // the animation. mDeferredTaskInfo = info; return; } @@ -648,16 +708,60 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, public void onFixedRotationStarted(int displayId, int newRotation) { mNextRotation = newRotation; mWaitForFixedRotation = true; + + if (mState.isInPip()) { + // Fade out the existing PiP to avoid jump cut during seamless rotation. + fadeExistingPip(false /* show */); + } } @Override public void onFixedRotationFinished(int displayId) { - if (mWaitForFixedRotation && mState.isInPip()) { - final Rect destinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); - // schedule a regular animation to ensure all the callbacks are still being sent - enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */); + if (!mWaitForFixedRotation) { + return; } + if (mState == State.TASK_APPEARED) { + if (mInSwipePipToHomeTransition) { + onEndOfSwipePipToHomeTransition(); + } else { + // Schedule a regular animation to ensure all the callbacks are still being sent. + enterPipWithAlphaAnimation(mPipBoundsAlgorithm.getEntryDestinationBounds(), + mEnterAnimationDuration); + } + } else if (mState == State.ENTERED_PIP && mHasFadeOut) { + fadeExistingPip(true /* show */); + } else if (mState == State.ENTERING_PIP && mDeferredAnimEndTransaction != null) { + final PipAnimationController.PipTransitionAnimator<?> animator = + mPipAnimationController.getCurrentAnimator(); + final Rect destinationBounds = animator.getDestinationBounds(); + mPipBoundsState.setBounds(destinationBounds); + applyEnterPipSyncTransaction(destinationBounds, () -> { + finishResizeForMenu(destinationBounds); + sendOnPipTransitionFinished(TRANSITION_DIRECTION_TO_PIP); + }, mDeferredAnimEndTransaction); + } + clearWaitForFixedRotation(); + } + + private void fadeExistingPip(boolean show) { + final float alphaStart = show ? 0 : 1; + final float alphaEnd = show ? 1 : 0; + mPipAnimationController + .getAnimator(mTaskInfo, mLeash, mPipBoundsState.getBounds(), alphaStart, alphaEnd) + .setTransitionDirection(TRANSITION_DIRECTION_SAME) + .setDuration(show ? mEnterAnimationDuration : mExitAnimationDuration) + .start(); + mHasFadeOut = !show; + } + + private void clearWaitForFixedRotation() { mWaitForFixedRotation = false; + mDeferredAnimEndTransaction = null; + } + + @Override + public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) { + mCurrentRotation = newConfig.windowConfiguration.getRotation(); } /** @@ -686,7 +790,11 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, mPipAnimationController.getCurrentAnimator(); if (animator == null || !animator.isRunning() || animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) { - if (mState.isInPip() && fromRotation && !mWaitForFixedRotation) { + final boolean rotatingPip = mState.isInPip() && fromRotation; + if (rotatingPip && mWaitForFixedRotation && mHasFadeOut) { + // The position will be used by fade-in animation when the fixed rotation is done. + mPipBoundsState.setBounds(destinationBoundsOut); + } else if (rotatingPip) { // Update bounds state to final destination first. It's important to do this // before finishing & cancelling the transition animation so that the MotionHelper // bounds are synchronized to the destination bounds when the animation ends. @@ -737,7 +845,17 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, final Rect newDestinationBounds = mPipBoundsAlgorithm.getEntryDestinationBounds(); if (newDestinationBounds.equals(currentDestinationBounds)) return; if (animator.getAnimationType() == ANIM_TYPE_BOUNDS) { - animator.updateEndValue(newDestinationBounds); + if (mWaitForFixedRotation) { + // The new destination bounds are in next rotation (DisplayLayout has been rotated + // in computeRotatedBounds). The animation runs in previous rotation so the end + // bounds need to be transformed. + final Rect displayBounds = mPipBoundsState.getDisplayBounds(); + final Rect rotatedEndBounds = new Rect(newDestinationBounds); + rotateBounds(rotatedEndBounds, displayBounds, mNextRotation, mCurrentRotation); + animator.updateEndValue(rotatedEndBounds); + } else { + animator.updateEndValue(newDestinationBounds); + } } animator.setDestinationBounds(newDestinationBounds); destinationBoundsOut.set(newDestinationBounds); @@ -1050,7 +1168,6 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, // activity windowing mode set by WM, and set the task bounds to the final bounds taskBounds = destinationBounds; wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED); - wct.scheduleFinishEnterPip(mToken, destinationBounds); } else if (isOutPipDirection(direction)) { // If we are animating to fullscreen or split screen, then we need to reset the // override bounds on the task to ensure that the task "matches" the parent's bounds. @@ -1096,8 +1213,12 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, return null; } final int rotationDelta = mWaitForFixedRotation - ? ((mNextRotation - mPipBoundsState.getDisplayLayout().rotation()) + 4) % 4 + ? deltaRotation(mCurrentRotation, mNextRotation) : Surface.ROTATION_0; + if (rotationDelta != Surface.ROTATION_0) { + sourceHintRect = computeRotatedBounds(rotationDelta, direction, destinationBounds, + sourceHintRect); + } Rect baseBounds = direction == TRANSITION_DIRECTION_SNAP_AFTER_RESIZE ? mPipBoundsState.getBounds() : currentBounds; final PipAnimationController.PipTransitionAnimator<?> animator = mPipAnimationController @@ -1107,9 +1228,35 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, .setPipAnimationCallback(mPipAnimationCallback) .setDuration(durationMs) .start(); + if (rotationDelta != Surface.ROTATION_0 && direction == TRANSITION_DIRECTION_TO_PIP) { + // The destination bounds are used for the end rect of animation and the final bounds + // after animation finishes. So after the animation is started, the destination bounds + // can be updated to new rotation (computeRotatedBounds has changed the DisplayLayout + // without affecting the animation. + animator.setDestinationBounds(mPipBoundsAlgorithm.getEntryDestinationBounds()); + } return animator; } + /** Computes destination bounds in old rotation and returns source hint rect if available. */ + private @Nullable Rect computeRotatedBounds(int rotationDelta, int direction, + Rect outDestinationBounds, Rect sourceHintRect) { + if (direction == TRANSITION_DIRECTION_TO_PIP) { + mPipBoundsState.getDisplayLayout().rotateTo(mContext.getResources(), mNextRotation); + final Rect displayBounds = mPipBoundsState.getDisplayBounds(); + outDestinationBounds.set(mPipBoundsAlgorithm.getEntryDestinationBounds()); + // Transform the destination bounds to current display coordinates. + rotateBounds(outDestinationBounds, displayBounds, mNextRotation, mCurrentRotation); + } else if (direction == TRANSITION_DIRECTION_LEAVE_PIP) { + final Rect rotatedDestinationBounds = new Rect(outDestinationBounds); + rotateBounds(rotatedDestinationBounds, mPipBoundsState.getDisplayBounds(), + rotationDelta); + return PipBoundsAlgorithm.getValidSourceHintRect(mPictureInPictureParams, + rotatedDestinationBounds); + } + return sourceHintRect; + } + /** * Sync with {@link LegacySplitScreenController} on destination bounds if PiP is going to split * screen. diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java index 17cde731faa2..9cf0b721cc48 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipMenuController.java @@ -18,6 +18,8 @@ package com.android.wm.shell.pip.phone; import static android.view.WindowManager.SHELL_ROOT_LAYER_PIP; +import static com.android.wm.shell.pip.phone.PipMenuView.ANIM_TYPE_HIDE; + import android.annotation.Nullable; import android.app.RemoteAction; import android.content.Context; @@ -397,26 +399,26 @@ public class PhonePipMenuController implements PipMenuController { * Hides the menu view. */ public void hideMenu() { - hideMenu(true /* animate */, true /* resize */); + hideMenu(ANIM_TYPE_HIDE, true /* resize */); } /** * Hides the menu view. * - * @param animate whether to animate the menu fadeout + * @param animationType the animation type to use upon hiding the menu * @param resize whether or not to resize the PiP with the state change */ - public void hideMenu(boolean animate, boolean resize) { + public void hideMenu(@PipMenuView.AnimationType int animationType, boolean resize) { final boolean isMenuVisible = isMenuVisible(); if (DEBUG) { Log.d(TAG, "hideMenu() state=" + mMenuState + " isMenuVisible=" + isMenuVisible - + " animate=" + animate + + " animationType=" + animationType + " resize=" + resize + " callers=\n" + Debug.getCallers(5, " ")); } if (isMenuVisible) { - mPipMenuView.hideMenu(animate, resize); + mPipMenuView.hideMenu(resize, animationType); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index f505e60de61e..fa5caf00dde7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -114,13 +114,17 @@ public class PipController implements PipTransitionController.PipTransitionCallb */ private final DisplayChangeController.OnDisplayChangingListener mRotationController = ( int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> { - if (!mPipTaskOrganizer.isInPip() - || mPipBoundsState.getDisplayLayout().rotation() == toRotation - || mPipTaskOrganizer.isDeferringEnterPipAnimation() - || mPipTaskOrganizer.isEntryScheduled()) { - // Skip if the same rotation has been set or we aren't in PIP or haven't actually - // entered PIP yet. We still need to update the display layout in the bounds handler - // in this case. + if (mPipBoundsState.getDisplayLayout().rotation() == toRotation) { + // The same rotation may have been set by auto PiP-able or fixed rotation. So notify + // the change with fromRotation=false to apply the rotated destination bounds from + // PipTaskOrganizer#onMovementBoundsChanged. + updateMovementBounds(null, false /* fromRotation */, + false /* fromImeAdjustment */, false /* fromShelfAdjustment */, t); + return; + } + if (!mPipTaskOrganizer.isInPip() || mPipTaskOrganizer.isEntryScheduled()) { + // Update display layout and bounds handler if we aren't in PIP or haven't actually + // entered PIP yet. onDisplayRotationChangedNotInPip(mContext, toRotation); // do not forget to update the movement bounds as well. updateMovementBounds(mPipBoundsState.getNormalBounds(), true /* fromRotation */, @@ -460,7 +464,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb pipSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds, snapFraction, mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(), - mPipBoundsState.getDisplayBounds()); + mPipBoundsState.getDisplayBounds(), + mPipBoundsState.getDisplayLayout().stableInsets()); mTouchHandler.getMotionHelper().movePip(postChangeStackBounds); } else { @@ -664,7 +669,8 @@ public class PipController implements PipTransitionController.PipTransitionCallb postChangeStackBounds, false /* adjustForIme */); pipSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds, snapFraction, mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(), - mPipBoundsState.getDisplayBounds()); + mPipBoundsState.getDisplayBounds(), + mPipBoundsState.getDisplayLayout().stableInsets()); mPipBoundsAlgorithm.getInsetBounds(outInsetBounds); outBounds.set(postChangeStackBounds); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java index 3c25a13e94eb..2b45346cfa5c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java @@ -32,6 +32,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; +import android.annotation.IntDef; import android.app.PendingIntent.CanceledException; import android.app.RemoteAction; import android.content.ComponentName; @@ -44,6 +45,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.os.SystemProperties; import android.os.UserHandle; import android.util.Log; import android.util.Pair; @@ -63,6 +65,8 @@ import com.android.wm.shell.animation.Interpolators; import com.android.wm.shell.common.ShellExecutor; import com.android.wm.shell.pip.PipUtils; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; @@ -73,9 +77,26 @@ public class PipMenuView extends FrameLayout { private static final String TAG = "PipMenuView"; + private static final int ANIMATION_NONE_DURATION_MS = 0; + private static final int ANIMATION_HIDE_DURATION_MS = 125; + + /** No animation performed during menu hide. */ + public static final int ANIM_TYPE_NONE = 0; + /** Fade out the menu until it's invisible. Used when the PIP window remains visible. */ + public static final int ANIM_TYPE_HIDE = 1; + /** Fade out the menu in sync with the PIP window. */ + public static final int ANIM_TYPE_DISMISS = 2; + + @IntDef(prefix = { "ANIM_TYPE_" }, value = { + ANIM_TYPE_NONE, + ANIM_TYPE_HIDE, + ANIM_TYPE_DISMISS + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AnimationType {} + private static final int INITIAL_DISMISS_DELAY = 3500; private static final int POST_INTERACTION_DISMISS_DELAY = 2000; - private static final long MENU_FADE_DURATION = 125; private static final long MENU_SHOW_ON_EXPAND_START_DELAY = 30; private static final float MENU_BACKGROUND_ALPHA = 0.3f; @@ -86,6 +107,7 @@ public class PipMenuView extends FrameLayout { private int mMenuState; private boolean mAllowMenuTimeout = true; private boolean mAllowTouches = true; + private int mDismissFadeOutDurationMs; private final List<RemoteAction> mActions = new ArrayList<>(); @@ -131,7 +153,8 @@ public class PipMenuView extends FrameLayout { inflate(context, R.layout.pip_menu, this); final boolean enableCornerRadius = mContext.getResources() - .getBoolean(R.bool.config_pipEnableRoundCorner); + .getBoolean(R.bool.config_pipEnableRoundCorner) + || SystemProperties.getBoolean("debug.sf.enable_hole_punch_pip", false); mBackgroundDrawable = enableCornerRadius ? mContext.getDrawable(R.drawable.pip_menu_background) : new ColorDrawable(Color.BLACK); @@ -165,6 +188,8 @@ public class PipMenuView extends FrameLayout { mPipMenuIconsAlgorithm = new PipMenuIconsAlgorithm(mContext); mPipMenuIconsAlgorithm.bindViews((ViewGroup) mViewRoot, (ViewGroup) mTopEndContainer, mResizeHandle, mSettingsButton, mDismissButton); + mDismissFadeOutDurationMs = context.getResources() + .getInteger(R.integer.config_pipExitAnimationDuration); initAccessibility(); } @@ -256,7 +281,7 @@ public class PipMenuView extends FrameLayout { mMenuContainerAnimator.playTogether(dismissAnim, resizeAnim); } mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN); - mMenuContainerAnimator.setDuration(MENU_FADE_DURATION); + mMenuContainerAnimator.setDuration(ANIMATION_HIDE_DURATION_MS); if (allowMenuTimeout) { mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() { @Override @@ -318,17 +343,18 @@ public class PipMenuView extends FrameLayout { hideMenu(null); } - void hideMenu(boolean animate, boolean resize) { - hideMenu(null, true /* notifyMenuVisibility */, animate, resize); + void hideMenu(Runnable animationEndCallback) { + hideMenu(animationEndCallback, true /* notifyMenuVisibility */, true /* resize */, + ANIM_TYPE_HIDE); } - void hideMenu(Runnable animationEndCallback) { - hideMenu(animationEndCallback, true /* notifyMenuVisibility */, true /* animate */, - true /* resize */); + void hideMenu(boolean resize, @AnimationType int animationType) { + hideMenu(null /* animationFinishedRunnable */, true /* notifyMenuVisibility */, resize, + animationType); } - private void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility, - boolean animate, boolean resize) { + void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility, + boolean resize, @AnimationType int animationType) { if (mMenuState != MENU_STATE_NONE) { cancelDelayedHide(); if (notifyMenuVisibility) { @@ -346,7 +372,7 @@ public class PipMenuView extends FrameLayout { mResizeHandle.getAlpha(), 0f); mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim, resizeAnim); mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_OUT); - mMenuContainerAnimator.setDuration(animate ? MENU_FADE_DURATION : 0); + mMenuContainerAnimator.setDuration(getFadeOutDuration(animationType)); mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -476,19 +502,17 @@ public class PipMenuView extends FrameLayout { private void expandPip() { // Do not notify menu visibility when hiding the menu, the controller will do this when it // handles the message - hideMenu(mController::onPipExpand, false /* notifyMenuVisibility */, true /* animate */, - true /* resize */); + hideMenu(mController::onPipExpand, false /* notifyMenuVisibility */, true /* resize */, + ANIM_TYPE_HIDE); } private void dismissPip() { - // Since tapping on the close-button invokes a double-tap wait callback in PipTouchHandler, - // we want to disable animating the fadeout animation of the buttons in order to call on - // PipTouchHandler#onPipDismiss fast enough. - final boolean animate = mMenuState != MENU_STATE_CLOSE; - // Do not notify menu visibility when hiding the menu, the controller will do this when it - // handles the message - hideMenu(mController::onPipDismiss, false /* notifyMenuVisibility */, animate, - true /* resize */); + if (mMenuState != MENU_STATE_NONE) { + // Do not call hideMenu() directly. Instead, let the menu controller handle it just as + // any other dismissal that will update the touch state and fade out the PIP task + // and the menu view at the same time. + mController.onPipDismiss(); + } } private void showSettings() { @@ -512,4 +536,17 @@ public class PipMenuView extends FrameLayout { mMainExecutor.removeCallbacks(mHideMenuRunnable); mMainExecutor.executeDelayed(mHideMenuRunnable, recommendedTimeout); } + + private long getFadeOutDuration(@AnimationType int animationType) { + switch (animationType) { + case ANIM_TYPE_NONE: + return ANIMATION_NONE_DURATION_MS; + case ANIM_TYPE_HIDE: + return ANIMATION_HIDE_DURATION_MS; + case ANIM_TYPE_DISMISS: + return mDismissFadeOutDurationMs; + default: + throw new IllegalStateException("Invalid animation type " + animationType); + } + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java index 10625617a379..9401cd6a2954 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java @@ -22,6 +22,8 @@ import static androidx.dynamicanimation.animation.SpringForce.STIFFNESS_MEDIUM; import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_EXPAND_OR_UNEXPAND; import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_NONE; +import static com.android.wm.shell.pip.phone.PipMenuView.ANIM_TYPE_DISMISS; +import static com.android.wm.shell.pip.phone.PipMenuView.ANIM_TYPE_NONE; import android.annotation.NonNull; import android.annotation.Nullable; @@ -336,7 +338,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, + " callers=\n" + Debug.getCallers(5, " ")); } cancelPhysicsAnimation(); - mMenuController.hideMenu(false /* animate */, false /* resize */); + mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */); mPipTaskOrganizer.exitPip(skipAnimation ? 0 : LEAVE_PIP_DURATION); } @@ -349,7 +351,7 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, Log.d(TAG, "removePip: callers=\n" + Debug.getCallers(5, " ")); } cancelPhysicsAnimation(); - mMenuController.hideMenu(true /* animate*/, false /* resize */); + mMenuController.hideMenu(ANIM_TYPE_DISMISS, false /* resize */); mPipTaskOrganizer.removePip(); } @@ -406,11 +408,14 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, .flingThenSpring( FloatProperties.RECT_Y, velocityY, mFlingConfigY, mSpringConfig); + final Rect insetBounds = mPipBoundsState.getDisplayLayout().stableInsets(); final float leftEdge = isStash ? mPipBoundsState.getStashOffset() - mPipBoundsState.getBounds().width() + + insetBounds.left : mPipBoundsState.getMovementBounds().left; final float rightEdge = isStash ? mPipBoundsState.getDisplayBounds().right - mPipBoundsState.getStashOffset() + - insetBounds.right : mPipBoundsState.getMovementBounds().right; final float xEndValue = velocityX < 0 ? leftEdge : rightEdge; @@ -483,7 +488,8 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, mSnapAlgorithm.applySnapFraction(normalBounds, normalMovementBounds, savedSnapFraction, mPipBoundsState.getStashedState(), mPipBoundsState.getStashOffset(), - mPipBoundsState.getDisplayBounds()); + mPipBoundsState.getDisplayBounds(), + mPipBoundsState.getDisplayLayout().stableInsets()); if (immediate) { movePip(normalBounds); @@ -529,10 +535,13 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, mFlingConfigY = new PhysicsAnimator.FlingConfig(DEFAULT_FRICTION, mPipBoundsState.getMovementBounds().top, mPipBoundsState.getMovementBounds().bottom); + final Rect insetBounds = mPipBoundsState.getDisplayLayout().stableInsets(); mStashConfigX = new PhysicsAnimator.FlingConfig( DEFAULT_FRICTION, - mPipBoundsState.getStashOffset() - mPipBoundsState.getBounds().width(), - mPipBoundsState.getDisplayBounds().right - mPipBoundsState.getStashOffset()); + mPipBoundsState.getStashOffset() - mPipBoundsState.getBounds().width() + + insetBounds.left, + mPipBoundsState.getDisplayBounds().right - mPipBoundsState.getStashOffset() + - insetBounds.right); } private void startBoundsAnimator(float toX, float toY) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java index 0a148c413c0f..8726ee76d29a 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java @@ -21,6 +21,7 @@ import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_LEFT; import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE; import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_RIGHT; import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_TOP; +import static com.android.wm.shell.pip.phone.PipMenuView.ANIM_TYPE_NONE; import android.content.Context; import android.content.res.Resources; @@ -232,7 +233,8 @@ public class PipResizeGestureHandler { } } - private void onInputEvent(InputEvent ev) { + @VisibleForTesting + void onInputEvent(InputEvent ev) { // Don't allow resize when PiP is stashed. if (mPipBoundsState.isStashed()) { return; @@ -366,7 +368,8 @@ public class PipResizeGestureHandler { return mIsSysUiStateValid; } - private void onPinchResize(MotionEvent ev) { + @VisibleForTesting + void onPinchResize(MotionEvent ev) { int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { @@ -411,7 +414,7 @@ public class PipResizeGestureHandler { if (!mThresholdCrossed && (distanceBetween(mDownSecondPoint, mLastSecondPoint) > mTouchSlop || distanceBetween(mDownPoint, mLastPoint) > mTouchSlop)) { - mInputMonitor.pilferPointers(); + pilferPointers(); mThresholdCrossed = true; // Reset the down to begin resizing from this point mDownPoint.set(mLastPoint); @@ -469,7 +472,7 @@ public class PipResizeGestureHandler { } if (mThresholdCrossed) { if (mPhonePipMenuController.isMenuVisible()) { - mPhonePipMenuController.hideMenu(false /* animate */, + mPhonePipMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */); } final Rect currentPipBounds = mPipBoundsState.getBounds(); @@ -548,6 +551,17 @@ public class PipResizeGestureHandler { return mUserResizeBounds; } + @VisibleForTesting + Rect getLastResizeBounds() { + return mLastResizeBounds; + } + + @VisibleForTesting + void pilferPointers() { + mInputMonitor.pilferPointers(); + } + + @VisibleForTesting public void updateMaxSize(int maxX, int maxY) { mMaxSize.set(maxX, maxY); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java index f29d4f59493e..0a0798ef24c1 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java @@ -25,6 +25,7 @@ import static com.android.wm.shell.pip.PipBoundsState.STASH_TYPE_RIGHT; import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_CLOSE; import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_FULL; import static com.android.wm.shell.pip.phone.PhonePipMenuController.MENU_STATE_NONE; +import static com.android.wm.shell.pip.phone.PipMenuView.ANIM_TYPE_NONE; import android.annotation.NonNull; import android.annotation.SuppressLint; @@ -625,6 +626,7 @@ public class PipTouchHandler { } mMenuController.handlePointerEvent(cloneEvent); + cloneEvent.recycle(); } return true; @@ -871,7 +873,8 @@ public class PipTouchHandler { mMotionHelper.flingToSnapTarget(vel.x, vel.y, this::flingEndAction /* endAction */); } - } else if (mTouchState.isDoubleTap() && !mPipBoundsState.isStashed()) { + } else if (mTouchState.isDoubleTap() && !mPipBoundsState.isStashed() + && mMenuState != MENU_STATE_FULL) { // If using pinch to zoom, double-tap functions as resizing between max/min size if (mPipResizeGestureHandler.isUsingPinchToZoom()) { final boolean toExpand = mPipBoundsState.getBounds().width() @@ -879,7 +882,7 @@ public class PipTouchHandler { && mPipBoundsState.getBounds().height() < mPipBoundsState.getMaxSize().y; if (mMenuController.isMenuVisible()) { - mMenuController.hideMenu(false /* animate */, false /* resize */); + mMenuController.hideMenu(ANIM_TYPE_NONE, false /* resize */); } if (toExpand) { mPipResizeGestureHandler.setUserResizeBounds(mPipBoundsState.getBounds()); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index c91a92ad3242..efaa2696cbeb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -337,6 +337,7 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, final WindowContainerTransaction wct = new WindowContainerTransaction(); // Make the stages adjacent to each other so they occlude what's behind them. wct.setAdjacentRoots(mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token); + wct.setLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token); mTaskOrganizer.applyTransaction(wct); } } @@ -346,6 +347,7 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, final WindowContainerTransaction wct = new WindowContainerTransaction(); // Deactivate the main stage if it no longer has a root task. mMainStage.deactivate(wct); + wct.clearLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token); mTaskOrganizer.applyTransaction(wct); } } @@ -449,6 +451,7 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, final WindowContainerTransaction wct = new WindowContainerTransaction(); // Make sure the main stage is active. mMainStage.activate(getMainStageBounds(), wct); + mSideStage.setBounds(getSideStageBounds(), wct); mTaskOrganizer.applyTransaction(wct); } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java index 147f2e2ec846..1d3a60b8193d 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenContentDrawer.java @@ -18,7 +18,6 @@ package com.android.wm.shell.startingsurface; import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; -import static android.os.UserHandle.getUserHandleForUid; import android.annotation.ColorInt; import android.annotation.NonNull; @@ -68,11 +67,12 @@ public class SplashscreenContentDrawer { // For example, an icon with the foreground 108*108 opaque pixels and it's background // also 108*108 pixels, then do not enlarge this icon if only need to show foreground icon. private static final float ENLARGE_FOREGROUND_ICON_THRESHOLD = (72f * 72f) / (108f * 108f); + private static final float NO_BACKGROUND_SCALE = 1.3f; private final Context mContext; private final IconProvider mIconProvider; - private final int mMaxAnimatableIconDuration; private int mIconSize; + private int mDefaultIconSize; private int mBrandingImageWidth; private int mBrandingImageHeight; private final int mAppRevealDuration; @@ -84,11 +84,10 @@ public class SplashscreenContentDrawer { private final SplashScreenWindowAttrs mTmpAttrs = new SplashScreenWindowAttrs(); private final Handler mSplashscreenWorkerHandler; - SplashscreenContentDrawer(Context context, int maxAnimatableIconDuration, - int iconExitAnimDuration, int appRevealAnimDuration, TransactionPool pool) { + SplashscreenContentDrawer(Context context, int iconExitAnimDuration, int appRevealAnimDuration, + TransactionPool pool) { mContext = context; mIconProvider = new IconProvider(context); - mMaxAnimatableIconDuration = maxAnimatableIconDuration; mAppRevealDuration = appRevealAnimDuration; mIconExitDuration = iconExitAnimDuration; mTransactionPool = pool; @@ -109,11 +108,12 @@ public class SplashscreenContentDrawer { * view on background thread so the view and the drawable can be create and pre-draw in * parallel. * + * @param emptyView Create a splash screen view without icon on it. * @param consumer Receiving the SplashScreenView object, which will also be executed * on splash screen thread. Note that the view can be null if failed. */ - void createContentView(Context context, int splashScreenResId, ActivityInfo info, - int taskId, Consumer<SplashScreenView> consumer) { + void createContentView(Context context, boolean emptyView, int splashScreenResId, + ActivityInfo info, int taskId, Consumer<SplashScreenView> consumer) { mSplashscreenWorkerHandler.post(() -> { SplashScreenView contentView; try { @@ -121,7 +121,7 @@ public class SplashscreenContentDrawer { context, splashScreenResId); if (contentView == null) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "makeSplashScreenContentView"); - contentView = makeSplashScreenContentView(context, info); + contentView = makeSplashScreenContentView(context, info, emptyView); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } } catch (RuntimeException e) { @@ -136,6 +136,8 @@ public class SplashscreenContentDrawer { private void updateDensity() { mIconSize = mContext.getResources().getDimensionPixelSize( com.android.wm.shell.R.dimen.starting_surface_icon_size); + mDefaultIconSize = mContext.getResources().getDimensionPixelSize( + com.android.wm.shell.R.dimen.default_icon_size); mBrandingImageWidth = mContext.getResources().getDimensionPixelSize( com.android.wm.shell.R.dimen.starting_surface_brand_image_width); mBrandingImageHeight = mContext.getResources().getDimensionPixelSize( @@ -190,34 +192,20 @@ public class SplashscreenContentDrawer { } } - private SplashScreenView makeSplashScreenContentView(Context context, ActivityInfo ai) { + private SplashScreenView makeSplashScreenContentView(Context context, ActivityInfo ai, + boolean emptyView) { updateDensity(); getWindowAttrs(context, mTmpAttrs); final StartingWindowViewBuilder builder = new StartingWindowViewBuilder(); - final int animationDuration; - Drawable iconDrawable; - if (mTmpAttrs.mReplaceIcon != null) { - iconDrawable = mTmpAttrs.mReplaceIcon; - animationDuration = Math.max(0, - Math.min(mTmpAttrs.mAnimationDuration, mMaxAnimatableIconDuration)); - } else { - iconDrawable = mIconProvider.getIconForUI( - ai, getUserHandleForUid(ai.applicationInfo.uid)); - if (iconDrawable == null) { - iconDrawable = context.getPackageManager().getDefaultActivityIcon(); - } - animationDuration = 0; - } final int themeBGColor = peekWindowBGColor(context); // TODO (b/173975965) Tracking the performance on improved splash screen. return builder .setContext(context) .setWindowBGColor(themeBGColor) - .setIconDrawable(iconDrawable) - .setIconAnimationDuration(animationDuration) - .setBrandingDrawable(mTmpAttrs.mBrandingImage) - .setIconBackground(mTmpAttrs.mIconBgColor).build(); + .makeEmptyView(emptyView) + .setActivityInfo(ai) + .build(); } private static void getWindowAttrs(Context context, SplashScreenWindowAttrs attrs) { @@ -253,11 +241,9 @@ public class SplashscreenContentDrawer { } private class StartingWindowViewBuilder { - private Drawable mIconDrawable; - private int mIconAnimationDuration; + private ActivityInfo mActivityInfo; private Context mContext; - private Drawable mBrandingDrawable; - private @ColorInt int mIconBackground; + private boolean mEmptyView; // result private boolean mBuildComplete = false; @@ -272,26 +258,14 @@ public class SplashscreenContentDrawer { return this; } - StartingWindowViewBuilder setIconDrawable(Drawable iconDrawable) { - mIconDrawable = iconDrawable; - mBuildComplete = false; - return this; - } - - StartingWindowViewBuilder setIconAnimationDuration(int iconAnimationDuration) { - mIconAnimationDuration = iconAnimationDuration; + StartingWindowViewBuilder makeEmptyView(boolean empty) { + mEmptyView = empty; mBuildComplete = false; return this; } - StartingWindowViewBuilder setBrandingDrawable(Drawable branding) { - mBrandingDrawable = branding; - mBuildComplete = false; - return this; - } - - StartingWindowViewBuilder setIconBackground(int color) { - mIconBackground = color; + StartingWindowViewBuilder setActivityInfo(ActivityInfo ai) { + mActivityInfo = ai; mBuildComplete = false; return this; } @@ -306,40 +280,66 @@ public class SplashscreenContentDrawer { if (mBuildComplete) { return mCachedResult; } - if (mContext == null) { + if (mContext == null || mActivityInfo == null) { Slog.e(TAG, "Unable to create StartingWindowView, lack of materials!"); return null; } - if (!processAdaptiveIcon() && mIconDrawable != null) { - if (DEBUG) { - Slog.d(TAG, "The icon is not an AdaptiveIconDrawable"); + Drawable iconDrawable; + final int animationDuration; + final int iconSize; + if (mEmptyView) { + // empty splash screen case + animationDuration = 0; + iconSize = 0; + } else if (mTmpAttrs.mReplaceIcon != null) { + // replaced icon, don't process + iconDrawable = mTmpAttrs.mReplaceIcon; + animationDuration = mTmpAttrs.mAnimationDuration; + createIconDrawable(iconDrawable, mIconSize); + iconSize = mIconSize; + } else { + final float iconScale = (float) mIconSize / (float) mDefaultIconSize; + iconDrawable = mIconProvider.getIcon(mActivityInfo); + if (iconDrawable == null) { + iconDrawable = mContext.getPackageManager().getDefaultActivityIcon(); } - createIconDrawable(mIconDrawable, mIconSize); + if (!processAdaptiveIcon(iconDrawable, iconScale)) { + if (DEBUG) { + Slog.d(TAG, "The icon is not an AdaptiveIconDrawable"); + } + // TODO process legacy icon(bitmap) + final Drawable tempIcon = loadIconByDensity(iconDrawable, iconScale); + createIconDrawable(tempIcon, mIconSize); + } + animationDuration = 0; + iconSize = (int) (0.5 + mIconSize * mScale); } - final int iconSize = mFinalIconDrawable != null ? (int) (mIconSize * mScale) : 0; - mCachedResult = fillViewWithIcon(mContext, iconSize, mFinalIconDrawable); + + mCachedResult = fillViewWithIcon(iconSize, mFinalIconDrawable, animationDuration); mBuildComplete = true; return mCachedResult; } private void createIconDrawable(Drawable iconDrawable, int iconSize) { mFinalIconDrawable = SplashscreenIconDrawableFactory.makeIconDrawable( - mIconBackground != Color.TRANSPARENT ? mIconBackground : mThemeColor, + mTmpAttrs.mIconBgColor != Color.TRANSPARENT + ? mTmpAttrs.mIconBgColor : mThemeColor, iconDrawable, iconSize, mSplashscreenWorkerHandler); } - private boolean processAdaptiveIcon() { - if (!(mIconDrawable instanceof AdaptiveIconDrawable)) { + private boolean processAdaptiveIcon(Drawable iconDrawable, float iconScale) { + if (!(iconDrawable instanceof AdaptiveIconDrawable)) { return false; } Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "processAdaptiveIcon"); - final AdaptiveIconDrawable adaptiveIconDrawable = (AdaptiveIconDrawable) mIconDrawable; + final AdaptiveIconDrawable adaptiveIconDrawable = + (AdaptiveIconDrawable) iconDrawable; final DrawableColorTester backIconTester = new DrawableColorTester(adaptiveIconDrawable.getBackground()); - final Drawable iconForeground = adaptiveIconDrawable.getForeground(); + Drawable iconForeground = adaptiveIconDrawable.getForeground(); final DrawableColorTester foreIconTester = new DrawableColorTester(iconForeground, true /* filterTransparent */); @@ -365,7 +365,9 @@ public class SplashscreenContentDrawer { // B. The background of the adaptive icon is similar to the theme color, or // C. The background of the adaptive icon is grayscale, and the foreground of the // adaptive icon forms a certain contrast with the theme color. - if (!backComplex && (isRgbSimilarInHsv(mThemeColor, backMainColor) + // D. Didn't specify icon background color. + if (!backComplex && mTmpAttrs.mIconBgColor == Color.TRANSPARENT + && (isRgbSimilarInHsv(mThemeColor, backMainColor) || (backIconTester.isGrayscale() && !isRgbSimilarInHsv(mThemeColor, foreMainColor)))) { if (DEBUG) { @@ -373,8 +375,13 @@ public class SplashscreenContentDrawer { } // Reference AdaptiveIcon description, outer is 108 and inner is 72, so we // should enlarge the size 108/72 if we only draw adaptiveIcon's foreground. - if (foreIconTester.nonTransparentRatio() < ENLARGE_FOREGROUND_ICON_THRESHOLD) { - mScale = 1.5f; + final float noBgScale = + foreIconTester.nonTransparentRatio() < ENLARGE_FOREGROUND_ICON_THRESHOLD + ? NO_BACKGROUND_SCALE : 1f; + final Drawable tempIcon = loadIconByDensity(iconDrawable, iconScale * noBgScale); + if (tempIcon instanceof AdaptiveIconDrawable) { + mScale = noBgScale; + iconForeground = ((AdaptiveIconDrawable) tempIcon).getForeground(); } // Using AdaptiveIconDrawable here can help keep the shape consistent with the // current settings. @@ -384,30 +391,44 @@ public class SplashscreenContentDrawer { if (DEBUG) { Slog.d(TAG, "makeSplashScreenContentView: draw whole icon"); } - createIconDrawable(adaptiveIconDrawable, mIconSize); + final Drawable tempIcon = loadIconByDensity(iconDrawable, iconScale); + createIconDrawable(tempIcon, mIconSize); } Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); return true; } - private SplashScreenView fillViewWithIcon(Context context, - int iconSize, Drawable iconDrawable) { + private Drawable loadIconByDensity(Drawable baseDrawable, float scale) { + if (scale == 1 && baseDrawable != null) { + return baseDrawable; + } + final int densityDpi = mContext.getResources().getDisplayMetrics().densityDpi; + final int updateDpi = (int) (0.5f + scale * densityDpi); + return mIconProvider.getIcon(mActivityInfo, updateDpi); + } + + private SplashScreenView fillViewWithIcon(int iconSize, Drawable iconDrawable, + int animationDuration) { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "fillViewWithIcon"); - final SplashScreenView.Builder builder = new SplashScreenView.Builder(context); - builder.setIconSize(iconSize).setBackgroundColor(mThemeColor) - .setIconBackground(mIconBackground); + final SplashScreenView.Builder builder = new SplashScreenView.Builder(mContext); + builder.setBackgroundColor(mThemeColor); if (iconDrawable != null) { - builder.setCenterViewDrawable(iconDrawable); + builder.setIconSize(iconSize) + .setIconBackground(mTmpAttrs.mIconBgColor) + .setCenterViewDrawable(iconDrawable) + .setAnimationDurationMillis(animationDuration); } - builder.setAnimationDurationMillis(mIconAnimationDuration); - if (mBrandingDrawable != null) { - builder.setBrandingDrawable(mBrandingDrawable, mBrandingImageWidth, + if (mTmpAttrs.mBrandingImage != null) { + builder.setBrandingDrawable(mTmpAttrs.mBrandingImage, mBrandingImageWidth, mBrandingImageHeight); } final SplashScreenView splashScreenView = builder.build(); if (DEBUG) { Slog.d(TAG, "fillViewWithIcon surfaceWindowView " + splashScreenView); } + if (mEmptyView) { + splashScreenView.setNotCopyable(); + } splashScreenView.makeSystemUIColorsTransparent(); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); return splashScreenView; @@ -418,6 +439,18 @@ public class SplashscreenContentDrawer { if (a == b) { return true; } + final float lumA = Color.luminance(a); + final float lumB = Color.luminance(b); + final float contrastRatio = lumA > lumB + ? (lumA + 0.05f) / (lumB + 0.05f) : (lumB + 0.05f) / (lumA + 0.05f); + if (DEBUG) { + Slog.d(TAG, "isRgbSimilarInHsv a: " + Integer.toHexString(a) + + " b " + Integer.toHexString(b) + " contrast ratio: " + contrastRatio); + } + if (contrastRatio < 2) { + return true; + } + final float[] aHsv = new float[3]; final float[] bHsv = new float[3]; Color.colorToHSV(a, aHsv); @@ -428,14 +461,18 @@ public class SplashscreenContentDrawer { // Calculate the difference between two colors based on the HSV dimensions. final float normalizeH = minAngle / 180f; - final double square = Math.pow(normalizeH, 2) - + Math.pow(aHsv[1] - bHsv[1], 2) - + Math.pow(aHsv[2] - bHsv[2], 2); + final double squareH = Math.pow(normalizeH, 2); + final double squareS = Math.pow(aHsv[1] - bHsv[1], 2); + final double squareV = Math.pow(aHsv[2] - bHsv[2], 2); + final double square = squareH + squareS + squareV; final double mean = square / 3; final double root = Math.sqrt(mean); if (DEBUG) { - Slog.d(TAG, "hsvDiff " + minAngle + " a: " + Integer.toHexString(a) - + " b " + Integer.toHexString(b) + " ah " + aHsv[0] + " bh " + bHsv[0] + Slog.d(TAG, "hsvDiff " + minAngle + + " ah " + aHsv[0] + " bh " + bHsv[0] + + " as " + aHsv[1] + " bs " + bHsv[1] + + " av " + aHsv[2] + " bv " + bHsv[2] + + " sqH " + squareH + " sqS " + squareS + " sqV " + squareV + " root " + root); } return root < 0.1; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java index 85845d0d9c89..6cbba9f13586 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/SplashscreenIconDrawableFactory.java @@ -59,6 +59,7 @@ public class SplashscreenIconDrawableFactory { return new ImmobileIconDrawable((AdaptiveIconDrawable) foregroundDrawable, iconSize, splashscreenWorkerHandler); } else { + // TODO for legacy icon don't use adaptive icon drawable to wrapper it return new ImmobileIconDrawable(new AdaptiveIconDrawable( new ColorDrawable(backgroundColor), foregroundDrawable), iconSize, splashscreenWorkerHandler); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java index 7037d18decbe..6d3eeae43a96 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingSurfaceDrawer.java @@ -114,14 +114,12 @@ public class StartingSurfaceDrawer { mContext = context; mDisplayManager = mContext.getSystemService(DisplayManager.class); mSplashScreenExecutor = splashScreenExecutor; - final int maxAnimatableIconDuration = context.getResources().getInteger( - com.android.wm.shell.R.integer.max_starting_window_intro_icon_anim_duration); final int iconExitAnimDuration = context.getResources().getInteger( com.android.wm.shell.R.integer.starting_window_icon_exit_anim_duration); final int appRevealAnimDuration = context.getResources().getInteger( com.android.wm.shell.R.integer.starting_window_app_reveal_anim_duration); - mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, - maxAnimatableIconDuration, iconExitAnimDuration, appRevealAnimDuration, pool); + mSplashscreenContentDrawer = new SplashscreenContentDrawer(mContext, iconExitAnimDuration, + appRevealAnimDuration, pool); mSplashScreenExecutor.execute(() -> mChoreographer = Choreographer.getInstance()); } @@ -317,46 +315,38 @@ public class StartingSurfaceDrawer { // 3. Pre-draw the BitmapShader if the icon is immobile on splash screen worker thread, at // the same time the splash screen thread should be executing Session#relayout. Blocking the // traversal -> draw on splash screen thread until the BitmapShader of the icon is ready. - final Runnable setViewSynchronized; - if (!emptyView) { - // Record whether create splash screen view success, notify to current thread after - // create splash screen view finished. - final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier(); - setViewSynchronized = () -> { - // waiting for setContentView before relayoutWindow - SplashScreenView contentView = viewSupplier.get(); - final StartingWindowRecord record = mStartingWindowRecords.get(taskId); - // if record == null, either the starting window added fail or removed already. - if (record != null) { - // if view == null then creation of content view was failed. - if (contentView != null) { - try { - win.setContentView(contentView); - contentView.cacheRootWindow(win); - } catch (RuntimeException e) { - Slog.w(TAG, "failed set content view to starting window " - + "at taskId: " + taskId, e); - contentView = null; - } + + // Record whether create splash screen view success, notify to current thread after + // create splash screen view finished. + final SplashScreenViewSupplier viewSupplier = new SplashScreenViewSupplier(); + final Runnable setViewSynchronized = () -> { + // waiting for setContentView before relayoutWindow + SplashScreenView contentView = viewSupplier.get(); + final StartingWindowRecord record = mStartingWindowRecords.get(taskId); + // if record == null, either the starting window added fail or removed already. + if (record != null) { + // if view == null then creation of content view was failed. + if (contentView != null) { + try { + win.setContentView(contentView); + contentView.cacheRootWindow(win); + } catch (RuntimeException e) { + Slog.w(TAG, "failed set content view to starting window " + + "at taskId: " + taskId, e); + contentView = null; } - record.setSplashScreenView(contentView); } - }; - mSplashscreenContentDrawer.createContentView(context, - splashscreenContentResId[0], activityInfo, taskId, viewSupplier::setView); - } else { - setViewSynchronized = null; - } + record.setSplashScreenView(contentView); + } + }; + mSplashscreenContentDrawer.createContentView(context, emptyView, + splashscreenContentResId[0], activityInfo, taskId, viewSupplier::setView); try { final View view = win.getDecorView(); final WindowManager wm = mContext.getSystemService(WindowManager.class); postAddWindow(taskId, appToken, view, wm, params); - // all done - if (emptyView) { - return; - } // We use the splash screen worker thread to create SplashScreenView while adding the // window, as otherwise Choreographer#doFrame might be delayed on this thread. // And since Choreographer#doFrame won't happen immediately after adding the window, if diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java index e3362870cdf0..cb7afc77a65b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowController.java @@ -15,18 +15,10 @@ */ package com.android.wm.shell.startingsurface; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN; -import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_NONE; import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT; import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN; -import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED; -import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT; -import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK; -import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING; -import static android.window.StartingWindowInfo.TYPE_PARAMETER_SAME_PACKAGE; -import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH; import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; @@ -68,27 +60,24 @@ import java.util.function.BiConsumer; */ public class StartingWindowController implements RemoteCallable<StartingWindowController> { private static final String TAG = StartingWindowController.class.getSimpleName(); + // TODO b/183150443 Keep this flag open for a while, several things might need to adjust. - static final boolean DEBUG_SPLASH_SCREEN = true; - static final boolean DEBUG_TASK_SNAPSHOT = false; + public static final boolean DEBUG_SPLASH_SCREEN = true; + public static final boolean DEBUG_TASK_SNAPSHOT = false; private final StartingSurfaceDrawer mStartingSurfaceDrawer; - private final StartingTypeChecker mStartingTypeChecker = new StartingTypeChecker(); + private final StartingWindowTypeAlgorithm mStartingWindowTypeAlgorithm; private BiConsumer<Integer, Integer> mTaskLaunchingCallback; private final StartingSurfaceImpl mImpl = new StartingSurfaceImpl(); private final Context mContext; private final ShellExecutor mSplashScreenExecutor; - // For Car Launcher - public StartingWindowController(Context context, ShellExecutor splashScreenExecutor) { - this(context, splashScreenExecutor, new TransactionPool()); - } - public StartingWindowController(Context context, ShellExecutor splashScreenExecutor, - TransactionPool pool) { + StartingWindowTypeAlgorithm startingWindowTypeAlgorithm, TransactionPool pool) { mContext = context; mStartingSurfaceDrawer = new StartingSurfaceDrawer(context, splashScreenExecutor, pool); + mStartingWindowTypeAlgorithm = startingWindowTypeAlgorithm; mSplashScreenExecutor = splashScreenExecutor; } @@ -109,90 +98,6 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo return mSplashScreenExecutor; } - private static class StartingTypeChecker { - - private @StartingWindowInfo.StartingWindowType int - estimateStartingWindowType(StartingWindowInfo windowInfo) { - final int parameter = windowInfo.startingWindowTypeParameter; - final boolean newTask = (parameter & TYPE_PARAMETER_NEW_TASK) != 0; - final boolean taskSwitch = (parameter & TYPE_PARAMETER_TASK_SWITCH) != 0; - final boolean processRunning = (parameter & TYPE_PARAMETER_PROCESS_RUNNING) != 0; - final boolean allowTaskSnapshot = (parameter & TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT) != 0; - final boolean activityCreated = (parameter & TYPE_PARAMETER_ACTIVITY_CREATED) != 0; - final boolean samePackage = (parameter & TYPE_PARAMETER_SAME_PACKAGE) != 0; - return estimateStartingWindowType(windowInfo, newTask, taskSwitch, - processRunning, allowTaskSnapshot, activityCreated, samePackage); - } - - // reference from ActivityRecord#getStartingWindowType - private int estimateStartingWindowType(StartingWindowInfo windowInfo, - boolean newTask, boolean taskSwitch, boolean processRunning, - boolean allowTaskSnapshot, boolean activityCreated, boolean samePackage) { - if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { - Slog.d(TAG, "preferredStartingWindowType newTask " + newTask - + " taskSwitch " + taskSwitch - + " processRunning " + processRunning - + " allowTaskSnapshot " + allowTaskSnapshot - + " activityCreated " + activityCreated - + " samePackage " + samePackage); - } - if (windowInfo.taskInfo.topActivityType != ACTIVITY_TYPE_HOME) { - if (!processRunning) { - return STARTING_WINDOW_TYPE_SPLASH_SCREEN; - } - if (newTask) { - if (samePackage) { - return STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN; - } else { - return STARTING_WINDOW_TYPE_SPLASH_SCREEN; - } - } - if (taskSwitch && !activityCreated) { - return STARTING_WINDOW_TYPE_SPLASH_SCREEN; - } - } - if (taskSwitch && allowTaskSnapshot) { - final TaskSnapshot snapshot = windowInfo.mTaskSnapshot; - if (isSnapshotCompatible(windowInfo, snapshot)) { - return STARTING_WINDOW_TYPE_SNAPSHOT; - } - if (windowInfo.taskInfo.topActivityType != ACTIVITY_TYPE_HOME) { - return STARTING_WINDOW_TYPE_SPLASH_SCREEN; - } - } - return STARTING_WINDOW_TYPE_NONE; - } - - /** - * Returns {@code true} if the task snapshot is compatible with this activity (at least the - * rotation must be the same). - */ - private boolean isSnapshotCompatible(StartingWindowInfo windowInfo, TaskSnapshot snapshot) { - if (snapshot == null) { - if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { - Slog.d(TAG, "isSnapshotCompatible no snapshot " + windowInfo.taskInfo.taskId); - } - return false; - } - if (!snapshot.getTopActivityComponent().equals(windowInfo.taskInfo.topActivity)) { - if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { - Slog.d(TAG, "isSnapshotCompatible obsoleted snapshot " - + windowInfo.taskInfo.topActivity); - } - return false; - } - - final int taskRotation = windowInfo.taskInfo.configuration - .windowConfiguration.getRotation(); - final int snapshotRotation = snapshot.getRotation(); - if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { - Slog.d(TAG, "isSnapshotCompatible rotation " + taskRotation - + " snapshot " + snapshotRotation); - } - return taskRotation == snapshotRotation; - } - } - /* * Registers the starting window listener. * @@ -212,7 +117,8 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo public void addStartingWindow(StartingWindowInfo windowInfo, IBinder appToken) { mSplashScreenExecutor.execute(() -> { Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "addStartingWindow"); - final int suggestionType = mStartingTypeChecker.estimateStartingWindowType( + + final int suggestionType = mStartingWindowTypeAlgorithm.getSuggestedWindowType( windowInfo); final RunningTaskInfo runningTaskInfo = windowInfo.taskInfo; if (mTaskLaunchingCallback != null && shouldSendToListener(suggestionType)) { @@ -228,8 +134,10 @@ public class StartingWindowController implements RemoteCallable<StartingWindowCo final TaskSnapshot snapshot = windowInfo.mTaskSnapshot; mStartingSurfaceDrawer.makeTaskSnapshotWindow(windowInfo, appToken, snapshot); + } else /* suggestionType == STARTING_WINDOW_TYPE_NONE */ { + // Don't add a staring window. } - // If prefer don't show, then don't show! + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); }); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowTypeAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowTypeAlgorithm.java new file mode 100644 index 000000000000..de221ed4cea7 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/StartingWindowTypeAlgorithm.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.startingsurface; + +import android.window.StartingWindowInfo; + +/** + * Used by {@link StartingWindowController} for determining the type of a new starting window. + */ +public interface StartingWindowTypeAlgorithm { + /** + * @return suggested type for the given window. + */ + @StartingWindowInfo.StartingWindowType + int getSuggestedWindowType(StartingWindowInfo windowInfo); +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java index e9ce2addd464..b46846215ebb 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/TaskSnapshotWindow.java @@ -38,6 +38,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS; import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_USE_BLAST; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_ATTRIBUTES; @@ -52,8 +53,10 @@ import android.app.ActivityThread; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.GraphicBuffer; import android.graphics.Matrix; import android.graphics.Paint; +import android.graphics.PixelFormat; import android.graphics.Point; import android.graphics.Rect; import android.graphics.RectF; @@ -68,7 +71,6 @@ import android.view.IWindowSession; import android.view.InputChannel; import android.view.InsetsSourceControl; import android.view.InsetsState; -import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.View; @@ -122,11 +124,9 @@ public class TaskSnapshotWindow { private static final Point TMP_SURFACE_SIZE = new Point(); private final Window mWindow; - private final Surface mSurface; private final Runnable mClearWindowHandler; private final ShellExecutor mSplashScreenExecutor; - private SurfaceControl mSurfaceControl; - private SurfaceControl mChildSurfaceControl; + private final SurfaceControl mSurfaceControl; private final IWindowSession mSession; private final Rect mTaskBounds; private final Rect mFrame = new Rect(); @@ -179,7 +179,7 @@ public class TaskSnapshotWindow { // Setting as trusted overlay to let touches pass through. This is safe because this // window is controlled by the system. layoutParams.privateFlags = (windowPrivateFlags & PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS) - | PRIVATE_FLAG_TRUSTED_OVERLAY; + | PRIVATE_FLAG_TRUSTED_OVERLAY | PRIVATE_FLAG_USE_BLAST; layoutParams.token = appToken; layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT; @@ -259,7 +259,6 @@ public class TaskSnapshotWindow { int currentOrientation, int activityType, InsetsState topWindowInsetsState, Runnable clearWindowHandler, ShellExecutor splashScreenExecutor) { mSplashScreenExecutor = splashScreenExecutor; - mSurface = new Surface(); mSession = WindowManagerGlobal.getWindowSession(); mWindow = new Window(); mWindow.setSession(mSession); @@ -336,7 +335,6 @@ public class TaskSnapshotWindow { } private void drawSnapshot() { - mSurface.copyFrom(mSurfaceControl); if (DEBUG) { Slog.d(TAG, "Drawing snapshot surface sizeMismatch= " + mSizeMismatch); } @@ -357,15 +355,14 @@ public class TaskSnapshotWindow { } private void drawSizeMatchSnapshot() { - mSurface.attachAndQueueBufferWithColorSpace(mSnapshot.getHardwareBuffer(), - mSnapshot.getColorSpace()); - mSurface.release(); + GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer( + mSnapshot.getHardwareBuffer()); + mTransaction.setBuffer(mSurfaceControl, graphicBuffer) + .setColorSpace(mSurfaceControl, mSnapshot.getColorSpace()) + .apply(); } private void drawSizeMismatchSnapshot() { - if (!mSurface.isValid()) { - throw new IllegalStateException("mSurface does not hold a valid surface."); - } final HardwareBuffer buffer = mSnapshot.getHardwareBuffer(); final SurfaceSession session = new SurfaceSession(); @@ -376,26 +373,24 @@ public class TaskSnapshotWindow { - ((float) mFrame.width() / mFrame.height())) > 0.01f; // Keep a reference to it such that it doesn't get destroyed when finalized. - mChildSurfaceControl = new SurfaceControl.Builder(session) + SurfaceControl childSurfaceControl = new SurfaceControl.Builder(session) .setName(mTitle + " - task-snapshot-surface") - .setBufferSize(buffer.getWidth(), buffer.getHeight()) + .setBLASTLayer() .setFormat(buffer.getFormat()) .setParent(mSurfaceControl) .setCallsite("TaskSnapshotWindow.drawSizeMismatchSnapshot") .build(); - Surface surface = new Surface(); - surface.copyFrom(mChildSurfaceControl); final Rect frame; // We can just show the surface here as it will still be hidden as the parent is // still hidden. - mTransaction.show(mChildSurfaceControl); + mTransaction.show(childSurfaceControl); if (aspectRatioMismatch) { // Clip off ugly navigation bar. final Rect crop = calculateSnapshotCrop(); frame = calculateSnapshotFrame(crop); - mTransaction.setWindowCrop(mChildSurfaceControl, crop); - mTransaction.setPosition(mChildSurfaceControl, frame.left, frame.top); + mTransaction.setWindowCrop(childSurfaceControl, crop); + mTransaction.setPosition(childSurfaceControl, frame.left, frame.top); mTmpSnapshotSize.set(crop); mTmpDstFrame.set(frame); } else { @@ -407,18 +402,23 @@ public class TaskSnapshotWindow { // Scale the mismatch dimensions to fill the task bounds mSnapshotMatrix.setRectToRect(mTmpSnapshotSize, mTmpDstFrame, Matrix.ScaleToFit.FILL); - mTransaction.setMatrix(mChildSurfaceControl, mSnapshotMatrix, mTmpFloat9); - - mTransaction.apply(); - surface.attachAndQueueBufferWithColorSpace(buffer, mSnapshot.getColorSpace()); - surface.release(); + mTransaction.setMatrix(childSurfaceControl, mSnapshotMatrix, mTmpFloat9); + GraphicBuffer graphicBuffer = GraphicBuffer.createFromHardwareBuffer( + mSnapshot.getHardwareBuffer()); + mTransaction.setColorSpace(childSurfaceControl, mSnapshot.getColorSpace()); + mTransaction.setBuffer(childSurfaceControl, graphicBuffer); if (aspectRatioMismatch) { - final Canvas c = mSurface.lockCanvas(null); + GraphicBuffer background = GraphicBuffer.create(mFrame.width(), mFrame.height(), + PixelFormat.RGBA_8888, + GraphicBuffer.USAGE_HW_TEXTURE | GraphicBuffer.USAGE_HW_COMPOSER + | GraphicBuffer.USAGE_SW_WRITE_RARELY); + final Canvas c = background.lockCanvas(); drawBackgroundAndBars(c, frame); - mSurface.unlockCanvasAndPost(c); - mSurface.release(); + background.unlockCanvasAndPost(c); + mTransaction.setBuffer(mSurfaceControl, background); } + mTransaction.apply(); } /** diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java new file mode 100644 index 000000000000..9948e7d1f9c4 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.startingsurface.phone; + +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; +import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN; +import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_NONE; +import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SNAPSHOT; +import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN; +import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED; +import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT; +import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK; +import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING; +import static android.window.StartingWindowInfo.TYPE_PARAMETER_SAME_PACKAGE; +import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH; + +import static com.android.wm.shell.startingsurface.StartingWindowController.DEBUG_SPLASH_SCREEN; +import static com.android.wm.shell.startingsurface.StartingWindowController.DEBUG_TASK_SNAPSHOT; + +import android.util.Slog; +import android.window.StartingWindowInfo; +import android.window.TaskSnapshot; + +import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm; + +/** + * Algorithm for determining the type of a new starting window on handheld devices. + * At the moment also used on Android Auto. + */ +public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgorithm { + private static final String TAG = PhoneStartingWindowTypeAlgorithm.class.getSimpleName(); + + @Override + public int getSuggestedWindowType(StartingWindowInfo windowInfo) { + final int parameter = windowInfo.startingWindowTypeParameter; + final boolean newTask = (parameter & TYPE_PARAMETER_NEW_TASK) != 0; + final boolean taskSwitch = (parameter & TYPE_PARAMETER_TASK_SWITCH) != 0; + final boolean processRunning = (parameter & TYPE_PARAMETER_PROCESS_RUNNING) != 0; + final boolean allowTaskSnapshot = (parameter & TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT) != 0; + final boolean activityCreated = (parameter & TYPE_PARAMETER_ACTIVITY_CREATED) != 0; + final boolean samePackage = (parameter & TYPE_PARAMETER_SAME_PACKAGE) != 0; + final boolean topIsHome = windowInfo.taskInfo.topActivityType == ACTIVITY_TYPE_HOME; + + if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { + Slog.d(TAG, "preferredStartingWindowType newTask " + newTask + + " taskSwitch " + taskSwitch + + " processRunning " + processRunning + + " allowTaskSnapshot " + allowTaskSnapshot + + " activityCreated " + activityCreated + + " samePackage " + samePackage + + " topIsHome " + topIsHome); + } + if (!topIsHome) { + if (!processRunning) { + return STARTING_WINDOW_TYPE_SPLASH_SCREEN; + } + if (newTask) { + if (samePackage) { + return STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN; + } else { + return STARTING_WINDOW_TYPE_SPLASH_SCREEN; + } + } + if (taskSwitch && !activityCreated) { + return STARTING_WINDOW_TYPE_SPLASH_SCREEN; + } + } + if (taskSwitch && allowTaskSnapshot) { + if (isSnapshotCompatible(windowInfo)) { + return STARTING_WINDOW_TYPE_SNAPSHOT; + } + if (!topIsHome) { + return STARTING_WINDOW_TYPE_SPLASH_SCREEN; + } + } + return STARTING_WINDOW_TYPE_NONE; + } + + + /** + * Returns {@code true} if the task snapshot is compatible with this activity (at least the + * rotation must be the same). + */ + private boolean isSnapshotCompatible(StartingWindowInfo windowInfo) { + final TaskSnapshot snapshot = windowInfo.mTaskSnapshot; + if (snapshot == null) { + if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { + Slog.d(TAG, "isSnapshotCompatible no snapshot " + windowInfo.taskInfo.taskId); + } + return false; + } + if (!snapshot.getTopActivityComponent().equals(windowInfo.taskInfo.topActivity)) { + if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { + Slog.d(TAG, "isSnapshotCompatible obsoleted snapshot " + + windowInfo.taskInfo.topActivity); + } + return false; + } + + final int taskRotation = windowInfo.taskInfo.configuration + .windowConfiguration.getRotation(); + final int snapshotRotation = snapshot.getRotation(); + if (DEBUG_SPLASH_SCREEN || DEBUG_TASK_SNAPSHOT) { + Slog.d(TAG, "isSnapshotCompatible rotation " + taskRotation + + " snapshot " + snapshotRotation); + } + return taskRotation == snapshotRotation; + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/tv/TvStartingWindowTypeAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/tv/TvStartingWindowTypeAlgorithm.java new file mode 100644 index 000000000000..6e7dec590308 --- /dev/null +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/tv/TvStartingWindowTypeAlgorithm.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.startingsurface.tv; + +import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN; + +import android.window.StartingWindowInfo; + +import com.android.wm.shell.startingsurface.StartingWindowTypeAlgorithm; + +/** + * Algorithm for determining the type of a new starting window on Android TV. + * For now we always show empty splash screens on Android TV. + */ +public class TvStartingWindowTypeAlgorithm implements StartingWindowTypeAlgorithm { + @Override + public int getSuggestedWindowType(StartingWindowInfo windowInfo) { + // For now we want to always show empty splash screens on TV. + return STARTING_WINDOW_TYPE_EMPTY_SPLASH_SCREEN; + } +} diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java index b29b18bec032..c6fb5af7d4be 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultTransitionHandler.java @@ -18,9 +18,14 @@ package com.android.wm.shell.transition; import static android.view.WindowManager.TRANSIT_CHANGE; import static android.view.WindowManager.TRANSIT_CLOSE; +import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY; +import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE; import static android.view.WindowManager.TRANSIT_OPEN; +import static android.view.WindowManager.TRANSIT_RELAUNCH; import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; +import static android.window.TransitionInfo.FLAG_IS_VOICE_INTERACTION; +import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER; import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT; import static android.window.TransitionInfo.FLAG_TRANSLUCENT; @@ -64,6 +69,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { /** Keeps track of the currently-running animations associated with each transition. */ private final ArrayMap<IBinder, ArrayList<Animator>> mAnimations = new ArrayMap<>(); + private final Rect mInsets = new Rect(0, 0, 0, 0); private float mTransitionAnimationScaleSetting = 1.0f; DefaultTransitionHandler(@NonNull TransactionPool transactionPool, Context context, @@ -111,7 +117,7 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { // Don't animate anything that isn't independent. if (!TransitionInfo.isIndependent(change, info)) continue; - Animation a = loadAnimation(info.getType(), change); + Animation a = loadAnimation(info.getType(), info.getFlags(), change); if (a != null) { startAnimInternal(animations, a, change.getLeash(), onAnimFinish); } @@ -135,47 +141,69 @@ public class DefaultTransitionHandler implements Transitions.TransitionHandler { } @Nullable - private Animation loadAnimation(int type, TransitionInfo.Change change) { + private Animation loadAnimation(int type, int flags, TransitionInfo.Change change) { // TODO(b/178678389): It should handle more type animation here Animation a = null; final boolean isOpening = Transitions.isOpeningType(type); - final int mode = change.getMode(); - final int flags = change.getFlags(); + final int changeMode = change.getMode(); + final int changeFlags = change.getFlags(); - if (mode == TRANSIT_OPEN && isOpening) { - if ((flags & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0) { + if (type == TRANSIT_RELAUNCH) { + a = mTransitionAnimation.createRelaunchAnimation( + change.getStartAbsBounds(), mInsets, change.getEndAbsBounds()); + } else if (type == TRANSIT_KEYGUARD_GOING_AWAY) { + a = mTransitionAnimation.loadKeyguardExitAnimation(flags, + (changeFlags & FLAG_SHOW_WALLPAPER) != 0); + } else if (type == TRANSIT_KEYGUARD_UNOCCLUDE) { + a = mTransitionAnimation.loadKeyguardUnoccludeAnimation(); + } else if (changeMode == TRANSIT_OPEN && isOpening) { + if ((changeFlags & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0) { // This received a transferred starting window, so don't animate return null; } - if (change.getTaskInfo() != null) { + if ((changeFlags & FLAG_IS_VOICE_INTERACTION) != 0) { + a = mTransitionAnimation.loadVoiceActivityOpenAnimation(true /** enter */); + } else if (change.getTaskInfo() != null) { a = mTransitionAnimation.loadDefaultAnimationAttr( R.styleable.WindowAnimation_taskOpenEnterAnimation); } else { - a = mTransitionAnimation.loadDefaultAnimationRes((flags & FLAG_TRANSLUCENT) == 0 + a = mTransitionAnimation.loadDefaultAnimationRes( + (changeFlags & FLAG_TRANSLUCENT) == 0 ? R.anim.activity_open_enter : R.anim.activity_translucent_open_enter); } - } else if (mode == TRANSIT_TO_FRONT && isOpening) { - if ((flags & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0) { + } else if (changeMode == TRANSIT_TO_FRONT && isOpening) { + if ((changeFlags & FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT) != 0) { // This received a transferred starting window, so don't animate return null; } - a = mTransitionAnimation.loadDefaultAnimationAttr( - R.styleable.WindowAnimation_taskToFrontEnterAnimation); - } else if (mode == TRANSIT_CLOSE && !isOpening) { - if (change.getTaskInfo() != null) { + if ((changeFlags & FLAG_IS_VOICE_INTERACTION) != 0) { + a = mTransitionAnimation.loadVoiceActivityOpenAnimation(true /** enter */); + } else { + a = mTransitionAnimation.loadDefaultAnimationAttr( + R.styleable.WindowAnimation_taskToFrontEnterAnimation); + } + } else if (changeMode == TRANSIT_CLOSE && !isOpening) { + if ((changeFlags & FLAG_IS_VOICE_INTERACTION) != 0) { + a = mTransitionAnimation.loadVoiceActivityExitAnimation(false /** enter */); + } else if (change.getTaskInfo() != null) { a = mTransitionAnimation.loadDefaultAnimationAttr( R.styleable.WindowAnimation_taskCloseExitAnimation); } else { - a = mTransitionAnimation.loadDefaultAnimationRes((flags & FLAG_TRANSLUCENT) == 0 + a = mTransitionAnimation.loadDefaultAnimationRes( + (changeFlags & FLAG_TRANSLUCENT) == 0 ? R.anim.activity_close_exit : R.anim.activity_translucent_close_exit); } - } else if (mode == TRANSIT_TO_BACK && !isOpening) { - a = mTransitionAnimation.loadDefaultAnimationAttr( - R.styleable.WindowAnimation_taskToBackExitAnimation); - } else if (mode == TRANSIT_CHANGE) { + } else if (changeMode == TRANSIT_TO_BACK && !isOpening) { + if ((changeFlags & FLAG_IS_VOICE_INTERACTION) != 0) { + a = mTransitionAnimation.loadVoiceActivityExitAnimation(false /** enter */); + } else { + a = mTransitionAnimation.loadDefaultAnimationAttr( + R.styleable.WindowAnimation_taskToBackExitAnimation); + } + } else if (changeMode == TRANSIT_CHANGE) { // In the absence of a specific adapter, we just want to keep everything stationary. a = new AlphaAnimation(1.f, 1.f); a.setDuration(TransitionAnimation.DEFAULT_APP_TRANSITION_DURATION); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java index 71fd917275ea..4da6664aa3dc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/OneShotRemoteHandler.java @@ -82,18 +82,39 @@ public class OneShotRemoteHandler implements Transitions.TransitionHandler { if (mRemote.asBinder() != null) { mRemote.asBinder().linkToDeath(remoteDied, 0 /* flags */); } - mRemote.startAnimation(info, t, cb); + mRemote.startAnimation(transition, info, t, cb); } catch (RemoteException e) { + Log.e(Transitions.TAG, "Error running remote transition.", e); if (mRemote.asBinder() != null) { mRemote.asBinder().unlinkToDeath(remoteDied, 0 /* flags */); } - Log.e(Transitions.TAG, "Error running remote transition.", e); finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */); } return true; } @Override + public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, + @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget, + @NonNull Transitions.TransitionFinishCallback finishCallback) { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Using registered One-shot remote" + + " transition %s for %s.", mRemote, transition); + + IRemoteTransitionFinishedCallback cb = new IRemoteTransitionFinishedCallback.Stub() { + @Override + public void onTransitionFinished(WindowContainerTransaction wct) { + mMainExecutor.execute( + () -> finishCallback.onTransitionFinished(wct, null /* wctCB */)); + } + }; + try { + mRemote.mergeAnimation(transition, info, t, mergeTarget, cb); + } catch (RemoteException e) { + Log.e(Transitions.TAG, "Error merging remote transition.", e); + } + } + + @Override @Nullable public WindowContainerTransaction handleRequest(@NonNull IBinder transition, @Nullable TransitionRequestInfo request) { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java index 8876e5f86139..9bfb261fcb85 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/RemoteTransitionHandler.java @@ -16,8 +16,6 @@ package com.android.wm.shell.transition; -import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission; - import android.annotation.NonNull; import android.annotation.Nullable; import android.os.IBinder; @@ -52,7 +50,7 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { private final ShellExecutor mMainExecutor; /** Includes remotes explicitly requested by, eg, ActivityOptions */ - private final ArrayMap<IBinder, IRemoteTransition> mPendingRemotes = new ArrayMap<>(); + private final ArrayMap<IBinder, IRemoteTransition> mRequestedRemotes = new ArrayMap<>(); /** Ordered by specificity. Last filters will be checked first */ private final ArrayList<Pair<TransitionFilter, IRemoteTransition>> mFilters = @@ -63,9 +61,7 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { @Override @BinderThread public void binderDied() { - mMainExecutor.execute(() -> { - mFilters.clear(); - }); + mMainExecutor.execute(() -> mFilters.clear()); } }; @@ -97,10 +93,15 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { } @Override + public void onTransitionMerged(@NonNull IBinder transition) { + mRequestedRemotes.remove(transition); + } + + @Override public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t, @NonNull Transitions.TransitionFinishCallback finishCallback) { - IRemoteTransition pendingRemote = mPendingRemotes.remove(transition); + IRemoteTransition pendingRemote = mRequestedRemotes.get(transition); if (pendingRemote == null) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition %s doesn't have " + "explicit remote, search filters for match for %s", transition, info); @@ -110,6 +111,8 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { mFilters.get(i)); if (mFilters.get(i).first.matches(info)) { pendingRemote = mFilters.get(i).second; + // Add to requested list so that it can be found for merge requests. + mRequestedRemotes.put(transition, pendingRemote); break; } } @@ -122,8 +125,10 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { final IRemoteTransition remote = pendingRemote; final IBinder.DeathRecipient remoteDied = () -> { Log.e(Transitions.TAG, "Remote transition died, finishing"); - mMainExecutor.execute( - () -> finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */)); + mMainExecutor.execute(() -> { + mRequestedRemotes.remove(transition); + finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */); + }); }; IRemoteTransitionFinishedCallback cb = new IRemoteTransitionFinishedCallback.Stub() { @Override @@ -131,20 +136,23 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { if (remote.asBinder() != null) { remote.asBinder().unlinkToDeath(remoteDied, 0 /* flags */); } - mMainExecutor.execute( - () -> finishCallback.onTransitionFinished(wct, null /* wctCB */)); + mMainExecutor.execute(() -> { + mRequestedRemotes.remove(transition); + finishCallback.onTransitionFinished(wct, null /* wctCB */); + }); } }; try { if (remote.asBinder() != null) { remote.asBinder().linkToDeath(remoteDied, 0 /* flags */); } - remote.startAnimation(info, t, cb); + remote.startAnimation(transition, info, t, cb); } catch (RemoteException e) { + Log.e(Transitions.TAG, "Error running remote transition.", e); if (remote.asBinder() != null) { remote.asBinder().unlinkToDeath(remoteDied, 0 /* flags */); } - Log.e(Transitions.TAG, "Error running remote transition.", e); + mRequestedRemotes.remove(transition); mMainExecutor.execute( () -> finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */)); } @@ -152,12 +160,42 @@ public class RemoteTransitionHandler implements Transitions.TransitionHandler { } @Override + public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, + @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget, + @NonNull Transitions.TransitionFinishCallback finishCallback) { + final IRemoteTransition remote = mRequestedRemotes.get(mergeTarget); + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Attempt merge %s into %s", + transition, remote); + if (remote == null) return; + + IRemoteTransitionFinishedCallback cb = new IRemoteTransitionFinishedCallback.Stub() { + @Override + public void onTransitionFinished(WindowContainerTransaction wct) { + mMainExecutor.execute(() -> { + if (!mRequestedRemotes.containsKey(mergeTarget)) { + Log.e(TAG, "Merged transition finished after it's mergeTarget (the " + + "transition it was supposed to merge into). This usually means " + + "that the mergeTarget's RemoteTransition impl erroneously " + + "accepted/ran the merge request after finishing the mergeTarget"); + } + finishCallback.onTransitionFinished(wct, null /* wctCB */); + }); + } + }; + try { + remote.mergeAnimation(transition, info, t, mergeTarget, cb); + } catch (RemoteException e) { + Log.e(Transitions.TAG, "Error attempting to merge remote transition.", e); + } + } + + @Override @Nullable public WindowContainerTransaction handleRequest(@NonNull IBinder transition, @Nullable TransitionRequestInfo request) { IRemoteTransition remote = request.getRemoteTransition(); if (remote == null) return null; - mPendingRemotes.put(transition, remote); + mRequestedRemotes.put(transition, remote); ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "RemoteTransition directly requested" + " for %s: %s", transition, remote); return new WindowContainerTransaction(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java index 64dc47f5549a..3251abc3a8b8 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java @@ -35,7 +35,6 @@ import android.os.IBinder; import android.os.RemoteException; import android.os.SystemProperties; import android.provider.Settings; -import android.util.ArrayMap; import android.util.Log; import android.view.SurfaceControl; import android.view.WindowManager; @@ -91,11 +90,16 @@ public class Transitions implements RemoteCallable<Transitions> { private float mTransitionAnimationScaleSetting = 1.0f; private static final class ActiveTransition { - TransitionHandler mFirstHandler = null; + IBinder mToken = null; + TransitionHandler mHandler = null; + boolean mMerged = false; + TransitionInfo mInfo = null; + SurfaceControl.Transaction mStartT = null; + SurfaceControl.Transaction mFinishT = null; } - /** Keeps track of currently tracked transitions and all the animations associated with each */ - private final ArrayMap<IBinder, ActiveTransition> mActiveTransitions = new ArrayMap<>(); + /** Keeps track of currently playing transitions in the order of receipt. */ + private final ArrayList<ActiveTransition> mActiveTransitions = new ArrayList<>(); public Transitions(@NonNull WindowOrganizer organizer, @NonNull TransactionPool pool, @NonNull Context context, @NonNull ShellExecutor mainExecutor, @@ -226,7 +230,7 @@ public class Transitions implements RemoteCallable<Transitions> { * type, their transit mode, and their destination z-order. */ private static void setupStartState(@NonNull TransitionInfo info, - @NonNull SurfaceControl.Transaction t) { + @NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl.Transaction finishT) { boolean isOpening = isOpeningType(info.getType()); if (info.getRootLeash().isValid()) { t.show(info.getRootLeash()); @@ -270,6 +274,8 @@ public class Transitions implements RemoteCallable<Transitions> { t.setAlpha(leash, 1.f); } else { t.setAlpha(leash, 0.f); + // fix alpha in finish transaction in case the animator itself no-ops. + finishT.setAlpha(leash, 1.f); } } else { // put on bottom and leave it visible @@ -290,16 +296,24 @@ public class Transitions implements RemoteCallable<Transitions> { } } + private int findActiveTransition(IBinder token) { + for (int i = mActiveTransitions.size() - 1; i >= 0; --i) { + if (mActiveTransitions.get(i).mToken == token) return i; + } + return -1; + } + @VisibleForTesting void onTransitionReady(@NonNull IBinder transitionToken, @NonNull TransitionInfo info, - @NonNull SurfaceControl.Transaction t) { + @NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl.Transaction finishT) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "onTransitionReady %s: %s", transitionToken, info); - final ActiveTransition active = mActiveTransitions.get(transitionToken); - if (active == null) { + final int activeIdx = findActiveTransition(transitionToken); + if (activeIdx < 0) { throw new IllegalStateException("Got transitionReady for non-active transition " + transitionToken + ". expecting one of " - + Arrays.toString(mActiveTransitions.keySet().toArray())); + + Arrays.toString(mActiveTransitions.stream().map( + activeTransition -> activeTransition.mToken).toArray())); } if (!info.getRootLeash().isValid()) { // Invalid root-leash implies that the transition is empty/no-op, so just do @@ -307,30 +321,62 @@ public class Transitions implements RemoteCallable<Transitions> { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Invalid root leash (%s): %s", transitionToken, info); t.apply(); - onFinish(transitionToken, null /* wct */, null /* wctCB */); + onAbort(transitionToken); return; } - setupStartState(info, t); + final ActiveTransition active = mActiveTransitions.get(activeIdx); + active.mInfo = info; + active.mStartT = t; + active.mFinishT = finishT; + if (activeIdx > 0) { + // This is now playing at the same time as an existing animation, so try merging it. + attemptMergeTransition(mActiveTransitions.get(0), active); + return; + } + // The normal case, just play it. + playTransition(active); + } - final TransitionFinishCallback finishCb = (wct, cb) -> onFinish(transitionToken, wct, cb); - // If a handler chose to uniquely run this animation, try delegating to it. - if (active.mFirstHandler != null) { + /** + * Attempt to merge by delegating the transition start to the handler of the currently + * playing transition. + */ + void attemptMergeTransition(@NonNull ActiveTransition playing, + @NonNull ActiveTransition merging) { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition %s ready while" + + " another transition %s is still animating. Notify the animating transition" + + " in case they can be merged", merging.mToken, playing.mToken); + playing.mHandler.mergeAnimation(merging.mToken, merging.mInfo, merging.mStartT, + playing.mToken, (wct, cb) -> onFinish(merging.mToken, wct, cb)); + } + + boolean startAnimation(@NonNull ActiveTransition active, TransitionHandler handler) { + return handler.startAnimation(active.mToken, active.mInfo, active.mStartT, + (wct, cb) -> onFinish(active.mToken, wct, cb)); + } + + void playTransition(@NonNull ActiveTransition active) { + setupStartState(active.mInfo, active.mStartT, active.mFinishT); + + // If a handler already chose to run this animation, try delegating to it first. + if (active.mHandler != null) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " try firstHandler %s", - active.mFirstHandler); - if (active.mFirstHandler.startAnimation(transitionToken, info, t, finishCb)) { + active.mHandler); + if (startAnimation(active, active.mHandler)) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " animated by firstHandler"); return; } } // Otherwise give every other handler a chance (in order) for (int i = mHandlers.size() - 1; i >= 0; --i) { - if (mHandlers.get(i) == active.mFirstHandler) continue; + if (mHandlers.get(i) == active.mHandler) continue; ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " try handler %s", mHandlers.get(i)); - if (mHandlers.get(i).startAnimation(transitionToken, info, t, finishCb)) { + if (startAnimation(active, mHandlers.get(i))) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " animated by %s", mHandlers.get(i)); + active.mHandler = mHandlers.get(i); return; } } @@ -338,23 +384,107 @@ public class Transitions implements RemoteCallable<Transitions> { "This shouldn't happen, maybe the default handler is broken."); } - private void onFinish(IBinder transition, @Nullable WindowContainerTransaction wct, + /** Special version of finish just for dealing with no-op/invalid transitions. */ + private void onAbort(IBinder transition) { + final int activeIdx = findActiveTransition(transition); + if (activeIdx < 0) return; + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, + "Transition animation aborted due to no-op, notifying core %s", transition); + mActiveTransitions.remove(activeIdx); + mOrganizer.finishTransition(transition, null /* wct */, null /* wctCB */); + } + + private void onFinish(IBinder transition, + @Nullable WindowContainerTransaction wct, @Nullable WindowContainerTransactionCallback wctCB) { - if (!mActiveTransitions.containsKey(transition)) { - Log.e(TAG, "Trying to finish a non-running transition. Maybe remote crashed?"); + int activeIdx = findActiveTransition(transition); + if (activeIdx < 0) { + Log.e(TAG, "Trying to finish a non-running transition. Either remote crashed or " + + " a handler didn't properly deal with a merge.", new RuntimeException()); + return; + } else if (activeIdx > 0) { + // This transition was merged. + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition was merged: %s", + transition); + final ActiveTransition active = mActiveTransitions.get(activeIdx); + active.mMerged = true; + if (active.mHandler != null) { + active.mHandler.onTransitionMerged(active.mToken); + } return; } ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, - "Transition animations finished, notifying core %s", transition); - mActiveTransitions.remove(transition); + "Transition animation finished, notifying core %s", transition); + // Merge all relevant transactions together + SurfaceControl.Transaction fullFinish = mActiveTransitions.get(activeIdx).mFinishT; + for (int iA = activeIdx + 1; iA < mActiveTransitions.size(); ++iA) { + final ActiveTransition toMerge = mActiveTransitions.get(iA); + if (!toMerge.mMerged) break; + // Include start. It will be a no-op if it was already applied. Otherwise, we need it + // to maintain consistent state. + fullFinish.merge(mActiveTransitions.get(iA).mStartT); + fullFinish.merge(mActiveTransitions.get(iA).mFinishT); + } + fullFinish.apply(); + // Now perform all the finishes. + mActiveTransitions.remove(activeIdx); mOrganizer.finishTransition(transition, wct, wctCB); + while (activeIdx < mActiveTransitions.size()) { + if (!mActiveTransitions.get(activeIdx).mMerged) break; + ActiveTransition merged = mActiveTransitions.remove(activeIdx); + mOrganizer.finishTransition(merged.mToken, null /* wct */, null /* wctCB */); + } + if (mActiveTransitions.size() <= activeIdx) { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "All active transition animations " + + "finished"); + return; + } + // Start animating the next active transition + final ActiveTransition next = mActiveTransitions.get(activeIdx); + if (next.mInfo == null) { + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Pending transition after one" + + " finished, but it isn't ready yet."); + return; + } + ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Pending transitions after one" + + " finished, so start the next one."); + playTransition(next); + // Now try to merge the rest of the transitions (re-acquire activeIdx since next may have + // finished immediately) + activeIdx = findActiveTransition(next.mToken); + if (activeIdx < 0) { + // This means 'next' finished immediately and thus re-entered this function. Since + // that is the case, just return here since all relevant logic has already run in the + // re-entered call. + return; + } + + // This logic is also convoluted because 'next' may finish immediately in response to any of + // the merge requests (eg. if it decided to "cancel" itself). + int mergeIdx = activeIdx + 1; + while (mergeIdx < mActiveTransitions.size()) { + ActiveTransition mergeCandidate = mActiveTransitions.get(mergeIdx); + if (mergeCandidate.mMerged) { + throw new IllegalStateException("Can't merge a transition after not-merging" + + " a preceding one."); + } + attemptMergeTransition(next, mergeCandidate); + mergeIdx = findActiveTransition(mergeCandidate.mToken); + if (mergeIdx < 0) { + // This means 'next' finished immediately and thus re-entered this function. Since + // that is the case, just return here since all relevant logic has already run in + // the re-entered call. + return; + } + ++mergeIdx; + } } void requestStartTransition(@NonNull IBinder transitionToken, @Nullable TransitionRequestInfo request) { ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition requested: %s %s", transitionToken, request); - if (mActiveTransitions.containsKey(transitionToken)) { + if (findActiveTransition(transitionToken) >= 0) { throw new RuntimeException("Transition already started " + transitionToken); } final ActiveTransition active = new ActiveTransition(); @@ -362,23 +492,23 @@ public class Transitions implements RemoteCallable<Transitions> { for (int i = mHandlers.size() - 1; i >= 0; --i) { wct = mHandlers.get(i).handleRequest(transitionToken, request); if (wct != null) { - active.mFirstHandler = mHandlers.get(i); + active.mHandler = mHandlers.get(i); break; } } - IBinder transition = mOrganizer.startTransition( + active.mToken = mOrganizer.startTransition( request.getType(), transitionToken, wct); - mActiveTransitions.put(transition, active); + mActiveTransitions.add(active); } /** Start a new transition directly. */ public IBinder startTransition(@WindowManager.TransitionType int type, @NonNull WindowContainerTransaction wct, @Nullable TransitionHandler handler) { final ActiveTransition active = new ActiveTransition(); - active.mFirstHandler = handler; - IBinder transition = mOrganizer.startTransition(type, null /* token */, wct); - mActiveTransitions.put(transition, active); - return transition; + active.mHandler = handler; + active.mToken = mOrganizer.startTransition(type, null /* token */, wct); + mActiveTransitions.add(active); + return active.mToken; } /** @@ -415,6 +545,32 @@ public class Transitions implements RemoteCallable<Transitions> { @NonNull TransitionFinishCallback finishCallback); /** + * Attempts to merge a different transition's animation into an animation that this handler + * is currently playing. If a merge is not possible/supported, this should be a no-op. + * + * This gets called if another transition becomes ready while this handler is still playing + * an animation. This is called regardless of whether this handler claims to support that + * particular transition or not. + * + * When this happens, there are 2 options: + * 1. Do nothing. This effectively rejects the merge request. This is the "safest" option. + * 2. Merge the incoming transition into this one. The implementation is up to this + * handler. To indicate that this handler has "consumed" the merge transition, it + * must call the finishCallback immediately, or at-least before the original + * transition's finishCallback is called. + * + * @param transition This is the transition that wants to be merged. + * @param info Information about what is changing in the transition. + * @param t Contains surface changes that resulted from the transition. + * @param mergeTarget This is the transition that we are attempting to merge with (ie. the + * one this handler is currently already animating). + * @param finishCallback Call this if merged. This MUST be called on main thread. + */ + default void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, + @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget, + @NonNull TransitionFinishCallback finishCallback) { } + + /** * Potentially handles a startTransition request. * * @param transition The transition whose start is being requested. @@ -427,6 +583,12 @@ public class Transitions implements RemoteCallable<Transitions> { @NonNull TransitionRequestInfo request); /** + * Called when a transition which was already "claimed" by this handler has been merged + * into another animation. Gives this handler a chance to clean-up any expectations. + */ + default void onTransitionMerged(@NonNull IBinder transition) { } + + /** * Sets transition animation scale settings value to handler. * * @param scale The setting value of transition animation scale. @@ -438,10 +600,10 @@ public class Transitions implements RemoteCallable<Transitions> { private class TransitionPlayerImpl extends ITransitionPlayer.Stub { @Override public void onTransitionReady(IBinder iBinder, TransitionInfo transitionInfo, - SurfaceControl.Transaction transaction) throws RemoteException { - mMainExecutor.execute(() -> { - Transitions.this.onTransitionReady(iBinder, transitionInfo, transaction); - }); + SurfaceControl.Transaction t, SurfaceControl.Transaction finishT) + throws RemoteException { + mMainExecutor.execute(() -> Transitions.this.onTransitionReady( + iBinder, transitionInfo, t, finishT)); } @Override diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTransition.kt index 134d00be73e8..741773e8f61a 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/apppairs/AppPairsTransition.kt @@ -22,6 +22,7 @@ import android.platform.test.annotations.Presubmit import android.system.helpers.ActivityHelper import android.util.Log import android.view.Surface +import androidx.test.filters.FlakyTest import androidx.test.platform.app.InstrumentationRegistry import com.android.compatibility.common.util.SystemUtil import com.android.server.wm.flicker.FlickerBuilderProvider @@ -138,7 +139,7 @@ abstract class AppPairsTransition(protected val testSpec: FlickerTestParameter) append("$primaryApp $secondaryApp") } - @Presubmit + @FlakyTest(bugId = 186510496) @Test open fun navBarLayerIsAlwaysVisible() { testSpec.navBarLayerIsAlwaysVisible() diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt index 6494f89997e5..91d51de3a872 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenDockActivity.kt @@ -74,12 +74,6 @@ class EnterSplitScreenDockActivity( @Test fun dockedStackDividerBecomesVisible() = testSpec.dockedStackDividerBecomesVisible() - @FlakyTest(bugId = 178531736) - @Test - // b/178531736 - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - @Presubmit @Test fun navBarWindowIsAlwaysVisible() = testSpec.navBarWindowIsAlwaysVisible() @@ -88,12 +82,6 @@ class EnterSplitScreenDockActivity( @Test fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() - @FlakyTest(bugId = 178531736) - @Test - // b/178531736 - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - @Presubmit @Test fun appWindowIsVisible() { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenLaunchToSide.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenLaunchToSide.kt index 9000f22fb03d..f975ed92e872 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenLaunchToSide.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenLaunchToSide.kt @@ -83,13 +83,6 @@ class EnterSplitScreenLaunchToSide( // b/169271943 fun dockedStackDividerBecomesVisible() = testSpec.dockedStackDividerBecomesVisible() - @FlakyTest(bugId = 178447631) - @Test - // TODO(b/178447631) Remove Splash Screen from white list when flicker lib - // add a wait for splash screen be gone - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - @Presubmit @Test fun appWindowBecomesVisible() = testSpec.appWindowBecomesVisible(secondaryApp.defaultWindowName) @@ -102,11 +95,6 @@ class EnterSplitScreenLaunchToSide( @Test fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() - @Presubmit - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenNotSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenNotSupportNonResizable.kt index 7d22d4dbe5ab..04f97c8a4c99 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenNotSupportNonResizable.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenNotSupportNonResizable.kt @@ -16,17 +16,15 @@ package com.android.wm.shell.flicker.legacysplitscreen -import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit import android.provider.Settings import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.FlickerTestParameterFactory import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.canSplitScreen -import com.android.server.wm.flicker.helpers.openQuickstep import com.android.server.wm.traces.parser.windowmanager.WindowManagerStateHelper import com.android.wm.shell.flicker.dockedStackDividerIsInvisible import com.android.wm.shell.flicker.helpers.SplitScreenHelper @@ -46,7 +44,6 @@ import org.junit.runners.Parameterized * * To run this test: `atest WMShellFlickerTests:EnterSplitScreenNotSupportNonResizable` */ -@Postsubmit @RequiresDevice @RunWith(Parameterized::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @@ -65,7 +62,6 @@ class EnterSplitScreenNotSupportNonResizable( } } transitions { - device.openQuickstep(wmHelper) if (device.canSplitScreen(wmHelper)) { Assert.fail("Non-resizeable app should not enter split screen") } @@ -97,25 +93,10 @@ class EnterSplitScreenNotSupportNonResizable( prevSupportNonResizableInMultiWindow) } - @FlakyTest(bugId = 178447631) - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - + @Presubmit @Test fun dockedStackDividerIsInvisible() = testSpec.dockedStackDividerIsInvisible() - @Test - fun appWindowIsVisible() { - testSpec.assertWmEnd { - isInvisible(nonResizeableApp.defaultWindowName) - } - } - companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenSupportNonResizable.kt index 9b4a10389619..2832bb4d15d4 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenSupportNonResizable.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/EnterSplitScreenSupportNonResizable.kt @@ -16,10 +16,9 @@ package com.android.wm.shell.flicker.legacysplitscreen -import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit import android.provider.Settings import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -44,7 +43,6 @@ import org.junit.runners.Parameterized * * To run this test: `atest WMShellFlickerTests:EnterSplitScreenSupportNonResizable` */ -@Postsubmit @RequiresDevice @RunWith(Parameterized::class) @FixMethodOrder(MethodSorters.NAME_ASCENDING) @@ -92,18 +90,11 @@ class EnterSplitScreenSupportNonResizable( prevSupportNonResizableInMultiWindow) } - @FlakyTest(bugId = 178447631) - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - + @Presubmit @Test fun dockedStackDividerIsVisible() = testSpec.dockedStackDividerIsVisible() + @Presubmit @Test fun appWindowIsVisible() { testSpec.assertWmEnd { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottom.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottom.kt index 64cc85340a38..faf7aa75a1de 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottom.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitLegacySplitScreenFromBottom.kt @@ -78,12 +78,6 @@ class ExitLegacySplitScreenFromBottom( @Test fun layerBecomesInvisible() = testSpec.layerBecomesInvisible(DOCKED_STACK_DIVIDER) - @FlakyTest(bugId = 178447631) - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() { - super.visibleLayersShownMoreThanOneConsecutiveEntry() - } - @FlakyTest @Test fun appWindowBecomesInVisible() = @@ -97,11 +91,6 @@ class ExitLegacySplitScreenFromBottom( @Test fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() - @FlakyTest(bugId = 178447631) - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitPrimarySplitScreenShowSecondaryFullscreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitPrimarySplitScreenShowSecondaryFullscreen.kt index 2e115518721f..8845777dda6e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitPrimarySplitScreenShowSecondaryFullscreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ExitPrimarySplitScreenShowSecondaryFullscreen.kt @@ -82,11 +82,6 @@ class ExitPrimarySplitScreenShowSecondaryFullscreen( @Test fun layerBecomesInvisible() = testSpec.layerBecomesInvisible(splitScreenApp.defaultWindowName) - @FlakyTest(bugId = 178447631) - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - @FlakyTest @Test fun appWindowBecomesInVisible() = @@ -100,11 +95,6 @@ class ExitPrimarySplitScreenShowSecondaryFullscreen( @Test fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() - @FlakyTest(bugId = 178447631) - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - companion object { @Parameterized.Parameters(name = "{0}") @JvmStatic diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentNotSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentNotSupportNonResizable.kt index 892384561eb2..32afd190af2b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentNotSupportNonResizable.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentNotSupportNonResizable.kt @@ -16,10 +16,9 @@ package com.android.wm.shell.flicker.legacysplitscreen -import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit import android.provider.Settings import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -47,7 +46,6 @@ import org.junit.runners.Parameterized * support non-resizable in multi window, it should trigger exit split screen. * To run this test: `atest WMShellFlickerTests:LegacySplitScreenFromIntentNotSupportNonResizable` */ -@Postsubmit @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @@ -96,35 +94,31 @@ class LegacySplitScreenFromIntentNotSupportNonResizable( prevSupportNonResizableInMultiWindow) } - @FlakyTest(bugId = 178447631) - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - - @FlakyTest(bugId = 178447631) - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - + @Presubmit @Test fun resizableAppLayerBecomesInvisible() = testSpec.layerBecomesInvisible(splitScreenApp.defaultWindowName) + @Presubmit @Test fun nonResizableAppLayerBecomesVisible() = testSpec.layerBecomesVisible(nonResizeableApp.defaultWindowName) + @Presubmit @Test fun resizableAppWindowBecomesInvisible() = testSpec.appWindowBecomesInVisible(splitScreenApp.defaultWindowName) + @Presubmit @Test fun nonResizableAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(nonResizeableApp.defaultWindowName) + @Presubmit @Test fun dockedStackDividerIsInvisibleAtEnd() = testSpec.dockedStackDividerIsInvisible() + @Presubmit @Test fun onlyNonResizableAppWindowIsVisibleAtEnd() { testSpec.assertWmEnd { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentSupportNonResizable.kt index 2f5e0bddd71f..af307580df3f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentSupportNonResizable.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromIntentSupportNonResizable.kt @@ -16,10 +16,9 @@ package com.android.wm.shell.flicker.legacysplitscreen -import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit import android.provider.Settings import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -45,7 +44,6 @@ import org.junit.runners.Parameterized * non-resizable in multi window, it should show the non-resizable app in split screen. * To run this test: `atest WMShellFlickerTests:LegacySplitScreenFromIntentSupportNonResizable` */ -@Postsubmit @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @@ -94,27 +92,21 @@ class LegacySplitScreenFromIntentSupportNonResizable( prevSupportNonResizableInMultiWindow) } - @FlakyTest(bugId = 178447631) - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - - @FlakyTest(bugId = 178447631) - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - + @Presubmit @Test fun nonResizableAppLayerBecomesVisible() = testSpec.layerBecomesVisible(nonResizeableApp.defaultWindowName) + @Presubmit @Test fun nonResizableAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(nonResizeableApp.defaultWindowName) + @Presubmit @Test fun dockedStackDividerIsVisibleAtEnd() = testSpec.dockedStackDividerIsVisible() + @Presubmit @Test fun bothAppsWindowsAreVisibleAtEnd() { testSpec.assertWmEnd { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentNotSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentNotSupportNonResizable.kt index a42774d93b5b..8c6275821b97 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentNotSupportNonResizable.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentNotSupportNonResizable.kt @@ -16,10 +16,9 @@ package com.android.wm.shell.flicker.legacysplitscreen -import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit import android.provider.Settings import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -48,7 +47,6 @@ import org.junit.runners.Parameterized * not support non-resizable in multi window, it should trigger exit split screen. * To run this test: `atest WMShellFlickerTests:LegacySplitScreenFromRecentNotSupportNonResizable` */ -@Postsubmit @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @@ -97,35 +95,31 @@ class LegacySplitScreenFromRecentNotSupportNonResizable( prevSupportNonResizableInMultiWindow) } - @FlakyTest(bugId = 178447631) - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - - @FlakyTest(bugId = 178447631) - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - + @Presubmit @Test fun resizableAppLayerBecomesInvisible() = testSpec.layerBecomesInvisible(splitScreenApp.defaultWindowName) + @Presubmit @Test fun nonResizableAppLayerBecomesVisible() = testSpec.layerBecomesVisible(nonResizeableApp.defaultWindowName) + @Presubmit @Test fun resizableAppWindowBecomesInvisible() = testSpec.appWindowBecomesInVisible(splitScreenApp.defaultWindowName) + @Presubmit @Test fun nonResizableAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(nonResizeableApp.defaultWindowName) + @Presubmit @Test fun dockedStackDividerIsInvisibleAtEnd() = testSpec.dockedStackDividerIsInvisible() + @Presubmit @Test fun onlyNonResizableAppWindowIsVisibleAtEnd() { testSpec.assertWmEnd { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentSupportNonResizable.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentSupportNonResizable.kt index 14f6deef6ff4..5b48f8a1df1d 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentSupportNonResizable.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenFromRecentSupportNonResizable.kt @@ -16,10 +16,9 @@ package com.android.wm.shell.flicker.legacysplitscreen -import android.platform.test.annotations.Postsubmit +import android.platform.test.annotations.Presubmit import android.provider.Settings import android.view.Surface -import androidx.test.filters.FlakyTest import androidx.test.filters.RequiresDevice import com.android.server.wm.flicker.FlickerParametersRunnerFactory import com.android.server.wm.flicker.FlickerTestParameter @@ -46,7 +45,6 @@ import org.junit.runners.Parameterized * supports non-resizable in multi window, it should show the non-resizable app in split screen. * To run this test: `atest WMShellFlickerTests:LegacySplitScreenFromRecentSupportNonResizable` */ -@Postsubmit @RequiresDevice @RunWith(Parameterized::class) @Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class) @@ -95,27 +93,21 @@ class LegacySplitScreenFromRecentSupportNonResizable( prevSupportNonResizableInMultiWindow) } - @FlakyTest(bugId = 178447631) - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - - @FlakyTest(bugId = 178447631) - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - + @Presubmit @Test fun nonResizableAppLayerBecomesVisible() = testSpec.layerBecomesVisible(nonResizeableApp.defaultWindowName) + @Presubmit @Test fun nonResizableAppWindowBecomesVisible() = testSpec.appWindowBecomesVisible(nonResizeableApp.defaultWindowName) + @Presubmit @Test fun dockedStackDividerIsVisibleAtEnd() = testSpec.dockedStackDividerIsVisible() + @Presubmit @Test fun bothAppsWindowsAreVisibleAtEnd() { testSpec.assertWmEnd { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenRotateTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenRotateTransition.kt index 08d5db0f9124..1e89a25c06df 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenRotateTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenRotateTransition.kt @@ -17,13 +17,11 @@ package com.android.wm.shell.flicker.legacysplitscreen import android.view.Surface -import androidx.test.filters.FlakyTest import com.android.server.wm.flicker.FlickerTestParameter import com.android.server.wm.flicker.dsl.FlickerBuilder import com.android.server.wm.flicker.helpers.openQuickStepAndClearRecentAppsFromOverview import com.android.server.wm.flicker.helpers.setRotation import com.android.server.wm.flicker.helpers.wakeUpAndGoToHomeScreen -import org.junit.Test abstract class LegacySplitScreenRotateTransition( testSpec: FlickerTestParameter @@ -46,16 +44,4 @@ abstract class LegacySplitScreenRotateTransition( } } } - - @FlakyTest - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() { - super.visibleLayersShownMoreThanOneConsecutiveEntry() - } - - @FlakyTest - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() { - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncher.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncher.kt index 39f4ce298ff5..976668e60231 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncher.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenToLauncher.kt @@ -118,11 +118,6 @@ class LegacySplitScreenToLauncher( fun statusBarLayerRotatesScales() = testSpec.statusBarLayerRotatesScales(testSpec.config.endRotation) - @FlakyTest - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - @Presubmit @Test fun statusBarLayerIsAlwaysVisible() = testSpec.statusBarLayerIsAlwaysVisible() diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenTransition.kt index e13056c36684..8684ba52bd52 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenTransition.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/LegacySplitScreenTransition.kt @@ -18,9 +18,9 @@ package com.android.wm.shell.flicker.legacysplitscreen import android.app.Instrumentation import android.content.Context -import android.platform.test.annotations.Presubmit import android.support.test.launcherhelper.LauncherStrategyFactory import android.view.Surface +import androidx.test.filters.FlakyTest import androidx.test.platform.app.InstrumentationRegistry import com.android.server.wm.flicker.FlickerBuilderProvider import com.android.server.wm.flicker.FlickerTestParameter @@ -102,7 +102,7 @@ abstract class LegacySplitScreenTransition(protected val testSpec: FlickerTestPa } } - @Presubmit + @FlakyTest(bugId = 178447631) @Test open fun visibleWindowsShownMoreThanOneConsecutiveEntry() { testSpec.assertWm { @@ -110,7 +110,7 @@ abstract class LegacySplitScreenTransition(protected val testSpec: FlickerTestPa } } - @Presubmit + @FlakyTest(bugId = 178447631) @Test open fun visibleLayersShownMoreThanOneConsecutiveEntry() { testSpec.assertLayers { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreen.kt index 7cf30ec116eb..69520c291522 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/OpenAppToLegacySplitScreen.kt @@ -65,11 +65,6 @@ class OpenAppToLegacySplitScreen( WindowManagerStateHelper.SPLASH_SCREEN_NAME, WindowManagerStateHelper.SNAPSHOT_WINDOW_NAME) - @FlakyTest(bugId = 178447631) - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = - super.visibleWindowsShownMoreThanOneConsecutiveEntry() - @FlakyTest @Test fun appWindowBecomesVisible() = testSpec.appWindowBecomesVisible(splitScreenApp.getPackage()) @@ -90,11 +85,6 @@ class OpenAppToLegacySplitScreen( @Test fun layerBecomesVisible() = testSpec.layerBecomesVisible(splitScreenApp.getPackage()) - @FlakyTest(bugId = 178447631) - @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - @FlakyTest(bugId = 151179149) @Test fun focusChanges() = testSpec.focusChanges(splitScreenApp.`package`, diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt index 33ade38d0373..ecbb887e2f9b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/legacysplitscreen/ResizeLegacySplitScreen.kt @@ -104,13 +104,6 @@ class ResizeLegacySplitScreen( @Test fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible() - @Test - override fun visibleWindowsShownMoreThanOneConsecutiveEntry() { - testSpec.assertWm { - this.visibleWindowsShownMoreThanOneConsecutiveEntry() - } - } - @FlakyTest(bugId = 156223549) @Test fun topAppWindowIsAlwaysVisible() { @@ -145,10 +138,6 @@ class ResizeLegacySplitScreen( testSpec.statusBarLayerRotatesScales(testSpec.config.endRotation) @Test - override fun visibleLayersShownMoreThanOneConsecutiveEntry() = - super.visibleLayersShownMoreThanOneConsecutiveEntry() - - @Test fun topAppLayerIsAlwaysVisible() { testSpec.assertLayers { this.isVisible(sSimpleActivity) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt index 2609258e48e0..95672f439275 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt @@ -47,6 +47,12 @@ class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { } } + @FlakyTest + @Test + override fun noUncoveredRegions() { + super.noUncoveredRegions() + } + @Presubmit @Test fun pipAppWindowAlwaysVisible() { @@ -59,7 +65,7 @@ class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { @Test fun pipLayerBecomesVisible() { testSpec.assertLayers { - this.isVisible(pipApp.launcherName) + this.isVisible(pipApp.windowName) } } @@ -67,9 +73,11 @@ class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) { @Test fun pipWindowBecomesVisible() { testSpec.assertWm { - invoke("pipWindowIsNotVisible") { !it.wmState.hasPipWindow() } - .then() - .invoke("pipWindowIsVisible") { it.wmState.hasPipWindow() } + invoke("pipWindowIsNotVisible") { + verify("Has no pip window").that(it.wmState.hasPipWindow()).isTrue() + }.then().invoke("pipWindowIsVisible") { + verify("Has pip window").that(it.wmState.hasPipWindow()).isTrue() + } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt index 0d686f514116..fb7dac35a60a 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt @@ -71,7 +71,7 @@ class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) } } - @Presubmit + @FlakyTest(bugId = 185400889) @Test override fun noUncoveredRegions() = testSpec.noUncoveredRegions(testSpec.config.startRotation, testSpec.config.endRotation, allStates = false) @@ -88,7 +88,7 @@ class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) testSpec.statusBarLayerRotatesScales(testSpec.config.startRotation, testSpec.config.endRotation) - @Presubmit + @FlakyTest(bugId = 185400889) @Test fun appLayerRotates_StartingBounds() { testSpec.assertLayersStart { @@ -97,7 +97,7 @@ class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testSpec) } } - @Presubmit + @FlakyTest(bugId = 185400889) @Test fun appLayerRotates_EndingBounds() { testSpec.assertLayersEnd { diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java index b0de02922f74..2b5cd601b200 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/TestRunningTaskInfoBuilder.java @@ -69,6 +69,7 @@ public final class TestRunningTaskInfoBuilder { info.configuration.windowConfiguration.setActivityType(mActivityType); info.token = mToken; info.isResizeable = true; + info.supportsMultiWindow = true; return info; } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java index 9a80a5545984..2bb7204c7941 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java @@ -19,6 +19,8 @@ package com.android.wm.shell.bubbles; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static junit.framework.TestCase.assertEquals; + import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; @@ -799,6 +801,15 @@ public class BubbleDataTest extends ShellTestCase { assertExpandedChangedTo(false); } + @Test + public void test_addToOverflow_doesntAllowDupes() { + assertEquals(0, mBubbleData.getOverflowBubbles().size()); + mBubbleData.overflowBubble(Bubbles.DISMISS_AGED, mBubbleA1); + mBubbleData.overflowBubble(Bubbles.DISMISS_AGED, mBubbleA1); + mBubbleData.overflowBubble(Bubbles.DISMISS_AGED, mBubbleA1); + assertEquals(1, mBubbleData.getOverflowBubbles().size()); + } + private void verifyUpdateReceived() { verify(mListener).applyUpdate(mUpdateCaptor.capture()); reset(mListener); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt index 2f064ac95204..0972cf2c032f 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubblePersistentRepositoryTest.kt @@ -18,8 +18,10 @@ package com.android.wm.shell.bubbles.storage import android.app.ActivityTaskManager.INVALID_TASK_ID import android.testing.AndroidTestingRunner +import android.util.SparseArray import androidx.test.filters.SmallTest import com.android.wm.shell.ShellTestCase +import com.android.wm.shell.bubbles.storage.BubbleXmlHelperTest.Companion.sparseArraysEqual import junit.framework.Assert.assertEquals import junit.framework.Assert.assertNotNull import junit.framework.Assert.assertTrue @@ -31,19 +33,32 @@ import org.junit.runner.RunWith @RunWith(AndroidTestingRunner::class) class BubblePersistentRepositoryTest : ShellTestCase() { - private val bubbles = listOf( - // user, package, shortcut, notification key, height, res-height, title, taskId, locusId - BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1", 120, 0, null, 1, null), - BubbleEntity(10, "com.example.chat", "alice and bob", "key-2", 0, 16537428, "title", - 2, null), - BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3", 120, 0, null, - INVALID_TASK_ID, "key-3") + // user, package, shortcut, notification key, height, res-height, title, taskId, locusId + private val user0Bubbles = listOf( + BubbleEntity(0, "com.example.messenger", "shortcut-1", "0k1", 120, 0, null, 1, null), + BubbleEntity(10, "com.example.chat", "alice and bob", "0k2", 0, 16537428, "title", 2, + null), + BubbleEntity(0, "com.example.messenger", "shortcut-2", "0k3", 120, 0, null, + INVALID_TASK_ID, null) ) + + private val user1Bubbles = listOf( + BubbleEntity(1, "com.example.messenger", "shortcut-1", "1k1", 120, 0, null, 3, null), + BubbleEntity(12, "com.example.chat", "alice and bob", "1k2", 0, 16537428, "title", 4, + null), + BubbleEntity(1, "com.example.messenger", "shortcut-2", "1k3", 120, 0, null, + INVALID_TASK_ID, null) + ) + + private val bubbles = SparseArray<List<BubbleEntity>>() + private lateinit var repository: BubblePersistentRepository @Before fun setup() { repository = BubblePersistentRepository(mContext) + bubbles.put(0, user0Bubbles) + bubbles.put(1, user1Bubbles) } @Test @@ -51,9 +66,9 @@ class BubblePersistentRepositoryTest : ShellTestCase() { // Verify read before write doesn't cause FileNotFoundException val actual = repository.readFromDisk() assertNotNull(actual) - assertTrue(actual.isEmpty()) + assertEquals(actual.size(), 0) repository.persistsToDisk(bubbles) - assertEquals(bubbles, repository.readFromDisk()) + assertTrue(sparseArraysEqual(bubbles, repository.readFromDisk())) } }
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt index 03aa6c2eba12..bfdf5208bbf0 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleVolatileRepositoryTest.kt @@ -21,32 +21,40 @@ import android.content.pm.LauncherApps import android.os.UserHandle import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest +import org.junit.Test import com.android.wm.shell.ShellTestCase import junit.framework.Assert.assertEquals import org.junit.Before -import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentMatchers.eq +import org.mockito.Mockito import org.mockito.Mockito.mock import org.mockito.Mockito.verify -import org.mockito.Mockito.verifyNoMoreInteractions +import org.mockito.Mockito.reset @SmallTest @RunWith(AndroidTestingRunner::class) class BubbleVolatileRepositoryTest : ShellTestCase() { private val user0 = UserHandle.of(0) - private val user10 = UserHandle.of(10) + private val user10_managed = UserHandle.of(10) // In test, acts as workprofile of user0 + private val user11 = UserHandle.of(11) // user, package, shortcut, notification key, height, res-height, title, taskId, locusId - private val bubble1 = BubbleEntity(0, "com.example.messenger", "shortcut-1", "key-1", 120, 0, - null, 1, null) + private val bubble1 = BubbleEntity(0, "com.example.messenger", "shortcut-1", + "0key-1", 120, 0, null, 1, null) private val bubble2 = BubbleEntity(10, "com.example.chat", "alice and bob", - "key-2", 0, 16537428, "title", 2, null) - private val bubble3 = BubbleEntity(0, "com.example.messenger", "shortcut-2", "key-3", 120, 0, - null, INVALID_TASK_ID, "key-3") + "10key-2", 0, 16537428, "title", 2, null) + private val bubble3 = BubbleEntity(0, "com.example.messenger", "shortcut-2", + "0key-3", 120, 0, null, INVALID_TASK_ID, null) - private val bubbles = listOf(bubble1, bubble2, bubble3) + private val bubble11 = BubbleEntity(11, "com.example.messenger", + "shortcut-1", "01key-1", 120, 0, null, 3) + private val bubble12 = BubbleEntity(11, "com.example.chat", "alice and bob", + "11key-2", 0, 16537428, "title", INVALID_TASK_ID) + + private val user0bubbles = listOf(bubble1, bubble2, bubble3) + private val user11bubbles = listOf(bubble11, bubble12) private lateinit var repository: BubbleVolatileRepository private lateinit var launcherApps: LauncherApps @@ -59,51 +67,74 @@ class BubbleVolatileRepositoryTest : ShellTestCase() { @Test fun testAddBubbles() { - repository.addBubbles(bubbles) - assertEquals(bubbles, repository.bubbles) + repository.addBubbles(user0.identifier, user0bubbles) + repository.addBubbles(user11.identifier, user11bubbles) + + assertEquals(user0bubbles, repository.getEntities(user0.identifier).toList()) + assertEquals(user11bubbles, repository.getEntities(user11.identifier).toList()) + verify(launcherApps).cacheShortcuts(eq(PKG_MESSENGER), eq(listOf("shortcut-1", "shortcut-2")), eq(user0), eq(LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS)) verify(launcherApps).cacheShortcuts(eq(PKG_CHAT), - eq(listOf("alice and bob")), eq(user10), + eq(listOf("alice and bob")), eq(user10_managed), + eq(LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS)) + + verify(launcherApps).cacheShortcuts(eq(PKG_MESSENGER), + eq(listOf("shortcut-1")), eq(user11), + eq(LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS)) + verify(launcherApps).cacheShortcuts(eq(PKG_CHAT), + eq(listOf("alice and bob")), eq(user11), eq(LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS)) - repository.addBubbles(listOf(bubble1)) - assertEquals(listOf(bubble2, bubble3, bubble1), repository.bubbles) - verifyNoMoreInteractions(launcherApps) + repository.addBubbles(user0.identifier, listOf(bubble1)) + assertEquals(listOf(bubble2, bubble3, bubble1), repository.getEntities(user0.identifier)) + + repository.addBubbles(user11.identifier, listOf(bubble12)) + assertEquals(listOf(bubble11, bubble12), repository.getEntities(user11.identifier)) + + Mockito.verifyNoMoreInteractions(launcherApps) } @Test fun testRemoveBubbles() { - repository.addBubbles(bubbles) - assertEquals(bubbles, repository.bubbles) + repository.addBubbles(user0.identifier, user0bubbles) + repository.addBubbles(user11.identifier, user11bubbles) - repository.removeBubbles(listOf(bubble3)) - assertEquals(listOf(bubble1, bubble2), repository.bubbles) + repository.removeBubbles(user0.identifier, listOf(bubble3)) + assertEquals(listOf(bubble1, bubble2), repository.getEntities(user0.identifier).toList()) verify(launcherApps).uncacheShortcuts(eq(PKG_MESSENGER), eq(listOf("shortcut-2")), eq(user0), eq(LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS)) + + reset(launcherApps) + + repository.removeBubbles(user11.identifier, listOf(bubble12)) + assertEquals(listOf(bubble11), repository.getEntities(user11.identifier).toList()) + verify(launcherApps).uncacheShortcuts(eq(PKG_CHAT), + eq(listOf("alice and bob")), eq(user11), + eq(LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS)) } @Test fun testAddAndRemoveBubblesWhenExceedingCapacity() { repository.capacity = 2 // push bubbles beyond capacity - repository.addBubbles(bubbles) + repository.addBubbles(user0.identifier, user0bubbles) // verify it is trim down to capacity - assertEquals(listOf(bubble2, bubble3), repository.bubbles) + assertEquals(listOf(bubble2, bubble3), repository.getEntities(user0.identifier).toList()) verify(launcherApps).cacheShortcuts(eq(PKG_MESSENGER), eq(listOf("shortcut-2")), eq(user0), eq(LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS)) verify(launcherApps).cacheShortcuts(eq(PKG_CHAT), - eq(listOf("alice and bob")), eq(user10), + eq(listOf("alice and bob")), eq(user10_managed), eq(LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS)) - repository.addBubbles(listOf(bubble1)) - // verify the oldest bubble is popped - assertEquals(listOf(bubble3, bubble1), repository.bubbles) + repository.addBubbles(user0.identifier, listOf(bubble1)) + // verify the oldest bubble is popped 2, 3 + assertEquals(listOf(bubble3, bubble1), repository.getEntities(user0.identifier).toList()) verify(launcherApps).uncacheShortcuts(eq(PKG_CHAT), - eq(listOf("alice and bob")), eq(user10), + eq(listOf("alice and bob")), eq(user10_managed), eq(LauncherApps.FLAG_CACHE_BUBBLE_SHORTCUTS)) } @@ -111,14 +142,14 @@ class BubbleVolatileRepositoryTest : ShellTestCase() { fun testAddBubbleMatchesByKey() { val bubble = BubbleEntity(0, "com.example.pkg", "shortcut-id", "key", 120, 0, "title", 1, null) - repository.addBubbles(listOf(bubble)) - assertEquals(bubble, repository.bubbles.get(0)) + repository.addBubbles(user0.identifier, listOf(bubble)) + assertEquals(bubble, repository.getEntities(user0.identifier).get(0)) // Same key as first bubble but different entry val bubbleModified = BubbleEntity(0, "com.example.pkg", "shortcut-id", "key", 120, 0, - "different title", 2, null) - repository.addBubbles(listOf(bubbleModified)) - assertEquals(bubbleModified, repository.bubbles.get(0)) + "different title", 2) + repository.addBubbles(user0.identifier, listOf(bubbleModified)) + assertEquals(bubbleModified, repository.getEntities(user0.identifier).get(0)) } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelperTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelperTest.kt index 8d719e7a7378..4ab9f87dbbf6 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelperTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/storage/BubbleXmlHelperTest.kt @@ -18,10 +18,12 @@ package com.android.wm.shell.bubbles.storage import android.app.ActivityTaskManager.INVALID_TASK_ID import android.testing.AndroidTestingRunner +import android.util.SparseArray import androidx.test.filters.SmallTest import com.android.wm.shell.ShellTestCase import junit.framework.Assert.assertEquals import junit.framework.Assert.assertTrue +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import java.io.ByteArrayInputStream @@ -31,21 +33,65 @@ import java.io.ByteArrayOutputStream @RunWith(AndroidTestingRunner::class) class BubbleXmlHelperTest : ShellTestCase() { - private val bubbles = listOf( - // user, package, shortcut, notification key, height, res-height, title, taskId, locusId - BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0, null, 1), - BubbleEntity(10, "com.example.chat", "alice and bob", "k2", 0, 16537428, "title", - 2, null), - BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3", 120, 0, null, + private val user0Bubbles = listOf( + BubbleEntity(0, "com.example.messenger", "shortcut-1", "0k1", 120, 0, null, 1), + BubbleEntity(10, "com.example.chat", "alice and bob", "0k2", 0, 16537428, "title", 2, + null), + BubbleEntity(0, "com.example.messenger", "shortcut-2", "0k3", 120, 0, null, INVALID_TASK_ID, "l3") ) + private val user1Bubbles = listOf( + BubbleEntity(1, "com.example.messenger", "shortcut-1", "1k1", 120, 0, null, 3), + BubbleEntity(12, "com.example.chat", "alice and bob", "1k2", 0, 16537428, "title", 4, + null), + BubbleEntity(1, "com.example.messenger", "shortcut-2", "1k3", 120, 0, null, + INVALID_TASK_ID, "l4") + ) + + private val bubbles = SparseArray<List<BubbleEntity>>() + + // Checks that the contents of the two sparse arrays are the same. + companion object { + fun sparseArraysEqual( + one: SparseArray<List<BubbleEntity>>?, + two: SparseArray<List<BubbleEntity>>? + ): Boolean { + if (one == null && two == null) return true + if ((one == null) != (two == null)) return false + if (one!!.size() != two!!.size()) return false + for (i in 0 until one.size()) { + val k1 = one.keyAt(i) + val v1 = one.valueAt(i) + val k2 = two.keyAt(i) + val v2 = two.valueAt(i) + if (k1 != k2 && v1 != v2) { + return false + } + } + return true + } + } + + @Before + fun setup() { + bubbles.put(0, user0Bubbles) + bubbles.put(1, user1Bubbles) + } + @Test fun testWriteXml() { val expectedEntries = """ -<bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" h="120" hid="0" tid="1" /> -<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" h="0" hid="16537428" t="title" tid="2" /> -<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" h="120" hid="0" tid="-1" l="l3" /> +<bs uid="0"> +<bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="0k1" h="120" hid="0" tid="1" /> +<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="0k2" h="0" hid="16537428" t="title" tid="2" /> +<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="0k3" h="120" hid="0" tid="-1" l="l3" /> +</bs> +<bs uid="1"> +<bb uid="1" pkg="com.example.messenger" sid="shortcut-1" key="1k1" h="120" hid="0" tid="3" /> +<bb uid="12" pkg="com.example.chat" sid="alice and bob" key="1k2" h="0" hid="16537428" t="title" tid="4" /> +<bb uid="1" pkg="com.example.messenger" sid="shortcut-2" key="1k3" h="120" hid="0" tid="-1" l="l4" /> +</bs> """.trimIndent() ByteArrayOutputStream().use { writeXml(it, bubbles) @@ -59,19 +105,26 @@ class BubbleXmlHelperTest : ShellTestCase() { fun testReadXml() { val src = """ <?xml version='1.0' encoding='utf-8' standalone='yes' ?> -<bs v="1"> -<bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" h="120" hid="0" tid="1" /> -<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" h="0" hid="16537428" t="title" tid="2" /> -<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" h="120" hid="0" tid="-1" l="l3" /> +<bs v="2"> +<bs uid="0"> +<bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="0k1" h="120" hid="0" tid="1" /> +<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="0k2" h="0" hid="16537428" t="title" tid="2" /> +<bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="0k3" h="120" hid="0" tid="-1" l="l3" /> +</bs> +<bs uid="1"> +<bb uid="1" pkg="com.example.messenger" sid="shortcut-1" key="1k1" h="120" hid="0" tid="3" /> +<bb uid="12" pkg="com.example.chat" sid="alice and bob" key="1k2" h="0" hid="16537428" t="title" tid="4" /> +<bb uid="1" pkg="com.example.messenger" sid="shortcut-2" key="1k3" h="120" hid="0" tid="-1" l="l4" /> +</bs> </bs> """.trimIndent() val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8))) - assertEquals("failed parsing bubbles from xml\n$src", bubbles, actual) + assertTrue("failed parsing bubbles from xml\n$src", sparseArraysEqual(bubbles, actual)) } - // TODO: We should handle upgrades gracefully but this is v1 + // V0 -> V1 happened prior to release / during dogfood so nothing is saved @Test - fun testUpgradeDropsPreviousData() { + fun testUpgradeFromV0DropsPreviousData() { val src = """ <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <bs> @@ -81,7 +134,7 @@ class BubbleXmlHelperTest : ShellTestCase() { </bs> """.trimIndent() val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8))) - assertEquals("failed parsing bubbles from xml\n$src", emptyList<BubbleEntity>(), actual) + assertEquals("failed parsing bubbles from xml\n$src", 0, actual.size()) } /** @@ -91,24 +144,25 @@ class BubbleXmlHelperTest : ShellTestCase() { */ @Test fun testReadXMLWithoutTaskId() { - val expectedBubbles = listOf( - BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0, null, - INVALID_TASK_ID), - BubbleEntity(10, "com.example.chat", "alice and bob", "k2", 0, 16537428, "title", - INVALID_TASK_ID), - BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3", 120, 0, null, - INVALID_TASK_ID) - ) + val expectedBubbles = SparseArray<List<BubbleEntity>>() + expectedBubbles.put(0, listOf( + BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0, + null, INVALID_TASK_ID), + BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3", 120, 0, + null, INVALID_TASK_ID)) + ) val src = """ <?xml version='1.0' encoding='utf-8' standalone='yes' ?> -<bs v="1"> +<bs v="2"> +<bs uid="0"> <bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" h="120" hid="0" /> -<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" h="0" hid="16537428" t="title" /> <bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" h="120" hid="0" /> </bs> +</bs> """.trimIndent() val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8))) - assertEquals("failed parsing bubbles from xml\n$src", expectedBubbles, actual) + assertTrue("failed parsing bubbles from xml\n$src", + sparseArraysEqual(expectedBubbles, actual)) } /** @@ -117,23 +171,45 @@ class BubbleXmlHelperTest : ShellTestCase() { */ @Test fun testXMLWithoutLocusToLocus() { - val expectedBubbles = listOf( - BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0, null, - INVALID_TASK_ID, null), - BubbleEntity(10, "com.example.chat", "alice and bob", "k2", 0, 16537428, "title", - INVALID_TASK_ID, null), - BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3", 120, 0, null, - INVALID_TASK_ID, null) + val expectedBubbles = SparseArray<List<BubbleEntity>>() + expectedBubbles.put(0, listOf( + BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0, + null, INVALID_TASK_ID), + BubbleEntity(0, "com.example.messenger", "shortcut-2", "k3", 120, 0, + null, INVALID_TASK_ID)) ) val src = """ <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <bs v="1"> <bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" h="120" hid="0" /> -<bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" h="0" hid="16537428" t="title" /> <bb uid="0" pkg="com.example.messenger" sid="shortcut-2" key="k3" h="120" hid="0" /> </bs> """.trimIndent() val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8))) - assertEquals("failed parsing bubbles from xml\n$src", expectedBubbles, actual) + assertTrue("failed parsing bubbles from xml\n$src", + sparseArraysEqual(expectedBubbles, actual)) + } + + @Test + fun testUpgradeToV2SavesPreviousData() { + val src = """ + <?xml version='1.0' encoding='utf-8' standalone='yes' ?> + <bs v="1"> + <bb uid="0" pkg="com.example.messenger" sid="shortcut-1" key="k1" h="120" hid="0" /> + <bb uid="10" pkg="com.example.chat" sid="alice and bob" key="k2" h="0" hid="16537428" t="title" /> + <bb uid="2" pkg="com.example.messenger" sid="shortcut-2" key="k3" h="120" hid="0" /> + <bb uid="0" pkg="com.example.messenger" sid="shortcut-4" key="k4" h="0" hid="16537428" /> + </bs> + """.trimIndent() + val expectedBubbles = SparseArray<List<BubbleEntity>>() + expectedBubbles.put(0, listOf( + BubbleEntity(0, "com.example.messenger", "shortcut-1", "k1", 120, 0, + null, INVALID_TASK_ID, null), + BubbleEntity(0, "com.example.messenger", "shortcut-4", "k4", 0, 16537428, + null, INVALID_TASK_ID, null)) + ) + val actual = readXml(ByteArrayInputStream(src.toByteArray(Charsets.UTF_8))) + assertTrue("failed parsing bubbles from xml\n$src", + sparseArraysEqual(expectedBubbles, actual)) } }
\ No newline at end of file diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java index 105bd828aa9e..c1282c9d7b12 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java @@ -16,6 +16,9 @@ package com.android.wm.shell.onehanded; +import static com.android.wm.shell.onehanded.OneHandedState.STATE_ENTERING; +import static com.android.wm.shell.onehanded.OneHandedState.STATE_NONE; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; @@ -61,6 +64,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { OneHandedAccessibilityUtil mOneHandedAccessibilityUtil; OneHandedController mSpiedOneHandedController; OneHandedTimeoutHandler mSpiedTimeoutHandler; + OneHandedState mSpiedTransitionState; @Mock DisplayController mMockDisplayController; @@ -99,9 +103,9 @@ public class OneHandedControllerTest extends OneHandedTestCase { mDisplay = mContext.getDisplay(); mDisplayLayout = new DisplayLayout(mContext, mDisplay); mSpiedTimeoutHandler = spy(new OneHandedTimeoutHandler(mMockShellMainExecutor)); + mSpiedTransitionState = spy(new OneHandedState()); when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay); - when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>()); when(mMockBackgroundOrganizer.getBackgroundSurface()).thenReturn(mMockLeash); when(mMockSettingsUitl.getSettingsOneHandedModeEnabled(any(), anyInt())).thenReturn( @@ -129,6 +133,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { mMockSettingsUitl, mOneHandedAccessibilityUtil, mSpiedTimeoutHandler, + mSpiedTransitionState, mMockUiEventLogger, mMockOverlayManager, mMockTaskStackListener, @@ -139,18 +144,13 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Test public void testDefaultShouldNotInOneHanded() { - final OneHandedAnimationController animationController = new OneHandedAnimationController( - mContext); - OneHandedDisplayAreaOrganizer displayAreaOrganizer = new OneHandedDisplayAreaOrganizer( - mContext, mDisplayLayout, mMockSettingsUitl, animationController, - mMockTutorialHandler, mMockBackgroundOrganizer, mMockShellMainExecutor); - - assertThat(displayAreaOrganizer.isInOneHanded()).isFalse(); + // Assert default transition state is STATE_NONE + assertThat(mSpiedTransitionState.getState()).isEqualTo(STATE_NONE); } @Test public void testStartOneHandedShouldTriggerScheduleOffset() { - when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); + mSpiedTransitionState.setState(STATE_NONE); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.startOneHanded(); @@ -160,7 +160,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Test public void testStartOneHandedShouldNotTriggerScheduleOffset() { mSpiedOneHandedController.setOneHandedEnabled(true); - when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(true); + mSpiedTransitionState.setState(STATE_ENTERING); mSpiedOneHandedController.startOneHanded(); verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt()); @@ -168,7 +168,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Test public void testStopOneHanded() { - when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); + mSpiedTransitionState.setState(STATE_NONE); mSpiedOneHandedController.stopOneHanded(); verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt()); @@ -192,7 +192,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Test public void testStopOneHandedShouldRemoveTimer() { - when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(true); + mSpiedTransitionState.setState(STATE_ENTERING); mSpiedOneHandedController.stopOneHanded(); verify(mSpiedTimeoutHandler, atLeastOnce()).removeTimer(); @@ -280,7 +280,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Test public void testKeyguardShowingLockOneHandedDisabled() { - when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); + mSpiedTransitionState.setState(STATE_NONE); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(true /* locked */, false /* enabled */); mSpiedOneHandedController.startOneHanded(); @@ -290,7 +290,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { @Test public void testResetKeyguardShowingLockOneHandedDisabled() { - when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); + mSpiedTransitionState.setState(STATE_NONE); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */); mSpiedOneHandedController.startOneHanded(); @@ -302,7 +302,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { public void testRotation90CanNotStartOneHanded() { final DisplayLayout landscapeDisplayLayout = new DisplayLayout(mDisplayLayout); landscapeDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_90); - when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); + mSpiedTransitionState.setState(STATE_NONE); when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(landscapeDisplayLayout); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */); @@ -315,7 +315,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { public void testRotation180CanStartOneHanded() { final DisplayLayout testDisplayLayout = new DisplayLayout(mDisplayLayout); testDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_180); - when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); + mSpiedTransitionState.setState(STATE_NONE); when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(testDisplayLayout); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */); @@ -328,7 +328,7 @@ public class OneHandedControllerTest extends OneHandedTestCase { public void testRotation270CanNotStartOneHanded() { final DisplayLayout testDisplayLayout = new DisplayLayout(mDisplayLayout); testDisplayLayout.rotateTo(mContext.getResources(), Surface.ROTATION_270); - when(mMockDisplayAreaOrganizer.isInOneHanded()).thenReturn(false); + mSpiedTransitionState.setState(STATE_NONE); when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(testDisplayLayout); mSpiedOneHandedController.setOneHandedEnabled(true); mSpiedOneHandedController.setLockedDisabled(false /* locked */, false /* enabled */); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java new file mode 100644 index 000000000000..89aae652444f --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedStateTest.java @@ -0,0 +1,221 @@ +/* + * 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.wm.shell.onehanded; + +import static com.android.wm.shell.onehanded.OneHandedState.STATE_ACTIVE; +import static com.android.wm.shell.onehanded.OneHandedState.STATE_ENTERING; +import static com.android.wm.shell.onehanded.OneHandedState.STATE_EXITING; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.om.IOverlayManager; +import android.graphics.Rect; +import android.os.Handler; +import android.os.UserHandle; +import android.testing.AndroidTestingRunner; +import android.util.ArrayMap; +import android.view.Display; +import android.view.SurfaceControl; + +import androidx.test.filters.SmallTest; + +import com.android.wm.shell.common.DisplayController; +import com.android.wm.shell.common.DisplayLayout; +import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.common.TaskStackListenerImpl; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class OneHandedStateTest extends OneHandedTestCase { + private int mCurrentUser = UserHandle.myUserId(); + + Display mDisplay; + DisplayLayout mDisplayLayout; + OneHandedAccessibilityUtil mOneHandedAccessibilityUtil; + OneHandedController mSpiedOneHandedController; + OneHandedTimeoutHandler mSpiedTimeoutHandler; + OneHandedState mSpiedState; + + @Mock + DisplayController mMockDisplayController; + @Mock + OneHandedBackgroundPanelOrganizer mMockBackgroundOrganizer; + @Mock + OneHandedDisplayAreaOrganizer mMockDisplayAreaOrganizer; + @Mock + OneHandedTouchHandler mMockTouchHandler; + @Mock + OneHandedTutorialHandler mMockTutorialHandler; + @Mock + OneHandedGestureHandler mMockGestureHandler; + @Mock + OneHandedSettingsUtil mMockSettingsUitl; + @Mock + OneHandedUiEventLogger mMockUiEventLogger; + @Mock + IOverlayManager mMockOverlayManager; + @Mock + TaskStackListenerImpl mMockTaskStackListener; + @Mock + ShellExecutor mMockShellMainExecutor; + @Mock + SurfaceControl mMockLeash; + @Mock + Handler mMockShellMainHandler; + + final boolean mDefaultEnabled = true; + final boolean mDefaultSwipeToNotificationEnabled = false; + final boolean mDefaultTapAppToExitEnabled = true; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mDisplay = mContext.getDisplay(); + mDisplayLayout = new DisplayLayout(mContext, mDisplay); + mSpiedTimeoutHandler = spy(new OneHandedTimeoutHandler(mMockShellMainExecutor)); + mSpiedState = spy(new OneHandedState()); + + when(mMockDisplayController.getDisplay(anyInt())).thenReturn(mDisplay); + when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>()); + when(mMockBackgroundOrganizer.getBackgroundSurface()).thenReturn(mMockLeash); + when(mMockSettingsUitl.getSettingsOneHandedModeEnabled(any(), anyInt())).thenReturn( + mDefaultEnabled); + when(mMockSettingsUitl.getSettingsOneHandedModeTimeout(any(), anyInt())).thenReturn( + OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS); + when(mMockSettingsUitl.getSettingsTapsAppToExit(any(), anyInt())).thenReturn( + mDefaultTapAppToExitEnabled); + when(mMockSettingsUitl.getSettingsSwipeToNotificationEnabled(any(), anyInt())).thenReturn( + mDefaultSwipeToNotificationEnabled); + + when(mMockDisplayAreaOrganizer.getLastDisplayBounds()).thenReturn( + new Rect(0, 0, mDisplayLayout.width(), mDisplayLayout.height())); + when(mMockDisplayAreaOrganizer.getDisplayLayout()).thenReturn(mDisplayLayout); + + mOneHandedAccessibilityUtil = new OneHandedAccessibilityUtil(mContext); + mSpiedOneHandedController = spy(new OneHandedController( + mContext, + mMockDisplayController, + mMockBackgroundOrganizer, + mMockDisplayAreaOrganizer, + mMockTouchHandler, + mMockTutorialHandler, + mMockGestureHandler, + mMockSettingsUitl, + mOneHandedAccessibilityUtil, + mSpiedTimeoutHandler, + mSpiedState, + mMockUiEventLogger, + mMockOverlayManager, + mMockTaskStackListener, + mMockShellMainExecutor, + mMockShellMainHandler) + ); + } + + @Test + public void testState_stateEntering_isTransitioning() { + mSpiedState.setState(STATE_ENTERING); + + assertThat(mSpiedState.isTransitioning()).isTrue(); + } + + @Test + public void testState_stateExiting_isTransitioning() { + mSpiedState.setState(STATE_EXITING); + + assertThat(mSpiedState.isTransitioning()).isTrue(); + } + + @Test + public void testInEnteringState_shouldSkipDupTrigger() { + when(mSpiedState.getState()).thenReturn(STATE_ENTERING); + when(mSpiedState.isTransitioning()).thenReturn(true); + when(mSpiedState.isInOneHanded()).thenReturn(false); + mSpiedOneHandedController.startOneHanded(); + + verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt()); + } + + @Test + public void testInActiveState_shouldSkipDupTrigger() { + when(mSpiedState.getState()).thenReturn(STATE_ACTIVE); + when(mSpiedState.isTransitioning()).thenReturn(false); + when(mSpiedState.isInOneHanded()).thenReturn(true); + mSpiedOneHandedController.startOneHanded(); + + verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt()); + } + + @Test + public void testInActiveState_canExit() { + when(mSpiedState.getState()).thenReturn(STATE_ACTIVE); + when(mSpiedState.isTransitioning()).thenReturn(false); + mSpiedOneHandedController.stopOneHanded(); + + verify(mSpiedState).setState(STATE_EXITING); + } + + @Test + public void testInEnteringState_shouldSkipExitAction() { + when(mSpiedState.getState()).thenReturn(STATE_ENTERING); + when(mSpiedState.isTransitioning()).thenReturn(true); + mSpiedOneHandedController.stopOneHanded(); + + verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt()); + } + + @Test + public void testInExitingState_shouldSkipStartAction() { + when(mSpiedState.getState()).thenReturn(STATE_EXITING); + when(mSpiedState.isTransitioning()).thenReturn(true); + mSpiedOneHandedController.startOneHanded(); + + verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt()); + } + + @Test + public void testInExitingState_shouldSkipStopAction() { + when(mSpiedState.getState()).thenReturn(STATE_EXITING); + when(mSpiedState.isTransitioning()).thenReturn(true); + mSpiedOneHandedController.stopOneHanded(); + + verify(mMockDisplayAreaOrganizer, never()).scheduleOffset(anyInt(), anyInt()); + } + + @Test + public void testInActiveState_disableOHM_shouldStopOHM() { + when(mSpiedState.getState()).thenReturn(STATE_ACTIVE); + when(mSpiedState.isTransitioning()).thenReturn(false); + when(mSpiedState.isInOneHanded()).thenReturn(true); + mSpiedOneHandedController.setOneHandedEnabled(false); + + verify(mMockShellMainExecutor).execute(any()); + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java index 06a66717ed31..b82a8ca4ffa0 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedTutorialHandlerTest.java @@ -41,6 +41,7 @@ import org.mockito.MockitoAnnotations; public class OneHandedTutorialHandlerTest extends OneHandedTestCase { OneHandedTimeoutHandler mTimeoutHandler; OneHandedController mOneHandedController; + OneHandedState mSpiedTransitionState; @Mock OneHandedGestureHandler mMockGestureHandler; @@ -73,6 +74,7 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { public void setUp() { MockitoAnnotations.initMocks(this); mTimeoutHandler = new OneHandedTimeoutHandler(mMockShellMainExecutor); + mSpiedTransitionState = new OneHandedState(); when(mMockDisplayAreaOrganizer.getDisplayAreaTokenMap()).thenReturn(new ArrayMap<>()); mOneHandedController = new OneHandedController( @@ -86,6 +88,7 @@ public class OneHandedTutorialHandlerTest extends OneHandedTestCase { mMockSettingsUtil, mMockAccessibilityUtil, mTimeoutHandler, + mSpiedTransitionState, mMockUiEventLogger, mMockOverlayManager, mMockTaskStackListener, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java index 63b94139dd9c..882d38286130 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java @@ -18,6 +18,7 @@ package com.android.wm.shell.pip; import static android.util.RotationUtils.rotateBounds; import static android.view.Surface.ROTATION_0; +import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_LEAVE_PIP; @@ -133,17 +134,30 @@ public class PipAnimationControllerTest extends ShellTestCase { @Test public void pipTransitionAnimator_rotatedEndValue() { + final DummySurfaceControlTx tx = new DummySurfaceControlTx(); final Rect startBounds = new Rect(200, 700, 400, 800); final Rect endBounds = new Rect(0, 0, 500, 1000); - final PipAnimationController.PipTransitionAnimator<?> animator = mPipAnimationController + // Fullscreen to PiP. + PipAnimationController.PipTransitionAnimator<?> animator = mPipAnimationController .getAnimator(mTaskInfo, mLeash, null, startBounds, endBounds, null, - TRANSITION_DIRECTION_TO_PIP, 0, ROTATION_90); + TRANSITION_DIRECTION_LEAVE_PIP, 0, ROTATION_90); // Apply fraction 1 to compute the end value. - animator.applySurfaceControlTransaction(mLeash, new DummySurfaceControlTx(), 1); + animator.applySurfaceControlTransaction(mLeash, tx, 1); final Rect rotatedEndBounds = new Rect(endBounds); rotateBounds(rotatedEndBounds, endBounds, ROTATION_90); assertEquals("Expect 90 degree rotated bounds", rotatedEndBounds, animator.mCurrentValue); + + // PiP to fullscreen. + startBounds.set(0, 0, 1000, 500); + endBounds.set(200, 100, 400, 500); + animator = mPipAnimationController.getAnimator(mTaskInfo, mLeash, startBounds, startBounds, + endBounds, null, TRANSITION_DIRECTION_TO_PIP, 0, ROTATION_270); + animator.applySurfaceControlTransaction(mLeash, tx, 1); + rotatedEndBounds.set(endBounds); + rotateBounds(rotatedEndBounds, startBounds, ROTATION_270); + + assertEquals("Expect 270 degree rotated bounds", rotatedEndBounds, animator.mCurrentValue); } @Test diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java index dea24d3c2ec0..a6215d3347a8 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsStateTest.java @@ -38,6 +38,8 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.function.Consumer; + /** * Tests for {@link PipBoundsState}. */ @@ -178,4 +180,20 @@ public class PipBoundsStateTest extends ShellTestCase { mPipBoundsState.setOverrideMinSize(new Size(15, 10)); assertEquals(10, mPipBoundsState.getOverrideMinEdgeSize()); } + + @Test + public void testSetBounds_updatesPipExclusionBounds() { + final Consumer<Rect> callback = mock(Consumer.class); + final Rect currentBounds = new Rect(10, 10, 20, 15); + final Rect newBounds = new Rect(50, 50, 100, 75); + mPipBoundsState.setBounds(currentBounds); + + mPipBoundsState.setPipExclusionBoundsChangeCallback(callback); + // Setting the listener immediately calls back with the current bounds. + verify(callback).accept(currentBounds); + + mPipBoundsState.setBounds(newBounds); + // Updating the bounds makes the listener call back back with the new rect. + verify(callback).accept(newBounds); + } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipSnapAlgorithmTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipSnapAlgorithmTest.java index dcee2e1847b2..b9226d2b9b91 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipSnapAlgorithmTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipSnapAlgorithmTest.java @@ -38,6 +38,8 @@ public class PipSnapAlgorithmTest extends ShellTestCase { private static final int DEFAULT_STASH_OFFSET = 32; private static final Rect DISPLAY_BOUNDS = new Rect(0, 0, 2000, 2000); private static final Rect STACK_BOUNDS_CENTERED = new Rect(900, 900, 1100, 1100); + private static final Rect INSET_BOUNDS_EMPTY = new Rect(0, 0, 0, 0); + private static final Rect INSET_BOUNDS_RIGHT = new Rect(0, 0, 200, 0); private static final Rect MOVEMENT_BOUNDS = new Rect(0, 0, DISPLAY_BOUNDS.width() - STACK_BOUNDS_CENTERED.width(), DISPLAY_BOUNDS.width() - STACK_BOUNDS_CENTERED.width()); @@ -99,7 +101,8 @@ public class PipSnapAlgorithmTest extends ShellTestCase { final Rect bounds = new Rect(STACK_BOUNDS_CENTERED); mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, snapFraction, - PipBoundsState.STASH_TYPE_NONE, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS); + PipBoundsState.STASH_TYPE_NONE, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS, + INSET_BOUNDS_EMPTY); assertEquals(MOVEMENT_BOUNDS.right, bounds.left); assertEquals(MOVEMENT_BOUNDS.bottom, bounds.top); @@ -111,7 +114,8 @@ public class PipSnapAlgorithmTest extends ShellTestCase { final Rect bounds = new Rect(STACK_BOUNDS_CENTERED); mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, snapFraction, - PipBoundsState.STASH_TYPE_LEFT, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS); + PipBoundsState.STASH_TYPE_LEFT, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS, + INSET_BOUNDS_EMPTY); final int offBoundsWidth = bounds.width() - DEFAULT_STASH_OFFSET; assertEquals(MOVEMENT_BOUNDS.left - offBoundsWidth, bounds.left); @@ -124,13 +128,28 @@ public class PipSnapAlgorithmTest extends ShellTestCase { final Rect bounds = new Rect(STACK_BOUNDS_CENTERED); mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, snapFraction, - PipBoundsState.STASH_TYPE_RIGHT, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS); + PipBoundsState.STASH_TYPE_RIGHT, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS, + INSET_BOUNDS_EMPTY); assertEquals(DISPLAY_BOUNDS.right - DEFAULT_STASH_OFFSET, bounds.left); assertEquals(MOVEMENT_BOUNDS.bottom, bounds.top); } @Test + public void testApplySnapFraction_stashedRight_withInset() { + final float snapFraction = 2f; + final Rect bounds = new Rect(STACK_BOUNDS_CENTERED); + + mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, snapFraction, + PipBoundsState.STASH_TYPE_RIGHT, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS, + INSET_BOUNDS_RIGHT); + + assertEquals(DISPLAY_BOUNDS.right - DEFAULT_STASH_OFFSET - INSET_BOUNDS_RIGHT.right, + bounds.left); + assertEquals(MOVEMENT_BOUNDS.bottom, bounds.top); + } + + @Test public void testSnapRectToClosestEdge_rightEdge() { final Rect bounds = new Rect(STACK_BOUNDS_CENTERED); // Move the centered rect slightly to the right side. @@ -183,7 +202,8 @@ public class PipSnapAlgorithmTest extends ShellTestCase { final Rect bounds = new Rect(STACK_BOUNDS_CENTERED); // Stash it on the left side. mPipSnapAlgorithm.applySnapFraction(bounds, MOVEMENT_BOUNDS, 3.5f, - PipBoundsState.STASH_TYPE_LEFT, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS); + PipBoundsState.STASH_TYPE_LEFT, DEFAULT_STASH_OFFSET, DISPLAY_BOUNDS, + INSET_BOUNDS_EMPTY); mPipSnapAlgorithm.snapRectToClosestEdge(bounds, MOVEMENT_BOUNDS, bounds, PipBoundsState.STASH_TYPE_LEFT); diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java index 5df391f919a7..9d7c82bb8550 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTaskOrganizerTest.java @@ -19,6 +19,7 @@ package com.android.wm.shell.pip; import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; @@ -31,6 +32,7 @@ import android.app.ActivityManager; import android.app.PictureInPictureParams; import android.content.ComponentName; import android.content.pm.ActivityInfo; +import android.graphics.Rect; import android.os.RemoteException; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; @@ -222,6 +224,16 @@ public class PipTaskOrganizerTest extends ShellTestCase { assertEquals(minSize, mPipBoundsState.getOverrideMinSize()); } + @Test + public void onTaskVanished_clearsPipBounds() { + mSpiedPipTaskOrganizer.onTaskAppeared(createTaskInfo(mComponent1, + createPipParams(null)), null /* leash */); + mPipBoundsState.setBounds(new Rect(100, 100, 200, 150)); + + mSpiedPipTaskOrganizer.onTaskVanished(createTaskInfo(mComponent1, createPipParams(null))); + assertTrue(mPipBoundsState.getBounds().isEmpty()); + } + private void preparePipTaskOrg() { final DisplayInfo info = new DisplayInfo(); mPipBoundsState.setDisplayLayout(new DisplayLayout(info, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java new file mode 100644 index 000000000000..dd10aa7752f5 --- /dev/null +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipResizeGestureHandlerTest.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.wm.shell.pip.phone; + +import static junit.framework.Assert.assertTrue; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.graphics.Rect; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.MotionEvent; + +import androidx.test.filters.SmallTest; + +import com.android.wm.shell.ShellTestCase; +import com.android.wm.shell.common.FloatingContentCoordinator; +import com.android.wm.shell.common.ShellExecutor; +import com.android.wm.shell.pip.PipBoundsAlgorithm; +import com.android.wm.shell.pip.PipBoundsState; +import com.android.wm.shell.pip.PipSnapAlgorithm; +import com.android.wm.shell.pip.PipTaskOrganizer; +import com.android.wm.shell.pip.PipTransitionController; +import com.android.wm.shell.pip.PipUiEventLogger; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** + * Unit tests against {@link PipResizeGestureHandler} + */ +@RunWith(AndroidTestingRunner.class) +@SmallTest +@TestableLooper.RunWithLooper(setAsMainLooper = true) +public class PipResizeGestureHandlerTest extends ShellTestCase { + private static final int STEP_SIZE = 40; + private final MotionEvent.PointerProperties[] mPp = new MotionEvent.PointerProperties[2]; + + @Mock + private PhonePipMenuController mPhonePipMenuController; + + @Mock + private PipTaskOrganizer mPipTaskOrganizer; + + @Mock + private PipDismissTargetHandler mPipDismissTargetHandler; + + @Mock + private PipTransitionController mMockPipTransitionController; + + @Mock + private FloatingContentCoordinator mFloatingContentCoordinator; + + @Mock + private PipUiEventLogger mPipUiEventLogger; + + @Mock + private ShellExecutor mMainExecutor; + + private PipResizeGestureHandler mPipResizeGestureHandler; + + private PipBoundsState mPipBoundsState; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + mPipBoundsState = new PipBoundsState(mContext); + final PipSnapAlgorithm pipSnapAlgorithm = new PipSnapAlgorithm(); + final PipBoundsAlgorithm pipBoundsAlgorithm = new PipBoundsAlgorithm(mContext, + mPipBoundsState, pipSnapAlgorithm); + final PipMotionHelper motionHelper = new PipMotionHelper(mContext, mPipBoundsState, + mPipTaskOrganizer, mPhonePipMenuController, pipSnapAlgorithm, + mMockPipTransitionController, mFloatingContentCoordinator); + mPipResizeGestureHandler = new PipResizeGestureHandler(mContext, pipBoundsAlgorithm, + mPipBoundsState, motionHelper, mPipTaskOrganizer, mPipDismissTargetHandler, + (Rect bounds) -> new Rect(), () -> {}, mPipUiEventLogger, mPhonePipMenuController, + mMainExecutor) { + @Override + public void pilferPointers() { + // Overridden just to avoid calling into InputMonitor. + } + }; + + for (int i = 0; i < 2; i++) { + MotionEvent.PointerProperties pointerProperty = new MotionEvent.PointerProperties(); + pointerProperty.id = i; + pointerProperty.toolType = MotionEvent.TOOL_TYPE_FINGER; + mPp[i] = pointerProperty; + } + + mPipResizeGestureHandler.init(); + mPipResizeGestureHandler.onSystemUiStateChanged(true); + } + + @Test + public void twoInput_triggersPinchResize_getBigger() { + assertTrue(mPipResizeGestureHandler.isUsingPinchToZoom()); + + int topLeft = 200; + int bottomRight = 500; + mPipBoundsState.setBounds(new Rect(topLeft, topLeft, bottomRight, bottomRight)); + + // Start inside the PiP bounds first. + topLeft += STEP_SIZE; + bottomRight -= STEP_SIZE; + MotionEvent downEvent = + obtainMotionEvent(MotionEvent.ACTION_POINTER_DOWN, topLeft, bottomRight); + assertTrue(mPipResizeGestureHandler.willStartResizeGesture(downEvent)); + + // Slowly move outward. + topLeft -= STEP_SIZE; + bottomRight += STEP_SIZE; + MotionEvent moveEvent1 = obtainMotionEvent(MotionEvent.ACTION_MOVE, topLeft, bottomRight); + mPipResizeGestureHandler.onPinchResize(moveEvent1); + + // Move outward more. + topLeft -= STEP_SIZE; + bottomRight += STEP_SIZE; + MotionEvent moveEvent2 = obtainMotionEvent(MotionEvent.ACTION_MOVE, topLeft, bottomRight); + mPipResizeGestureHandler.onPinchResize(moveEvent2); + + verify(mPipTaskOrganizer, times(2)) + .scheduleUserResizePip(any(), any(), anyFloat(), any()); + + MotionEvent upEvent = obtainMotionEvent(MotionEvent.ACTION_UP, topLeft, bottomRight); + mPipResizeGestureHandler.onPinchResize(upEvent); + + verify(mPipTaskOrganizer, times(1)) + .scheduleAnimateResizePip(any(), any(), anyInt(), anyFloat(), any()); + + assertTrue("The new size should be bigger than the original PiP size.", + mPipResizeGestureHandler.getLastResizeBounds().width() + > mPipBoundsState.getBounds().width()); + } + + @Test + public void twoInput_triggersPinchResize_getSmaller() { + assertTrue(mPipResizeGestureHandler.isUsingPinchToZoom()); + + int topLeft = 200; + int bottomRight = 500; + mPipBoundsState.setBounds(new Rect(topLeft, topLeft, bottomRight, bottomRight)); + + + topLeft += STEP_SIZE; + bottomRight -= STEP_SIZE; + MotionEvent downEvent = + obtainMotionEvent(MotionEvent.ACTION_POINTER_DOWN, topLeft, bottomRight); + assertTrue(mPipResizeGestureHandler.willStartResizeGesture(downEvent)); + + topLeft += STEP_SIZE; + bottomRight -= STEP_SIZE; + MotionEvent moveEvent1 = obtainMotionEvent(MotionEvent.ACTION_MOVE, topLeft, bottomRight); + mPipResizeGestureHandler.onPinchResize(moveEvent1); + + topLeft += STEP_SIZE; + bottomRight -= STEP_SIZE; + MotionEvent moveEvent2 = obtainMotionEvent(MotionEvent.ACTION_MOVE, topLeft, bottomRight); + mPipResizeGestureHandler.onPinchResize(moveEvent2); + + verify(mPipTaskOrganizer, times(2)) + .scheduleUserResizePip(any(), any(), anyFloat(), any()); + + MotionEvent upEvent = obtainMotionEvent(MotionEvent.ACTION_UP, topLeft, bottomRight); + mPipResizeGestureHandler.onPinchResize(upEvent); + + verify(mPipTaskOrganizer, times(1)) + .scheduleAnimateResizePip(any(), any(), anyInt(), anyFloat(), any()); + + assertTrue("The new size should be smaller than the original PiP size.", + mPipResizeGestureHandler.getLastResizeBounds().width() + < mPipBoundsState.getBounds().width()); + } + + private MotionEvent obtainMotionEvent(int action, int topLeft, int bottomRight) { + final MotionEvent.PointerCoords[] pc = new MotionEvent.PointerCoords[2]; + for (int i = 0; i < 2; i++) { + MotionEvent.PointerCoords pointerCoord = new MotionEvent.PointerCoords(); + if (i == 0) { + pointerCoord.x = topLeft; + pointerCoord.y = topLeft; + } else { + pointerCoord.x = bottomRight; + pointerCoord.y = bottomRight; + } + pc[i] = pointerCoord; + } + return MotionEvent.obtain(0 /* downTime */, + System.currentTimeMillis(), + action, + 2 /* pointerCount */, + mPp, + pc, + 0 /* metaState */, + 0 /* buttonState */, + 0 /* xPrecision */, + 0 /* yPrecision */, + 0 /* deviceId */, + 0 /* edgeFlags */, + 0 /* source */, + 0 /* flags */); + } +} diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java index 18642fcfef6c..08ac2a6cfa77 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java @@ -332,11 +332,18 @@ public class SplitTransitionTests extends ShellTestCase { final WindowContainerTransaction mRemoteFinishWCT = new WindowContainerTransaction(); @Override - public void startAnimation(TransitionInfo info, SurfaceControl.Transaction t, - IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { + public void startAnimation(IBinder transition, TransitionInfo info, + SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback) + throws RemoteException { mCalled = true; finishCallback.onTransitionFinished(mRemoteFinishWCT); } + + @Override + public void mergeAnimation(IBinder transition, TransitionInfo info, + SurfaceControl.Transaction t, IBinder mergeTarget, + IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { + } } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java index c1733de75535..2d2ab2c9f674 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/transition/ShellTransitionTests.java @@ -107,7 +107,8 @@ public class ShellTransitionTests { verify(mOrganizer, times(1)).startTransition(eq(TRANSIT_OPEN), eq(transitToken), any()); TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN) .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build(); - transitions.onTransitionReady(transitToken, info, mock(SurfaceControl.Transaction.class)); + transitions.onTransitionReady(transitToken, info, mock(SurfaceControl.Transaction.class), + mock(SurfaceControl.Transaction.class)); assertEquals(1, mDefaultHandler.activeCount()); mDefaultHandler.finishAll(); mMainExecutor.flushAll(); @@ -155,7 +156,8 @@ public class ShellTransitionTests { transitions.requestStartTransition(transitToken, new TransitionRequestInfo(TRANSIT_OPEN, null /* trigger */, null /* remote */)); verify(mOrganizer, times(1)).startTransition(eq(TRANSIT_OPEN), eq(transitToken), isNull()); - transitions.onTransitionReady(transitToken, open, mock(SurfaceControl.Transaction.class)); + transitions.onTransitionReady(transitToken, open, mock(SurfaceControl.Transaction.class), + mock(SurfaceControl.Transaction.class)); assertEquals(1, mDefaultHandler.activeCount()); assertEquals(0, testHandler.activeCount()); mDefaultHandler.finishAll(); @@ -168,7 +170,8 @@ public class ShellTransitionTests { new TransitionRequestInfo(TRANSIT_OPEN, mwTaskInfo, null /* remote */)); verify(mOrganizer, times(1)).startTransition( eq(TRANSIT_OPEN), eq(transitToken), eq(handlerWCT)); - transitions.onTransitionReady(transitToken, open, mock(SurfaceControl.Transaction.class)); + transitions.onTransitionReady(transitToken, open, mock(SurfaceControl.Transaction.class), + mock(SurfaceControl.Transaction.class)); assertEquals(1, mDefaultHandler.activeCount()); assertEquals(0, testHandler.activeCount()); mDefaultHandler.finishAll(); @@ -185,7 +188,8 @@ public class ShellTransitionTests { eq(TRANSIT_CHANGE), eq(transitToken), eq(handlerWCT)); TransitionInfo change = new TransitionInfoBuilder(TRANSIT_CHANGE) .addChange(TRANSIT_CHANGE).build(); - transitions.onTransitionReady(transitToken, change, mock(SurfaceControl.Transaction.class)); + transitions.onTransitionReady(transitToken, change, mock(SurfaceControl.Transaction.class), + mock(SurfaceControl.Transaction.class)); assertEquals(0, mDefaultHandler.activeCount()); assertEquals(1, testHandler.activeCount()); assertEquals(0, topHandler.activeCount()); @@ -203,11 +207,18 @@ public class ShellTransitionTests { final WindowContainerTransaction remoteFinishWCT = new WindowContainerTransaction(); IRemoteTransition testRemote = new IRemoteTransition.Stub() { @Override - public void startAnimation(TransitionInfo info, SurfaceControl.Transaction t, + public void startAnimation(IBinder token, TransitionInfo info, + SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { remoteCalled[0] = true; finishCallback.onTransitionFinished(remoteFinishWCT); } + + @Override + public void mergeAnimation(IBinder token, TransitionInfo info, + SurfaceControl.Transaction t, IBinder mergeTarget, + IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { + } }; IBinder transitToken = new Binder(); transitions.requestStartTransition(transitToken, @@ -215,7 +226,8 @@ public class ShellTransitionTests { verify(mOrganizer, times(1)).startTransition(eq(TRANSIT_OPEN), eq(transitToken), any()); TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN) .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build(); - transitions.onTransitionReady(transitToken, info, mock(SurfaceControl.Transaction.class)); + transitions.onTransitionReady(transitToken, info, mock(SurfaceControl.Transaction.class), + mock(SurfaceControl.Transaction.class)); assertEquals(0, mDefaultHandler.activeCount()); assertTrue(remoteCalled[0]); mDefaultHandler.finishAll(); @@ -269,11 +281,18 @@ public class ShellTransitionTests { final boolean[] remoteCalled = new boolean[]{false}; IRemoteTransition testRemote = new IRemoteTransition.Stub() { @Override - public void startAnimation(TransitionInfo info, SurfaceControl.Transaction t, + public void startAnimation(IBinder token, TransitionInfo info, + SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { remoteCalled[0] = true; finishCallback.onTransitionFinished(null /* wct */); } + + @Override + public void mergeAnimation(IBinder token, TransitionInfo info, + SurfaceControl.Transaction t, IBinder mergeTarget, + IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { + } }; TransitionFilter filter = new TransitionFilter(); @@ -290,7 +309,8 @@ public class ShellTransitionTests { verify(mOrganizer, times(1)).startTransition(eq(TRANSIT_OPEN), eq(transitToken), any()); TransitionInfo info = new TransitionInfoBuilder(TRANSIT_OPEN) .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build(); - transitions.onTransitionReady(transitToken, info, mock(SurfaceControl.Transaction.class)); + transitions.onTransitionReady(transitToken, info, mock(SurfaceControl.Transaction.class), + mock(SurfaceControl.Transaction.class)); assertEquals(0, mDefaultHandler.activeCount()); assertTrue(remoteCalled[0]); mDefaultHandler.finishAll(); @@ -308,11 +328,18 @@ public class ShellTransitionTests { final WindowContainerTransaction remoteFinishWCT = new WindowContainerTransaction(); IRemoteTransition testRemote = new IRemoteTransition.Stub() { @Override - public void startAnimation(TransitionInfo info, SurfaceControl.Transaction t, + public void startAnimation(IBinder token, TransitionInfo info, + SurfaceControl.Transaction t, IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { remoteCalled[0] = true; finishCallback.onTransitionFinished(remoteFinishWCT); } + + @Override + public void mergeAnimation(IBinder token, TransitionInfo info, + SurfaceControl.Transaction t, IBinder mergeTarget, + IRemoteTransitionFinishedCallback finishCallback) throws RemoteException { + } }; final int transitType = TRANSIT_FIRST_CUSTOM + 1; @@ -336,6 +363,86 @@ public class ShellTransitionTests { mock(SurfaceControl.Transaction.class), testFinish)); } + @Test + public void testTransitionQueueing() { + Transitions transitions = new Transitions(mOrganizer, mTransactionPool, mContext, + mMainExecutor, mAnimExecutor); + transitions.replaceDefaultHandlerForTest(mDefaultHandler); + + IBinder transitToken1 = new Binder(); + transitions.requestStartTransition(transitToken1, + new TransitionRequestInfo(TRANSIT_OPEN, null /* trigger */, null /* remote */)); + TransitionInfo info1 = new TransitionInfoBuilder(TRANSIT_OPEN) + .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build(); + transitions.onTransitionReady(transitToken1, info1, mock(SurfaceControl.Transaction.class), + mock(SurfaceControl.Transaction.class)); + assertEquals(1, mDefaultHandler.activeCount()); + + IBinder transitToken2 = new Binder(); + transitions.requestStartTransition(transitToken2, + new TransitionRequestInfo(TRANSIT_CLOSE, null /* trigger */, null /* remote */)); + TransitionInfo info2 = new TransitionInfoBuilder(TRANSIT_CLOSE) + .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build(); + transitions.onTransitionReady(transitToken2, info2, mock(SurfaceControl.Transaction.class), + mock(SurfaceControl.Transaction.class)); + // default handler doesn't merge by default, so it shouldn't increment active count. + assertEquals(1, mDefaultHandler.activeCount()); + assertEquals(0, mDefaultHandler.mergeCount()); + verify(mOrganizer, times(0)).finishTransition(eq(transitToken1), any(), any()); + verify(mOrganizer, times(0)).finishTransition(eq(transitToken2), any(), any()); + + mDefaultHandler.finishAll(); + mMainExecutor.flushAll(); + // first transition finished + verify(mOrganizer, times(1)).finishTransition(eq(transitToken1), any(), any()); + verify(mOrganizer, times(0)).finishTransition(eq(transitToken2), any(), any()); + // But now the "queued" transition is running + assertEquals(1, mDefaultHandler.activeCount()); + + mDefaultHandler.finishAll(); + mMainExecutor.flushAll(); + verify(mOrganizer, times(1)).finishTransition(eq(transitToken2), any(), any()); + } + + @Test + public void testTransitionMerging() { + Transitions transitions = new Transitions(mOrganizer, mTransactionPool, mContext, + mMainExecutor, mAnimExecutor); + mDefaultHandler.setSimulateMerge(true); + transitions.replaceDefaultHandlerForTest(mDefaultHandler); + + IBinder transitToken1 = new Binder(); + transitions.requestStartTransition(transitToken1, + new TransitionRequestInfo(TRANSIT_OPEN, null /* trigger */, null /* remote */)); + TransitionInfo info1 = new TransitionInfoBuilder(TRANSIT_OPEN) + .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build(); + transitions.onTransitionReady(transitToken1, info1, mock(SurfaceControl.Transaction.class), + mock(SurfaceControl.Transaction.class)); + assertEquals(1, mDefaultHandler.activeCount()); + + IBinder transitToken2 = new Binder(); + transitions.requestStartTransition(transitToken2, + new TransitionRequestInfo(TRANSIT_CLOSE, null /* trigger */, null /* remote */)); + TransitionInfo info2 = new TransitionInfoBuilder(TRANSIT_CLOSE) + .addChange(TRANSIT_OPEN).addChange(TRANSIT_CLOSE).build(); + transitions.onTransitionReady(transitToken2, info2, mock(SurfaceControl.Transaction.class), + mock(SurfaceControl.Transaction.class)); + // it should still only have 1 active, but then show 1 merged + assertEquals(1, mDefaultHandler.activeCount()); + assertEquals(1, mDefaultHandler.mergeCount()); + verify(mOrganizer, times(0)).finishTransition(eq(transitToken1), any(), any()); + // We don't tell organizer it is finished yet (since we still want to maintain ordering) + verify(mOrganizer, times(0)).finishTransition(eq(transitToken2), any(), any()); + + mDefaultHandler.finishAll(); + mMainExecutor.flushAll(); + // transition + merged all finished. + verify(mOrganizer, times(1)).finishTransition(eq(transitToken1), any(), any()); + verify(mOrganizer, times(1)).finishTransition(eq(transitToken2), any(), any()); + // Make sure nothing was queued + assertEquals(0, mDefaultHandler.activeCount()); + } + class TransitionInfoBuilder { final TransitionInfo mInfo; @@ -364,7 +471,9 @@ public class ShellTransitionTests { } class TestTransitionHandler implements Transitions.TransitionHandler { - final ArrayList<Transitions.TransitionFinishCallback> mFinishes = new ArrayList<>(); + ArrayList<Transitions.TransitionFinishCallback> mFinishes = new ArrayList<>(); + final ArrayList<IBinder> mMerged = new ArrayList<>(); + boolean mSimulateMerge = false; @Override public boolean startAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, @@ -374,6 +483,15 @@ public class ShellTransitionTests { return true; } + @Override + public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info, + @NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget, + @NonNull Transitions.TransitionFinishCallback finishCallback) { + if (!mSimulateMerge) return; + mMerged.add(transition); + finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */); + } + @Nullable @Override public WindowContainerTransaction handleRequest(@NonNull IBinder transition, @@ -381,16 +499,25 @@ public class ShellTransitionTests { return null; } + void setSimulateMerge(boolean sim) { + mSimulateMerge = sim; + } + void finishAll() { - for (int i = mFinishes.size() - 1; i >= 0; --i) { - mFinishes.get(i).onTransitionFinished(null /* wct */, null /* wctCB */); + final ArrayList<Transitions.TransitionFinishCallback> finishes = mFinishes; + mFinishes = new ArrayList<>(); + for (int i = finishes.size() - 1; i >= 0; --i) { + finishes.get(i).onTransitionFinished(null /* wct */, null /* wctCB */); } - mFinishes.clear(); } int activeCount() { return mFinishes.size(); } + + int mergeCount() { + return mMerged.size(); + } } private static SurfaceControl createMockSurface(boolean valid) { diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp index 2a70f0d6a804..cb620cc475a9 100644 --- a/libs/androidfw/LoadedArsc.cpp +++ b/libs/androidfw/LoadedArsc.cpp @@ -70,9 +70,6 @@ struct TypeSpecBuilder { } // namespace -LoadedPackage::LoadedPackage() = default; -LoadedPackage::~LoadedPackage() = default; - // Precondition: The header passed in has already been verified, so reading any fields and trusting // the ResChunk_header is safe. static bool VerifyResTableType(incfs::map_ptr<ResTable_type> header) { diff --git a/libs/androidfw/PosixUtils.cpp b/libs/androidfw/PosixUtils.cpp index f1ab1493012a..4ec525a01da5 100644 --- a/libs/androidfw/PosixUtils.cpp +++ b/libs/androidfw/PosixUtils.cpp @@ -72,7 +72,8 @@ std::unique_ptr<ProcResult> ExecuteBinary(const std::vector<std::string>& argv) argv0[i] = argv[i].c_str(); } argv0[argv.size()] = nullptr; - switch (fork()) { + int pid = fork(); + switch (pid) { case -1: // error free(argv0); PLOG(ERROR) << "fork"; @@ -104,8 +105,10 @@ std::unique_ptr<ProcResult> ExecuteBinary(const std::vector<std::string>& argv) close(stdout[1]); close(stderr[1]); int status; - wait(&status); + waitpid(pid, &status, 0); if (!WIFEXITED(status)) { + close(stdout[0]); + close(stderr[0]); return nullptr; } std::unique_ptr<ProcResult> result(new ProcResult()); diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h index 119f531b8634..10666adfdceb 100644 --- a/libs/androidfw/include/androidfw/AssetManager2.h +++ b/libs/androidfw/include/androidfw/AssetManager2.h @@ -94,6 +94,7 @@ class AssetManager2 { }; AssetManager2(); + explicit AssetManager2(AssetManager2&& other) = default; // Sets/resets the underlying ApkAssets for this AssetManager. The ApkAssets // are not owned by the AssetManager, and must have a longer lifetime. diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h index d9225cd812ef..3b222c556bfa 100644 --- a/libs/androidfw/include/androidfw/LoadedArsc.h +++ b/libs/androidfw/include/androidfw/LoadedArsc.h @@ -153,8 +153,6 @@ class LoadedPackage { static std::unique_ptr<const LoadedPackage> Load(const Chunk& chunk, package_property_t property_flags); - ~LoadedPackage(); - // Finds the entry with the specified type name and entry name. The names are in UTF-16 because // the underlying ResStringPool API expects this. For now this is acceptable, but since // the default policy in AAPT2 is to build UTF-8 string pools, this needs to change. @@ -275,7 +273,7 @@ class LoadedPackage { private: DISALLOW_COPY_AND_ASSIGN(LoadedPackage); - LoadedPackage(); + LoadedPackage() = default; ResStringPool type_string_pool_; ResStringPool key_string_pool_; diff --git a/libs/androidfw/include/androidfw/MutexGuard.h b/libs/androidfw/include/androidfw/MutexGuard.h index 64924f433245..6fc6d64e2f6e 100644 --- a/libs/androidfw/include/androidfw/MutexGuard.h +++ b/libs/androidfw/include/androidfw/MutexGuard.h @@ -18,6 +18,7 @@ #define ANDROIDFW_MUTEXGUARD_H #include <mutex> +#include <optional> #include <type_traits> #include "android-base/macros.h" @@ -47,34 +48,32 @@ class Guarded { static_assert(!std::is_pointer<T>::value, "T must not be a raw pointer"); public: - explicit Guarded() : guarded_() { + Guarded() : guarded_(std::in_place, T()) { } - template <typename U = T> - explicit Guarded(const T& guarded, - typename std::enable_if<std::is_copy_constructible<U>::value>::type = void()) - : guarded_(guarded) { + explicit Guarded(const T& guarded) : guarded_(std::in_place, guarded) { } - template <typename U = T> - explicit Guarded(T&& guarded, - typename std::enable_if<std::is_move_constructible<U>::value>::type = void()) - : guarded_(std::move(guarded)) { + explicit Guarded(T&& guarded) : guarded_(std::in_place, std::forward<T>(guarded)) { + } + + ~Guarded() { + std::lock_guard<std::mutex> scoped_lock(lock_); + guarded_.reset(); } private: friend class ScopedLock<T>; - DISALLOW_COPY_AND_ASSIGN(Guarded); std::mutex lock_; - T guarded_; + std::optional<T> guarded_; }; template <typename T> class ScopedLock { public: - explicit ScopedLock(Guarded<T>& guarded) : lock_(guarded.lock_), guarded_(guarded.guarded_) { + explicit ScopedLock(Guarded<T>& guarded) : lock_(guarded.lock_), guarded_(*guarded.guarded_) { } T& operator*() { diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp index c2642d3fdb55..6eb6e1ee4a5c 100644 --- a/libs/hwui/effects/StretchEffect.cpp +++ b/libs/hwui/effects/StretchEffect.cpp @@ -237,7 +237,7 @@ sk_sp<SkShader> StretchEffect::getShader(const sk_sp<SkImage>& snapshotImage) co } sk_sp<SkRuntimeEffect> StretchEffect::getStretchEffect() { - const static SkRuntimeEffect::Result instance = SkRuntimeEffect::Make(stretchShader); + const static SkRuntimeEffect::Result instance = SkRuntimeEffect::MakeForShader(stretchShader); return instance.effect; } diff --git a/libs/hwui/hwui/AnimatedImageThread.cpp b/libs/hwui/hwui/AnimatedImageThread.cpp index c8990039875e..3d5841d308fb 100644 --- a/libs/hwui/hwui/AnimatedImageThread.cpp +++ b/libs/hwui/hwui/AnimatedImageThread.cpp @@ -22,13 +22,16 @@ namespace android { namespace uirenderer { AnimatedImageThread& AnimatedImageThread::getInstance() { - static AnimatedImageThread* sInstance = new AnimatedImageThread(); - return *sInstance; + [[clang::no_destroy]] static sp<AnimatedImageThread> sInstance = []() { + sp<AnimatedImageThread> thread = sp<AnimatedImageThread>::make(); + thread->start("AnimatedImageThread"); + return thread; + }(); + return *sInstance.get(); } AnimatedImageThread::AnimatedImageThread() { setpriority(PRIO_PROCESS, 0, PRIORITY_NORMAL + PRIORITY_MORE_FAVORABLE); - start("AnimatedImageThread"); } std::future<AnimatedImageDrawable::Snapshot> AnimatedImageThread::decodeNextFrame( diff --git a/libs/hwui/hwui/AnimatedImageThread.h b/libs/hwui/hwui/AnimatedImageThread.h index 9e3537430d5a..fac80e5310e8 100644 --- a/libs/hwui/hwui/AnimatedImageThread.h +++ b/libs/hwui/hwui/AnimatedImageThread.h @@ -37,6 +37,7 @@ public: std::future<AnimatedImageDrawable::Snapshot> reset(const sk_sp<AnimatedImageDrawable>&); private: + friend sp<AnimatedImageThread>; AnimatedImageThread(); }; diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp index 2e4d7f62f671..90184432e8a4 100644 --- a/libs/hwui/jni/Shader.cpp +++ b/libs/hwui/jni/Shader.cpp @@ -239,7 +239,8 @@ static jlong ComposeShader_create(JNIEnv* env, jobject o, jlong matrixPtr, static jlong RuntimeShader_createShaderBuilder(JNIEnv* env, jobject, jstring sksl) { ScopedUtfChars strSksl(env, sksl); - auto result = SkRuntimeEffect::Make(SkString(strSksl.c_str()), SkRuntimeEffect::Options{}); + auto result = SkRuntimeEffect::MakeForShader(SkString(strSksl.c_str()), + SkRuntimeEffect::Options{}); if (result.effect.get() == nullptr) { doThrowIAE(env, result.errorText.c_str()); return 0; diff --git a/libs/incident/Android.bp b/libs/incident/Android.bp index f322bff8e6ee..547d7192090a 100644 --- a/libs/incident/Android.bp +++ b/libs/incident/Android.bp @@ -104,7 +104,7 @@ cc_test { name: "libincident_test", test_config: "AndroidTest.xml", defaults: ["libincidentpriv_defaults"], - test_suites: ["device-tests", "mts-statsd"], + test_suites: ["device-tests"], compile_multilib: "both", multilib: { lib64: { |