diff options
11 files changed, 145 insertions, 69 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 431755e092e3..17bb797bf8c5 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -39,6 +39,12 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.RemoteServiceException.BadForegroundServiceNotificationException; +import android.app.RemoteServiceException.CannotDeliverBroadcastException; +import android.app.RemoteServiceException.CannotPostForegroundServiceNotificationException; +import android.app.RemoteServiceException.CrashedByAdbException; +import android.app.RemoteServiceException.ForegroundServiceDidNotStartInTimeException; +import android.app.RemoteServiceException.MissingRequestPasswordComplexityPermissionException; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; import android.app.backup.BackupAgent; @@ -1921,11 +1927,27 @@ public final class ActivityThread extends ClientTransactionHandler private void throwRemoteServiceException(String message, int typeId) { // Use a switch to ensure all the type IDs are unique. switch (typeId) { - case ForegroundServiceDidNotStartInTimeException.TYPE_ID: // 1 + case ForegroundServiceDidNotStartInTimeException.TYPE_ID: throw new ForegroundServiceDidNotStartInTimeException(message); - case RemoteServiceException.TYPE_ID: // 0 + + case CannotDeliverBroadcastException.TYPE_ID: + throw new CannotDeliverBroadcastException(message); + + case CannotPostForegroundServiceNotificationException.TYPE_ID: + throw new CannotPostForegroundServiceNotificationException(message); + + case BadForegroundServiceNotificationException.TYPE_ID: + throw new BadForegroundServiceNotificationException(message); + + case MissingRequestPasswordComplexityPermissionException.TYPE_ID: + throw new MissingRequestPasswordComplexityPermissionException(message); + + case CrashedByAdbException.TYPE_ID: + throw new CrashedByAdbException(message); + default: - throw new RemoteServiceException(message); + throw new RemoteServiceException(message + + " (with unwknown typeId:" + typeId + ")"); } } diff --git a/core/java/android/app/ForegroundServiceDidNotStartInTimeException.java b/core/java/android/app/ForegroundServiceDidNotStartInTimeException.java deleted file mode 100644 index 364291e69ad6..000000000000 --- a/core/java/android/app/ForegroundServiceDidNotStartInTimeException.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app; - -/** - * Exception used to crash an app process when it didn't call {@link Service#startForeground} - * in time after the service was started with - * {@link android.content.Context#startForegroundService}. - * - * @hide - */ -public class ForegroundServiceDidNotStartInTimeException extends RemoteServiceException { - /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ - public static final int TYPE_ID = 1; - - public ForegroundServiceDidNotStartInTimeException(String msg) { - super(msg); - } -} diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 0210a94eafcc..9e9e28b8bd4c 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -319,8 +319,6 @@ interface IActivityManager { void handleApplicationStrictModeViolation(in IBinder app, int penaltyMask, in StrictMode.ViolationInfo crashInfo); boolean isTopActivityImmersive(); - void crashApplication(int uid, int initialPid, in String packageName, int userId, - in String message, boolean force); void crashApplicationWithType(int uid, int initialPid, in String packageName, int userId, in String message, boolean force, int exceptionTypeId); /** @deprecated -- use getProviderMimeTypeAsync */ diff --git a/core/java/android/app/RemoteServiceException.java b/core/java/android/app/RemoteServiceException.java index 4b32463e2996..1038530d92d3 100644 --- a/core/java/android/app/RemoteServiceException.java +++ b/core/java/android/app/RemoteServiceException.java @@ -19,20 +19,109 @@ package android.app; import android.util.AndroidRuntimeException; /** - * Exception used by {@link ActivityThread} to crash an app process. + * Exception used by {@link ActivityThread} to crash an app process for an unknown cause. + * An exception of this class is no longer supposed to be thrown. Instead, we use fine-grained + * sub-exceptions. + * + * Subclasses must be registered in + * {@link android.app.ActivityThread#throwRemoteServiceException(java.lang.String, int)}. * * @hide */ public class RemoteServiceException extends AndroidRuntimeException { + public RemoteServiceException(String msg) { + super(msg); + } + /** - * The type ID passed to {@link IApplicationThread#scheduleCrash}. + * Exception used to crash an app process when it didn't call {@link Service#startForeground} + * in time after the service was started with + * {@link android.content.Context#startForegroundService}. * - * Assign a unique ID to each subclass. See the above method for the numbers that are already - * taken. + * @hide */ - public static final int TYPE_ID = 0; + public static class ForegroundServiceDidNotStartInTimeException extends RemoteServiceException { + /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ + public static final int TYPE_ID = 1; - public RemoteServiceException(String msg) { - super(msg); + public ForegroundServiceDidNotStartInTimeException(String msg) { + super(msg); + } + } + + /** + * Exception used to crash an app process when the system received a RemoteException + * while delivering a broadcast to an app process. + * + * @hide + */ + public static class CannotDeliverBroadcastException extends RemoteServiceException { + /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ + public static final int TYPE_ID = 2; + + public CannotDeliverBroadcastException(String msg) { + super(msg); + } + } + + /** + * Exception used to crash an app process when the system received a RemoteException + * while posting a notification of a foreground service. + * + * @hide + */ + public static class CannotPostForegroundServiceNotificationException + extends RemoteServiceException { + /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ + public static final int TYPE_ID = 3; + + public CannotPostForegroundServiceNotificationException(String msg) { + super(msg); + } + } + + /** + * Exception used to crash an app process when the system finds an error in a foreground service + * notification. + * + * @hide + */ + public static class BadForegroundServiceNotificationException extends RemoteServiceException { + /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ + public static final int TYPE_ID = 4; + + public BadForegroundServiceNotificationException(String msg) { + super(msg); + } + } + + /** + * Exception used to crash an app process when it calls a setting activity that requires + * the {@code REQUEST_PASSWORD_COMPLEXITY} permission. + * + * @hide + */ + public static class MissingRequestPasswordComplexityPermissionException + extends RemoteServiceException { + /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ + public static final int TYPE_ID = 5; + + public MissingRequestPasswordComplexityPermissionException(String msg) { + super(msg); + } + } + + /** + * Exception used to crash an app process by {@code adb shell am crash}. + * + * @hide + */ + public static class CrashedByAdbException extends RemoteServiceException { + /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */ + public static final int TYPE_ID = 6; + + public CrashedByAdbException(String msg) { + super(msg); + } } } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index a2fec2753340..df2ae987f8cb 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -87,13 +87,13 @@ import android.app.ActivityManagerInternal.ServiceNotificationPolicy; import android.app.ActivityThread; import android.app.AppGlobals; import android.app.AppOpsManager; -import android.app.ForegroundServiceDidNotStartInTimeException; import android.app.ForegroundServiceStartNotAllowedException; import android.app.IApplicationThread; import android.app.IServiceConnection; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; +import android.app.RemoteServiceException.ForegroundServiceDidNotStartInTimeException; import android.app.Service; import android.app.ServiceStartArgs; import android.app.admin.DevicePolicyEventLogger; @@ -1243,7 +1243,7 @@ public final class ActiveServices { } void killMisbehavingService(ServiceRecord r, - int appUid, int appPid, String localPackageName) { + int appUid, int appPid, String localPackageName, int exceptionTypeId) { synchronized (mAm) { if (!r.destroying) { // This service is still alive, stop it. @@ -1257,8 +1257,8 @@ public final class ActiveServices { stopServiceLocked(found, false); } } - mAm.crashApplication(appUid, appPid, localPackageName, -1, - "Bad notification for startForeground", true /*force*/); + mAm.crashApplicationWithType(appUid, appPid, localPackageName, -1, + "Bad notification for startForeground", true /*force*/, exceptionTypeId); } } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b5f3389c50e0..5cd66aabbf2e 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -183,7 +183,6 @@ import android.app.PendingIntent; import android.app.ProcessMemoryState; import android.app.ProfilerInfo; import android.app.PropertyInvalidatedCache; -import android.app.RemoteServiceException; import android.app.SyncNotedAppOp; import android.app.WaitResult; import android.app.backup.BackupManager.OperationType; @@ -3000,13 +2999,6 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void crashApplication(int uid, int initialPid, String packageName, int userId, - String message, boolean force) { - crashApplicationWithType(uid, initialPid, packageName, userId, message, force, - RemoteServiceException.TYPE_ID); - } - - @Override public void crashApplicationWithType(int uid, int initialPid, String packageName, int userId, String message, boolean force, int exceptionTypeId) { if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 31e48fb0837f..ea28117a6a3d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -46,6 +46,7 @@ import android.app.IStopUserCallback; import android.app.IUidObserver; import android.app.KeyguardManager; import android.app.ProfilerInfo; +import android.app.RemoteServiceException.CrashedByAdbException; import android.app.UserSwitchObserver; import android.app.WaitResult; import android.app.usage.AppStandbyInfo; @@ -1154,7 +1155,8 @@ final class ActivityManagerShellCommand extends ShellCommand { } catch (NumberFormatException e) { packageName = arg; } - mInterface.crashApplication(-1, pid, packageName, userId, "shell-induced crash", false); + mInterface.crashApplicationWithType(-1, pid, packageName, userId, "shell-induced crash", + false, CrashedByAdbException.TYPE_ID); return 0; } diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 94bf62f8b9b7..487101b7eac4 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -20,7 +20,13 @@ import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY; import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE; import static android.text.TextUtils.formatSimple; -import static com.android.server.am.ActivityManagerDebugConfig.*; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_DEFERRAL; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU; import android.annotation.Nullable; import android.app.ActivityManager; @@ -29,6 +35,7 @@ import android.app.AppOpsManager; import android.app.BroadcastOptions; import android.app.IApplicationThread; import android.app.PendingIntent; +import android.app.RemoteServiceException.CannotDeliverBroadcastException; import android.app.usage.UsageEvents.Event; import android.content.ComponentName; import android.content.ContentResolver; @@ -603,7 +610,8 @@ public final class BroadcastQueue { synchronized (mService) { Slog.w(TAG, "Can't deliver broadcast to " + app.processName + " (pid " + app.getPid() + "). Crashing it."); - app.scheduleCrashLocked("can't deliver broadcast"); + app.scheduleCrashLocked("can't deliver broadcast", + CannotDeliverBroadcastException.TYPE_ID); } throw ex; } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 9e94d4aa2c0f..14ba7167f529 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -26,7 +26,6 @@ import android.app.ApplicationExitInfo; import android.app.ApplicationExitInfo.Reason; import android.app.ApplicationExitInfo.SubReason; import android.app.IApplicationThread; -import android.app.RemoteServiceException; import android.content.pm.ApplicationInfo; import android.content.pm.ProcessInfo; import android.content.pm.VersionedPackage; @@ -948,11 +947,6 @@ class ProcessRecord implements WindowProcessListener { return mServices.hasForegroundServices(); } - @GuardedBy("mService") - void scheduleCrashLocked(String message) { - scheduleCrashLocked(message, RemoteServiceException.TYPE_ID); - } - /** * Let an app process throw an exception on a binder thread, which typically crashes the * process, unless it has an unhandled exception handler. diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 17930ea9c93c..e36898fee387 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -28,6 +28,7 @@ import android.annotation.Nullable; import android.app.IApplicationThread; import android.app.Notification; import android.app.PendingIntent; +import android.app.RemoteServiceException.CannotPostForegroundServiceNotificationException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; @@ -1039,7 +1040,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN // If it gave us a garbage notification, it doesn't // get to be foreground. ams.mServices.killMisbehavingService(record, - appUid, appPid, localPackageName); + appUid, appPid, localPackageName, + CannotPostForegroundServiceNotificationException.TYPE_ID); } } }); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 47d8022a5acc..e597972a540b 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -149,6 +149,7 @@ import android.app.NotificationHistory.HistoricalNotification; import android.app.NotificationManager; import android.app.NotificationManager.Policy; import android.app.PendingIntent; +import android.app.RemoteServiceException.BadForegroundServiceNotificationException; import android.app.StatsManager; import android.app.StatusBarManager; import android.app.UriGrantsManager; @@ -1256,10 +1257,11 @@ public class NotificationManagerService extends SystemService { // Still crash for foreground services, preventing the not-crash behaviour abused // by apps to give us a garbage notification and silently start a fg service. Binder.withCleanCallingIdentity( - () -> mAm.crashApplication(uid, initialPid, pkg, -1, + () -> mAm.crashApplicationWithType(uid, initialPid, pkg, -1, "Bad notification(tag=" + tag + ", id=" + id + ") posted from package " + pkg + ", crashing app(uid=" + uid + ", pid=" + initialPid + "): " - + message, true /* force */)); + + message, true /* force */, + BadForegroundServiceNotificationException.TYPE_ID)); } } |