1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.app;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.content.ComponentName;
22 import android.os.Bundle;
23 import android.util.AndroidRuntimeException;
24 
25 /**
26  * Exception used by {@link ActivityThread} to crash an app process for an unknown cause.
27  * An exception of this class is no longer supposed to be thrown. Instead, we use fine-grained
28  * sub-exceptions.
29  *
30  * Subclasses must be registered in
31  * {@link android.app.ActivityThread#throwRemoteServiceException(java.lang.String, int)}.
32  *
33  * @hide
34  */
35 public class RemoteServiceException extends AndroidRuntimeException {
RemoteServiceException(String msg)36     public RemoteServiceException(String msg) {
37         super(msg);
38     }
39 
RemoteServiceException(String msg, Throwable cause)40     public RemoteServiceException(String msg, Throwable cause) {
41         super(msg, cause);
42     }
43 
44     /**
45      * Exception used to crash an app process when it didn't call {@link Service#startForeground}
46      * in time after the service was started with
47      * {@link android.content.Context#startForegroundService}.
48      *
49      * @hide
50      */
51     public static class ForegroundServiceDidNotStartInTimeException extends RemoteServiceException {
52         /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */
53         public static final int TYPE_ID = 1;
54 
55         private static final String KEY_SERVICE_CLASS_NAME = "serviceclassname";
56 
ForegroundServiceDidNotStartInTimeException(String msg, Throwable cause)57         public ForegroundServiceDidNotStartInTimeException(String msg, Throwable cause) {
58             super(msg, cause);
59         }
60 
createExtrasForService(@onNull ComponentName service)61         public static Bundle createExtrasForService(@NonNull ComponentName service) {
62             Bundle b = new Bundle();
63             b.putString(KEY_SERVICE_CLASS_NAME, service.getClassName());
64             return b;
65         }
66 
67         @Nullable
getServiceClassNameFromExtras(@ullable Bundle extras)68         public static String getServiceClassNameFromExtras(@Nullable Bundle extras) {
69             return (extras == null) ? null : extras.getString(KEY_SERVICE_CLASS_NAME);
70         }
71     }
72 
73     /**
74      * Exception used to crash an app process when it didn't stop after hitting its time limit.
75      *
76      * @hide
77      */
78     public static class ForegroundServiceDidNotStopInTimeException extends RemoteServiceException {
79         /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */
80         public static final int TYPE_ID = 7;
81 
82         private static final String KEY_SERVICE_CLASS_NAME = "serviceclassname";
83 
ForegroundServiceDidNotStopInTimeException(String msg, Throwable cause)84         public ForegroundServiceDidNotStopInTimeException(String msg, Throwable cause) {
85             super(msg, cause);
86         }
87 
createExtrasForService(@onNull ComponentName service)88         public static Bundle createExtrasForService(@NonNull ComponentName service) {
89             Bundle b = new Bundle();
90             b.putString(KEY_SERVICE_CLASS_NAME, service.getClassName());
91             return b;
92         }
93 
94         @Nullable
getServiceClassNameFromExtras(@ullable Bundle extras)95         public static String getServiceClassNameFromExtras(@Nullable Bundle extras) {
96             return (extras == null) ? null : extras.getString(KEY_SERVICE_CLASS_NAME);
97         }
98     }
99 
100     /**
101      * Exception used to crash an app process when the system received a RemoteException
102      * while posting a notification of a foreground service.
103      *
104      * @hide
105      */
106     public static class CannotPostForegroundServiceNotificationException
107             extends RemoteServiceException {
108         /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */
109         public static final int TYPE_ID = 2;
110 
CannotPostForegroundServiceNotificationException(String msg)111         public CannotPostForegroundServiceNotificationException(String msg) {
112             super(msg);
113         }
114     }
115 
116     /**
117      * Exception used to crash an app process when the system finds an error in a foreground service
118      * notification.
119      *
120      * @hide
121      */
122     public static class BadForegroundServiceNotificationException extends RemoteServiceException {
123         /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */
124         public static final int TYPE_ID = 3;
125 
BadForegroundServiceNotificationException(String msg)126         public BadForegroundServiceNotificationException(String msg) {
127             super(msg);
128         }
129     }
130 
131     /**
132      * Exception used to crash an app process when the system finds an error in a user-initiated job
133      * notification.
134      *
135      * @hide
136      */
137     public static class BadUserInitiatedJobNotificationException extends RemoteServiceException {
138         /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */
139         public static final int TYPE_ID = 6;
140 
BadUserInitiatedJobNotificationException(String msg)141         public BadUserInitiatedJobNotificationException(String msg) {
142             super(msg);
143         }
144     }
145 
146     /**
147      * Exception used to crash an app process when it calls a setting activity that requires
148      * the {@code REQUEST_PASSWORD_COMPLEXITY} permission.
149      *
150      * @hide
151      */
152     public static class MissingRequestPasswordComplexityPermissionException
153             extends RemoteServiceException {
154         /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */
155         public static final int TYPE_ID = 4;
156 
MissingRequestPasswordComplexityPermissionException(String msg)157         public MissingRequestPasswordComplexityPermissionException(String msg) {
158             super(msg);
159         }
160     }
161 
162     /**
163      * Exception used to crash an app process by {@code adb shell am crash}.
164      *
165      * @hide
166      */
167     public static class CrashedByAdbException extends RemoteServiceException {
168         /** The type ID passed to {@link IApplicationThread#scheduleCrash}. */
169         public static final int TYPE_ID = 5;
170 
CrashedByAdbException(String msg)171         public CrashedByAdbException(String msg) {
172             super(msg);
173         }
174     }
175 }
176