Merge "UI fixes for the progress bar and handle display density changes" into main
diff --git a/core/java/android/app/BackgroundStartPrivileges.java b/core/java/android/app/BackgroundStartPrivileges.java
index 76c0ccf..20278ea 100644
--- a/core/java/android/app/BackgroundStartPrivileges.java
+++ b/core/java/android/app/BackgroundStartPrivileges.java
@@ -174,6 +174,15 @@
@Override
public String toString() {
+ if (this == ALLOW_BAL) {
+ return "BSP.ALLOW_BAL";
+ }
+ if (this == ALLOW_FGS) {
+ return "BSP.ALLOW_FGS";
+ }
+ if (this == NONE) {
+ return "BSP.NONE";
+ }
return "BackgroundStartPrivileges["
+ "allowsBackgroundActivityStarts=" + mAllowsBackgroundActivityStarts
+ ", allowsBackgroundForegroundServiceStarts="
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 2c428ef..1f8784b 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -259,12 +259,10 @@
* @param taskId the id of the task to retrieve the sAutoapshots for
* @param isLowResolution if set, if the snapshot needs to be loaded from disk, this will load
* a reduced resolution of it, which is much faster
- * @param takeSnapshotIfNeeded if set, call {@link #takeTaskSnapshot} to trigger the snapshot
- if no cache exists.
* @return a graphic buffer representing a screenshot of a task
*/
android.window.TaskSnapshot getTaskSnapshot(
- int taskId, boolean isLowResolution, boolean takeSnapshotIfNeeded);
+ int taskId, boolean isLowResolution);
/**
* Requests for a new snapshot to be taken for the task with the given id, storing it in the
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
index 84feb03..108aa82 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/pip/PipUtils.kt
@@ -129,9 +129,7 @@
@JvmStatic
fun getTaskSnapshot(taskId: Int, isLowResolution: Boolean): TaskSnapshot? {
return if (taskId <= 0) null else try {
- ActivityTaskManager.getService().getTaskSnapshot(
- taskId, isLowResolution, false /* takeSnapshotIfNeeded */
- )
+ ActivityTaskManager.getService().getTaskSnapshot(taskId, isLowResolution)
} catch (e: RemoteException) {
Log.e(TAG, "Failed to get task snapshot, taskId=$taskId", e)
null
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 631423e..10393cf 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -137,14 +137,12 @@
}
/**
- * @return a {@link ThumbnailData} with {@link TaskSnapshot} for the given {@param taskId}.
- * The snapshot will be triggered if no cached {@link TaskSnapshot} exists.
+ * @return the task snapshot for the given {@param taskId}.
*/
public @NonNull ThumbnailData getTaskThumbnail(int taskId, boolean isLowResolution) {
TaskSnapshot snapshot = null;
try {
- snapshot = getService().getTaskSnapshot(taskId, isLowResolution,
- true /* takeSnapshotIfNeeded */);
+ snapshot = getService().getTaskSnapshot(taskId, isLowResolution);
} catch (RemoteException e) {
Log.w(TAG, "Failed to retrieve task snapshot", e);
}
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
index cfe2af9..5953d0d 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
@@ -39,9 +39,12 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.accessibility.AccessibilityTraceManager;
import com.android.server.accessibility.EventStreamTransformation;
+import com.android.server.accessibility.Flags;
+import com.android.server.accessibility.gestures.GestureMatcher;
import com.android.server.accessibility.gestures.MultiTap;
import com.android.server.accessibility.gestures.MultiTapAndHold;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -453,20 +456,45 @@
private final MagnificationGesturesObserver mGesturesObserver;
DetectingState(@UiContext Context context) {
- final MultiTap multiTap = new MultiTap(context, mDetectSingleFingerTripleTap ? 3 : 1,
- mDetectSingleFingerTripleTap
- ? MagnificationGestureMatcher.GESTURE_TRIPLE_TAP
- : MagnificationGestureMatcher.GESTURE_SINGLE_TAP, null);
- final MultiTapAndHold multiTapAndHold = new MultiTapAndHold(context,
- mDetectSingleFingerTripleTap ? 3 : 1,
- mDetectSingleFingerTripleTap
- ? MagnificationGestureMatcher.GESTURE_TRIPLE_TAP_AND_HOLD
- : MagnificationGestureMatcher.GESTURE_SINGLE_TAP_AND_HOLD, null);
- mGesturesObserver = new MagnificationGesturesObserver(this,
- new SimpleSwipe(context),
- multiTap,
- multiTapAndHold,
- new TwoFingersDownOrSwipe(context));
+ if (Flags.enableMagnificationMultipleFingerMultipleTapGesture()) {
+ final List<GestureMatcher> mGestureMatchers = new ArrayList<>();
+
+ mGestureMatchers.add(new SimpleSwipe(context));
+ // Observe single tap and single tap and hold to reduce response time when the
+ // user performs these two gestures inside the window magnifier.
+ mGestureMatchers.add(new MultiTap(context,
+ mDetectSingleFingerTripleTap ? 3 : 1,
+ mDetectSingleFingerTripleTap
+ ? MagnificationGestureMatcher.GESTURE_TRIPLE_TAP
+ : MagnificationGestureMatcher.GESTURE_SINGLE_TAP,
+ null));
+ mGestureMatchers.add(new MultiTapAndHold(context,
+ mDetectSingleFingerTripleTap ? 3 : 1,
+ mDetectSingleFingerTripleTap
+ ? MagnificationGestureMatcher.GESTURE_TRIPLE_TAP_AND_HOLD
+ : MagnificationGestureMatcher.GESTURE_SINGLE_TAP_AND_HOLD,
+ null));
+ mGestureMatchers.add(new TwoFingersDownOrSwipe(context));
+
+ mGesturesObserver = new MagnificationGesturesObserver(this,
+ mGestureMatchers.toArray(new GestureMatcher[mGestureMatchers.size()]));
+ } else {
+ final MultiTap multiTap = new MultiTap(context,
+ mDetectSingleFingerTripleTap ? 3 : 1,
+ mDetectSingleFingerTripleTap
+ ? MagnificationGestureMatcher.GESTURE_TRIPLE_TAP
+ : MagnificationGestureMatcher.GESTURE_SINGLE_TAP, null);
+ final MultiTapAndHold multiTapAndHold = new MultiTapAndHold(context,
+ mDetectSingleFingerTripleTap ? 3 : 1,
+ mDetectSingleFingerTripleTap
+ ? MagnificationGestureMatcher.GESTURE_TRIPLE_TAP_AND_HOLD
+ : MagnificationGestureMatcher.GESTURE_SINGLE_TAP_AND_HOLD, null);
+ mGesturesObserver = new MagnificationGesturesObserver(this,
+ new SimpleSwipe(context),
+ multiTap,
+ multiTapAndHold,
+ new TwoFingersDownOrSwipe(context));
+ }
}
@Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 88bb66f..9677248 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1886,7 +1886,7 @@
int exitInfoReason = (int) args.arg3;
args.recycle();
forceStopPackageLocked(pkg, appId, false, false, true, false,
- false, userId, reason, exitInfoReason);
+ false, false, userId, reason, exitInfoReason);
}
} break;
@@ -3914,7 +3914,10 @@
+ packageName + ": " + e);
}
if (mUserController.isUserRunning(user, userRunningFlags)) {
- forceStopPackageLocked(packageName, pkgUid,
+ forceStopPackageLocked(packageName, UserHandle.getAppId(pkgUid),
+ false /* callerWillRestart */, false /* purgeCache */,
+ true /* doIt */, false /* evenPersistent */,
+ false /* uninstalling */, true /* packageStateStopped */, user,
reason == null ? ("from pid " + callingPid) : reason);
finishForceStopPackageLocked(packageName, pkgUid);
}
@@ -4163,7 +4166,7 @@
@GuardedBy("this")
private void forceStopPackageLocked(final String packageName, int uid, String reason) {
forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
- false, true, false, false, UserHandle.getUserId(uid), reason);
+ false, true, false, false, false, UserHandle.getUserId(uid), reason);
}
@GuardedBy("this")
@@ -4349,20 +4352,20 @@
@GuardedBy("this")
final boolean forceStopPackageLocked(String packageName, int appId,
boolean callerWillRestart, boolean purgeCache, boolean doit,
- boolean evenPersistent, boolean uninstalling, int userId, String reasonString) {
-
+ boolean evenPersistent, boolean uninstalling, boolean packageStateStopped,
+ int userId, String reasonString) {
int reason = packageName == null ? ApplicationExitInfo.REASON_USER_STOPPED
: ApplicationExitInfo.REASON_USER_REQUESTED;
return forceStopPackageLocked(packageName, appId, callerWillRestart, purgeCache, doit,
- evenPersistent, uninstalling, userId, reasonString, reason);
+ evenPersistent, uninstalling, packageStateStopped, userId, reasonString, reason);
}
@GuardedBy("this")
final boolean forceStopPackageLocked(String packageName, int appId,
boolean callerWillRestart, boolean purgeCache, boolean doit,
- boolean evenPersistent, boolean uninstalling, int userId, String reasonString,
- int reason) {
+ boolean evenPersistent, boolean uninstalling, boolean packageStateStopped,
+ int userId, String reasonString, int reason) {
int i;
if (userId == UserHandle.USER_ALL && packageName == null) {
@@ -4443,7 +4446,7 @@
}
}
- if (packageName == null || uninstalling) {
+ if (packageName == null || uninstalling || packageStateStopped) {
didSomething |= mPendingIntentController.removePendingIntentsForPackage(
packageName, userId, appId, doit);
}
@@ -5148,7 +5151,7 @@
for (String pkg : pkgs) {
synchronized (ActivityManagerService.this) {
if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
- 0, "query restart")) {
+ false, 0, "query restart")) {
setResultCode(Activity.RESULT_OK);
return;
}
@@ -7342,7 +7345,7 @@
mDebugTransient = !persistent;
if (packageName != null) {
forceStopPackageLocked(packageName, -1, false, false, true, true,
- false, UserHandle.USER_ALL, "set debug app");
+ false, false, UserHandle.USER_ALL, "set debug app");
}
}
} finally {
@@ -14918,7 +14921,7 @@
if (list != null && list.length > 0) {
for (int i = 0; i < list.length; i++) {
forceStopPackageLocked(list[i], -1, false, true, true,
- false, false, userId, "storage unmount");
+ false, false, false, userId, "storage unmount");
}
mAtmInternal.cleanupRecentTasksForUser(UserHandle.USER_ALL);
sendPackageBroadcastLocked(
@@ -14945,8 +14948,8 @@
if (killProcess) {
forceStopPackageLocked(ssp, UserHandle.getAppId(
intent.getIntExtra(Intent.EXTRA_UID, -1)),
- false, true, true, false, fullUninstall, userId,
- "pkg removed");
+ false, true, true, false, fullUninstall, false,
+ userId, "pkg removed");
getPackageManagerInternal()
.onPackageProcessKilledForUninstall(ssp);
} else {
@@ -15864,7 +15867,7 @@
} else {
// Instrumentation can kill and relaunch even persistent processes
forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false,
- userId, "start instr");
+ false, userId, "start instr");
// Inform usage stats to make the target package active
if (mUsageStatsService != null) {
mUsageStatsService.reportEvent(ii.targetPackage, userId,
@@ -15993,6 +15996,7 @@
/* doIt= */ true,
/* evenPersistent= */ true,
/* uninstalling= */ false,
+ /* packageStateStopped= */ false,
userId,
"start instr");
@@ -16163,8 +16167,7 @@
}
} else if (!instr.mNoRestart) {
forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false,
- app.userId,
- "finished inst");
+ false, app.userId, "finished inst");
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 7c079702..2efac12 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -2040,7 +2040,7 @@
// the package was initially frozen through KILL_APPLICATION_MSG, so
// it doesn't hurt to use it again.)
mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
- false, false, true, false, false, app.userId, "start failure");
+ false, false, true, false, false, false, app.userId, "start failure");
return false;
}
}
@@ -2115,7 +2115,7 @@
+ app.processName, e);
app.setPendingStart(false);
mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
- false, false, true, false, false, app.userId, "start failure");
+ false, false, true, false, false, false, app.userId, "start failure");
}
return app.getPid() > 0;
}
@@ -2148,7 +2148,7 @@
app.setPendingStart(false);
mService.forceStopPackageLocked(app.info.packageName,
UserHandle.getAppId(app.uid),
- false, false, true, false, false, app.userId, "start failure");
+ false, false, true, false, false, false, app.userId, "start failure");
}
}
};
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index c5dd01f..ae62a7a 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -3629,7 +3629,7 @@
void activityManagerForceStopPackage(@UserIdInt int userId, String reason) {
synchronized (mService) {
- mService.forceStopPackageLocked(null, -1, false, false, true, false, false,
+ mService.forceStopPackageLocked(null, -1, false, false, true, false, false, false,
userId, reason);
}
};
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index c021785..f462efc 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -69,6 +69,7 @@
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
import static android.window.TransitionInfo.FLAG_IN_TASK_WITH_EMBEDDED_ACTIVITY;
+
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_DREAM;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
@@ -3825,8 +3826,7 @@
}
@Override
- public TaskSnapshot getTaskSnapshot(int taskId, boolean isLowResolution,
- boolean takeSnapshotIfNeeded) {
+ public TaskSnapshot getTaskSnapshot(int taskId, boolean isLowResolution) {
mAmInternal.enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
final long ident = Binder.clearCallingIdentity();
try {
@@ -3840,12 +3840,8 @@
}
}
// Don't call this while holding the lock as this operation might hit the disk.
- TaskSnapshot taskSnapshot = mWindowManager.mTaskSnapshotController.getSnapshot(taskId,
+ return mWindowManager.mTaskSnapshotController.getSnapshot(taskId,
task.mUserId, true /* restoreFromDisk */, isLowResolution);
- if (taskSnapshot == null && takeSnapshotIfNeeded) {
- taskSnapshot = takeTaskSnapshot(taskId, false /* updateCache */);
- }
- return taskSnapshot;
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -7064,8 +7060,7 @@
@Override
public TaskSnapshot getTaskSnapshotBlocking(
int taskId, boolean isLowResolution) {
- return ActivityTaskManagerService.this.getTaskSnapshot(taskId, isLowResolution,
- false /* takeSnapshotIfNeeded */);
+ return ActivityTaskManagerService.this.getTaskSnapshot(taskId, isLowResolution);
}
@Override
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index 9f3e162..668cd87 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -28,6 +28,7 @@
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW;
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONLY;
import static com.android.server.wm.ActivityTaskSupervisor.getApplicationLabel;
+import static com.android.window.flags.Flags.balShowToasts;
import static com.android.server.wm.PendingRemoteAnimationRegistry.TIMEOUT_MS;
import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -459,6 +460,7 @@
"With Android 15 BAL hardening this activity start would be blocked"
+ " (missing opt in by PI creator)! "
+ state.dump(resultForCaller, resultForRealCaller));
+ showBalToast("BAL would be blocked", state);
// return the realCaller result for backwards compatibility
return statsLog(resultForRealCaller, state);
}
@@ -470,6 +472,7 @@
"With Android 15 BAL hardening this activity start would be blocked"
+ " (missing opt in by PI creator)! "
+ state.dump(resultForCaller, resultForRealCaller));
+ showBalToast("BAL would be blocked", state);
return statsLog(resultForCaller, state);
}
if (resultForRealCaller.allows()
@@ -481,6 +484,7 @@
"With Android 14 BAL hardening this activity start would be blocked"
+ " (missing opt in by PI sender)! "
+ state.dump(resultForCaller, resultForRealCaller));
+ showBalToast("BAL would be blocked", state);
return statsLog(resultForRealCaller, state);
}
Slog.wtf(TAG, "Without Android 14 BAL hardening this activity start would be allowed"
@@ -488,6 +492,7 @@
+ state.dump(resultForCaller, resultForRealCaller));
// fall through
}
+ showBalToast("BAL blocked", state);
// anything that has fallen through would currently be aborted
Slog.w(TAG, "Background activity launch blocked"
+ state.dump(resultForCaller, resultForRealCaller));
@@ -862,8 +867,7 @@
+ (blockActivityStartAndFeatureEnabled ? " blocked " : " would block ")
+ getApplicationLabel(mService.mContext.getPackageManager(),
launchedFromPackageName);
- UiThread.getHandler().post(() -> Toast.makeText(mService.mContext,
- toastText, Toast.LENGTH_LONG).show());
+ showToast(toastText);
Slog.i(TAG, asmDebugInfo);
}
@@ -882,6 +886,19 @@
return true;
}
+ private void showBalToast(String toastText, BalState state) {
+ if (balShowToasts()) {
+ showToast(toastText
+ + " caller:" + state.mCallingPackage
+ + " realCaller:" + state.mRealCallingPackage);
+ }
+ }
+
+ private void showToast(String toastText) {
+ UiThread.getHandler().post(() -> Toast.makeText(mService.mContext,
+ toastText, Toast.LENGTH_LONG).show());
+ }
+
/**
* If the top activity uid does not match the launching or launched activity, and the launch was
* not requested from the top uid, we want to clear out all non matching activities to prevent
@@ -930,12 +947,10 @@
if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid)
&& (!shouldBlockActivityStart || finishCount[0] > 0)) {
- UiThread.getHandler().post(() -> Toast.makeText(mService.mContext,
- (shouldBlockActivityStart
- ? "Top activities cleared by "
- : "Top activities would be cleared by ")
- + ActivitySecurityModelFeatureFlags.DOC_LINK,
- Toast.LENGTH_LONG).show());
+ showToast((shouldBlockActivityStart
+ ? "Top activities cleared by "
+ : "Top activities would be cleared by ")
+ + ActivitySecurityModelFeatureFlags.DOC_LINK);
Slog.i(TAG, getDebugInfoForActivitySecurity("Clear Top", sourceRecord, targetRecord,
targetTask, targetTaskTop, realCallingUid, balCode, shouldBlockActivityStart,
@@ -1013,11 +1028,10 @@
}
if (ActivitySecurityModelFeatureFlags.shouldShowToast(callingUid)) {
- UiThread.getHandler().post(() -> Toast.makeText(mService.mContext,
- (ActivitySecurityModelFeatureFlags.DOC_LINK
- + (restrictActivitySwitch ? " returned home due to "
- : " would return home due to ")
- + callingLabel), Toast.LENGTH_LONG).show());
+ showToast((ActivitySecurityModelFeatureFlags.DOC_LINK
+ + (restrictActivitySwitch ? " returned home due to "
+ : " would return home due to ")
+ + callingLabel));
}
// If the activity switch should be restricted, return home rather than the
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 5c5a1e1..f348928 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -3508,10 +3508,13 @@
top.mLetterboxUiController.getLetterboxPositionForVerticalReachability();
}
}
- // User Aspect Ratio Settings is enabled if the app is not in SCM
+ // User Aspect Ratio Settings button is enabled if the app is not in SCM and has
+ // launchable activities
info.topActivityEligibleForUserAspectRatioButton = top != null
&& !info.topActivityInSizeCompat
- && top.mLetterboxUiController.shouldEnableUserAspectRatioSettings();
+ && top.mLetterboxUiController.shouldEnableUserAspectRatioSettings()
+ && mAtmService.mContext.getPackageManager()
+ .getLaunchIntentForPackage(getBasePackageName()) != null;
info.topActivityBoundsLetterboxed = top != null && top.areBoundsLetterboxed();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 4c25a4b..3b4b220 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -1444,7 +1444,7 @@
});
assertSecurityException(expectCallable,
() -> mAtm.startActivityFromRecents(0, new Bundle()));
- assertSecurityException(expectCallable, () -> mAtm.getTaskSnapshot(0, true, false));
+ assertSecurityException(expectCallable, () -> mAtm.getTaskSnapshot(0, true));
assertSecurityException(expectCallable, () -> mAtm.registerTaskStackListener(null));
assertSecurityException(expectCallable,
() -> mAtm.unregisterTaskStackListener(null));
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 435a835..0639deb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -73,6 +73,7 @@
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
@@ -570,12 +571,15 @@
.setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
final Task task = rootTask.getBottomMostTask();
final ActivityRecord root = task.getTopNonFinishingActivity();
+ final PackageManager pm = mContext.getPackageManager();
+ spyOn(pm);
spyOn(mWm.mLetterboxConfiguration);
spyOn(root);
spyOn(root.mLetterboxUiController);
doReturn(true).when(root.mLetterboxUiController)
.shouldEnableUserAspectRatioSettings();
+ doReturn(new Intent()).when(pm).getLaunchIntentForPackage(anyString());
doReturn(false).when(root).inSizeCompatMode();
doReturn(task).when(root).getOrganizedTask();
@@ -593,6 +597,10 @@
doReturn(true).when(root).inSizeCompatMode();
assertFalse(task.getTaskInfo().topActivityEligibleForUserAspectRatioButton);
doReturn(false).when(root).inSizeCompatMode();
+
+ // When app doesn't have any launchable activities the button is not enabled
+ doReturn(null).when(pm).getLaunchIntentForPackage(anyString());
+ assertFalse(task.getTaskInfo().topActivityEligibleForUserAspectRatioButton);
}
/**