blob: 040ad062e5121fe519343bda74e1fc7f039c736f [file] [log] [blame]
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001/*
2 * Copyright (C) 2012 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
17package android.app;
18
Svet Ganov16a16892015-04-16 10:32:04 -070019import android.Manifest;
Svet Ganovad0a49b2018-10-29 10:07:08 -070020import android.annotation.IntDef;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080021import android.annotation.NonNull;
Hai Zhangb7776682018-09-25 15:10:57 -070022import android.annotation.Nullable;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060023import android.annotation.RequiresPermission;
Jeff Davidson05542602014-08-11 14:07:27 -070024import android.annotation.SystemApi;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060025import android.annotation.SystemService;
Peter Visontay5a2a1ef2017-12-18 20:34:03 +000026import android.annotation.TestApi;
Mathew Inwood61e8ae62018-08-14 14:17:44 +010027import android.annotation.UnsupportedAppUsage;
Jeff Davidson05542602014-08-11 14:07:27 -070028import android.app.usage.UsageStatsManager;
29import android.content.Context;
Ng Zhi An65a99b62018-10-01 11:57:53 -070030import android.content.pm.PackageManager;
Svet Ganovad0a49b2018-10-29 10:07:08 -070031import android.content.pm.ParceledListSlice;
Svet Ganov55203682018-11-02 22:34:52 -070032import android.database.ContentObserver;
John Spurlock7b414672014-07-18 13:02:39 -040033import android.media.AudioAttributes.AttributeUsage;
Svet Ganov55203682018-11-02 22:34:52 -070034import android.net.Uri;
Dianne Hackborne98f5db2013-07-17 17:23:25 -070035import android.os.Binder;
36import android.os.IBinder;
Dianne Hackborn35654b62013-01-14 17:38:02 -080037import android.os.Parcel;
38import android.os.Parcelable;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080039import android.os.Process;
Svet Ganov8455ba22019-01-02 13:05:56 -080040import android.os.RemoteCallback;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080041import android.os.RemoteException;
Chad Brubaker7c6dba62019-01-23 15:51:43 -080042import android.os.SystemProperties;
Jeff Davidson05542602014-08-11 14:07:27 -070043import android.os.UserManager;
Svet Ganov55203682018-11-02 22:34:52 -070044import android.provider.Settings;
Jeff Davidson05542602014-08-11 14:07:27 -070045import android.util.ArrayMap;
Ng Zhi An65a99b62018-10-01 11:57:53 -070046import android.util.SparseArray;
Jeff Davidson05542602014-08-11 14:07:27 -070047
Svet Ganovb3d2ae22018-12-17 22:06:15 -080048import com.android.internal.annotations.GuardedBy;
Svet Ganov23c88db2019-01-22 20:38:11 -080049
50import com.android.internal.annotations.Immutable;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080051import com.android.internal.app.IAppOpsActiveCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070052import com.android.internal.app.IAppOpsCallback;
Svet Ganovb3d2ae22018-12-17 22:06:15 -080053import com.android.internal.app.IAppOpsNotedCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070054import com.android.internal.app.IAppOpsService;
Svet Ganov8455ba22019-01-02 13:05:56 -080055import com.android.internal.util.ArrayUtils;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080056import com.android.internal.util.Preconditions;
Jeff Davidson05542602014-08-11 14:07:27 -070057
Svet Ganovad0a49b2018-10-29 10:07:08 -070058import java.lang.annotation.Retention;
59import java.lang.annotation.RetentionPolicy;
Svet Ganov8455ba22019-01-02 13:05:56 -080060import java.math.BigDecimal;
61import java.math.RoundingMode;
Jeff Davidson05542602014-08-11 14:07:27 -070062import java.util.ArrayList;
Peter Visontay5a2a1ef2017-12-18 20:34:03 +000063import java.util.Arrays;
Svet Ganovad0a49b2018-10-29 10:07:08 -070064import java.util.Collections;
Jeff Davidson05542602014-08-11 14:07:27 -070065import java.util.HashMap;
66import java.util.List;
Svet Ganov8455ba22019-01-02 13:05:56 -080067import java.util.concurrent.Executor;
Ng Zhi An65a99b62018-10-01 11:57:53 -070068import java.util.concurrent.atomic.AtomicInteger;
Svet Ganov8455ba22019-01-02 13:05:56 -080069import java.util.function.Consumer;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080070
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080071/**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070072 * API for interacting with "application operation" tracking.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080073 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070074 * <p>This API is not generally intended for third party application developers; most
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060075 * features are only available to system applications.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080076 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060077@SystemService(Context.APP_OPS_SERVICE)
Dianne Hackborna06de0f2012-12-11 16:34:47 -080078public class AppOpsManager {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070079 /**
80 * <p>App ops allows callers to:</p>
81 *
82 * <ul>
83 * <li> Note when operations are happening, and find out if they are allowed for the current
84 * caller.</li>
85 * <li> Disallow specific apps from doing specific operations.</li>
86 * <li> Collect all of the current information about operations that have been executed or
87 * are not being allowed.</li>
88 * <li> Monitor for changes in whether an operation is allowed.</li>
89 * </ul>
90 *
91 * <p>Each operation is identified by a single integer; these integers are a fixed set of
92 * operations, enumerated by the OP_* constants.
93 *
94 * <p></p>When checking operations, the result is a "mode" integer indicating the current
95 * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
96 * the operation but fake its behavior enough so that the caller doesn't crash),
97 * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
98 * will do this for you).
99 */
100
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800101 final Context mContext;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800102
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100103 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800104 final IAppOpsService mService;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800105
106 @GuardedBy("mModeWatchers")
107 private final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers =
108 new ArrayMap<>();
109
110 @GuardedBy("mActiveWatchers")
111 private final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers =
112 new ArrayMap<>();
113
114 @GuardedBy("mNotedWatchers")
115 private final ArrayMap<OnOpNotedListener, IAppOpsNotedCallback> mNotedWatchers =
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -0800116 new ArrayMap<>();
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800117
Dianne Hackborne98f5db2013-07-17 17:23:25 -0700118 static IBinder sToken;
119
Svet Ganov8455ba22019-01-02 13:05:56 -0800120 /** @hide */
121 @Retention(RetentionPolicy.SOURCE)
122 @IntDef(flag = true, prefix = { "HISTORICAL_MODE_" }, value = {
123 HISTORICAL_MODE_DISABLED,
124 HISTORICAL_MODE_ENABLED_ACTIVE,
125 HISTORICAL_MODE_ENABLED_PASSIVE
126 })
127 public @interface HistoricalMode {}
128
129 /**
130 * Mode in which app op history is completely disabled.
131 * @hide
132 */
133 @TestApi
134 public static final int HISTORICAL_MODE_DISABLED = 0;
135
136 /**
137 * Mode in which app op history is enabled and app ops performed by apps would
138 * be tracked. This is the mode in which the feature is completely enabled.
139 * @hide
140 */
141 @TestApi
142 public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1;
143
144 /**
145 * Mode in which app op history is enabled but app ops performed by apps would
146 * not be tracked and the only way to add ops to the history is via explicit calls
147 * to dedicated APIs. This mode is useful for testing to allow full control of
148 * the historical content.
149 * @hide
150 */
151 @TestApi
152 public static final int HISTORICAL_MODE_ENABLED_PASSIVE = 2;
153
154 /** @hide */
155 @Retention(RetentionPolicy.SOURCE)
156 @IntDef(flag = true, prefix = { "MODE_" }, value = {
157 MODE_ALLOWED,
158 MODE_IGNORED,
159 MODE_ERRORED,
160 MODE_DEFAULT,
161 MODE_FOREGROUND
162 })
163 public @interface Mode {}
164
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700165 /**
166 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
167 * allowed to perform the given operation.
168 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800169 public static final int MODE_ALLOWED = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700170
171 /**
172 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
173 * not allowed to perform the given operation, and this attempt should
174 * <em>silently fail</em> (it should not cause the app to crash).
175 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800176 public static final int MODE_IGNORED = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700177
178 /**
179 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
180 * given caller is not allowed to perform the given operation, and this attempt should
181 * cause it to have a fatal error, typically a {@link SecurityException}.
182 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800183 public static final int MODE_ERRORED = 2;
184
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -0700185 /**
186 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
187 * use its default security check. This mode is not normally used; it should only be used
188 * with appop permissions, and callers must explicitly check for it and deal with it.
189 */
190 public static final int MODE_DEFAULT = 3;
191
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700192 /**
Dianne Hackbornc216a262018-04-26 13:46:22 -0700193 * Special mode that means "allow only when app is in foreground." This is <b>not</b>
Dianne Hackbornf8709f52019-02-04 16:31:24 -0800194 * returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}. Rather,
195 * {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always
196 * possible for it to be ultimately allowed, depending on the app's background state),
197 * and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app
198 * being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}.
199 *
200 * <p>The only place you will this normally see this value is through
201 * {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op. Note that because
202 * you can't know the current state of the app being checked (and it can change at any
203 * point), you can only treat the result here as an indication that it will vary between
204 * {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background
205 * state of the app. You thus must always use {@link #noteOp} or {@link #startOp} to do
206 * the actual check for access to the op.</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -0700207 */
208 public static final int MODE_FOREGROUND = 4;
209
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700210 /**
211 * Flag for {@link #startWatchingMode(String, String, int, OnOpChangedListener)}:
212 * Also get reports if the foreground state of an op's uid changes. This only works
213 * when watching a particular op, not when watching a package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700214 */
215 public static final int WATCH_FOREGROUND_CHANGES = 1 << 0;
Dianne Hackbornc216a262018-04-26 13:46:22 -0700216
217 /**
218 * @hide
219 */
220 public static final String[] MODE_NAMES = new String[] {
221 "allow", // MODE_ALLOWED
222 "ignore", // MODE_IGNORED
223 "deny", // MODE_ERRORED
224 "default", // MODE_DEFAULT
225 "foreground", // MODE_FOREGROUND
226 };
227
Svet Ganovad0a49b2018-10-29 10:07:08 -0700228 /** @hide */
229 @Retention(RetentionPolicy.SOURCE)
230 @IntDef(flag = true, prefix = { "UID_STATE_" }, value = {
231 UID_STATE_PERSISTENT,
232 UID_STATE_TOP,
Amith Yamasania0a30a12019-01-22 11:38:06 -0800233 UID_STATE_FOREGROUND_SERVICE_LOCATION,
Svet Ganovad0a49b2018-10-29 10:07:08 -0700234 UID_STATE_FOREGROUND_SERVICE,
235 UID_STATE_FOREGROUND,
236 UID_STATE_BACKGROUND,
237 UID_STATE_CACHED
238 })
239 public @interface UidState {}
240
Dianne Hackbornc216a262018-04-26 13:46:22 -0700241 /**
Svet Ganov8455ba22019-01-02 13:05:56 -0800242 * Invalid UID state.
243 * @hide
244 */
245 public static final int UID_STATE_INVALID = -1;
246
247 /**
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700248 * Metrics about an op when its uid is persistent.
249 * @hide
250 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800251 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700252 @SystemApi
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700253 public static final int UID_STATE_PERSISTENT = 0;
254
255 /**
256 * Metrics about an op when its uid is at the top.
257 * @hide
258 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800259 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700260 @SystemApi
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700261 public static final int UID_STATE_TOP = 1;
262
263 /**
Amith Yamasania0a30a12019-01-22 11:38:06 -0800264 * Metrics about an op when its uid is running a foreground service with location type.
265 * @hide
266 */
267 @TestApi
268 @SystemApi
269 public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 2;
270
271 /**
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700272 * Metrics about an op when its uid is running a foreground service.
273 * @hide
274 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800275 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700276 @SystemApi
Amith Yamasania0a30a12019-01-22 11:38:06 -0800277 public static final int UID_STATE_FOREGROUND_SERVICE = 3;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700278
279 /**
Dianne Hackborne93ab412018-05-14 17:52:30 -0700280 * Last UID state in which we don't restrict what an op can do.
281 * @hide
282 */
Amith Yamasania0a30a12019-01-22 11:38:06 -0800283 public static final int UID_STATE_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE_LOCATION;
Dianne Hackborne93ab412018-05-14 17:52:30 -0700284
285 /**
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700286 * Metrics about an op when its uid is in the foreground for any other reasons.
287 * @hide
288 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800289 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700290 @SystemApi
Amith Yamasania0a30a12019-01-22 11:38:06 -0800291 public static final int UID_STATE_FOREGROUND = 4;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700292
293 /**
294 * Metrics about an op when its uid is in the background for any reason.
295 * @hide
296 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800297 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700298 @SystemApi
Amith Yamasania0a30a12019-01-22 11:38:06 -0800299 public static final int UID_STATE_BACKGROUND = 5;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700300
301 /**
302 * Metrics about an op when its uid is cached.
303 * @hide
304 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800305 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700306 @SystemApi
Amith Yamasania0a30a12019-01-22 11:38:06 -0800307 public static final int UID_STATE_CACHED = 6;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700308
309 /**
310 * Number of uid states we track.
311 * @hide
312 */
Amith Yamasania0a30a12019-01-22 11:38:06 -0800313 public static final int _NUM_UID_STATE = 7;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700314
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500315 // when adding one of these:
316 // - increment _NUM_OP
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000317 // - define an OPSTR_* constant (marked as @SystemApi)
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700318 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500319 // - add descriptive strings to Settings/res/values/arrays.xml
David Christie0b837452013-07-29 16:02:13 -0700320 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700321
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700322 /** @hide No operation specified. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100323 @UnsupportedAppUsage
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800324 public static final int OP_NONE = -1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700325 /** @hide Access to coarse location information. */
Svet Ganov8455ba22019-01-02 13:05:56 -0800326 @TestApi
Dianne Hackborn35654b62013-01-14 17:38:02 -0800327 public static final int OP_COARSE_LOCATION = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700328 /** @hide Access to fine location information. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100329 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800330 public static final int OP_FINE_LOCATION = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700331 /** @hide Causing GPS to run. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100332 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800333 public static final int OP_GPS = 2;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800334 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100335 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700336 public static final int OP_VIBRATE = 3;
337 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100338 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700339 public static final int OP_READ_CONTACTS = 4;
340 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100341 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700342 public static final int OP_WRITE_CONTACTS = 5;
343 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100344 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700345 public static final int OP_READ_CALL_LOG = 6;
346 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100347 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700348 public static final int OP_WRITE_CALL_LOG = 7;
349 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100350 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700351 public static final int OP_READ_CALENDAR = 8;
352 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100353 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700354 public static final int OP_WRITE_CALENDAR = 9;
355 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100356 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700357 public static final int OP_WIFI_SCAN = 10;
358 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100359 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700360 public static final int OP_POST_NOTIFICATION = 11;
361 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100362 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700363 public static final int OP_NEIGHBORING_CELLS = 12;
364 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100365 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700366 public static final int OP_CALL_PHONE = 13;
367 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100368 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700369 public static final int OP_READ_SMS = 14;
370 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100371 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700372 public static final int OP_WRITE_SMS = 15;
373 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100374 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700375 public static final int OP_RECEIVE_SMS = 16;
376 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100377 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700378 public static final int OP_RECEIVE_EMERGECY_SMS = 17;
379 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100380 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700381 public static final int OP_RECEIVE_MMS = 18;
382 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100383 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700384 public static final int OP_RECEIVE_WAP_PUSH = 19;
385 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100386 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700387 public static final int OP_SEND_SMS = 20;
388 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100389 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700390 public static final int OP_READ_ICC_SMS = 21;
391 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100392 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700393 public static final int OP_WRITE_ICC_SMS = 22;
394 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100395 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700396 public static final int OP_WRITE_SETTINGS = 23;
Peter Visontay96449f62017-12-11 18:50:03 +0000397 /** @hide Required to draw on top of other apps. */
Svet Ganovf7b47252018-02-26 11:11:27 -0800398 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700399 public static final int OP_SYSTEM_ALERT_WINDOW = 24;
400 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100401 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700402 public static final int OP_ACCESS_NOTIFICATIONS = 25;
403 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100404 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700405 public static final int OP_CAMERA = 26;
406 /** @hide */
Svet Ganova7a0db62018-02-27 20:08:01 -0800407 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700408 public static final int OP_RECORD_AUDIO = 27;
409 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100410 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700411 public static final int OP_PLAY_AUDIO = 28;
412 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100413 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700414 public static final int OP_READ_CLIPBOARD = 29;
415 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100416 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700417 public static final int OP_WRITE_CLIPBOARD = 30;
418 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100419 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700420 public static final int OP_TAKE_MEDIA_BUTTONS = 31;
421 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100422 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700423 public static final int OP_TAKE_AUDIO_FOCUS = 32;
424 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100425 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700426 public static final int OP_AUDIO_MASTER_VOLUME = 33;
427 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100428 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700429 public static final int OP_AUDIO_VOICE_VOLUME = 34;
430 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100431 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700432 public static final int OP_AUDIO_RING_VOLUME = 35;
433 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100434 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700435 public static final int OP_AUDIO_MEDIA_VOLUME = 36;
436 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100437 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700438 public static final int OP_AUDIO_ALARM_VOLUME = 37;
439 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100440 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700441 public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
442 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100443 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700444 public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
445 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100446 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700447 public static final int OP_WAKE_LOCK = 40;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700448 /** @hide Continually monitoring location data. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100449 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700450 public static final int OP_MONITOR_LOCATION = 41;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700451 /** @hide Continually monitoring location data with a relatively high power request. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100452 @UnsupportedAppUsage
David Christie0b837452013-07-29 16:02:13 -0700453 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700454 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100455 @UnsupportedAppUsage
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700456 public static final int OP_GET_USAGE_STATS = 43;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700457 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100458 @UnsupportedAppUsage
Emily Bernier22c921a2014-05-28 11:01:32 -0400459 public static final int OP_MUTE_MICROPHONE = 44;
460 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100461 @UnsupportedAppUsage
Jason Monk1c7c3192014-06-26 12:52:18 -0400462 public static final int OP_TOAST_WINDOW = 45;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700463 /** @hide Capture the device's display contents and/or audio */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100464 @UnsupportedAppUsage
Michael Wrightc39d47a2014-07-08 18:07:36 -0700465 public static final int OP_PROJECT_MEDIA = 46;
Jeff Davidson05542602014-08-11 14:07:27 -0700466 /** @hide Activate a VPN connection without user intervention. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100467 @UnsupportedAppUsage
Jeff Davidson05542602014-08-11 14:07:27 -0700468 public static final int OP_ACTIVATE_VPN = 47;
Benjamin Franzf3ece362015-02-11 10:51:10 +0000469 /** @hide Access the WallpaperManagerAPI to write wallpapers. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100470 @UnsupportedAppUsage
Benjamin Franzf3ece362015-02-11 10:51:10 +0000471 public static final int OP_WRITE_WALLPAPER = 48;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700472 /** @hide Received the assist structure from an app. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100473 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700474 public static final int OP_ASSIST_STRUCTURE = 49;
475 /** @hide Received a screenshot from assist. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100476 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700477 public static final int OP_ASSIST_SCREENSHOT = 50;
Svet Ganov16a16892015-04-16 10:32:04 -0700478 /** @hide Read the phone state. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100479 @UnsupportedAppUsage
Svet Ganov16a16892015-04-16 10:32:04 -0700480 public static final int OP_READ_PHONE_STATE = 51;
Svet Ganovc3300092015-04-17 09:07:22 -0700481 /** @hide Add voicemail messages to the voicemail content provider. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100482 @UnsupportedAppUsage
Svet Ganovc3300092015-04-17 09:07:22 -0700483 public static final int OP_ADD_VOICEMAIL = 52;
Svetoslav5335b672015-04-29 12:00:51 -0700484 /** @hide Access APIs for SIP calling over VOIP or WiFi. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100485 @UnsupportedAppUsage
Svetoslav5335b672015-04-29 12:00:51 -0700486 public static final int OP_USE_SIP = 53;
Svetoslavc656e6f2015-04-29 14:08:16 -0700487 /** @hide Intercept outgoing calls. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100488 @UnsupportedAppUsage
Svetoslavc656e6f2015-04-29 14:08:16 -0700489 public static final int OP_PROCESS_OUTGOING_CALLS = 54;
Svetoslav4af76a52015-04-29 15:29:46 -0700490 /** @hide User the fingerprint API. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100491 @UnsupportedAppUsage
Svetoslav4af76a52015-04-29 15:29:46 -0700492 public static final int OP_USE_FINGERPRINT = 55;
Svet Ganovb9d71a62015-04-30 10:38:13 -0700493 /** @hide Access to body sensors such as heart rate, etc. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100494 @UnsupportedAppUsage
Svet Ganovb9d71a62015-04-30 10:38:13 -0700495 public static final int OP_BODY_SENSORS = 56;
Svet Ganovede43162015-05-02 17:42:44 -0700496 /** @hide Read previously received cell broadcast messages. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100497 @UnsupportedAppUsage
Svet Ganovede43162015-05-02 17:42:44 -0700498 public static final int OP_READ_CELL_BROADCASTS = 57;
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700499 /** @hide Inject mock location into the system. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100500 @UnsupportedAppUsage
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700501 public static final int OP_MOCK_LOCATION = 58;
Svet Ganov921c7df2015-06-29 21:51:41 -0700502 /** @hide Read external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100503 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700504 public static final int OP_READ_EXTERNAL_STORAGE = 59;
505 /** @hide Write external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100506 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700507 public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700508 /** @hide Turned on the screen. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100509 @UnsupportedAppUsage
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700510 public static final int OP_TURN_SCREEN_ON = 61;
Svetoslavf3f02ac2015-09-08 14:36:35 -0700511 /** @hide Get device accounts. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100512 @UnsupportedAppUsage
Svetoslavf3f02ac2015-09-08 14:36:35 -0700513 public static final int OP_GET_ACCOUNTS = 62;
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700514 /** @hide Control whether an application is allowed to run in the background. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100515 @UnsupportedAppUsage
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700516 public static final int OP_RUN_IN_BACKGROUND = 63;
Jason Monk1c7c3192014-06-26 12:52:18 -0400517 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100518 @UnsupportedAppUsage
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800519 public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800520 /** @hide Read the phone number. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100521 @UnsupportedAppUsage
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700522 public static final int OP_READ_PHONE_NUMBERS = 65;
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800523 /** @hide Request package installs through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100524 @UnsupportedAppUsage
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800525 public static final int OP_REQUEST_INSTALL_PACKAGES = 66;
Winson Chungf4ac0632017-03-17 12:34:12 -0700526 /** @hide Enter picture-in-picture. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100527 @UnsupportedAppUsage
Winson Chungf4ac0632017-03-17 12:34:12 -0700528 public static final int OP_PICTURE_IN_PICTURE = 67;
Chad Brubaker97b383f2017-02-02 15:04:35 -0800529 /** @hide Instant app start foreground service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100530 @UnsupportedAppUsage
Chad Brubaker97b383f2017-02-02 15:04:35 -0800531 public static final int OP_INSTANT_APP_START_FOREGROUND = 68;
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800532 /** @hide Answer incoming phone calls */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100533 @UnsupportedAppUsage
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800534 public static final int OP_ANSWER_PHONE_CALLS = 69;
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700535 /** @hide Run jobs when in background */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100536 @UnsupportedAppUsage
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700537 public static final int OP_RUN_ANY_IN_BACKGROUND = 70;
Peter Visontay1246d9e2017-10-17 17:02:45 +0100538 /** @hide Change Wi-Fi connectivity state */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100539 @UnsupportedAppUsage
Peter Visontay1246d9e2017-10-17 17:02:45 +0100540 public static final int OP_CHANGE_WIFI_STATE = 71;
Peter Visontayf2e38362017-11-27 15:27:16 +0000541 /** @hide Request package deletion through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100542 @UnsupportedAppUsage
Peter Visontayf2e38362017-11-27 15:27:16 +0000543 public static final int OP_REQUEST_DELETE_PACKAGES = 72;
Peter Visontay11950832017-11-14 19:34:59 +0000544 /** @hide Bind an accessibility service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100545 @UnsupportedAppUsage
Peter Visontay11950832017-11-14 19:34:59 +0000546 public static final int OP_BIND_ACCESSIBILITY_SERVICE = 73;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800547 /** @hide Continue handover of a call from another app */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100548 @UnsupportedAppUsage
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800549 public static final int OP_ACCEPT_HANDOVER = 74;
Nathan Harold1bb420672018-03-14 17:08:53 -0700550 /** @hide Create and Manage IPsec Tunnels */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100551 @UnsupportedAppUsage
Nathan Harold1bb420672018-03-14 17:08:53 -0700552 public static final int OP_MANAGE_IPSEC_TUNNELS = 75;
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700553 /** @hide Any app start foreground service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100554 @UnsupportedAppUsage
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700555 public static final int OP_START_FOREGROUND = 76;
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800556 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100557 @UnsupportedAppUsage
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700558 public static final int OP_BLUETOOTH_SCAN = 77;
Kevin Chynb3c05aa2018-09-21 16:50:32 -0700559 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
560 public static final int OP_USE_BIOMETRIC = 78;
Zimuzo6cbf9cc2018-10-05 12:05:58 +0100561 /** @hide Physical activity recognition. */
562 public static final int OP_ACTIVITY_RECOGNITION = 79;
Hongming Jin228cd012018-11-09 14:47:50 -0800563 /** @hide Financial app sms read. */
564 public static final int OP_SMS_FINANCIAL_TRANSACTIONS = 80;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -0700565 /** @hide Read media of audio type. */
566 public static final int OP_READ_MEDIA_AUDIO = 81;
567 /** @hide Write media of audio type. */
568 public static final int OP_WRITE_MEDIA_AUDIO = 82;
569 /** @hide Read media of video type. */
570 public static final int OP_READ_MEDIA_VIDEO = 83;
571 /** @hide Write media of video type. */
572 public static final int OP_WRITE_MEDIA_VIDEO = 84;
573 /** @hide Read media of image type. */
574 public static final int OP_READ_MEDIA_IMAGES = 85;
575 /** @hide Write media of image type. */
576 public static final int OP_WRITE_MEDIA_IMAGES = 86;
Jeff Sharkeye82cbb12018-12-06 15:53:11 -0700577 /** @hide Has a legacy (non-isolated) view of storage. */
578 public static final int OP_LEGACY_STORAGE = 87;
Jackal Guo8dc791e2019-01-14 10:26:42 +0800579 /** @hide Accessing accessibility features */
580 public static final int OP_ACCESS_ACCESSIBILITY = 88;
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700581 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100582 @UnsupportedAppUsage
Jackal Guo8dc791e2019-01-14 10:26:42 +0800583 public static final int _NUM_OP = 89;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800584
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700585 /** Access to coarse location information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700586 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700587 /** Access to fine location information. */
588 public static final String OPSTR_FINE_LOCATION =
589 "android:fine_location";
590 /** Continually monitoring location data. */
591 public static final String OPSTR_MONITOR_LOCATION
592 = "android:monitor_location";
593 /** Continually monitoring location data with a relatively high power request. */
594 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
595 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700596 /** Access to {@link android.app.usage.UsageStatsManager}. */
597 public static final String OPSTR_GET_USAGE_STATS
598 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700599 /** Activate a VPN connection without user intervention. @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000600 @SystemApi @TestApi
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700601 public static final String OPSTR_ACTIVATE_VPN
602 = "android:activate_vpn";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700603 /** Allows an application to read the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700604 public static final String OPSTR_READ_CONTACTS
605 = "android:read_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700606 /** Allows an application to write to the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700607 public static final String OPSTR_WRITE_CONTACTS
608 = "android:write_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700609 /** Allows an application to read the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700610 public static final String OPSTR_READ_CALL_LOG
611 = "android:read_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700612 /** Allows an application to write to the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700613 public static final String OPSTR_WRITE_CALL_LOG
614 = "android:write_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700615 /** Allows an application to read the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700616 public static final String OPSTR_READ_CALENDAR
617 = "android:read_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700618 /** Allows an application to write to the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700619 public static final String OPSTR_WRITE_CALENDAR
620 = "android:write_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700621 /** Allows an application to initiate a phone call. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700622 public static final String OPSTR_CALL_PHONE
623 = "android:call_phone";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700624 /** Allows an application to read SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700625 public static final String OPSTR_READ_SMS
626 = "android:read_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700627 /** Allows an application to receive SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700628 public static final String OPSTR_RECEIVE_SMS
629 = "android:receive_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700630 /** Allows an application to receive MMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700631 public static final String OPSTR_RECEIVE_MMS
632 = "android:receive_mms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700633 /** Allows an application to receive WAP push messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700634 public static final String OPSTR_RECEIVE_WAP_PUSH
635 = "android:receive_wap_push";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700636 /** Allows an application to send SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700637 public static final String OPSTR_SEND_SMS
638 = "android:send_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700639 /** Required to be able to access the camera device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700640 public static final String OPSTR_CAMERA
641 = "android:camera";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700642 /** Required to be able to access the microphone device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700643 public static final String OPSTR_RECORD_AUDIO
644 = "android:record_audio";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700645 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700646 public static final String OPSTR_READ_PHONE_STATE
647 = "android:read_phone_state";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700648 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700649 public static final String OPSTR_ADD_VOICEMAIL
650 = "android:add_voicemail";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700651 /** Access APIs for SIP calling over VOIP or WiFi */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700652 public static final String OPSTR_USE_SIP
653 = "android:use_sip";
Svet Ganove8e89422016-09-22 19:56:50 -0700654 /** Access APIs for diverting outgoing calls */
Svet Ganov824ad6e2016-09-22 19:36:53 -0700655 public static final String OPSTR_PROCESS_OUTGOING_CALLS
656 = "android:process_outgoing_calls";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700657 /** Use the fingerprint API. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700658 public static final String OPSTR_USE_FINGERPRINT
659 = "android:use_fingerprint";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700660 /** Access to body sensors such as heart rate, etc. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700661 public static final String OPSTR_BODY_SENSORS
662 = "android:body_sensors";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700663 /** Read previously received cell broadcast messages. */
Svet Ganovede43162015-05-02 17:42:44 -0700664 public static final String OPSTR_READ_CELL_BROADCASTS
665 = "android:read_cell_broadcasts";
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700666 /** Inject mock location into the system. */
667 public static final String OPSTR_MOCK_LOCATION
668 = "android:mock_location";
Svet Ganov921c7df2015-06-29 21:51:41 -0700669 /** Read external storage. */
670 public static final String OPSTR_READ_EXTERNAL_STORAGE
671 = "android:read_external_storage";
672 /** Write external storage. */
673 public static final String OPSTR_WRITE_EXTERNAL_STORAGE
674 = "android:write_external_storage";
Billy Lau24b9c832015-07-20 17:34:09 +0100675 /** Required to draw on top of other apps. */
676 public static final String OPSTR_SYSTEM_ALERT_WINDOW
677 = "android:system_alert_window";
678 /** Required to write/modify/update system settingss. */
679 public static final String OPSTR_WRITE_SETTINGS
680 = "android:write_settings";
Svetoslavf3f02ac2015-09-08 14:36:35 -0700681 /** @hide Get device accounts. */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000682 @SystemApi @TestApi
Svetoslavf3f02ac2015-09-08 14:36:35 -0700683 public static final String OPSTR_GET_ACCOUNTS
684 = "android:get_accounts";
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700685 public static final String OPSTR_READ_PHONE_NUMBERS
686 = "android:read_phone_numbers";
Winson Chungf4ac0632017-03-17 12:34:12 -0700687 /** Access to picture-in-picture. */
688 public static final String OPSTR_PICTURE_IN_PICTURE
689 = "android:picture_in_picture";
Chad Brubaker97b383f2017-02-02 15:04:35 -0800690 /** @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000691 @SystemApi @TestApi
Chad Brubaker97b383f2017-02-02 15:04:35 -0800692 public static final String OPSTR_INSTANT_APP_START_FOREGROUND
693 = "android:instant_app_start_foreground";
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800694 /** Answer incoming phone calls */
695 public static final String OPSTR_ANSWER_PHONE_CALLS
696 = "android:answer_phone_calls";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800697 /**
698 * Accept call handover
699 * @hide
700 */
701 @SystemApi @TestApi
702 public static final String OPSTR_ACCEPT_HANDOVER
703 = "android:accept_handover";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000704 /** @hide */
705 @SystemApi @TestApi
706 public static final String OPSTR_GPS = "android:gps";
707 /** @hide */
708 @SystemApi @TestApi
709 public static final String OPSTR_VIBRATE = "android:vibrate";
710 /** @hide */
711 @SystemApi @TestApi
712 public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
713 /** @hide */
714 @SystemApi @TestApi
715 public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
716 /** @hide */
717 @SystemApi @TestApi
718 public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
719 /** @hide */
720 @SystemApi @TestApi
721 public static final String OPSTR_WRITE_SMS = "android:write_sms";
722 /** @hide */
723 @SystemApi @TestApi
724 public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST =
725 "android:receive_emergency_broadcast";
726 /** @hide */
727 @SystemApi @TestApi
728 public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
729 /** @hide */
730 @SystemApi @TestApi
731 public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
732 /** @hide */
733 @SystemApi @TestApi
734 public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
735 /** @hide */
736 @SystemApi @TestApi
737 public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
738 /** @hide */
739 @SystemApi @TestApi
740 public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
741 /** @hide */
742 @SystemApi @TestApi
743 public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
744 /** @hide */
745 @SystemApi @TestApi
746 public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
747 /** @hide */
748 @SystemApi @TestApi
749 public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
750 /** @hide */
751 @SystemApi @TestApi
752 public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
753 /** @hide */
754 @SystemApi @TestApi
755 public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
756 /** @hide */
757 @SystemApi @TestApi
758 public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
759 /** @hide */
760 @SystemApi @TestApi
761 public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
762 /** @hide */
763 @SystemApi @TestApi
764 public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
765 /** @hide */
766 @SystemApi @TestApi
767 public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME =
768 "android:audio_notification_volume";
769 /** @hide */
770 @SystemApi @TestApi
771 public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
772 /** @hide */
773 @SystemApi @TestApi
774 public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
775 /** @hide */
776 @SystemApi @TestApi
777 public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
778 /** @hide */
779 @SystemApi @TestApi
780 public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
781 /** @hide */
782 @SystemApi @TestApi
783 public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
784 /** @hide */
785 @SystemApi @TestApi
786 public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
787 /** @hide */
788 @SystemApi @TestApi
789 public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
790 /** @hide */
791 @SystemApi @TestApi
792 public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
793 /** @hide */
794 @SystemApi @TestApi
795 public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
796 /** @hide */
797 @SystemApi @TestApi
798 public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
799 /** @hide */
800 @SystemApi @TestApi
801 public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME =
802 "android:audio_accessibility_volume";
803 /** @hide */
804 @SystemApi @TestApi
805 public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
806 /** @hide */
807 @SystemApi @TestApi
808 public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
809 /** @hide */
810 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +0000811 public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000812 /** @hide */
813 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +0000814 public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000815 /** @hide */
816 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +0000817 public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE =
818 "android:bind_accessibility_service";
Nathan Harold1bb420672018-03-14 17:08:53 -0700819 /** @hide */
820 @SystemApi @TestApi
821 public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700822 /** @hide */
823 @SystemApi @TestApi
824 public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700825 /** @hide */
826 public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000827
Kevin Chynb3c05aa2018-09-21 16:50:32 -0700828 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
829 public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200830
Zimuzo6cbf9cc2018-10-05 12:05:58 +0100831 /** @hide Recognize physical activity. */
832 public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition";
833
Hongming Jin228cd012018-11-09 14:47:50 -0800834 /** @hide Financial app read sms. */
835 public static final String OPSTR_SMS_FINANCIAL_TRANSACTIONS =
836 "android:sms_financial_transactions";
837
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -0700838 /** @hide Read media of audio type. */
839 public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
840 /** @hide Write media of audio type. */
841 public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
842 /** @hide Read media of video type. */
843 public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
844 /** @hide Write media of video type. */
845 public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
846 /** @hide Read media of image type. */
847 public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
848 /** @hide Write media of image type. */
849 public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
Jeff Sharkeye82cbb12018-12-06 15:53:11 -0700850 /** @hide Has a legacy (non-isolated) view of storage. */
851 public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
Jackal Guo8dc791e2019-01-14 10:26:42 +0800852 /** @hide Interact with accessibility. */
Joel Galensonff4fe202019-02-06 14:43:58 -0800853 @SystemApi
Jackal Guo8dc791e2019-01-14 10:26:42 +0800854 public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -0700855
Philip P. Moltmanne56c08e2017-03-15 12:46:04 -0700856 // Warning: If an permission is added here it also has to be added to
857 // com.android.packageinstaller.permission.utils.EventLogger
Svet Ganovda0acdf2017-02-15 10:28:51 -0800858 private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
859 // RUNTIME PERMISSIONS
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700860 // Contacts
861 OP_READ_CONTACTS,
862 OP_WRITE_CONTACTS,
863 OP_GET_ACCOUNTS,
864 // Calendar
865 OP_READ_CALENDAR,
866 OP_WRITE_CALENDAR,
867 // SMS
868 OP_SEND_SMS,
869 OP_RECEIVE_SMS,
870 OP_READ_SMS,
871 OP_RECEIVE_WAP_PUSH,
872 OP_RECEIVE_MMS,
873 OP_READ_CELL_BROADCASTS,
874 // Storage
875 OP_READ_EXTERNAL_STORAGE,
876 OP_WRITE_EXTERNAL_STORAGE,
877 // Location
878 OP_COARSE_LOCATION,
879 OP_FINE_LOCATION,
880 // Phone
881 OP_READ_PHONE_STATE,
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700882 OP_READ_PHONE_NUMBERS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700883 OP_CALL_PHONE,
884 OP_READ_CALL_LOG,
885 OP_WRITE_CALL_LOG,
886 OP_ADD_VOICEMAIL,
887 OP_USE_SIP,
888 OP_PROCESS_OUTGOING_CALLS,
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800889 OP_ANSWER_PHONE_CALLS,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800890 OP_ACCEPT_HANDOVER,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700891 // Microphone
892 OP_RECORD_AUDIO,
893 // Camera
894 OP_CAMERA,
895 // Body sensors
Svet Ganovda0acdf2017-02-15 10:28:51 -0800896 OP_BODY_SENSORS,
Zimuzo6cbf9cc2018-10-05 12:05:58 +0100897 // Activity recognition
898 OP_ACTIVITY_RECOGNITION,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -0700899 // Aural
900 OP_READ_MEDIA_AUDIO,
901 OP_WRITE_MEDIA_AUDIO,
902 // Visual
903 OP_READ_MEDIA_VIDEO,
904 OP_WRITE_MEDIA_VIDEO,
905 OP_READ_MEDIA_IMAGES,
906 OP_WRITE_MEDIA_IMAGES,
Svet Ganovda0acdf2017-02-15 10:28:51 -0800907
908 // APPOP PERMISSIONS
909 OP_ACCESS_NOTIFICATIONS,
910 OP_SYSTEM_ALERT_WINDOW,
911 OP_WRITE_SETTINGS,
912 OP_REQUEST_INSTALL_PACKAGES,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700913 OP_START_FOREGROUND,
Hongming Jin228cd012018-11-09 14:47:50 -0800914 OP_SMS_FINANCIAL_TRANSACTIONS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700915 };
916
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800917 /**
918 * This maps each operation to the operation that serves as the
919 * switch to determine whether it is allowed. Generally this is
920 * a 1:1 mapping, but for some things (like location) that have
921 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -0700922 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800923 * make them all controlled by the same single operation.
924 */
925 private static int[] sOpToSwitch = new int[] {
Dianne Hackbornc216a262018-04-26 13:46:22 -0700926 OP_COARSE_LOCATION, // COARSE_LOCATION
927 OP_COARSE_LOCATION, // FINE_LOCATION
928 OP_COARSE_LOCATION, // GPS
929 OP_VIBRATE, // VIBRATE
930 OP_READ_CONTACTS, // READ_CONTACTS
931 OP_WRITE_CONTACTS, // WRITE_CONTACTS
932 OP_READ_CALL_LOG, // READ_CALL_LOG
933 OP_WRITE_CALL_LOG, // WRITE_CALL_LOG
934 OP_READ_CALENDAR, // READ_CALENDAR
935 OP_WRITE_CALENDAR, // WRITE_CALENDAR
936 OP_COARSE_LOCATION, // WIFI_SCAN
937 OP_POST_NOTIFICATION, // POST_NOTIFICATION
938 OP_COARSE_LOCATION, // NEIGHBORING_CELLS
939 OP_CALL_PHONE, // CALL_PHONE
940 OP_READ_SMS, // READ_SMS
941 OP_WRITE_SMS, // WRITE_SMS
942 OP_RECEIVE_SMS, // RECEIVE_SMS
943 OP_RECEIVE_SMS, // RECEIVE_EMERGECY_SMS
944 OP_RECEIVE_MMS, // RECEIVE_MMS
945 OP_RECEIVE_WAP_PUSH, // RECEIVE_WAP_PUSH
946 OP_SEND_SMS, // SEND_SMS
947 OP_READ_SMS, // READ_ICC_SMS
948 OP_WRITE_SMS, // WRITE_ICC_SMS
949 OP_WRITE_SETTINGS, // WRITE_SETTINGS
950 OP_SYSTEM_ALERT_WINDOW, // SYSTEM_ALERT_WINDOW
951 OP_ACCESS_NOTIFICATIONS, // ACCESS_NOTIFICATIONS
952 OP_CAMERA, // CAMERA
953 OP_RECORD_AUDIO, // RECORD_AUDIO
954 OP_PLAY_AUDIO, // PLAY_AUDIO
955 OP_READ_CLIPBOARD, // READ_CLIPBOARD
956 OP_WRITE_CLIPBOARD, // WRITE_CLIPBOARD
957 OP_TAKE_MEDIA_BUTTONS, // TAKE_MEDIA_BUTTONS
958 OP_TAKE_AUDIO_FOCUS, // TAKE_AUDIO_FOCUS
959 OP_AUDIO_MASTER_VOLUME, // AUDIO_MASTER_VOLUME
960 OP_AUDIO_VOICE_VOLUME, // AUDIO_VOICE_VOLUME
961 OP_AUDIO_RING_VOLUME, // AUDIO_RING_VOLUME
962 OP_AUDIO_MEDIA_VOLUME, // AUDIO_MEDIA_VOLUME
963 OP_AUDIO_ALARM_VOLUME, // AUDIO_ALARM_VOLUME
964 OP_AUDIO_NOTIFICATION_VOLUME, // AUDIO_NOTIFICATION_VOLUME
965 OP_AUDIO_BLUETOOTH_VOLUME, // AUDIO_BLUETOOTH_VOLUME
966 OP_WAKE_LOCK, // WAKE_LOCK
967 OP_COARSE_LOCATION, // MONITOR_LOCATION
968 OP_COARSE_LOCATION, // MONITOR_HIGH_POWER_LOCATION
969 OP_GET_USAGE_STATS, // GET_USAGE_STATS
970 OP_MUTE_MICROPHONE, // MUTE_MICROPHONE
971 OP_TOAST_WINDOW, // TOAST_WINDOW
972 OP_PROJECT_MEDIA, // PROJECT_MEDIA
973 OP_ACTIVATE_VPN, // ACTIVATE_VPN
974 OP_WRITE_WALLPAPER, // WRITE_WALLPAPER
975 OP_ASSIST_STRUCTURE, // ASSIST_STRUCTURE
976 OP_ASSIST_SCREENSHOT, // ASSIST_SCREENSHOT
977 OP_READ_PHONE_STATE, // READ_PHONE_STATE
978 OP_ADD_VOICEMAIL, // ADD_VOICEMAIL
979 OP_USE_SIP, // USE_SIP
980 OP_PROCESS_OUTGOING_CALLS, // PROCESS_OUTGOING_CALLS
981 OP_USE_FINGERPRINT, // USE_FINGERPRINT
982 OP_BODY_SENSORS, // BODY_SENSORS
983 OP_READ_CELL_BROADCASTS, // READ_CELL_BROADCASTS
984 OP_MOCK_LOCATION, // MOCK_LOCATION
985 OP_READ_EXTERNAL_STORAGE, // READ_EXTERNAL_STORAGE
986 OP_WRITE_EXTERNAL_STORAGE, // WRITE_EXTERNAL_STORAGE
987 OP_TURN_SCREEN_ON, // TURN_SCREEN_ON
988 OP_GET_ACCOUNTS, // GET_ACCOUNTS
989 OP_RUN_IN_BACKGROUND, // RUN_IN_BACKGROUND
990 OP_AUDIO_ACCESSIBILITY_VOLUME, // AUDIO_ACCESSIBILITY_VOLUME
991 OP_READ_PHONE_NUMBERS, // READ_PHONE_NUMBERS
992 OP_REQUEST_INSTALL_PACKAGES, // REQUEST_INSTALL_PACKAGES
993 OP_PICTURE_IN_PICTURE, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
994 OP_INSTANT_APP_START_FOREGROUND, // INSTANT_APP_START_FOREGROUND
995 OP_ANSWER_PHONE_CALLS, // ANSWER_PHONE_CALLS
996 OP_RUN_ANY_IN_BACKGROUND, // OP_RUN_ANY_IN_BACKGROUND
997 OP_CHANGE_WIFI_STATE, // OP_CHANGE_WIFI_STATE
998 OP_REQUEST_DELETE_PACKAGES, // OP_REQUEST_DELETE_PACKAGES
999 OP_BIND_ACCESSIBILITY_SERVICE, // OP_BIND_ACCESSIBILITY_SERVICE
1000 OP_ACCEPT_HANDOVER, // ACCEPT_HANDOVER
1001 OP_MANAGE_IPSEC_TUNNELS, // MANAGE_IPSEC_HANDOVERS
1002 OP_START_FOREGROUND, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001003 OP_COARSE_LOCATION, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001004 OP_USE_BIOMETRIC, // BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001005 OP_ACTIVITY_RECOGNITION, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001006 OP_SMS_FINANCIAL_TRANSACTIONS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001007 OP_READ_MEDIA_AUDIO, // READ_MEDIA_AUDIO
1008 OP_WRITE_MEDIA_AUDIO, // WRITE_MEDIA_AUDIO
1009 OP_READ_MEDIA_VIDEO, // READ_MEDIA_VIDEO
1010 OP_WRITE_MEDIA_VIDEO, // WRITE_MEDIA_VIDEO
1011 OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES
1012 OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001013 OP_LEGACY_STORAGE, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001014 OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001015 };
1016
1017 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001018 * This maps each operation to the public string constant for it.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001019 */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001020 private static String[] sOpToString = new String[]{
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001021 OPSTR_COARSE_LOCATION,
1022 OPSTR_FINE_LOCATION,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001023 OPSTR_GPS,
1024 OPSTR_VIBRATE,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001025 OPSTR_READ_CONTACTS,
1026 OPSTR_WRITE_CONTACTS,
1027 OPSTR_READ_CALL_LOG,
1028 OPSTR_WRITE_CALL_LOG,
1029 OPSTR_READ_CALENDAR,
1030 OPSTR_WRITE_CALENDAR,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001031 OPSTR_WIFI_SCAN,
1032 OPSTR_POST_NOTIFICATION,
1033 OPSTR_NEIGHBORING_CELLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001034 OPSTR_CALL_PHONE,
1035 OPSTR_READ_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001036 OPSTR_WRITE_SMS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001037 OPSTR_RECEIVE_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001038 OPSTR_RECEIVE_EMERGENCY_BROADCAST,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001039 OPSTR_RECEIVE_MMS,
1040 OPSTR_RECEIVE_WAP_PUSH,
1041 OPSTR_SEND_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001042 OPSTR_READ_ICC_SMS,
1043 OPSTR_WRITE_ICC_SMS,
Billy Lau24b9c832015-07-20 17:34:09 +01001044 OPSTR_WRITE_SETTINGS,
1045 OPSTR_SYSTEM_ALERT_WINDOW,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001046 OPSTR_ACCESS_NOTIFICATIONS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001047 OPSTR_CAMERA,
1048 OPSTR_RECORD_AUDIO,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001049 OPSTR_PLAY_AUDIO,
1050 OPSTR_READ_CLIPBOARD,
1051 OPSTR_WRITE_CLIPBOARD,
1052 OPSTR_TAKE_MEDIA_BUTTONS,
1053 OPSTR_TAKE_AUDIO_FOCUS,
1054 OPSTR_AUDIO_MASTER_VOLUME,
1055 OPSTR_AUDIO_VOICE_VOLUME,
1056 OPSTR_AUDIO_RING_VOLUME,
1057 OPSTR_AUDIO_MEDIA_VOLUME,
1058 OPSTR_AUDIO_ALARM_VOLUME,
1059 OPSTR_AUDIO_NOTIFICATION_VOLUME,
1060 OPSTR_AUDIO_BLUETOOTH_VOLUME,
1061 OPSTR_WAKE_LOCK,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001062 OPSTR_MONITOR_LOCATION,
1063 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -07001064 OPSTR_GET_USAGE_STATS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001065 OPSTR_MUTE_MICROPHONE,
1066 OPSTR_TOAST_WINDOW,
1067 OPSTR_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -07001068 OPSTR_ACTIVATE_VPN,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001069 OPSTR_WRITE_WALLPAPER,
1070 OPSTR_ASSIST_STRUCTURE,
1071 OPSTR_ASSIST_SCREENSHOT,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001072 OPSTR_READ_PHONE_STATE,
1073 OPSTR_ADD_VOICEMAIL,
1074 OPSTR_USE_SIP,
Svet Ganov824ad6e2016-09-22 19:36:53 -07001075 OPSTR_PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001076 OPSTR_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001077 OPSTR_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001078 OPSTR_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001079 OPSTR_MOCK_LOCATION,
1080 OPSTR_READ_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001081 OPSTR_WRITE_EXTERNAL_STORAGE,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001082 OPSTR_TURN_SCREEN_ON,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001083 OPSTR_GET_ACCOUNTS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001084 OPSTR_RUN_IN_BACKGROUND,
1085 OPSTR_AUDIO_ACCESSIBILITY_VOLUME,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001086 OPSTR_READ_PHONE_NUMBERS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001087 OPSTR_REQUEST_INSTALL_PACKAGES,
Winson Chungf4ac0632017-03-17 12:34:12 -07001088 OPSTR_PICTURE_IN_PICTURE,
Chad Brubaker97b383f2017-02-02 15:04:35 -08001089 OPSTR_INSTANT_APP_START_FOREGROUND,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001090 OPSTR_ANSWER_PHONE_CALLS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001091 OPSTR_RUN_ANY_IN_BACKGROUND,
1092 OPSTR_CHANGE_WIFI_STATE,
1093 OPSTR_REQUEST_DELETE_PACKAGES,
1094 OPSTR_BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001095 OPSTR_ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001096 OPSTR_MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001097 OPSTR_START_FOREGROUND,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001098 OPSTR_BLUETOOTH_SCAN,
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001099 OPSTR_USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001100 OPSTR_ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001101 OPSTR_SMS_FINANCIAL_TRANSACTIONS,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001102 OPSTR_READ_MEDIA_AUDIO,
1103 OPSTR_WRITE_MEDIA_AUDIO,
1104 OPSTR_READ_MEDIA_VIDEO,
1105 OPSTR_WRITE_MEDIA_VIDEO,
1106 OPSTR_READ_MEDIA_IMAGES,
1107 OPSTR_WRITE_MEDIA_IMAGES,
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001108 OPSTR_LEGACY_STORAGE,
Jackal Guo8dc791e2019-01-14 10:26:42 +08001109 OPSTR_ACCESS_ACCESSIBILITY,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001110 };
1111
1112 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001113 * This provides a simple name for each operation to be used
1114 * in debug output.
1115 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001116 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001117 "COARSE_LOCATION",
1118 "FINE_LOCATION",
1119 "GPS",
1120 "VIBRATE",
1121 "READ_CONTACTS",
1122 "WRITE_CONTACTS",
1123 "READ_CALL_LOG",
1124 "WRITE_CALL_LOG",
1125 "READ_CALENDAR",
1126 "WRITE_CALENDAR",
1127 "WIFI_SCAN",
1128 "POST_NOTIFICATION",
1129 "NEIGHBORING_CELLS",
1130 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001131 "READ_SMS",
1132 "WRITE_SMS",
1133 "RECEIVE_SMS",
1134 "RECEIVE_EMERGECY_SMS",
1135 "RECEIVE_MMS",
1136 "RECEIVE_WAP_PUSH",
1137 "SEND_SMS",
1138 "READ_ICC_SMS",
1139 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -08001140 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -08001141 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001142 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001143 "CAMERA",
1144 "RECORD_AUDIO",
1145 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001146 "READ_CLIPBOARD",
1147 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001148 "TAKE_MEDIA_BUTTONS",
1149 "TAKE_AUDIO_FOCUS",
1150 "AUDIO_MASTER_VOLUME",
1151 "AUDIO_VOICE_VOLUME",
1152 "AUDIO_RING_VOLUME",
1153 "AUDIO_MEDIA_VOLUME",
1154 "AUDIO_ALARM_VOLUME",
1155 "AUDIO_NOTIFICATION_VOLUME",
1156 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -07001157 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001158 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -07001159 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -04001160 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001161 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -04001162 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001163 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -07001164 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +00001165 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001166 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -07001167 "ASSIST_SCREENSHOT",
Eugene Suslae4ee2c22018-11-05 12:23:30 -08001168 "READ_PHONE_STATE",
Svetoslav5335b672015-04-29 12:00:51 -07001169 "ADD_VOICEMAIL",
Svetoslavc656e6f2015-04-29 14:08:16 -07001170 "USE_SIP",
Svetoslav4af76a52015-04-29 15:29:46 -07001171 "PROCESS_OUTGOING_CALLS",
Svet Ganovb9d71a62015-04-30 10:38:13 -07001172 "USE_FINGERPRINT",
Svet Ganovede43162015-05-02 17:42:44 -07001173 "BODY_SENSORS",
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001174 "READ_CELL_BROADCASTS",
Svet Ganov921c7df2015-06-29 21:51:41 -07001175 "MOCK_LOCATION",
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001176 "READ_EXTERNAL_STORAGE",
1177 "WRITE_EXTERNAL_STORAGE",
1178 "TURN_ON_SCREEN",
Svetoslavf3f02ac2015-09-08 14:36:35 -07001179 "GET_ACCOUNTS",
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001180 "RUN_IN_BACKGROUND",
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001181 "AUDIO_ACCESSIBILITY_VOLUME",
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001182 "READ_PHONE_NUMBERS",
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001183 "REQUEST_INSTALL_PACKAGES",
Winson Chungf4ac0632017-03-17 12:34:12 -07001184 "PICTURE_IN_PICTURE",
Chad Brubaker97b383f2017-02-02 15:04:35 -08001185 "INSTANT_APP_START_FOREGROUND",
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001186 "ANSWER_PHONE_CALLS",
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001187 "RUN_ANY_IN_BACKGROUND",
Peter Visontay1246d9e2017-10-17 17:02:45 +01001188 "CHANGE_WIFI_STATE",
Peter Visontayf2e38362017-11-27 15:27:16 +00001189 "REQUEST_DELETE_PACKAGES",
Peter Visontay11950832017-11-14 19:34:59 +00001190 "BIND_ACCESSIBILITY_SERVICE",
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001191 "ACCEPT_HANDOVER",
Nathan Harold1bb420672018-03-14 17:08:53 -07001192 "MANAGE_IPSEC_TUNNELS",
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001193 "START_FOREGROUND",
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001194 "BLUETOOTH_SCAN",
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001195 "USE_BIOMETRIC",
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001196 "ACTIVITY_RECOGNITION",
Hongming Jin228cd012018-11-09 14:47:50 -08001197 "SMS_FINANCIAL_TRANSACTIONS",
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001198 "READ_MEDIA_AUDIO",
1199 "WRITE_MEDIA_AUDIO",
1200 "READ_MEDIA_VIDEO",
1201 "WRITE_MEDIA_VIDEO",
1202 "READ_MEDIA_IMAGES",
1203 "WRITE_MEDIA_IMAGES",
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001204 "LEGACY_STORAGE",
Jackal Guo8dc791e2019-01-14 10:26:42 +08001205 "ACCESS_ACCESSIBILITY",
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001206 };
1207
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001208 /**
1209 * This optionally maps a permission to an operation. If there
1210 * is no permission associated with an operation, it is null.
1211 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001212 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001213 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001214 android.Manifest.permission.ACCESS_COARSE_LOCATION,
1215 android.Manifest.permission.ACCESS_FINE_LOCATION,
1216 null,
1217 android.Manifest.permission.VIBRATE,
1218 android.Manifest.permission.READ_CONTACTS,
1219 android.Manifest.permission.WRITE_CONTACTS,
1220 android.Manifest.permission.READ_CALL_LOG,
1221 android.Manifest.permission.WRITE_CALL_LOG,
1222 android.Manifest.permission.READ_CALENDAR,
1223 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001224 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -04001225 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001226 null, // neighboring cells shares the coarse location perm
1227 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001228 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001229 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001230 android.Manifest.permission.RECEIVE_SMS,
1231 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
1232 android.Manifest.permission.RECEIVE_MMS,
1233 android.Manifest.permission.RECEIVE_WAP_PUSH,
1234 android.Manifest.permission.SEND_SMS,
1235 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001236 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -08001237 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -08001238 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001239 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001240 android.Manifest.permission.CAMERA,
1241 android.Manifest.permission.RECORD_AUDIO,
1242 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001243 null, // no permission for reading clipboard
1244 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001245 null, // no permission for taking media buttons
1246 null, // no permission for taking audio focus
1247 null, // no permission for changing master volume
1248 null, // no permission for changing voice volume
1249 null, // no permission for changing ring volume
1250 null, // no permission for changing media volume
1251 null, // no permission for changing alarm volume
1252 null, // no permission for changing notification volume
1253 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -07001254 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001255 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -07001256 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -07001257 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -04001258 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -04001259 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -07001260 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -07001261 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +00001262 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001263 null, // no permission for receiving assist structure
1264 null, // no permission for receiving assist screenshot
Svet Ganovc3300092015-04-17 09:07:22 -07001265 Manifest.permission.READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -07001266 Manifest.permission.ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -07001267 Manifest.permission.USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -07001268 Manifest.permission.PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001269 Manifest.permission.USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001270 Manifest.permission.BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001271 Manifest.permission.READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001272 null,
1273 Manifest.permission.READ_EXTERNAL_STORAGE,
1274 Manifest.permission.WRITE_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001275 null, // no permission for turning the screen on
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001276 Manifest.permission.GET_ACCOUNTS,
1277 null, // no permission for running in background
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001278 null, // no permission for changing accessibility volume
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001279 Manifest.permission.READ_PHONE_NUMBERS,
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001280 Manifest.permission.REQUEST_INSTALL_PACKAGES,
Winson Chung59fda9e2017-01-20 16:14:51 -08001281 null, // no permission for entering picture-in-picture on hide
Chad Brubaker97b383f2017-02-02 15:04:35 -08001282 Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001283 Manifest.permission.ANSWER_PHONE_CALLS,
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001284 null, // no permission for OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001285 Manifest.permission.CHANGE_WIFI_STATE,
Peter Visontayf2e38362017-11-27 15:27:16 +00001286 Manifest.permission.REQUEST_DELETE_PACKAGES,
Peter Visontay11950832017-11-14 19:34:59 +00001287 Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001288 Manifest.permission.ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001289 null, // no permission for OP_MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001290 Manifest.permission.FOREGROUND_SERVICE,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001291 null, // no permission for OP_BLUETOOTH_SCAN
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001292 Manifest.permission.USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001293 Manifest.permission.ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001294 Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001295 Manifest.permission.READ_MEDIA_AUDIO,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001296 null, // no permission for OP_WRITE_MEDIA_AUDIO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001297 Manifest.permission.READ_MEDIA_VIDEO,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001298 null, // no permission for OP_WRITE_MEDIA_VIDEO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001299 Manifest.permission.READ_MEDIA_IMAGES,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001300 null, // no permission for OP_WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001301 null, // no permission for OP_LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001302 null, // no permission for OP_ACCESS_ACCESSIBILITY
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001303 };
1304
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001305 /**
Jason Monk62062992014-05-06 09:55:28 -04001306 * Specifies whether an Op should be restricted by a user restriction.
1307 * Each Op should be filled with a restriction string from UserManager or
1308 * null to specify it is not affected by any user restriction.
1309 */
1310 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -04001311 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
1312 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
1313 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -04001314 null, //VIBRATE
1315 null, //READ_CONTACTS
1316 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -07001317 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
1318 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -04001319 null, //READ_CALENDAR
1320 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001321 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -04001322 null, //POST_NOTIFICATION
1323 null, //NEIGHBORING_CELLS
1324 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001325 UserManager.DISALLOW_SMS, //READ_SMS
1326 UserManager.DISALLOW_SMS, //WRITE_SMS
1327 UserManager.DISALLOW_SMS, //RECEIVE_SMS
1328 null, //RECEIVE_EMERGENCY_SMS
1329 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -04001330 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001331 UserManager.DISALLOW_SMS, //SEND_SMS
1332 UserManager.DISALLOW_SMS, //READ_ICC_SMS
1333 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -04001334 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -04001335 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -04001336 null, //ACCESS_NOTIFICATIONS
Makoto Onuki759a7632015-10-28 16:43:10 -07001337 UserManager.DISALLOW_CAMERA, //CAMERA
Fyodor Kupolovb5013302015-04-17 17:59:14 -07001338 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
Jason Monk62062992014-05-06 09:55:28 -04001339 null, //PLAY_AUDIO
1340 null, //READ_CLIPBOARD
1341 null, //WRITE_CLIPBOARD
1342 null, //TAKE_MEDIA_BUTTONS
1343 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -04001344 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
1345 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
1346 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
1347 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
1348 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
1349 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
1350 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -04001351 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -04001352 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
1353 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -04001354 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -04001355 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -04001356 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -07001357 null, //PROJECT_MEDIA
Tony Mak33d03a92016-06-02 15:01:16 +01001358 null, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001359 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001360 null, // ASSIST_STRUCTURE
1361 null, // ASSIST_SCREENSHOT
Svet Ganovc3300092015-04-17 09:07:22 -07001362 null, // READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001363 null, // ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001364 null, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001365 null, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001366 null, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001367 null, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001368 null, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001369 null, // MOCK_LOCATION
1370 null, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001371 null, // WRITE_EXTERNAL_STORAGE
1372 null, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001373 null, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001374 null, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001375 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001376 null, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001377 null, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001378 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001379 null, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001380 null, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001381 null, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001382 null, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001383 null, // REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001384 null, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001385 null, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001386 null, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001387 null, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001388 null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001389 null, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001390 null, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001391 UserManager.DISALLOW_SMS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001392 null, // READ_MEDIA_AUDIO
1393 null, // WRITE_MEDIA_AUDIO
1394 null, // READ_MEDIA_VIDEO
1395 null, // WRITE_MEDIA_VIDEO
1396 null, // READ_MEDIA_IMAGES
1397 null, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001398 null, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001399 null, // ACCESS_ACCESSIBILITY
Jason Monk1c7c3192014-06-26 12:52:18 -04001400 };
1401
1402 /**
1403 * This specifies whether each option should allow the system
1404 * (and system ui) to bypass the user restriction when active.
1405 */
1406 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
Fyodor Kupolov639e73d2016-02-25 11:58:21 -08001407 true, //COARSE_LOCATION
1408 true, //FINE_LOCATION
Jason Monk1c7c3192014-06-26 12:52:18 -04001409 false, //GPS
1410 false, //VIBRATE
1411 false, //READ_CONTACTS
1412 false, //WRITE_CONTACTS
1413 false, //READ_CALL_LOG
1414 false, //WRITE_CALL_LOG
1415 false, //READ_CALENDAR
1416 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001417 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -04001418 false, //POST_NOTIFICATION
1419 false, //NEIGHBORING_CELLS
1420 false, //CALL_PHONE
1421 false, //READ_SMS
1422 false, //WRITE_SMS
1423 false, //RECEIVE_SMS
1424 false, //RECEIVE_EMERGECY_SMS
1425 false, //RECEIVE_MMS
1426 false, //RECEIVE_WAP_PUSH
1427 false, //SEND_SMS
1428 false, //READ_ICC_SMS
1429 false, //WRITE_ICC_SMS
1430 false, //WRITE_SETTINGS
1431 true, //SYSTEM_ALERT_WINDOW
1432 false, //ACCESS_NOTIFICATIONS
1433 false, //CAMERA
1434 false, //RECORD_AUDIO
1435 false, //PLAY_AUDIO
1436 false, //READ_CLIPBOARD
1437 false, //WRITE_CLIPBOARD
1438 false, //TAKE_MEDIA_BUTTONS
1439 false, //TAKE_AUDIO_FOCUS
1440 false, //AUDIO_MASTER_VOLUME
1441 false, //AUDIO_VOICE_VOLUME
1442 false, //AUDIO_RING_VOLUME
1443 false, //AUDIO_MEDIA_VOLUME
1444 false, //AUDIO_ALARM_VOLUME
1445 false, //AUDIO_NOTIFICATION_VOLUME
1446 false, //AUDIO_BLUETOOTH_VOLUME
1447 false, //WAKE_LOCK
1448 false, //MONITOR_LOCATION
1449 false, //MONITOR_HIGH_POWER_LOCATION
1450 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -07001451 false, //MUTE_MICROPHONE
1452 true, //TOAST_WINDOW
1453 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -07001454 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001455 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001456 false, //ASSIST_STRUCTURE
1457 false, //ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -07001458 false, //READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001459 false, //ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001460 false, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001461 false, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001462 false, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001463 false, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001464 false, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001465 false, // MOCK_LOCATION
1466 false, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001467 false, // WRITE_EXTERNAL_STORAGE
1468 false, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001469 false, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001470 false, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001471 false, // AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001472 false, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001473 false, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001474 false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001475 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001476 false, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001477 false, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001478 false, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001479 false, // OP_REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001480 false, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001481 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001482 false, // MANAGE_IPSEC_HANDOVERS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001483 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001484 true, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001485 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001486 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001487 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001488 false, // READ_MEDIA_AUDIO
1489 false, // WRITE_MEDIA_AUDIO
1490 false, // READ_MEDIA_VIDEO
1491 false, // WRITE_MEDIA_VIDEO
1492 false, // READ_MEDIA_IMAGES
1493 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001494 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001495 false, // ACCESS_ACCESSIBILITY
Jason Monk62062992014-05-06 09:55:28 -04001496 };
1497
1498 /**
David Braunf5d83192013-09-16 13:43:51 -07001499 * This specifies the default mode for each operation.
1500 */
1501 private static int[] sOpDefaultMode = new int[] {
Eugene Susla93519852018-06-13 16:44:31 -07001502 AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION
1503 AppOpsManager.MODE_ALLOWED, // FINE_LOCATION
1504 AppOpsManager.MODE_ALLOWED, // GPS
1505 AppOpsManager.MODE_ALLOWED, // VIBRATE
1506 AppOpsManager.MODE_ALLOWED, // READ_CONTACTS
1507 AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS
1508 AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG
1509 AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG
1510 AppOpsManager.MODE_ALLOWED, // READ_CALENDAR
1511 AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR
1512 AppOpsManager.MODE_ALLOWED, // WIFI_SCAN
1513 AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION
1514 AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS
1515 AppOpsManager.MODE_ALLOWED, // CALL_PHONE
Eugene Suslaaaff0072018-10-30 13:35:03 -07001516 AppOpsManager.MODE_ALLOWED, // READ_SMS
1517 AppOpsManager.MODE_IGNORED, // WRITE_SMS
1518 AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001519 AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST
1520 AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS
Eugene Suslaaaff0072018-10-30 13:35:03 -07001521 AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH
1522 AppOpsManager.MODE_ALLOWED, // SEND_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001523 AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS
1524 AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS
1525 AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS
Ng Zhi An65a99b62018-10-01 11:57:53 -07001526 getSystemAlertWindowDefault(), // SYSTEM_ALERT_WINDOW
Eugene Susla93519852018-06-13 16:44:31 -07001527 AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS
1528 AppOpsManager.MODE_ALLOWED, // CAMERA
1529 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO
1530 AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO
1531 AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD
1532 AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD
1533 AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS
1534 AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS
1535 AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME
1536 AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME
1537 AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME
1538 AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME
1539 AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME
1540 AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME
1541 AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME
1542 AppOpsManager.MODE_ALLOWED, // WAKE_LOCK
1543 AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION
1544 AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION
1545 AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS
1546 AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE
1547 AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW
1548 AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA
1549 AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN
1550 AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER
1551 AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE
1552 AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT
1553 AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE
1554 AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL
1555 AppOpsManager.MODE_ALLOWED, // USE_SIP
1556 AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS
1557 AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT
1558 AppOpsManager.MODE_ALLOWED, // BODY_SENSORS
Eugene Suslaaaff0072018-10-30 13:35:03 -07001559 AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS
Eugene Susla93519852018-06-13 16:44:31 -07001560 AppOpsManager.MODE_ERRORED, // MOCK_LOCATION
1561 AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE
1562 AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE
1563 AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON
1564 AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS
1565 AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND
1566 AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME
1567 AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS
1568 AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES
1569 AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE
1570 AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND
1571 AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
1572 AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND
1573 AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE
1574 AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES
1575 AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE
1576 AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER
1577 AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS
1578 AppOpsManager.MODE_ALLOWED, // START_FOREGROUND
1579 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN
1580 AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001581 AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001582 AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001583 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001584 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001585 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001586 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001587 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001588 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001589 AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001590 AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY
David Braunf5d83192013-09-16 13:43:51 -07001591 };
1592
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001593 /**
1594 * This specifies whether each option is allowed to be reset
1595 * when resetting all app preferences. Disable reset for
1596 * app ops that are under strong control of some part of the
1597 * system (such as OP_WRITE_SMS, which should be allowed only
1598 * for whichever app is selected as the current SMS app).
1599 */
1600 private static boolean[] sOpDisableReset = new boolean[] {
Eugene Susla93519852018-06-13 16:44:31 -07001601 false, // COARSE_LOCATION
1602 false, // FINE_LOCATION
1603 false, // GPS
1604 false, // VIBRATE
1605 false, // READ_CONTACTS
1606 false, // WRITE_CONTACTS
1607 false, // READ_CALL_LOG
1608 false, // WRITE_CALL_LOG
1609 false, // READ_CALENDAR
1610 false, // WRITE_CALENDAR
1611 false, // WIFI_SCAN
1612 false, // POST_NOTIFICATION
1613 false, // NEIGHBORING_CELLS
1614 false, // CALL_PHONE
1615 true, // READ_SMS
1616 true, // WRITE_SMS
1617 true, // RECEIVE_SMS
1618 false, // RECEIVE_EMERGENCY_BROADCAST
1619 false, // RECEIVE_MMS
1620 true, // RECEIVE_WAP_PUSH
1621 true, // SEND_SMS
1622 false, // READ_ICC_SMS
1623 false, // WRITE_ICC_SMS
1624 false, // WRITE_SETTINGS
1625 false, // SYSTEM_ALERT_WINDOW
1626 false, // ACCESS_NOTIFICATIONS
1627 false, // CAMERA
1628 false, // RECORD_AUDIO
1629 false, // PLAY_AUDIO
1630 false, // READ_CLIPBOARD
1631 false, // WRITE_CLIPBOARD
1632 false, // TAKE_MEDIA_BUTTONS
1633 false, // TAKE_AUDIO_FOCUS
1634 false, // AUDIO_MASTER_VOLUME
1635 false, // AUDIO_VOICE_VOLUME
1636 false, // AUDIO_RING_VOLUME
1637 false, // AUDIO_MEDIA_VOLUME
1638 false, // AUDIO_ALARM_VOLUME
1639 false, // AUDIO_NOTIFICATION_VOLUME
1640 false, // AUDIO_BLUETOOTH_VOLUME
1641 false, // WAKE_LOCK
1642 false, // MONITOR_LOCATION
1643 false, // MONITOR_HIGH_POWER_LOCATION
1644 false, // GET_USAGE_STATS
1645 false, // MUTE_MICROPHONE
1646 false, // TOAST_WINDOW
1647 false, // PROJECT_MEDIA
1648 false, // ACTIVATE_VPN
1649 false, // WRITE_WALLPAPER
1650 false, // ASSIST_STRUCTURE
1651 false, // ASSIST_SCREENSHOT
1652 false, // READ_PHONE_STATE
1653 false, // ADD_VOICEMAIL
1654 false, // USE_SIP
1655 false, // PROCESS_OUTGOING_CALLS
1656 false, // USE_FINGERPRINT
1657 false, // BODY_SENSORS
1658 true, // READ_CELL_BROADCASTS
1659 false, // MOCK_LOCATION
1660 false, // READ_EXTERNAL_STORAGE
1661 false, // WRITE_EXTERNAL_STORAGE
1662 false, // TURN_SCREEN_ON
1663 false, // GET_ACCOUNTS
1664 false, // RUN_IN_BACKGROUND
1665 false, // AUDIO_ACCESSIBILITY_VOLUME
1666 false, // READ_PHONE_NUMBERS
1667 false, // REQUEST_INSTALL_PACKAGES
1668 false, // PICTURE_IN_PICTURE
1669 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001670 false, // ANSWER_PHONE_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07001671 false, // RUN_ANY_IN_BACKGROUND
1672 false, // CHANGE_WIFI_STATE
1673 false, // REQUEST_DELETE_PACKAGES
1674 false, // BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001675 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001676 false, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001677 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001678 false, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001679 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001680 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001681 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001682 false, // READ_MEDIA_AUDIO
1683 false, // WRITE_MEDIA_AUDIO
1684 false, // READ_MEDIA_VIDEO
1685 false, // WRITE_MEDIA_VIDEO
1686 false, // READ_MEDIA_IMAGES
1687 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001688 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001689 false, // ACCESS_ACCESSIBILITY
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001690 };
1691
Svet Ganovfbf01f72015-04-28 18:39:06 -07001692 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07001693 * Mapping from an app op name to the app op code.
Svet Ganovfbf01f72015-04-28 18:39:06 -07001694 */
Svet Ganovb9d71a62015-04-30 10:38:13 -07001695 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
Svet Ganovfbf01f72015-04-28 18:39:06 -07001696
Svet Ganovb9d71a62015-04-30 10:38:13 -07001697 /**
1698 * Mapping from a permission to the corresponding app op.
1699 */
Svet Ganovda0acdf2017-02-15 10:28:51 -08001700 private static HashMap<String, Integer> sPermToOp = new HashMap<>();
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001701
1702 static {
1703 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001704 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001705 + " should be " + _NUM_OP);
1706 }
1707 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001708 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001709 + " should be " + _NUM_OP);
1710 }
1711 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001712 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001713 + " should be " + _NUM_OP);
1714 }
1715 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001716 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001717 + " should be " + _NUM_OP);
1718 }
1719 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001720 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
1721 + " should be " + _NUM_OP);
1722 }
1723 if (sOpDisableReset.length != _NUM_OP) {
1724 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001725 + " should be " + _NUM_OP);
1726 }
Jason Monk62062992014-05-06 09:55:28 -04001727 if (sOpRestrictions.length != _NUM_OP) {
1728 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
1729 + " should be " + _NUM_OP);
1730 }
Jason Monk1c7c3192014-06-26 12:52:18 -04001731 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
1732 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
1733 + sOpRestrictions.length + " should be " + _NUM_OP);
1734 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001735 for (int i=0; i<_NUM_OP; i++) {
1736 if (sOpToString[i] != null) {
1737 sOpStrToOp.put(sOpToString[i], i);
1738 }
1739 }
Svet Ganovda0acdf2017-02-15 10:28:51 -08001740 for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001741 if (sOpPerms[op] != null) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08001742 sPermToOp.put(sOpPerms[op], op);
Svet Ganovb9d71a62015-04-30 10:38:13 -07001743 }
1744 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001745 }
1746
Svet Ganov8455ba22019-01-02 13:05:56 -08001747 /** @hide */
1748 public static final String KEY_HISTORICAL_OPS = "historical_ops";
1749
Chad Brubaker7c6dba62019-01-23 15:51:43 -08001750 /** System properties for debug logging of noteOp call sites */
1751 private static final String DEBUG_LOGGING_ENABLE_PROP = "appops.logging_enabled";
1752 private static final String DEBUG_LOGGING_PACKAGES_PROP = "appops.logging_packages";
1753 private static final String DEBUG_LOGGING_OPS_PROP = "appops.logging_ops";
1754 private static final String DEBUG_LOGGING_TAG = "AppOpsManager";
1755
David Braunf5d83192013-09-16 13:43:51 -07001756 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001757 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001758 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001759 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001760 @UnsupportedAppUsage
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001761 public static int opToSwitch(int op) {
1762 return sOpToSwitch[op];
1763 }
1764
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001765 /**
1766 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001767 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001768 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001769 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001770 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08001771 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001772 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
1773 }
1774
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001775 /**
Svet Ganov65f1b9e2019-01-17 19:19:40 -08001776 * Retrieve a non-localized public name for the operation.
1777 *
1778 * @hide
1779 */
1780 public static @NonNull String opToPublicName(int op) {
1781 return sOpToString[op];
1782 }
1783
1784 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08001785 * @hide
1786 */
1787 public static int strDebugOpToOp(String op) {
1788 for (int i=0; i<sOpNames.length; i++) {
1789 if (sOpNames[i].equals(op)) {
1790 return i;
1791 }
1792 }
1793 throw new IllegalArgumentException("Unknown operation string: " + op);
1794 }
1795
1796 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001797 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001798 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001799 */
Philip P. Moltmann33115152018-04-11 13:39:36 -07001800 @TestApi
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001801 public static String opToPermission(int op) {
1802 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001803 }
1804
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001805 /**
Hai Zhangb7776682018-09-25 15:10:57 -07001806 * Retrieve the permission associated with an operation, or null if there is not one.
1807 *
1808 * @param op The operation name.
1809 *
1810 * @hide
1811 */
1812 @Nullable
1813 @SystemApi
1814 public static String opToPermission(@NonNull String op) {
1815 return opToPermission(strOpToOp(op));
1816 }
1817
1818 /**
Jason Monk62062992014-05-06 09:55:28 -04001819 * Retrieve the user restriction associated with an operation, or null if there is not one.
1820 * @hide
1821 */
1822 public static String opToRestriction(int op) {
1823 return sOpRestrictions[op];
1824 }
1825
1826 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07001827 * Retrieve the app op code for a permission, or null if there is not one.
Svet Ganovda0acdf2017-02-15 10:28:51 -08001828 * This API is intended to be used for mapping runtime or appop permissions
1829 * to the corresponding app op.
Svet Ganovb9d71a62015-04-30 10:38:13 -07001830 * @hide
1831 */
Philip P. Moltmann33115152018-04-11 13:39:36 -07001832 @TestApi
Svet Ganovb9d71a62015-04-30 10:38:13 -07001833 public static int permissionToOpCode(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08001834 Integer boxedOpCode = sPermToOp.get(permission);
Svet Ganov019d2302015-05-04 11:07:38 -07001835 return boxedOpCode != null ? boxedOpCode : OP_NONE;
Svet Ganovb9d71a62015-04-30 10:38:13 -07001836 }
1837
1838 /**
Jason Monk1c7c3192014-06-26 12:52:18 -04001839 * Retrieve whether the op allows the system (and system ui) to
1840 * bypass the user restriction.
1841 * @hide
1842 */
1843 public static boolean opAllowSystemBypassRestriction(int op) {
1844 return sOpAllowSystemRestrictionBypass[op];
1845 }
1846
1847 /**
David Braunf5d83192013-09-16 13:43:51 -07001848 * Retrieve the default mode for the operation.
1849 * @hide
1850 */
Svet Ganov8455ba22019-01-02 13:05:56 -08001851 public static @Mode int opToDefaultMode(int op) {
Svet Ganov55203682018-11-02 22:34:52 -07001852 // STOPSHIP b/118520006: Hardcode the default values once the feature is stable.
1853 switch (op) {
1854 // SMS permissions
1855 case AppOpsManager.OP_SEND_SMS:
1856 case AppOpsManager.OP_RECEIVE_SMS:
1857 case AppOpsManager.OP_READ_SMS:
1858 case AppOpsManager.OP_RECEIVE_WAP_PUSH:
1859 case AppOpsManager.OP_RECEIVE_MMS:
1860 case AppOpsManager.OP_READ_CELL_BROADCASTS:
1861 // CallLog permissions
1862 case AppOpsManager.OP_READ_CALL_LOG:
1863 case AppOpsManager.OP_WRITE_CALL_LOG:
1864 case AppOpsManager.OP_PROCESS_OUTGOING_CALLS: {
Svet Ganov55203682018-11-02 22:34:52 -07001865 if (sSmsAndCallLogRestrictionEnabled.get() == 1) {
1866 return AppOpsManager.MODE_DEFAULT;
1867 }
1868 }
1869 }
David Braunf5d83192013-09-16 13:43:51 -07001870 return sOpDefaultMode[op];
1871 }
1872
Svet Ganov55203682018-11-02 22:34:52 -07001873 // STOPSHIP b/118520006: Hardcode the default values once the feature is stable.
1874 private static final AtomicInteger sSmsAndCallLogRestrictionEnabled = new AtomicInteger(-1);
1875
1876 // STOPSHIP b/118520006: Hardcode the default values once the feature is stable.
Todd Kennedye4a8dbd2018-11-14 09:22:05 -08001877 static {
Svet Ganov55203682018-11-02 22:34:52 -07001878 final Context context = ActivityThread.currentApplication();
Todd Kennedye4a8dbd2018-11-14 09:22:05 -08001879 if (context != null) {
1880 sSmsAndCallLogRestrictionEnabled.set(ActivityThread.currentActivityThread()
1881 .getIntCoreSetting(Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0));
1882
1883 final Uri uri =
1884 Settings.Global.getUriFor(Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED);
1885 context.getContentResolver().registerContentObserver(uri, false, new ContentObserver(
1886 context.getMainThreadHandler()) {
1887 @Override
1888 public void onChange(boolean selfChange) {
1889 sSmsAndCallLogRestrictionEnabled.set(Settings.Global.getInt(
1890 context.getContentResolver(),
1891 Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0));
1892 }
1893 });
Svet Ganov55203682018-11-02 22:34:52 -07001894 }
Svet Ganov55203682018-11-02 22:34:52 -07001895 }
1896
David Braunf5d83192013-09-16 13:43:51 -07001897 /**
Hai Zhangc595f112018-11-06 14:20:38 -08001898 * Retrieve the default mode for the app op.
1899 *
1900 * @param appOp The app op name
1901 *
1902 * @return the default mode for the app op
1903 *
1904 * @hide
1905 */
1906 @SystemApi
1907 public static int opToDefaultMode(@NonNull String appOp) {
1908 return opToDefaultMode(strOpToOp(appOp));
1909 }
1910
1911 /**
Svet Ganov82f09bc2018-01-12 22:08:40 -08001912 * Retrieve the human readable mode.
1913 * @hide
1914 */
Svet Ganov8455ba22019-01-02 13:05:56 -08001915 public static String modeToName(@Mode int mode) {
Dianne Hackbornc216a262018-04-26 13:46:22 -07001916 if (mode >= 0 && mode < MODE_NAMES.length) {
1917 return MODE_NAMES[mode];
Svet Ganov82f09bc2018-01-12 22:08:40 -08001918 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07001919 return "mode=" + mode;
Svet Ganov82f09bc2018-01-12 22:08:40 -08001920 }
1921
1922 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001923 * Retrieve whether the op allows itself to be reset.
1924 * @hide
1925 */
1926 public static boolean opAllowsReset(int op) {
1927 return !sOpDisableReset[op];
1928 }
1929
1930 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001931 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001932 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001933 */
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07001934 @SystemApi
1935 public static final class PackageOps implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08001936 private final String mPackageName;
1937 private final int mUid;
1938 private final List<OpEntry> mEntries;
1939
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07001940 /**
1941 * @hide
1942 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001943 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08001944 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
1945 mPackageName = packageName;
1946 mUid = uid;
1947 mEntries = entries;
1948 }
1949
1950 public String getPackageName() {
1951 return mPackageName;
1952 }
1953
1954 public int getUid() {
1955 return mUid;
1956 }
1957
1958 public List<OpEntry> getOps() {
1959 return mEntries;
1960 }
1961
1962 @Override
1963 public int describeContents() {
1964 return 0;
1965 }
1966
1967 @Override
1968 public void writeToParcel(Parcel dest, int flags) {
1969 dest.writeString(mPackageName);
1970 dest.writeInt(mUid);
1971 dest.writeInt(mEntries.size());
1972 for (int i=0; i<mEntries.size(); i++) {
1973 mEntries.get(i).writeToParcel(dest, flags);
1974 }
1975 }
1976
1977 PackageOps(Parcel source) {
1978 mPackageName = source.readString();
1979 mUid = source.readInt();
1980 mEntries = new ArrayList<OpEntry>();
1981 final int N = source.readInt();
1982 for (int i=0; i<N; i++) {
1983 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
1984 }
1985 }
1986
1987 public static final Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
1988 @Override public PackageOps createFromParcel(Parcel source) {
1989 return new PackageOps(source);
1990 }
1991
1992 @Override public PackageOps[] newArray(int size) {
1993 return new PackageOps[size];
1994 }
1995 };
1996 }
1997
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001998 /**
1999 * Class holding the information about one unique operation of an application.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002000 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002001 */
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002002 @SystemApi
2003 public static final class OpEntry implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002004 private final int mOp;
Svet Ganov8455ba22019-01-02 13:05:56 -08002005 private final @Mode int mMode;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002006 private final long[] mTimes;
2007 private final long[] mRejectTimes;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002008 private final int mDuration;
Svet Ganov99b60432015-06-27 13:15:22 -07002009 private final int mProxyUid;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002010 private final boolean mRunning;
Svet Ganov99b60432015-06-27 13:15:22 -07002011 private final String mProxyPackageName;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002012
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002013 /**
2014 * @hide
2015 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002016 public OpEntry(int op, @Mode int mode, long time, long rejectTime, int duration,
Svet Ganov99b60432015-06-27 13:15:22 -07002017 int proxyUid, String proxyPackage) {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002018 mOp = op;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002019 mMode = mode;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002020 mTimes = new long[_NUM_UID_STATE];
2021 mRejectTimes = new long[_NUM_UID_STATE];
2022 mTimes[0] = time;
2023 mRejectTimes[0] = rejectTime;
2024 mDuration = duration;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002025 mRunning = duration == -1;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002026 mProxyUid = proxyUid;
2027 mProxyPackageName = proxyPackage;
2028 }
2029
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002030 /**
2031 * @hide
2032 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002033 public OpEntry(int op, @Mode int mode, long[] times, long[] rejectTimes, int duration,
Amith Yamasania1ce9632018-05-28 20:50:48 -07002034 boolean running, int proxyUid, String proxyPackage) {
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002035 mOp = op;
2036 mMode = mode;
2037 mTimes = new long[_NUM_UID_STATE];
2038 mRejectTimes = new long[_NUM_UID_STATE];
2039 System.arraycopy(times, 0, mTimes, 0, _NUM_UID_STATE);
2040 System.arraycopy(rejectTimes, 0, mRejectTimes, 0, _NUM_UID_STATE);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002041 mDuration = duration;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002042 mRunning = running;
Svet Ganov99b60432015-06-27 13:15:22 -07002043 mProxyUid = proxyUid;
2044 mProxyPackageName = proxyPackage;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002045 }
2046
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002047 /**
2048 * @hide
2049 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002050 public OpEntry(int op, @Mode int mode, long[] times, long[] rejectTimes, int duration,
Amith Yamasania1ce9632018-05-28 20:50:48 -07002051 int proxyUid, String proxyPackage) {
2052 this(op, mode, times, rejectTimes, duration, duration == -1, proxyUid, proxyPackage);
2053 }
2054
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002055 /**
2056 * @hide
2057 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002058 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002059 public int getOp() {
2060 return mOp;
2061 }
2062
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002063 /**
2064 * Return this entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}.
2065 */
2066 public String getOpStr() {
2067 return sOpToString[mOp];
2068 }
2069
2070 /**
2071 * Return this entry's current mode, such as {@link #MODE_ALLOWED}.
2072 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002073 public @Mode int getMode() {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002074 return mMode;
2075 }
2076
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002077 /**
2078 * @hide
2079 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002080 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002081 public long getTime() {
Dianne Hackbornc216a262018-04-26 13:46:22 -07002082 return maxTime(mTimes, 0, _NUM_UID_STATE);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002083 }
2084
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002085 /**
2086 * Return the last wall clock time this op was accessed by the app.
2087 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07002088 public long getLastAccessTime() {
2089 return maxTime(mTimes, 0, _NUM_UID_STATE);
2090 }
2091
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002092 /**
2093 * Return the last wall clock time this op was accessed by the app while in the foreground.
2094 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07002095 public long getLastAccessForegroundTime() {
Dianne Hackborne93ab412018-05-14 17:52:30 -07002096 return maxTime(mTimes, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002097 }
2098
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002099 /**
2100 * Return the last wall clock time this op was accessed by the app while in the background.
2101 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07002102 public long getLastAccessBackgroundTime() {
Dianne Hackborne93ab412018-05-14 17:52:30 -07002103 return maxTime(mTimes, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002104 }
2105
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002106 /**
2107 * @hide
2108 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07002109 public long getLastTimeFor(int uidState) {
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002110 return mTimes[uidState];
Dianne Hackborn35654b62013-01-14 17:38:02 -08002111 }
2112
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002113 /**
2114 * @hide
2115 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002116 public long getRejectTime() {
Dianne Hackbornc216a262018-04-26 13:46:22 -07002117 return maxTime(mRejectTimes, 0, _NUM_UID_STATE);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002118 }
2119
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002120 /**
2121 * Return the last wall clock time the app made an attempt to access this op but
2122 * was rejected.
2123 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07002124 public long getLastRejectTime() {
2125 return maxTime(mRejectTimes, 0, _NUM_UID_STATE);
2126 }
2127
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002128 /**
2129 * Return the last wall clock time the app made an attempt to access this op while in
2130 * the foreground but was rejected.
2131 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07002132 public long getLastRejectForegroundTime() {
Dianne Hackborne93ab412018-05-14 17:52:30 -07002133 return maxTime(mRejectTimes, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002134 }
2135
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002136 /**
2137 * Return the last wall clock time the app made an attempt to access this op while in
2138 * the background but was rejected.
2139 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07002140 public long getLastRejectBackgroundTime() {
Dianne Hackborne93ab412018-05-14 17:52:30 -07002141 return maxTime(mRejectTimes, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002142 }
2143
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002144 /**
2145 * @hide
2146 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07002147 public long getLastRejectTimeFor(int uidState) {
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002148 return mRejectTimes[uidState];
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002149 }
2150
Dianne Hackborn35654b62013-01-14 17:38:02 -08002151 public boolean isRunning() {
Amith Yamasania1ce9632018-05-28 20:50:48 -07002152 return mRunning;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002153 }
2154
2155 public int getDuration() {
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002156 return mDuration;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002157 }
2158
Svet Ganov99b60432015-06-27 13:15:22 -07002159 public int getProxyUid() {
2160 return mProxyUid;
2161 }
2162
2163 public String getProxyPackageName() {
2164 return mProxyPackageName;
2165 }
2166
Dianne Hackborn35654b62013-01-14 17:38:02 -08002167 @Override
2168 public int describeContents() {
2169 return 0;
2170 }
2171
2172 @Override
2173 public void writeToParcel(Parcel dest, int flags) {
2174 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002175 dest.writeInt(mMode);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002176 dest.writeLongArray(mTimes);
2177 dest.writeLongArray(mRejectTimes);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002178 dest.writeInt(mDuration);
Amith Yamasania1ce9632018-05-28 20:50:48 -07002179 dest.writeBoolean(mRunning);
Svet Ganov99b60432015-06-27 13:15:22 -07002180 dest.writeInt(mProxyUid);
2181 dest.writeString(mProxyPackageName);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002182 }
2183
2184 OpEntry(Parcel source) {
2185 mOp = source.readInt();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002186 mMode = source.readInt();
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002187 mTimes = source.createLongArray();
2188 mRejectTimes = source.createLongArray();
Dianne Hackborn35654b62013-01-14 17:38:02 -08002189 mDuration = source.readInt();
Amith Yamasania1ce9632018-05-28 20:50:48 -07002190 mRunning = source.readBoolean();
Svet Ganov99b60432015-06-27 13:15:22 -07002191 mProxyUid = source.readInt();
2192 mProxyPackageName = source.readString();
Dianne Hackborn35654b62013-01-14 17:38:02 -08002193 }
2194
2195 public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
2196 @Override public OpEntry createFromParcel(Parcel source) {
2197 return new OpEntry(source);
2198 }
2199
2200 @Override public OpEntry[] newArray(int size) {
2201 return new OpEntry[size];
2202 }
2203 };
2204 }
2205
Svet Ganov8455ba22019-01-02 13:05:56 -08002206 /** @hide */
2207 public interface HistoricalOpsVisitor {
2208 void visitHistoricalOps(@NonNull HistoricalOps ops);
2209 void visitHistoricalUidOps(@NonNull HistoricalUidOps ops);
2210 void visitHistoricalPackageOps(@NonNull HistoricalPackageOps ops);
2211 void visitHistoricalOp(@NonNull HistoricalOp ops);
2212 }
2213
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002214 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08002215 * Request for getting historical app op usage. The request acts
2216 * as a filtering criteria when querying historical op usage.
2217 *
2218 * @hide
2219 */
2220 @Immutable
2221 @TestApi
2222 @SystemApi
2223 public static final class HistoricalOpsRequest {
2224 private final int mUid;
2225 private final @Nullable String mPackageName;
2226 private final @Nullable List<String> mOpNames;
2227 private final long mBeginTimeMillis;
2228 private final long mEndTimeMillis;
2229
2230 private HistoricalOpsRequest(int uid, @Nullable String packageName,
2231 @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis) {
2232 mUid = uid;
2233 mPackageName = packageName;
2234 mOpNames = opNames;
2235 mBeginTimeMillis = beginTimeMillis;
2236 mEndTimeMillis = endTimeMillis;
2237 }
2238
2239 /**
2240 * Builder for creating a {@link HistoricalOpsRequest}.
2241 *
2242 * @hide
2243 */
2244 @TestApi
2245 @SystemApi
2246 public static final class Builder {
2247 private int mUid = Process.INVALID_UID;
2248 private @Nullable String mPackageName;
2249 private @Nullable List<String> mOpNames;
2250 private final long mBeginTimeMillis;
2251 private final long mEndTimeMillis;
2252
2253 /**
2254 * Creates a new builder.
2255 *
2256 * @param beginTimeMillis The beginning of the interval in milliseconds since
2257 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non
2258 * negative.
2259 * @param endTimeMillis The end of the interval in milliseconds since
2260 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after
2261 * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent
2262 * history including ops that happen while this call is in flight.
2263 */
2264 public Builder(long beginTimeMillis, long endTimeMillis) {
2265 Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
2266 "beginTimeMillis must be non negative and lesser than endTimeMillis");
2267 mBeginTimeMillis = beginTimeMillis;
2268 mEndTimeMillis = endTimeMillis;
2269 }
2270
2271 /**
2272 * Sets the UID to query for.
2273 *
2274 * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid.
2275 * @return This builder.
2276 */
2277 public @NonNull Builder setUid(int uid) {
2278 Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
2279 "uid must be " + Process.INVALID_UID + " or non negative");
2280 mUid = uid;
2281 return this;
2282 }
2283
2284 /**
2285 * Sets the package to query for.
2286 *
2287 * @param packageName The package name. <code>Null</code> for any package.
2288 * @return This builder.
2289 */
2290 public @NonNull Builder setPackageName(@Nullable String packageName) {
2291 mPackageName = packageName;
2292 return this;
2293 }
2294
2295 /**
2296 * Sets the op names to query for.
2297 *
2298 * @param opNames The op names. <code>Null</code> for any op.
2299 * @return This builder.
2300 */
2301 public @NonNull Builder setOpNames(@Nullable List<String> opNames) {
2302 if (opNames != null) {
2303 final int opCount = opNames.size();
2304 for (int i = 0; i < opCount; i++) {
2305 Preconditions.checkArgument(AppOpsManager.strOpToOp(
2306 opNames.get(i)) != AppOpsManager.OP_NONE);
2307 }
2308 }
2309 mOpNames = opNames;
2310 return this;
2311 }
2312
2313 /**
2314 * @return a new {@link HistoricalOpsRequest}.
2315 */
2316 public @NonNull HistoricalOpsRequest build() {
2317 return new HistoricalOpsRequest(mUid, mPackageName, mOpNames,
2318 mBeginTimeMillis, mEndTimeMillis);
2319 }
2320 }
2321 }
2322
2323 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08002324 * This class represents historical app op state of all UIDs for a given time interval.
2325 *
2326 * @hide
2327 */
2328 @TestApi
2329 @SystemApi
2330 public static final class HistoricalOps implements Parcelable {
2331 private long mBeginTimeMillis;
2332 private long mEndTimeMillis;
2333 private @Nullable SparseArray<HistoricalUidOps> mHistoricalUidOps;
2334
2335 /** @hide */
2336 @TestApi
2337 public HistoricalOps(long beginTimeMillis, long endTimeMillis) {
2338 Preconditions.checkState(beginTimeMillis <= endTimeMillis);
2339 mBeginTimeMillis = beginTimeMillis;
2340 mEndTimeMillis = endTimeMillis;
2341 }
2342
2343 /** @hide */
2344 public HistoricalOps(@NonNull HistoricalOps other) {
2345 mBeginTimeMillis = other.mBeginTimeMillis;
2346 mEndTimeMillis = other.mEndTimeMillis;
2347 Preconditions.checkState(mBeginTimeMillis <= mEndTimeMillis);
2348 if (other.mHistoricalUidOps != null) {
2349 final int opCount = other.getUidCount();
2350 for (int i = 0; i < opCount; i++) {
2351 final HistoricalUidOps origOps = other.getUidOpsAt(i);
2352 final HistoricalUidOps clonedOps = new HistoricalUidOps(origOps);
2353 if (mHistoricalUidOps == null) {
2354 mHistoricalUidOps = new SparseArray<>(opCount);
2355 }
2356 mHistoricalUidOps.put(clonedOps.getUid(), clonedOps);
2357 }
2358 }
2359 }
2360
2361 private HistoricalOps(Parcel parcel) {
2362 mBeginTimeMillis = parcel.readLong();
2363 mEndTimeMillis = parcel.readLong();
2364 final int[] uids = parcel.createIntArray();
2365 if (!ArrayUtils.isEmpty(uids)) {
2366 final ParceledListSlice<HistoricalUidOps> listSlice = parcel.readParcelable(
2367 HistoricalOps.class.getClassLoader());
2368 final List<HistoricalUidOps> uidOps = (listSlice != null)
2369 ? listSlice.getList() : null;
2370 if (uidOps == null) {
2371 return;
2372 }
2373 for (int i = 0; i < uids.length; i++) {
2374 if (mHistoricalUidOps == null) {
2375 mHistoricalUidOps = new SparseArray<>();
2376 }
2377 mHistoricalUidOps.put(uids[i], uidOps.get(i));
2378 }
2379 }
2380 }
2381
2382 /**
2383 * Splice a piece from the beginning of these ops.
2384 *
2385 * @param splicePoint The fraction of the data to be spliced off.
2386 *
2387 * @hide
2388 */
2389 public @NonNull HistoricalOps spliceFromBeginning(double splicePoint) {
2390 return splice(splicePoint, true);
2391 }
2392
2393 /**
2394 * Splice a piece from the end of these ops.
2395 *
2396 * @param fractionToRemove The fraction of the data to be spliced off.
2397 *
2398 * @hide
2399 */
2400 public @NonNull HistoricalOps spliceFromEnd(double fractionToRemove) {
2401 return splice(fractionToRemove, false);
2402 }
2403
2404 /**
2405 * Splice a piece from the beginning or end of these ops.
2406 *
2407 * @param fractionToRemove The fraction of the data to be spliced off.
2408 * @param beginning Whether to splice off the beginning or the end.
2409 *
2410 * @return The spliced off part.
2411 *
2412 * @hide
2413 */
2414 private @Nullable HistoricalOps splice(double fractionToRemove, boolean beginning) {
2415 final long spliceBeginTimeMills;
2416 final long spliceEndTimeMills;
2417 if (beginning) {
2418 spliceBeginTimeMills = mBeginTimeMillis;
2419 spliceEndTimeMills = (long) (mBeginTimeMillis
2420 + getDurationMillis() * fractionToRemove);
2421 mBeginTimeMillis = spliceEndTimeMills;
2422 } else {
2423 spliceBeginTimeMills = (long) (mEndTimeMillis
2424 - getDurationMillis() * fractionToRemove);
2425 spliceEndTimeMills = mEndTimeMillis;
2426 mEndTimeMillis = spliceBeginTimeMills;
2427 }
2428
2429 HistoricalOps splice = null;
2430 final int uidCount = getUidCount();
2431 for (int i = 0; i < uidCount; i++) {
2432 final HistoricalUidOps origOps = getUidOpsAt(i);
2433 final HistoricalUidOps spliceOps = origOps.splice(fractionToRemove);
2434 if (spliceOps != null) {
2435 if (splice == null) {
2436 splice = new HistoricalOps(spliceBeginTimeMills, spliceEndTimeMills);
2437 }
2438 if (splice.mHistoricalUidOps == null) {
2439 splice.mHistoricalUidOps = new SparseArray<>();
2440 }
2441 splice.mHistoricalUidOps.put(spliceOps.getUid(), spliceOps);
2442 }
2443 }
2444 return splice;
2445 }
2446
2447 /**
2448 * Merge the passed ops into the current ones. The time interval is a
2449 * union of the current and passed in one and the passed in data is
2450 * folded into the data of this instance.
2451 *
2452 * @hide
2453 */
2454 public void merge(@NonNull HistoricalOps other) {
2455 mBeginTimeMillis = Math.min(mBeginTimeMillis, other.mBeginTimeMillis);
2456 mEndTimeMillis = Math.max(mEndTimeMillis, other.mEndTimeMillis);
2457 final int uidCount = other.getUidCount();
2458 for (int i = 0; i < uidCount; i++) {
2459 final HistoricalUidOps otherUidOps = other.getUidOpsAt(i);
2460 final HistoricalUidOps thisUidOps = getUidOps(otherUidOps.getUid());
2461 if (thisUidOps != null) {
2462 thisUidOps.merge(otherUidOps);
2463 } else {
2464 if (mHistoricalUidOps == null) {
2465 mHistoricalUidOps = new SparseArray<>();
2466 }
2467 mHistoricalUidOps.put(otherUidOps.getUid(), otherUidOps);
2468 }
2469 }
2470 }
2471
2472 /**
2473 * AppPermissionUsage the ops to leave only the data we filter for.
2474 *
2475 * @param uid Uid to filter for or {@link android.os.Process#INCIDENTD_UID} for all.
2476 * @param packageName Package to filter for or null for all.
2477 * @param opNames Ops to filter for or null for all.
2478 * @param beginTimeMillis The begin time to filter for or {@link Long#MIN_VALUE} for all.
2479 * @param endTimeMillis The end time to filter for or {@link Long#MAX_VALUE} for all.
2480 *
2481 * @hide
2482 */
2483 public void filter(int uid, @Nullable String packageName, @Nullable String[] opNames,
2484 long beginTimeMillis, long endTimeMillis) {
2485 final long durationMillis = getDurationMillis();
2486 mBeginTimeMillis = Math.max(mBeginTimeMillis, beginTimeMillis);
2487 mEndTimeMillis = Math.min(mEndTimeMillis, endTimeMillis);
2488 final double scaleFactor = Math.min((double) (endTimeMillis - beginTimeMillis)
2489 / (double) durationMillis, 1);
2490 final int uidCount = getUidCount();
2491 for (int i = uidCount - 1; i >= 0; i--) {
2492 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
2493 if (uid != Process.INVALID_UID && uid != uidOp.getUid()) {
2494 mHistoricalUidOps.removeAt(i);
2495 } else {
2496 uidOp.filter(packageName, opNames, scaleFactor);
2497 }
2498 }
2499 }
2500
2501 /** @hide */
2502 public boolean isEmpty() {
2503 if (getBeginTimeMillis() >= getEndTimeMillis()) {
2504 return true;
2505 }
2506 final int uidCount = getUidCount();
2507 for (int i = uidCount - 1; i >= 0; i--) {
2508 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
2509 if (!uidOp.isEmpty()) {
2510 return false;
2511 }
2512 }
2513 return true;
2514 }
2515
2516 /** @hide */
2517 public long getDurationMillis() {
2518 return mEndTimeMillis - mBeginTimeMillis;
2519 }
2520
2521 /** @hide */
2522 @TestApi
2523 public void increaseAccessCount(int opCode, int uid, @NonNull String packageName,
2524 @UidState int uidState, long increment) {
2525 getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode,
2526 packageName, uidState, increment);
2527 }
2528
2529 /** @hide */
2530 @TestApi
2531 public void increaseRejectCount(int opCode, int uid, @NonNull String packageName,
2532 @UidState int uidState, long increment) {
2533 getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode,
2534 packageName, uidState, increment);
2535 }
2536
2537 /** @hide */
2538 @TestApi
2539 public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName,
2540 @UidState int uidState, long increment) {
2541 getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode,
2542 packageName, uidState, increment);
2543 }
2544
2545 /** @hide */
2546 @TestApi
2547 public void offsetBeginAndEndTime(long offsetMillis) {
2548 mBeginTimeMillis += offsetMillis;
2549 mEndTimeMillis += offsetMillis;
2550 }
2551
2552 /** @hide */
2553 public void setBeginAndEndTime(long beginTimeMillis, long endTimeMillis) {
2554 mBeginTimeMillis = beginTimeMillis;
2555 mEndTimeMillis = endTimeMillis;
2556 }
2557
2558 /** @hide */
2559 public void setBeginTime(long beginTimeMillis) {
2560 mBeginTimeMillis = beginTimeMillis;
2561 }
2562
2563 /** @hide */
2564 public void setEndTime(long endTimeMillis) {
2565 mEndTimeMillis = endTimeMillis;
2566 }
2567
2568 /**
2569 * @return The beginning of the interval in milliseconds since
2570 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2571 */
2572 public long getBeginTimeMillis() {
2573 return mBeginTimeMillis;
2574 }
2575
2576 /**
2577 * @return The end of the interval in milliseconds since
2578 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2579 */
2580 public long getEndTimeMillis() {
2581 return mEndTimeMillis;
2582 }
2583
2584 /**
2585 * Gets number of UIDs with historical ops.
2586 *
2587 * @return The number of UIDs with historical ops.
2588 *
2589 * @see #getUidOpsAt(int)
2590 */
2591 public int getUidCount() {
2592 if (mHistoricalUidOps == null) {
2593 return 0;
2594 }
2595 return mHistoricalUidOps.size();
2596 }
2597
2598 /**
2599 * Gets the historical UID ops at a given index.
2600 *
2601 * @param index The index.
2602 *
2603 * @return The historical UID ops at the given index.
2604 *
2605 * @see #getUidCount()
2606 */
2607 public @NonNull HistoricalUidOps getUidOpsAt(int index) {
2608 if (mHistoricalUidOps == null) {
2609 throw new IndexOutOfBoundsException();
2610 }
2611 return mHistoricalUidOps.valueAt(index);
2612 }
2613
2614 /**
2615 * Gets the historical UID ops for a given UID.
2616 *
2617 * @param uid The UID.
2618 *
2619 * @return The historical ops for the UID.
2620 */
2621 public @Nullable HistoricalUidOps getUidOps(int uid) {
2622 if (mHistoricalUidOps == null) {
2623 return null;
2624 }
2625 return mHistoricalUidOps.get(uid);
2626 }
2627
2628 @Override
2629 public int describeContents() {
2630 return 0;
2631 }
2632
2633 @Override
2634 public void writeToParcel(Parcel parcel, int flags) {
2635 parcel.writeLong(mBeginTimeMillis);
2636 parcel.writeLong(mEndTimeMillis);
2637 if (mHistoricalUidOps != null) {
2638 final int uidCount = mHistoricalUidOps.size();
2639 parcel.writeInt(uidCount);
2640 for (int i = 0; i < uidCount; i++) {
2641 parcel.writeInt(mHistoricalUidOps.keyAt(i));
2642 }
2643 final List<HistoricalUidOps> opsList = new ArrayList<>(uidCount);
2644 for (int i = 0; i < uidCount; i++) {
2645 opsList.add(mHistoricalUidOps.valueAt(i));
2646 }
2647 parcel.writeParcelable(new ParceledListSlice<>(opsList), flags);
2648 } else {
2649 parcel.writeInt(-1);
2650 }
2651 }
2652
2653 /**
2654 * Accepts a visitor to traverse the ops tree.
2655 *
2656 * @param visitor The visitor.
2657 *
2658 * @hide
2659 */
2660 public void accept(@NonNull HistoricalOpsVisitor visitor) {
2661 visitor.visitHistoricalOps(this);
2662 final int uidCount = getUidCount();
2663 for (int i = 0; i < uidCount; i++) {
2664 getUidOpsAt(i).accept(visitor);
2665 }
2666 }
2667
2668 private @NonNull HistoricalUidOps getOrCreateHistoricalUidOps(int uid) {
2669 if (mHistoricalUidOps == null) {
2670 mHistoricalUidOps = new SparseArray<>();
2671 }
2672 HistoricalUidOps historicalUidOp = mHistoricalUidOps.get(uid);
2673 if (historicalUidOp == null) {
2674 historicalUidOp = new HistoricalUidOps(uid);
2675 mHistoricalUidOps.put(uid, historicalUidOp);
2676 }
2677 return historicalUidOp;
2678 }
2679
2680 /**
2681 * @return Rounded value up at the 0.5 boundary.
2682 *
2683 * @hide
2684 */
2685 public static double round(double value) {
2686 final BigDecimal decimalScale = new BigDecimal(value);
2687 return decimalScale.setScale(0, RoundingMode.HALF_UP).doubleValue();
2688 }
2689
2690 @Override
2691 public boolean equals(Object obj) {
2692 if (this == obj) {
2693 return true;
2694 }
2695 if (obj == null || getClass() != obj.getClass()) {
2696 return false;
2697 }
2698 final HistoricalOps other = (HistoricalOps) obj;
2699 if (mBeginTimeMillis != other.mBeginTimeMillis) {
2700 return false;
2701 }
2702 if (mEndTimeMillis != other.mEndTimeMillis) {
2703 return false;
2704 }
2705 if (mHistoricalUidOps == null) {
2706 if (other.mHistoricalUidOps != null) {
2707 return false;
2708 }
2709 } else if (!mHistoricalUidOps.equals(other.mHistoricalUidOps)) {
2710 return false;
2711 }
2712 return true;
2713 }
2714
2715 @Override
2716 public int hashCode() {
2717 int result = (int) (mBeginTimeMillis ^ (mBeginTimeMillis >>> 32));
2718 result = 31 * result + mHistoricalUidOps.hashCode();
2719 return result;
2720 }
2721
2722 @Override
2723 public String toString() {
2724 return getClass().getSimpleName() + "[from:"
2725 + mBeginTimeMillis + " to:" + mEndTimeMillis + "]";
2726 }
2727
2728 public static final Creator<HistoricalOps> CREATOR = new Creator<HistoricalOps>() {
2729 @Override
2730 public @NonNull HistoricalOps createFromParcel(@NonNull Parcel parcel) {
2731 return new HistoricalOps(parcel);
2732 }
2733
2734 @Override
2735 public @NonNull HistoricalOps[] newArray(int size) {
2736 return new HistoricalOps[size];
2737 }
2738 };
2739 }
2740
2741 /**
2742 * This class represents historical app op state for a UID.
2743 *
2744 * @hide
2745 */
2746 @TestApi
2747 @SystemApi
2748 public static final class HistoricalUidOps implements Parcelable {
2749 private final int mUid;
2750 private @Nullable ArrayMap<String, HistoricalPackageOps> mHistoricalPackageOps;
2751
2752 /** @hide */
2753 public HistoricalUidOps(int uid) {
2754 mUid = uid;
2755 }
2756
2757 private HistoricalUidOps(@NonNull HistoricalUidOps other) {
2758 mUid = other.mUid;
2759 final int opCount = other.getPackageCount();
2760 for (int i = 0; i < opCount; i++) {
2761 final HistoricalPackageOps origOps = other.getPackageOpsAt(i);
2762 final HistoricalPackageOps cloneOps = new HistoricalPackageOps(origOps);
2763 if (mHistoricalPackageOps == null) {
2764 mHistoricalPackageOps = new ArrayMap<>(opCount);
2765 }
2766 mHistoricalPackageOps.put(cloneOps.getPackageName(), cloneOps);
2767 }
2768 }
2769
2770 private HistoricalUidOps(@NonNull Parcel parcel) {
2771 // No arg check since we always read from a trusted source.
2772 mUid = parcel.readInt();
2773 mHistoricalPackageOps = parcel.createTypedArrayMap(HistoricalPackageOps.CREATOR);
2774 }
2775
2776 private @Nullable HistoricalUidOps splice(double fractionToRemove) {
2777 HistoricalUidOps splice = null;
2778 final int packageCount = getPackageCount();
2779 for (int i = 0; i < packageCount; i++) {
2780 final HistoricalPackageOps origOps = getPackageOpsAt(i);
2781 final HistoricalPackageOps spliceOps = origOps.splice(fractionToRemove);
2782 if (spliceOps != null) {
2783 if (splice == null) {
2784 splice = new HistoricalUidOps(mUid);
2785 }
2786 if (splice.mHistoricalPackageOps == null) {
2787 splice.mHistoricalPackageOps = new ArrayMap<>();
2788 }
2789 splice.mHistoricalPackageOps.put(spliceOps.getPackageName(), spliceOps);
2790 }
2791 }
2792 return splice;
2793 }
2794
2795 private void merge(@NonNull HistoricalUidOps other) {
2796 final int packageCount = other.getPackageCount();
2797 for (int i = 0; i < packageCount; i++) {
2798 final HistoricalPackageOps otherPackageOps = other.getPackageOpsAt(i);
2799 final HistoricalPackageOps thisPackageOps = getPackageOps(
2800 otherPackageOps.getPackageName());
2801 if (thisPackageOps != null) {
2802 thisPackageOps.merge(otherPackageOps);
2803 } else {
2804 if (mHistoricalPackageOps == null) {
2805 mHistoricalPackageOps = new ArrayMap<>();
2806 }
2807 mHistoricalPackageOps.put(otherPackageOps.getPackageName(), otherPackageOps);
2808 }
2809 }
2810 }
2811
2812 private void filter(@Nullable String packageName, @Nullable String[] opNames,
2813 double fractionToRemove) {
2814 final int packageCount = getPackageCount();
2815 for (int i = packageCount - 1; i >= 0; i--) {
2816 final HistoricalPackageOps packageOps = getPackageOpsAt(i);
2817 if (packageName != null && !packageName.equals(packageOps.getPackageName())) {
2818 mHistoricalPackageOps.removeAt(i);
2819 } else {
2820 packageOps.filter(opNames, fractionToRemove);
2821 }
2822 }
2823 }
2824
2825 private boolean isEmpty() {
2826 final int packageCount = getPackageCount();
2827 for (int i = packageCount - 1; i >= 0; i--) {
2828 final HistoricalPackageOps packageOps = mHistoricalPackageOps.valueAt(i);
2829 if (!packageOps.isEmpty()) {
2830 return false;
2831 }
2832 }
2833 return true;
2834 }
2835
2836 private void increaseAccessCount(int opCode, @NonNull String packageName,
2837 @UidState int uidState, long increment) {
2838 getOrCreateHistoricalPackageOps(packageName).increaseAccessCount(
2839 opCode, uidState, increment);
2840 }
2841
2842 private void increaseRejectCount(int opCode, @NonNull String packageName,
2843 @UidState int uidState, long increment) {
2844 getOrCreateHistoricalPackageOps(packageName).increaseRejectCount(
2845 opCode, uidState, increment);
2846 }
2847
2848 private void increaseAccessDuration(int opCode, @NonNull String packageName,
2849 @UidState int uidState, long increment) {
2850 getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration(
2851 opCode, uidState, increment);
2852 }
2853
2854 /**
2855 * @return The UID for which the data is related.
2856 */
2857 public int getUid() {
2858 return mUid;
2859 }
2860
2861 /**
2862 * Gets number of packages with historical ops.
2863 *
2864 * @return The number of packages with historical ops.
2865 *
2866 * @see #getPackageOpsAt(int)
2867 */
2868 public int getPackageCount() {
2869 if (mHistoricalPackageOps == null) {
2870 return 0;
2871 }
2872 return mHistoricalPackageOps.size();
2873 }
2874
2875 /**
2876 * Gets the historical package ops at a given index.
2877 *
2878 * @param index The index.
2879 *
2880 * @return The historical package ops at the given index.
2881 *
2882 * @see #getPackageCount()
2883 */
2884 public @NonNull HistoricalPackageOps getPackageOpsAt(int index) {
2885 if (mHistoricalPackageOps == null) {
2886 throw new IndexOutOfBoundsException();
2887 }
2888 return mHistoricalPackageOps.valueAt(index);
2889 }
2890
2891 /**
2892 * Gets the historical package ops for a given package.
2893 *
2894 * @param packageName The package.
2895 *
2896 * @return The historical ops for the package.
2897 */
2898 public @Nullable HistoricalPackageOps getPackageOps(@NonNull String packageName) {
2899 if (mHistoricalPackageOps == null) {
2900 return null;
2901 }
2902 return mHistoricalPackageOps.get(packageName);
2903 }
2904
2905 @Override
2906 public int describeContents() {
2907 return 0;
2908 }
2909
2910 @Override
2911 public void writeToParcel(Parcel parcel, int flags) {
2912 parcel.writeInt(mUid);
2913 parcel.writeTypedArrayMap(mHistoricalPackageOps, flags);
2914 }
2915
2916 private void accept(@NonNull HistoricalOpsVisitor visitor) {
2917 visitor.visitHistoricalUidOps(this);
2918 final int packageCount = getPackageCount();
2919 for (int i = 0; i < packageCount; i++) {
2920 getPackageOpsAt(i).accept(visitor);
2921 }
2922 }
2923
2924 private @NonNull HistoricalPackageOps getOrCreateHistoricalPackageOps(
2925 @NonNull String packageName) {
2926 if (mHistoricalPackageOps == null) {
2927 mHistoricalPackageOps = new ArrayMap<>();
2928 }
2929 HistoricalPackageOps historicalPackageOp = mHistoricalPackageOps.get(packageName);
2930 if (historicalPackageOp == null) {
2931 historicalPackageOp = new HistoricalPackageOps(packageName);
2932 mHistoricalPackageOps.put(packageName, historicalPackageOp);
2933 }
2934 return historicalPackageOp;
2935 }
2936
2937
2938 public static final Creator<HistoricalUidOps> CREATOR = new Creator<HistoricalUidOps>() {
2939 @Override
2940 public @NonNull HistoricalUidOps createFromParcel(@NonNull Parcel parcel) {
2941 return new HistoricalUidOps(parcel);
2942 }
2943
2944 @Override
2945 public @NonNull HistoricalUidOps[] newArray(int size) {
2946 return new HistoricalUidOps[size];
2947 }
2948 };
2949
2950 @Override
2951 public boolean equals(Object obj) {
2952 if (this == obj) {
2953 return true;
2954 }
2955 if (obj == null || getClass() != obj.getClass()) {
2956 return false;
2957 }
2958 final HistoricalUidOps other = (HistoricalUidOps) obj;
2959 if (mUid != other.mUid) {
2960 return false;
2961 }
2962 if (mHistoricalPackageOps == null) {
2963 if (other.mHistoricalPackageOps != null) {
2964 return false;
2965 }
2966 } else if (!mHistoricalPackageOps.equals(other.mHistoricalPackageOps)) {
2967 return false;
2968 }
2969 return true;
2970 }
2971
2972 @Override
2973 public int hashCode() {
2974 int result = mUid;
2975 result = 31 * result + (mHistoricalPackageOps != null
2976 ? mHistoricalPackageOps.hashCode() : 0);
2977 return result;
2978 }
2979 }
2980
2981 /**
2982 * This class represents historical app op information about a package.
Svet Ganovad0a49b2018-10-29 10:07:08 -07002983 *
2984 * @hide
2985 */
2986 @TestApi
2987 @SystemApi
2988 public static final class HistoricalPackageOps implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07002989 private final @NonNull String mPackageName;
Svet Ganov8455ba22019-01-02 13:05:56 -08002990 private @Nullable ArrayMap<String, HistoricalOp> mHistoricalOps;
Svet Ganovad0a49b2018-10-29 10:07:08 -07002991
Svet Ganov8455ba22019-01-02 13:05:56 -08002992 /** @hide */
2993 public HistoricalPackageOps(@NonNull String packageName) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07002994 mPackageName = packageName;
Svet Ganovad0a49b2018-10-29 10:07:08 -07002995 }
2996
Svet Ganov8455ba22019-01-02 13:05:56 -08002997 private HistoricalPackageOps(@NonNull HistoricalPackageOps other) {
2998 mPackageName = other.mPackageName;
2999 final int opCount = other.getOpCount();
3000 for (int i = 0; i < opCount; i++) {
3001 final HistoricalOp origOp = other.getOpAt(i);
3002 final HistoricalOp cloneOp = new HistoricalOp(origOp);
3003 if (mHistoricalOps == null) {
3004 mHistoricalOps = new ArrayMap<>(opCount);
3005 }
3006 mHistoricalOps.put(cloneOp.getOpName(), cloneOp);
3007 }
3008 }
3009
3010 private HistoricalPackageOps(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003011 mPackageName = parcel.readString();
Svet Ganov8455ba22019-01-02 13:05:56 -08003012 mHistoricalOps = parcel.createTypedArrayMap(HistoricalOp.CREATOR);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003013 }
3014
Svet Ganov8455ba22019-01-02 13:05:56 -08003015 private @Nullable HistoricalPackageOps splice(double fractionToRemove) {
3016 HistoricalPackageOps splice = null;
3017 final int opCount = getOpCount();
3018 for (int i = 0; i < opCount; i++) {
3019 final HistoricalOp origOps = getOpAt(i);
3020 final HistoricalOp spliceOps = origOps.splice(fractionToRemove);
3021 if (spliceOps != null) {
3022 if (splice == null) {
3023 splice = new HistoricalPackageOps(mPackageName);
3024 }
3025 if (splice.mHistoricalOps == null) {
3026 splice.mHistoricalOps = new ArrayMap<>();
3027 }
3028 splice.mHistoricalOps.put(spliceOps.getOpName(), spliceOps);
3029 }
3030 }
3031 return splice;
3032 }
3033
3034 private void merge(@NonNull HistoricalPackageOps other) {
3035 final int opCount = other.getOpCount();
3036 for (int i = 0; i < opCount; i++) {
3037 final HistoricalOp otherOp = other.getOpAt(i);
3038 final HistoricalOp thisOp = getOp(otherOp.getOpName());
3039 if (thisOp != null) {
3040 thisOp.merge(otherOp);
3041 } else {
3042 if (mHistoricalOps == null) {
3043 mHistoricalOps = new ArrayMap<>();
3044 }
3045 mHistoricalOps.put(otherOp.getOpName(), otherOp);
3046 }
3047 }
3048 }
3049
3050 private void filter(@Nullable String[] opNames, double scaleFactor) {
3051 final int opCount = getOpCount();
3052 for (int i = opCount - 1; i >= 0; i--) {
3053 final HistoricalOp op = mHistoricalOps.valueAt(i);
3054 if (opNames != null && !ArrayUtils.contains(opNames, op.getOpName())) {
3055 mHistoricalOps.removeAt(i);
3056 } else {
3057 op.filter(scaleFactor);
3058 }
3059 }
3060 }
3061
3062 private boolean isEmpty() {
3063 final int opCount = getOpCount();
3064 for (int i = opCount - 1; i >= 0; i--) {
3065 final HistoricalOp op = mHistoricalOps.valueAt(i);
3066 if (!op.isEmpty()) {
3067 return false;
3068 }
3069 }
3070 return true;
3071 }
3072
3073 private void increaseAccessCount(int opCode, @UidState int uidState, long increment) {
3074 getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, increment);
3075 }
3076
3077 private void increaseRejectCount(int opCode, @UidState int uidState, long increment) {
3078 getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, increment);
3079 }
3080
3081 private void increaseAccessDuration(int opCode, @UidState int uidState, long increment) {
3082 getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, increment);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003083 }
3084
3085 /**
3086 * Gets the package name which the data represents.
3087 *
3088 * @return The package name which the data represents.
3089 */
3090 public @NonNull String getPackageName() {
3091 return mPackageName;
3092 }
3093
3094 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003095 * Gets number historical app ops.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003096 *
Svet Ganov8455ba22019-01-02 13:05:56 -08003097 * @return The number historical app ops.
3098 *
3099 * @see #getOpAt(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003100 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003101 public int getOpCount() {
3102 if (mHistoricalOps == null) {
3103 return 0;
3104 }
3105 return mHistoricalOps.size();
Svet Ganovad0a49b2018-10-29 10:07:08 -07003106 }
3107
3108 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003109 * Gets the historical op at a given index.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003110 *
3111 * @param index The index to lookup.
3112 *
Svet Ganov8455ba22019-01-02 13:05:56 -08003113 * @return The op at the given index.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003114 *
Svet Ganov8455ba22019-01-02 13:05:56 -08003115 * @see #getOpCount()
Svet Ganovad0a49b2018-10-29 10:07:08 -07003116 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003117 public @NonNull HistoricalOp getOpAt(int index) {
3118 if (mHistoricalOps == null) {
3119 throw new IndexOutOfBoundsException();
3120 }
3121 return mHistoricalOps.valueAt(index);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003122 }
3123
3124 /**
3125 * Gets the historical entry for a given op name.
3126 *
3127 * @param opName The op name.
3128 *
3129 * @return The historical entry for that op name.
3130 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003131 public @Nullable HistoricalOp getOp(@NonNull String opName) {
3132 if (mHistoricalOps == null) {
3133 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003134 }
Svet Ganov8455ba22019-01-02 13:05:56 -08003135 return mHistoricalOps.get(opName);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003136 }
3137
3138 @Override
3139 public int describeContents() {
3140 return 0;
3141 }
3142
3143 @Override
3144 public void writeToParcel(@NonNull Parcel parcel, int flags) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003145 parcel.writeString(mPackageName);
Svet Ganov8455ba22019-01-02 13:05:56 -08003146 parcel.writeTypedArrayMap(mHistoricalOps, flags);
3147 }
3148
3149 private void accept(@NonNull HistoricalOpsVisitor visitor) {
3150 visitor.visitHistoricalPackageOps(this);
3151 final int opCount = getOpCount();
3152 for (int i = 0; i < opCount; i++) {
3153 getOpAt(i).accept(visitor);
3154 }
3155 }
3156
3157 private @NonNull HistoricalOp getOrCreateHistoricalOp(int opCode) {
3158 if (mHistoricalOps == null) {
3159 mHistoricalOps = new ArrayMap<>();
3160 }
3161 final String opStr = sOpToString[opCode];
3162 HistoricalOp op = mHistoricalOps.get(opStr);
3163 if (op == null) {
3164 op = new HistoricalOp(opCode);
3165 mHistoricalOps.put(opStr, op);
3166 }
3167 return op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003168 }
3169
3170 public static final Creator<HistoricalPackageOps> CREATOR =
3171 new Creator<HistoricalPackageOps>() {
3172 @Override
3173 public @NonNull HistoricalPackageOps createFromParcel(@NonNull Parcel parcel) {
3174 return new HistoricalPackageOps(parcel);
3175 }
3176
3177 @Override
3178 public @NonNull HistoricalPackageOps[] newArray(int size) {
3179 return new HistoricalPackageOps[size];
3180 }
3181 };
Svet Ganov8455ba22019-01-02 13:05:56 -08003182
3183 @Override
3184 public boolean equals(Object obj) {
3185 if (this == obj) {
3186 return true;
3187 }
3188 if (obj == null || getClass() != obj.getClass()) {
3189 return false;
3190 }
3191 final HistoricalPackageOps other = (HistoricalPackageOps) obj;
3192 if (!mPackageName.equals(other.mPackageName)) {
3193 return false;
3194 }
3195 if (mHistoricalOps == null) {
3196 if (other.mHistoricalOps != null) {
3197 return false;
3198 }
3199 } else if (!mHistoricalOps.equals(other.mHistoricalOps)) {
3200 return false;
3201 }
3202 return true;
3203 }
3204
3205 @Override
3206 public int hashCode() {
3207 int result = mPackageName != null ? mPackageName.hashCode() : 0;
3208 result = 31 * result + (mHistoricalOps != null ? mHistoricalOps.hashCode() : 0);
3209 return result;
3210 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003211 }
3212
3213 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003214 * This class represents historical information about an app op.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003215 *
3216 * @hide
3217 */
3218 @TestApi
3219 @SystemApi
Svet Ganov8455ba22019-01-02 13:05:56 -08003220 public static final class HistoricalOp implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003221 private final int mOp;
Svet Ganov8455ba22019-01-02 13:05:56 -08003222 private @Nullable long[] mAccessCount;
3223 private @Nullable long[] mRejectCount;
3224 private @Nullable long[] mAccessDuration;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003225
Svet Ganov8455ba22019-01-02 13:05:56 -08003226 /** @hide */
3227 public HistoricalOp(int op) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003228 mOp = op;
3229 mAccessCount = new long[_NUM_UID_STATE];
3230 mRejectCount = new long[_NUM_UID_STATE];
3231 mAccessDuration = new long[_NUM_UID_STATE];
3232 }
3233
Svet Ganov8455ba22019-01-02 13:05:56 -08003234 private HistoricalOp(@NonNull HistoricalOp other) {
3235 mOp = other.mOp;
3236 if (other.mAccessCount != null) {
3237 System.arraycopy(other.mAccessCount, 0, getOrCreateAccessCount(),
3238 0, other.mAccessCount.length);
3239 }
3240 if (other.mRejectCount != null) {
3241 System.arraycopy(other.mRejectCount, 0, getOrCreateRejectCount(),
3242 0, other.mRejectCount.length);
3243 }
3244 if (other.mAccessDuration != null) {
3245 System.arraycopy(other.mAccessDuration, 0, getOrCreateAccessDuration(),
3246 0, other.mAccessDuration.length);
3247 }
3248 }
3249
3250 private HistoricalOp(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003251 mOp = parcel.readInt();
3252 mAccessCount = parcel.createLongArray();
3253 mRejectCount = parcel.createLongArray();
3254 mAccessDuration = parcel.createLongArray();
3255 }
3256
Svet Ganov8455ba22019-01-02 13:05:56 -08003257 private void filter(double scaleFactor) {
3258 scale(mAccessCount, scaleFactor);
3259 scale(mRejectCount, scaleFactor);
3260 scale(mAccessDuration, scaleFactor);
3261 }
3262
3263 private boolean isEmpty() {
3264 return !hasData(mAccessCount)
3265 && !hasData(mRejectCount)
3266 && !hasData(mAccessDuration);
3267 }
3268
3269 private boolean hasData(@NonNull long[] array) {
3270 for (long value : array) {
3271 if (value != 0) {
3272 return true;
3273 }
3274 }
3275 return false;
3276 }
3277
3278 private @Nullable HistoricalOp splice(double fractionToRemove) {
3279 HistoricalOp splice = null;
3280 if (mAccessCount != null) {
3281 for (int i = 0; i < _NUM_UID_STATE; i++) {
3282 final long spliceAccessCount = Math.round(
3283 mAccessCount[i] * fractionToRemove);
3284 if (spliceAccessCount > 0) {
3285 if (splice == null) {
3286 splice = new HistoricalOp(mOp);
3287 }
3288 splice.getOrCreateAccessCount()[i] = spliceAccessCount;
3289 mAccessCount[i] -= spliceAccessCount;
3290 }
3291 }
3292 }
3293
3294 if (mRejectCount != null) {
3295 for (int i = 0; i < _NUM_UID_STATE; i++) {
3296 final long spliceRejectCount = Math.round(
3297 mRejectCount[i] * fractionToRemove);
3298
3299 if (spliceRejectCount > 0) {
3300 if (splice == null) {
3301 splice = new HistoricalOp(mOp);
3302 }
3303 splice.getOrCreateRejectCount()[i] = spliceRejectCount;
3304 mRejectCount[i] -= spliceRejectCount;
3305 }
3306 }
3307 }
3308
3309 if (mAccessDuration != null) {
3310 for (int i = 0; i < _NUM_UID_STATE; i++) {
3311 final long spliceAccessDuration = Math.round(
3312 mAccessDuration[i] * fractionToRemove);
3313 if (spliceAccessDuration > 0) {
3314 if (splice == null) {
3315 splice = new HistoricalOp(mOp);
3316 }
3317 splice.getOrCreateAccessDuration()[i] = spliceAccessDuration;
3318 mAccessDuration[i] -= spliceAccessDuration;
3319 }
3320 }
3321 }
3322 return splice;
3323 }
3324
3325 private void merge(@NonNull HistoricalOp other) {
3326 if (other.mAccessCount != null) {
3327 for (int i = 0; i < _NUM_UID_STATE; i++) {
3328 getOrCreateAccessCount()[i] += other.mAccessCount[i];
3329 }
3330 }
3331 if (other.mRejectCount != null) {
3332 for (int i = 0; i < _NUM_UID_STATE; i++) {
3333 getOrCreateRejectCount()[i] += other.mRejectCount[i];
3334 }
3335 }
3336 if (other.mAccessDuration != null) {
3337 for (int i = 0; i < _NUM_UID_STATE; i++) {
3338 getOrCreateAccessDuration()[i] += other.mAccessDuration[i];
3339 }
3340 }
3341 }
3342
3343 private void increaseAccessCount(@UidState int uidState, long increment) {
3344 getOrCreateAccessCount()[uidState] += increment;
3345 }
3346
3347 private void increaseRejectCount(@UidState int uidState, long increment) {
3348 getOrCreateRejectCount()[uidState] += increment;
3349 }
3350
3351 private void increaseAccessDuration(@UidState int uidState, long increment) {
3352 getOrCreateAccessDuration()[uidState] += increment;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003353 }
3354
3355 /**
3356 * Gets the op name.
3357 *
3358 * @return The op name.
3359 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003360 public @NonNull String getOpName() {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003361 return sOpToString[mOp];
3362 }
3363
Svet Ganov8455ba22019-01-02 13:05:56 -08003364 /** @hide */
3365 public int getOpCode() {
3366 return mOp;
3367 }
3368
Svet Ganovad0a49b2018-10-29 10:07:08 -07003369 /**
3370 * Gets the number times the op was accessed (performed) in the foreground.
3371 *
3372 * @return The times the op was accessed in the foreground.
3373 *
3374 * @see #getBackgroundAccessCount()
3375 * @see #getAccessCount(int)
3376 */
3377 public long getForegroundAccessCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003378 if (mAccessCount == null) {
3379 return 0;
3380 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003381 return sum(mAccessCount, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
3382 }
3383
3384 /**
3385 * Gets the number times the op was accessed (performed) in the background.
3386 *
3387 * @return The times the op was accessed in the background.
3388 *
3389 * @see #getForegroundAccessCount()
3390 * @see #getAccessCount(int)
3391 */
3392 public long getBackgroundAccessCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003393 if (mAccessCount == null) {
3394 return 0;
3395 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003396 return sum(mAccessCount, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
3397 }
3398
3399 /**
3400 * Gets the number times the op was accessed (performed) for a given uid state.
3401 *
3402 * @param uidState The UID state for which to query. Could be one of
3403 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08003404 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07003405 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3406 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3407 *
3408 * @return The times the op was accessed for the given UID state.
3409 *
3410 * @see #getForegroundAccessCount()
3411 * @see #getBackgroundAccessCount()
3412 */
3413 public long getAccessCount(@UidState int uidState) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003414 if (mAccessCount == null) {
3415 return 0;
3416 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003417 return mAccessCount[uidState];
3418 }
3419
3420 /**
3421 * Gets the number times the op was rejected in the foreground.
3422 *
3423 * @return The times the op was rejected in the foreground.
3424 *
3425 * @see #getBackgroundRejectCount()
3426 * @see #getRejectCount(int)
3427 */
3428 public long getForegroundRejectCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003429 if (mRejectCount == null) {
3430 return 0;
3431 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003432 return sum(mRejectCount, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
3433 }
3434
3435 /**
3436 * Gets the number times the op was rejected in the background.
3437 *
3438 * @return The times the op was rejected in the background.
3439 *
3440 * @see #getForegroundRejectCount()
3441 * @see #getRejectCount(int)
3442 */
3443 public long getBackgroundRejectCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003444 if (mRejectCount == null) {
3445 return 0;
3446 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003447 return sum(mRejectCount, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
3448 }
3449
3450 /**
3451 * Gets the number times the op was rejected for a given uid state.
3452 *
3453 * @param uidState The UID state for which to query. Could be one of
3454 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08003455 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07003456 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3457 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3458 *
3459 * @return The times the op was rejected for the given UID state.
3460 *
3461 * @see #getForegroundRejectCount()
3462 * @see #getBackgroundRejectCount()
3463 */
3464 public long getRejectCount(@UidState int uidState) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003465 if (mRejectCount == null) {
3466 return 0;
3467 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003468 return mRejectCount[uidState];
3469 }
3470
3471 /**
3472 * Gets the total duration the app op was accessed (performed) in the foreground.
3473 *
3474 * @return The total duration the app op was accessed in the foreground.
3475 *
3476 * @see #getBackgroundAccessDuration()
3477 * @see #getAccessDuration(int)
3478 */
3479 public long getForegroundAccessDuration() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003480 if (mAccessDuration == null) {
3481 return 0;
3482 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003483 return sum(mAccessDuration, UID_STATE_PERSISTENT, UID_STATE_LAST_NON_RESTRICTED + 1);
3484 }
3485
3486 /**
3487 * Gets the total duration the app op was accessed (performed) in the background.
3488 *
3489 * @return The total duration the app op was accessed in the background.
3490 *
3491 * @see #getForegroundAccessDuration()
3492 * @see #getAccessDuration(int)
3493 */
3494 public long getBackgroundAccessDuration() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003495 if (mAccessDuration == null) {
3496 return 0;
3497 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003498 return sum(mAccessDuration, UID_STATE_LAST_NON_RESTRICTED + 1, _NUM_UID_STATE);
3499 }
3500
3501 /**
3502 * Gets the total duration the app op was accessed (performed) for a given UID state.
3503 *
3504 * @param uidState The UID state for which to query. Could be one of
3505 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08003506 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07003507 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3508 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3509 *
3510 * @return The total duration the app op was accessed for the given UID state.
3511 *
3512 * @see #getForegroundAccessDuration()
3513 * @see #getBackgroundAccessDuration()
3514 */
3515 public long getAccessDuration(@UidState int uidState) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003516 if (mAccessDuration == null) {
3517 return 0;
3518 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003519 return mAccessDuration[uidState];
3520 }
3521
3522 @Override
3523 public int describeContents() {
3524 return 0;
3525 }
3526
3527 @Override
3528 public void writeToParcel(Parcel parcel, int flags) {
3529 parcel.writeInt(mOp);
3530 parcel.writeLongArray(mAccessCount);
3531 parcel.writeLongArray(mRejectCount);
3532 parcel.writeLongArray(mAccessDuration);
3533 }
3534
Svet Ganov8455ba22019-01-02 13:05:56 -08003535 private void accept(@NonNull HistoricalOpsVisitor visitor) {
3536 visitor.visitHistoricalOp(this);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003537 }
3538
Svet Ganov8455ba22019-01-02 13:05:56 -08003539 private @NonNull long[] getOrCreateAccessCount() {
3540 if (mAccessCount == null) {
3541 mAccessCount = new long[_NUM_UID_STATE];
3542 }
3543 return mAccessCount;
3544 }
3545
3546 private @NonNull long[] getOrCreateRejectCount() {
3547 if (mRejectCount == null) {
3548 mRejectCount = new long[_NUM_UID_STATE];
3549 }
3550 return mRejectCount;
3551 }
3552
3553 private @NonNull long[] getOrCreateAccessDuration() {
3554 if (mAccessDuration == null) {
3555 mAccessDuration = new long[_NUM_UID_STATE];
3556 }
3557 return mAccessDuration;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003558 }
3559
3560 /**
3561 *
3562 * Computes the sum given the start and end index.
3563 *
3564 * @param counts The data array.
3565 * @param start The start index (inclusive)
3566 * @param end The end index (exclusive)
3567 * @return The sum.
3568 */
3569 private static long sum(@NonNull long[] counts, int start, int end) {
3570 long totalCount = 0;
Joel Galensond829b162018-11-12 10:43:55 -08003571 for (int i = start; i < end; i++) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003572 totalCount += counts[i];
3573 }
3574 return totalCount;
3575 }
3576
Svet Ganov8455ba22019-01-02 13:05:56 -08003577 /**
3578 * Multiplies the entries in the array with the passed in scale factor and
3579 * rounds the result at up 0.5 boundary.
3580 *
3581 * @param data The data to scale.
3582 * @param scaleFactor The scale factor.
3583 */
3584 private static void scale(@NonNull long[] data, double scaleFactor) {
3585 if (data != null) {
3586 for (int i = 0; i < _NUM_UID_STATE; i++) {
3587 data[i] = (long) HistoricalOps.round((double) data[i] * scaleFactor);
3588 }
3589 }
3590 }
3591
3592 public static final Creator<HistoricalOp> CREATOR = new Creator<HistoricalOp>() {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003593 @Override
Svet Ganov8455ba22019-01-02 13:05:56 -08003594 public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) {
3595 return new HistoricalOp(source);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003596 }
3597
3598 @Override
Svet Ganov8455ba22019-01-02 13:05:56 -08003599 public @NonNull HistoricalOp[] newArray(int size) {
3600 return new HistoricalOp[size];
Svet Ganovad0a49b2018-10-29 10:07:08 -07003601 }
3602 };
Svet Ganov8455ba22019-01-02 13:05:56 -08003603
3604 @Override
3605 public boolean equals(Object obj) {
3606 if (this == obj) {
3607 return true;
3608 }
3609 if (obj == null || getClass() != obj.getClass()) {
3610 return false;
3611 }
3612 final HistoricalOp other = (HistoricalOp) obj;
3613 if (mOp != other.mOp) {
3614 return false;
3615 }
3616 if (!Arrays.equals(mAccessCount, other.mAccessCount)) {
3617 return false;
3618 }
3619 if (!Arrays.equals(mRejectCount, other.mRejectCount)) {
3620 return false;
3621 }
3622 return Arrays.equals(mAccessDuration, other.mAccessDuration);
3623 }
3624
3625 @Override
3626 public int hashCode() {
3627 int result = mOp;
3628 result = 31 * result + Arrays.hashCode(mAccessCount);
3629 result = 31 * result + Arrays.hashCode(mRejectCount);
3630 result = 31 * result + Arrays.hashCode(mAccessDuration);
3631 return result;
3632 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003633 }
3634
3635 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08003636 * Callback for notification of changes to operation state.
3637 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07003638 public interface OnOpChangedListener {
3639 public void onOpChanged(String op, String packageName);
3640 }
3641
3642 /**
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08003643 * Callback for notification of changes to operation active state.
3644 *
3645 * @hide
3646 */
Svet Ganovf7b47252018-02-26 11:11:27 -08003647 @TestApi
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08003648 public interface OnOpActiveChangedListener {
3649 /**
3650 * Called when the active state of an app op changes.
3651 *
3652 * @param code The op code.
3653 * @param uid The UID performing the operation.
3654 * @param packageName The package performing the operation.
3655 * @param active Whether the operation became active or inactive.
3656 */
3657 void onOpActiveChanged(int code, int uid, String packageName, boolean active);
3658 }
3659
3660 /**
Svet Ganovb3d2ae22018-12-17 22:06:15 -08003661 * Callback for notification of an op being noted.
3662 *
3663 * @hide
3664 */
3665 public interface OnOpNotedListener {
3666 /**
3667 * Called when an op was noted.
3668 *
3669 * @param code The op code.
3670 * @param uid The UID performing the operation.
3671 * @param packageName The package performing the operation.
3672 * @param result The result of the note.
3673 */
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05003674 void onOpNoted(int code, int uid, String packageName, int result);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08003675 }
3676
3677 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07003678 * Callback for notification of changes to operation state.
3679 * This allows you to see the raw op codes instead of strings.
3680 * @hide
3681 */
3682 public static class OnOpChangedInternalListener implements OnOpChangedListener {
3683 public void onOpChanged(String op, String packageName) { }
3684 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -08003685 }
3686
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07003687 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003688 mContext = context;
3689 mService = service;
3690 }
3691
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08003692 /**
3693 * Retrieve current operation state for all applications.
3694 *
3695 * @param ops The set of operations you are interested in, or null if you want all of them.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07003696 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08003697 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003698 @SystemApi
3699 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
3700 public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops) {
3701 final int opCount = ops.length;
3702 final int[] opCodes = new int[opCount];
3703 for (int i = 0; i < opCount; i++) {
3704 opCodes[i] = sOpStrToOp.get(ops[i]);
3705 }
3706 final List<AppOpsManager.PackageOps> result = getPackagesForOps(opCodes);
3707 return (result != null) ? result : Collections.emptyList();
3708 }
3709
3710 /**
3711 * Retrieve current operation state for all applications.
3712 *
3713 * @param ops The set of operations you are interested in, or null if you want all of them.
3714 * @hide
3715 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07003716 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01003717 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08003718 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
3719 try {
3720 return mService.getPackagesForOps(ops);
3721 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07003722 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08003723 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08003724 }
3725
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08003726 /**
3727 * Retrieve current operation state for one application.
3728 *
3729 * @param uid The uid of the application of interest.
3730 * @param packageName The name of the application of interest.
3731 * @param ops The set of operations you are interested in, or null if you want all of them.
Svet Ganov8455ba22019-01-02 13:05:56 -08003732 *
3733 * @deprecated The int op codes are not stable and you should use the string based op
3734 * names which are stable and namespaced. Use
3735 * {@link #getOpsForPackage(int, String, String...)})}.
3736 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07003737 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08003738 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003739 @Deprecated
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07003740 @SystemApi
Dianne Hackbornc216a262018-04-26 13:46:22 -07003741 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov8455ba22019-01-02 13:05:56 -08003742 public List<PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
Dianne Hackborn72e39832013-01-18 18:36:09 -08003743 try {
3744 return mService.getOpsForPackage(uid, packageName, ops);
3745 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07003746 throw e.rethrowFromSystemServer();
Dianne Hackborn72e39832013-01-18 18:36:09 -08003747 }
Dianne Hackborn72e39832013-01-18 18:36:09 -08003748 }
3749
Svet Ganovae0e03a2016-02-25 18:22:10 -08003750 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003751 * Retrieve current operation state for one application. The UID and the
3752 * package must match.
3753 *
3754 * @param uid The uid of the application of interest.
3755 * @param packageName The name of the application of interest.
3756 * @param ops The set of operations you are interested in, or null if you want all of them.
3757 *
3758 * @hide
3759 */
3760 @SystemApi
3761 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
3762 public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid,
3763 @NonNull String packageName, @Nullable String... ops) {
3764 int[] opCodes = null;
3765 if (ops != null) {
3766 opCodes = new int[ops.length];
3767 for (int i = 0; i < ops.length; i++) {
3768 opCodes[i] = strOpToOp(ops[i]);
3769 }
3770 }
3771 try {
3772 final List<PackageOps> result = mService.getOpsForPackage(uid, packageName, opCodes);
3773 if (result == null) {
3774 return Collections.emptyList();
3775 }
3776 return result;
3777 } catch (RemoteException e) {
3778 throw e.rethrowFromSystemServer();
3779 }
3780 }
3781
3782 /**
3783 * Retrieve historical app op stats for a period.
3784 *
Svet Ganov23c88db2019-01-22 20:38:11 -08003785 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08003786 * @param executor Executor on which to run the callback. If <code>null</code>
3787 * the callback is executed on the default executor running on the main thread.
3788 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003789 *
3790 * @throws IllegalArgumentException If any of the argument contracts is violated.
3791 *
3792 * @hide
3793 */
3794 @TestApi
3795 @SystemApi
3796 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov23c88db2019-01-22 20:38:11 -08003797 public void getHistoricalOps(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08003798 @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) {
3799 Preconditions.checkNotNull(executor, "executor cannot be null");
3800 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07003801 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08003802 mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames,
3803 request.mBeginTimeMillis, request.mEndTimeMillis,
Svet Ganov8455ba22019-01-02 13:05:56 -08003804 new RemoteCallback((result) -> {
3805 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
3806 final long identity = Binder.clearCallingIdentity();
3807 try {
3808 executor.execute(() -> callback.accept(ops));
3809 } finally {
3810 Binder.restoreCallingIdentity(identity);
3811 }
3812 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07003813 } catch (RemoteException e) {
3814 throw e.rethrowFromSystemServer();
3815 }
3816 }
3817
3818 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003819 * Retrieve historical app op stats for a period.
Svet Ganov8455ba22019-01-02 13:05:56 -08003820 * <p>
3821 * This method queries only the on disk state and the returned ops are raw,
3822 * which is their times are relative to the history start as opposed to the
3823 * epoch start.
3824 *
Svet Ganov23c88db2019-01-22 20:38:11 -08003825 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08003826 * @param executor Executor on which to run the callback. If <code>null</code>
3827 * the callback is executed on the default executor running on the main thread.
3828 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003829 *
3830 * @throws IllegalArgumentException If any of the argument contracts is violated.
3831 *
3832 * @hide
3833 */
3834 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -07003835 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov23c88db2019-01-22 20:38:11 -08003836 public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08003837 @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) {
3838 Preconditions.checkNotNull(executor, "executor cannot be null");
3839 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07003840 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08003841 mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName,
3842 request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis,
3843 new RemoteCallback((result) -> {
3844 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
Svet Ganov8455ba22019-01-02 13:05:56 -08003845 final long identity = Binder.clearCallingIdentity();
3846 try {
3847 executor.execute(() -> callback.accept(ops));
3848 } finally {
3849 Binder.restoreCallingIdentity(identity);
3850 }
3851 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07003852 } catch (RemoteException e) {
3853 throw e.rethrowFromSystemServer();
3854 }
3855 }
3856
3857 /**
Svet Ganovae0e03a2016-02-25 18:22:10 -08003858 * Sets given app op in the specified mode for app ops in the UID.
3859 * This applies to all apps currently in the UID or installed in
3860 * this UID in the future.
3861 *
3862 * @param code The app op.
3863 * @param uid The UID for which to set the app.
3864 * @param mode The app op mode to set.
3865 * @hide
3866 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08003867 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08003868 public void setUidMode(int code, int uid, @Mode int mode) {
Svet Ganov2af57082015-07-30 08:44:20 -07003869 try {
3870 mService.setUidMode(code, uid, mode);
3871 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07003872 throw e.rethrowFromSystemServer();
Svet Ganov2af57082015-07-30 08:44:20 -07003873 }
3874 }
3875
Svet Ganovae0e03a2016-02-25 18:22:10 -08003876 /**
3877 * Sets given app op in the specified mode for app ops in the UID.
3878 * This applies to all apps currently in the UID or installed in
3879 * this UID in the future.
3880 *
3881 * @param appOp The app op.
3882 * @param uid The UID for which to set the app.
3883 * @param mode The app op mode to set.
3884 * @hide
3885 */
3886 @SystemApi
Eugene Susla93519852018-06-13 16:44:31 -07003887 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08003888 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08003889 public void setUidMode(String appOp, int uid, @Mode int mode) {
Svet Ganovae0e03a2016-02-25 18:22:10 -08003890 try {
3891 mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
3892 } catch (RemoteException e) {
3893 throw e.rethrowFromSystemServer();
3894 }
3895 }
3896
Svet Ganov2af57082015-07-30 08:44:20 -07003897 /** @hide */
Svet Ganov9cea80cd2016-02-16 11:47:00 -08003898 public void setUserRestriction(int code, boolean restricted, IBinder token) {
Ruben Brunk29931bc2016-03-11 00:24:26 -08003899 setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
3900 }
3901
3902 /** @hide */
3903 public void setUserRestriction(int code, boolean restricted, IBinder token,
3904 String[] exceptionPackages) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07003905 setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
3906 }
3907
3908 /** @hide */
3909 public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
3910 String[] exceptionPackages, int userId) {
Svet Ganov9cea80cd2016-02-16 11:47:00 -08003911 try {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07003912 mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
Svet Ganov9cea80cd2016-02-16 11:47:00 -08003913 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07003914 throw e.rethrowFromSystemServer();
Svet Ganov9cea80cd2016-02-16 11:47:00 -08003915 }
3916 }
3917
3918 /** @hide */
Peter Visontayb97fbc82017-12-21 16:23:55 +00003919 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08003920 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08003921 public void setMode(int code, int uid, String packageName, @Mode int mode) {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08003922 try {
3923 mService.setMode(code, uid, packageName, mode);
3924 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07003925 throw e.rethrowFromSystemServer();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08003926 }
3927 }
3928
John Spurlock1af30c72014-03-10 08:33:35 -04003929 /**
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08003930 * Change the operating mode for the given op in the given app package. You must pass
3931 * in both the uid and name of the application whose mode is being modified; if these
3932 * do not match, the modification will not be applied.
3933 *
3934 * @param op The operation to modify. One of the OPSTR_* constants.
3935 * @param uid The user id of the application whose mode will be changed.
3936 * @param packageName The name of the application package name whose mode will
3937 * be changed.
3938 * @hide
3939 */
3940 @SystemApi
3941 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08003942 public void setMode(String op, int uid, String packageName, @Mode int mode) {
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08003943 try {
3944 mService.setMode(strOpToOp(op), uid, packageName, mode);
3945 } catch (RemoteException e) {
3946 throw e.rethrowFromSystemServer();
3947 }
3948 }
3949
3950 /**
John Spurlock1af30c72014-03-10 08:33:35 -04003951 * Set a non-persisted restriction on an audio operation at a stream-level.
3952 * Restrictions are temporary additional constraints imposed on top of the persisted rules
3953 * defined by {@link #setMode}.
3954 *
3955 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04003956 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04003957 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
3958 * @param exceptionPackages Optional list of packages to exclude from the restriction.
3959 * @hide
3960 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08003961 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01003962 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -08003963 public void setRestriction(int code, @AttributeUsage int usage, @Mode int mode,
John Spurlock7b414672014-07-18 13:02:39 -04003964 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04003965 try {
3966 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04003967 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04003968 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07003969 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04003970 }
3971 }
3972
Dianne Hackborn607b4142013-08-02 18:10:10 -07003973 /** @hide */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08003974 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01003975 @UnsupportedAppUsage
Dianne Hackborn607b4142013-08-02 18:10:10 -07003976 public void resetAllModes() {
3977 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -07003978 mService.resetAllModes(mContext.getUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07003979 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07003980 throw e.rethrowFromSystemServer();
Dianne Hackborn607b4142013-08-02 18:10:10 -07003981 }
3982 }
3983
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07003984 /**
Svet Ganovfbf01f72015-04-28 18:39:06 -07003985 * Gets the app op name associated with a given permission.
3986 * The app op name is one of the public constants defined
3987 * in this class such as {@link #OPSTR_COARSE_LOCATION}.
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07003988 * This API is intended to be used for mapping runtime
3989 * permissions to the corresponding app op.
Svet Ganovfbf01f72015-04-28 18:39:06 -07003990 *
3991 * @param permission The permission.
3992 * @return The app op associated with the permission or null.
Svet Ganovfbf01f72015-04-28 18:39:06 -07003993 */
Svet Ganovfbf01f72015-04-28 18:39:06 -07003994 public static String permissionToOp(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08003995 final Integer opCode = sPermToOp.get(permission);
Svet Ganovb9d71a62015-04-30 10:38:13 -07003996 if (opCode == null) {
3997 return null;
3998 }
3999 return sOpToString[opCode];
Svet Ganovfbf01f72015-04-28 18:39:06 -07004000 }
4001
4002 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004003 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004004 * You can watch op changes only for your UID.
4005 *
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07004006 * @param op The operation to monitor, one of OPSTR_*.
4007 * @param packageName The name of the application to monitor.
4008 * @param callback Where to report changes.
4009 */
4010 public void startWatchingMode(String op, String packageName,
4011 final OnOpChangedListener callback) {
4012 startWatchingMode(strOpToOp(op), packageName, callback);
4013 }
4014
4015 /**
4016 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004017 * You can watch op changes only for your UID.
4018 *
4019 * @param op The operation to monitor, one of OPSTR_*.
4020 * @param packageName The name of the application to monitor.
4021 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
4022 * @param callback Where to report changes.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004023 */
4024 public void startWatchingMode(String op, String packageName, int flags,
4025 final OnOpChangedListener callback) {
4026 startWatchingMode(strOpToOp(op), packageName, flags, callback);
4027 }
4028
4029 /**
4030 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004031 *
4032 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08004033 * you can watch changes only for your UID.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004034 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004035 * @param op The operation to monitor, one of OP_*.
4036 * @param packageName The name of the application to monitor.
4037 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07004038 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004039 */
Jeff Sharkeybf6b2132018-02-27 11:16:37 -07004040 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004041 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004042 startWatchingMode(op, packageName, 0, callback);
4043 }
4044
4045 /**
4046 * Monitor for changes to the operating mode for the given op in the given app package.
4047 *
4048 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4049 * you can watch changes only for your UID.
4050 *
4051 * @param op The operation to monitor, one of OP_*.
4052 * @param packageName The name of the application to monitor.
4053 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
4054 * @param callback Where to report changes.
4055 * @hide
4056 */
4057 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
4058 public void startWatchingMode(int op, String packageName, int flags,
4059 final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08004060 synchronized (mModeWatchers) {
4061 IAppOpsCallback cb = mModeWatchers.get(callback);
4062 if (cb == null) {
4063 cb = new IAppOpsCallback.Stub() {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07004064 public void opChanged(int op, int uid, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004065 if (callback instanceof OnOpChangedInternalListener) {
4066 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
4067 }
4068 if (sOpToString[op] != null) {
4069 callback.onOpChanged(sOpToString[op], packageName);
4070 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08004071 }
4072 };
4073 mModeWatchers.put(callback, cb);
4074 }
4075 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004076 mService.startWatchingModeWithFlags(op, packageName, flags, cb);
Dianne Hackbornc2293022013-02-06 23:14:49 -08004077 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004078 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08004079 }
4080 }
4081 }
4082
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004083 /**
4084 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
4085 * monitoring associated with this callback will be removed.
4086 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004087 public void stopWatchingMode(OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08004088 synchronized (mModeWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004089 IAppOpsCallback cb = mModeWatchers.remove(callback);
Dianne Hackbornc2293022013-02-06 23:14:49 -08004090 if (cb != null) {
4091 try {
4092 mService.stopWatchingMode(cb);
4093 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004094 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08004095 }
4096 }
4097 }
4098 }
4099
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004100 /**
4101 * Start watching for changes to the active state of app ops. An app op may be
4102 * long running and it has a clear start and stop delimiters. If an op is being
4103 * started or stopped by any package you will get a callback. To change the
4104 * watched ops for a registered callback you need to unregister and register it
4105 * again.
4106 *
Svet Ganovf7b47252018-02-26 11:11:27 -08004107 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4108 * you can watch changes only for your UID.
4109 *
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004110 * @param ops The ops to watch.
4111 * @param callback Where to report changes.
4112 *
4113 * @see #isOperationActive(int, int, String)
4114 * @see #stopWatchingActive(OnOpActiveChangedListener)
4115 * @see #startOp(int, int, String)
4116 * @see #finishOp(int, int, String)
4117 *
4118 * @hide
4119 */
Svet Ganovf7b47252018-02-26 11:11:27 -08004120 @TestApi
4121 // TODO: Uncomment below annotation once b/73559440 is fixed
4122 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004123 public void startWatchingActive(@NonNull int[] ops,
4124 @NonNull OnOpActiveChangedListener callback) {
4125 Preconditions.checkNotNull(ops, "ops cannot be null");
4126 Preconditions.checkNotNull(callback, "callback cannot be null");
4127 IAppOpsActiveCallback cb;
4128 synchronized (mActiveWatchers) {
4129 cb = mActiveWatchers.get(callback);
4130 if (cb != null) {
4131 return;
4132 }
4133 cb = new IAppOpsActiveCallback.Stub() {
4134 @Override
4135 public void opActiveChanged(int op, int uid, String packageName, boolean active) {
4136 callback.onOpActiveChanged(op, uid, packageName, active);
4137 }
4138 };
4139 mActiveWatchers.put(callback, cb);
4140 }
4141 try {
4142 mService.startWatchingActive(ops, cb);
4143 } catch (RemoteException e) {
4144 throw e.rethrowFromSystemServer();
4145 }
4146 }
4147
4148 /**
4149 * Stop watching for changes to the active state of an app op. An app op may be
4150 * long running and it has a clear start and stop delimiters. Unregistering a
4151 * non-registered callback has no effect.
4152 *
4153 * @see #isOperationActive#(int, int, String)
4154 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
4155 * @see #startOp(int, int, String)
4156 * @see #finishOp(int, int, String)
4157 *
4158 * @hide
4159 */
Svet Ganovf7b47252018-02-26 11:11:27 -08004160 @TestApi
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004161 public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
4162 synchronized (mActiveWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004163 final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004164 if (cb != null) {
4165 try {
4166 mService.stopWatchingActive(cb);
4167 } catch (RemoteException e) {
4168 throw e.rethrowFromSystemServer();
4169 }
4170 }
4171 }
4172 }
4173
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004174 /**
4175 * Start watching for noted app ops. An app op may be immediate or long running.
4176 * Immediate ops are noted while long running ones are started and stopped. This
4177 * method allows registering a listener to be notified when an app op is noted. If
4178 * an op is being noted by any package you will get a callback. To change the
4179 * watched ops for a registered callback you need to unregister and register it again.
4180 *
4181 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4182 * you can watch changes only for your UID.
4183 *
4184 * @param ops The ops to watch.
4185 * @param callback Where to report changes.
4186 *
4187 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
4188 * @see #stopWatchingNoted(OnOpNotedListener)
4189 * @see #noteOp(String, int, String)
4190 *
4191 * @hide
4192 */
4193 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004194 public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004195 IAppOpsNotedCallback cb;
4196 synchronized (mNotedWatchers) {
4197 cb = mNotedWatchers.get(callback);
4198 if (cb != null) {
4199 return;
4200 }
4201 cb = new IAppOpsNotedCallback.Stub() {
4202 @Override
4203 public void opNoted(int op, int uid, String packageName, int mode) {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004204 callback.onOpNoted(op, uid, packageName, mode);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004205 }
4206 };
4207 mNotedWatchers.put(callback, cb);
4208 }
4209 try {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004210 mService.startWatchingNoted(ops, cb);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004211 } catch (RemoteException e) {
4212 throw e.rethrowFromSystemServer();
4213 }
4214 }
4215
4216 /**
4217 * Stop watching for noted app ops. An app op may be immediate or long running.
4218 * Unregistering a non-registered callback has no effect.
4219 *
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004220 * @see #startWatchingNoted(int[], OnOpNotedListener)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004221 * @see #noteOp(String, int, String)
4222 *
4223 * @hide
4224 */
4225 public void stopWatchingNoted(@NonNull OnOpNotedListener callback) {
4226 synchronized (mNotedWatchers) {
4227 final IAppOpsNotedCallback cb = mNotedWatchers.get(callback);
4228 if (cb != null) {
4229 try {
4230 mService.stopWatchingNoted(cb);
4231 } catch (RemoteException e) {
4232 throw e.rethrowFromSystemServer();
4233 }
4234 }
4235 }
4236 }
4237
Dianne Hackborn95d78532013-09-11 09:51:14 -07004238 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
4239 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
4240 }
4241
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07004242 /**
4243 * {@hide}
4244 */
Philip P. Moltmann33115152018-04-11 13:39:36 -07004245 @TestApi
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07004246 public static int strOpToOp(String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004247 Integer val = sOpStrToOp.get(op);
4248 if (val == null) {
4249 throw new IllegalArgumentException("Unknown operation string: " + op);
4250 }
4251 return val;
4252 }
4253
4254 /**
4255 * Do a quick check for whether an application might be able to perform an operation.
4256 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
4257 * or {@link #startOp(String, int, String)} for your actual security checks, which also
4258 * ensure that the given uid and package name are consistent. This function can just be
4259 * used for a quick check to see if an operation has been disabled for the application,
4260 * as an early reject of some work. This does not modify the time stamp or other data
4261 * about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07004262 *
4263 * <p>Important things this will not do (which you need to ultimate use
4264 * {@link #noteOp(String, int, String)} or {@link #startOp(String, int, String)} to cover):</p>
4265 * <ul>
4266 * <li>Verifying the uid and package are consistent, so callers can't spoof
4267 * their identity.</li>
4268 * <li>Taking into account the current foreground/background state of the
4269 * app; apps whose mode varies by this state will always be reported
4270 * as {@link #MODE_ALLOWED}.</li>
4271 * </ul>
4272 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004273 * @param op The operation to check. One of the OPSTR_* constants.
4274 * @param uid The user id of the application attempting to perform the operation.
4275 * @param packageName The name of the application attempting to perform the operation.
4276 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4277 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4278 * causing the app to crash).
4279 * @throws SecurityException If the app has been configured to crash on this op.
4280 */
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07004281 public int unsafeCheckOp(String op, int uid, String packageName) {
4282 return checkOp(strOpToOp(op), uid, packageName);
4283 }
4284
4285 /**
4286 * @deprecated Renamed to {@link #unsafeCheckOp(String, int, String)}.
4287 */
4288 @Deprecated
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004289 public int checkOp(String op, int uid, String packageName) {
4290 return checkOp(strOpToOp(op), uid, packageName);
4291 }
4292
4293 /**
John Spurlock925b85e2014-03-10 16:52:11 -04004294 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004295 * returns {@link #MODE_ERRORED}.
4296 */
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07004297 public int unsafeCheckOpNoThrow(String op, int uid, String packageName) {
4298 return checkOpNoThrow(strOpToOp(op), uid, packageName);
4299 }
4300
4301 /**
4302 * @deprecated Renamed to {@link #unsafeCheckOpNoThrow(String, int, String)}.
4303 */
4304 @Deprecated
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004305 public int checkOpNoThrow(String op, int uid, String packageName) {
4306 return checkOpNoThrow(strOpToOp(op), uid, packageName);
4307 }
4308
4309 /**
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004310 * Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op.
4311 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004312 */
4313 public int unsafeCheckOpRaw(String op, int uid, String packageName) {
4314 try {
Svet Ganov9d528a12018-12-19 17:23:11 -08004315 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004316 } catch (RemoteException e) {
4317 throw e.rethrowFromSystemServer();
4318 }
4319 }
4320
4321 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004322 * Make note of an application performing an operation. Note that you must pass
4323 * in both the uid and name of the application to be checked; this function will verify
4324 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
4325 * succeeds, the last execution time of the operation for this app will be updated to
4326 * the current time.
4327 * @param op The operation to note. One of the OPSTR_* constants.
4328 * @param uid The user id of the application attempting to perform the operation.
4329 * @param packageName The name of the application attempting to perform the operation.
4330 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4331 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4332 * causing the app to crash).
4333 * @throws SecurityException If the app has been configured to crash on this op.
4334 */
4335 public int noteOp(String op, int uid, String packageName) {
4336 return noteOp(strOpToOp(op), uid, packageName);
4337 }
4338
4339 /**
4340 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
4341 * returns {@link #MODE_ERRORED}.
4342 */
4343 public int noteOpNoThrow(String op, int uid, String packageName) {
4344 return noteOpNoThrow(strOpToOp(op), uid, packageName);
4345 }
4346
4347 /**
Svet Ganov99b60432015-06-27 13:15:22 -07004348 * Make note of an application performing an operation on behalf of another
4349 * application when handling an IPC. Note that you must pass the package name
4350 * of the application that is being proxied while its UID will be inferred from
4351 * the IPC state; this function will verify that the calling uid and proxied
4352 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
4353 * succeeds, the last execution time of the operation for the proxied app and
4354 * your app will be updated to the current time.
4355 * @param op The operation to note. One of the OPSTR_* constants.
4356 * @param proxiedPackageName The name of the application calling into the proxy application.
4357 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4358 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4359 * causing the app to crash).
4360 * @throws SecurityException If the app has been configured to crash on this op.
4361 */
4362 public int noteProxyOp(String op, String proxiedPackageName) {
4363 return noteProxyOp(strOpToOp(op), proxiedPackageName);
4364 }
4365
4366 /**
4367 * Like {@link #noteProxyOp(String, String)} but instead
4368 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08004369 *
4370 * <p>This API requires the package with the {@code proxiedPackageName} to belongs to
4371 * {@link Binder#getCallingUid()}.
Svet Ganov99b60432015-06-27 13:15:22 -07004372 */
4373 public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
4374 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
4375 }
4376
4377 /**
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08004378 * Like {@link #noteProxyOp(String, String)} but instead
4379 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
4380 *
4381 * <p>This API requires package with the {@code proxiedPackageName} to belong to
4382 * {@code proxiedUid}.
4383 *
4384 * @param op The op to note
4385 * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
4386 * noted for the "android" package
4387 * @param proxiedUid The uid the package belongs to
4388 *
4389 * @hide
4390 */
4391 @SystemApi
4392 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
4393 int proxiedUid) {
4394 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid);
4395 }
4396
4397 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004398 * Report that an application has started executing a long-running operation. Note that you
4399 * must pass in both the uid and name of the application to be checked; this function will
4400 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
4401 * succeeds, the last execution time of the operation for this app will be updated to
4402 * the current time and the operation will be marked as "running". In this case you must
4403 * later call {@link #finishOp(String, int, String)} to report when the application is no
4404 * longer performing the operation.
4405 * @param op The operation to start. One of the OPSTR_* constants.
4406 * @param uid The user id of the application attempting to perform the operation.
4407 * @param packageName The name of the application attempting to perform the operation.
4408 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4409 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4410 * causing the app to crash).
4411 * @throws SecurityException If the app has been configured to crash on this op.
4412 */
4413 public int startOp(String op, int uid, String packageName) {
4414 return startOp(strOpToOp(op), uid, packageName);
4415 }
4416
4417 /**
4418 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
4419 * returns {@link #MODE_ERRORED}.
4420 */
4421 public int startOpNoThrow(String op, int uid, String packageName) {
4422 return startOpNoThrow(strOpToOp(op), uid, packageName);
4423 }
4424
4425 /**
4426 * Report that an application is no longer performing an operation that had previously
4427 * been started with {@link #startOp(String, int, String)}. There is no validation of input
4428 * or result; the parameters supplied here must be the exact same ones previously passed
4429 * in when starting the operation.
4430 */
4431 public void finishOp(String op, int uid, String packageName) {
4432 finishOp(strOpToOp(op), uid, packageName);
4433 }
4434
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004435 /**
4436 * Do a quick check for whether an application might be able to perform an operation.
4437 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
4438 * or {@link #startOp(int, int, String)} for your actual security checks, which also
4439 * ensure that the given uid and package name are consistent. This function can just be
4440 * used for a quick check to see if an operation has been disabled for the application,
4441 * as an early reject of some work. This does not modify the time stamp or other data
4442 * about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07004443 *
4444 * <p>Important things this will not do (which you need to ultimate use
4445 * {@link #noteOp(int, int, String)} or {@link #startOp(int, int, String)} to cover):</p>
4446 * <ul>
4447 * <li>Verifying the uid and package are consistent, so callers can't spoof
4448 * their identity.</li>
4449 * <li>Taking into account the current foreground/background state of the
4450 * app; apps whose mode varies by this state will always be reported
4451 * as {@link #MODE_ALLOWED}.</li>
4452 * </ul>
4453 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004454 * @param op The operation to check. One of the OP_* constants.
4455 * @param uid The user id of the application attempting to perform the operation.
4456 * @param packageName The name of the application attempting to perform the operation.
4457 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4458 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4459 * causing the app to crash).
4460 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004461 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004462 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004463 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08004464 public int checkOp(int op, int uid, String packageName) {
4465 try {
4466 int mode = mService.checkOperation(op, uid, packageName);
4467 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07004468 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08004469 }
4470 return mode;
4471 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004472 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08004473 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08004474 }
4475
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004476 /**
4477 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
4478 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004479 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004480 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004481 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08004482 public int checkOpNoThrow(int op, int uid, String packageName) {
4483 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004484 int mode = mService.checkOperation(op, uid, packageName);
4485 return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08004486 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004487 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08004488 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08004489 }
4490
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004491 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07004492 * Do a quick check to validate if a package name belongs to a UID.
4493 *
4494 * @throws SecurityException if the package name doesn't belong to the given
4495 * UID, or if ownership cannot be verified.
4496 */
4497 public void checkPackage(int uid, String packageName) {
4498 try {
4499 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
4500 throw new SecurityException(
4501 "Package " + packageName + " does not belong to " + uid);
4502 }
4503 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004504 throw e.rethrowFromSystemServer();
Jeff Sharkey911d7f42013-09-05 18:11:45 -07004505 }
4506 }
4507
4508 /**
John Spurlock1af30c72014-03-10 08:33:35 -04004509 * Like {@link #checkOp} but at a stream-level for audio operations.
4510 * @hide
4511 */
4512 public int checkAudioOp(int op, int stream, int uid, String packageName) {
4513 try {
4514 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
4515 if (mode == MODE_ERRORED) {
4516 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
4517 }
4518 return mode;
4519 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004520 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04004521 }
John Spurlock1af30c72014-03-10 08:33:35 -04004522 }
4523
4524 /**
4525 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
4526 * returns {@link #MODE_ERRORED}.
4527 * @hide
4528 */
4529 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
4530 try {
4531 return mService.checkAudioOperation(op, stream, uid, packageName);
4532 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004533 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04004534 }
John Spurlock1af30c72014-03-10 08:33:35 -04004535 }
4536
4537 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004538 * Make note of an application performing an operation. Note that you must pass
4539 * in both the uid and name of the application to be checked; this function will verify
4540 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
4541 * succeeds, the last execution time of the operation for this app will be updated to
4542 * the current time.
4543 * @param op The operation to note. One of the OP_* constants.
4544 * @param uid The user id of the application attempting to perform the operation.
4545 * @param packageName The name of the application attempting to perform the operation.
4546 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4547 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4548 * causing the app to crash).
4549 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004550 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004551 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004552 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004553 public int noteOp(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08004554 final int mode = noteOpNoThrow(op, uid, packageName);
4555 if (mode == MODE_ERRORED) {
4556 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004557 }
Svet Ganovf7b47252018-02-26 11:11:27 -08004558 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004559 }
4560
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004561 /**
Svet Ganov99b60432015-06-27 13:15:22 -07004562 * Make note of an application performing an operation on behalf of another
4563 * application when handling an IPC. Note that you must pass the package name
4564 * of the application that is being proxied while its UID will be inferred from
4565 * the IPC state; this function will verify that the calling uid and proxied
4566 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
4567 * succeeds, the last execution time of the operation for the proxied app and
4568 * your app will be updated to the current time.
4569 * @param op The operation to note. One of the OPSTR_* constants.
4570 * @param proxiedPackageName The name of the application calling into the proxy application.
4571 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4572 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4573 * causing the app to crash).
4574 * @throws SecurityException If the proxy or proxied app has been configured to
4575 * crash on this op.
4576 *
4577 * @hide
4578 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004579 @UnsupportedAppUsage
Svet Ganov99b60432015-06-27 13:15:22 -07004580 public int noteProxyOp(int op, String proxiedPackageName) {
4581 int mode = noteProxyOpNoThrow(op, proxiedPackageName);
4582 if (mode == MODE_ERRORED) {
4583 throw new SecurityException("Proxy package " + mContext.getOpPackageName()
4584 + " from uid " + Process.myUid() + " or calling package "
4585 + proxiedPackageName + " from uid " + Binder.getCallingUid()
4586 + " not allowed to perform " + sOpNames[op]);
4587 }
4588 return mode;
4589 }
4590
4591 /**
4592 * Like {@link #noteProxyOp(int, String)} but instead
4593 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
4594 * @hide
4595 */
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08004596 public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) {
Chad Brubaker9f394312019-02-01 10:29:39 -08004597 logOperationIfNeeded(op, mContext.getOpPackageName(), proxiedPackageName);
Svet Ganov99b60432015-06-27 13:15:22 -07004598 try {
Svet Ganovd873ae62018-06-25 16:39:23 -07004599 return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08004600 proxiedUid, proxiedPackageName);
Svet Ganov99b60432015-06-27 13:15:22 -07004601 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004602 throw e.rethrowFromSystemServer();
Svet Ganov99b60432015-06-27 13:15:22 -07004603 }
Svet Ganov99b60432015-06-27 13:15:22 -07004604 }
4605
4606 /**
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08004607 * Like {@link #noteProxyOp(int, String)} but instead
4608 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
4609 *
4610 * <p>This API requires the package with {@code proxiedPackageName} to belongs to
4611 * {@link Binder#getCallingUid()}.
4612 *
4613 * @hide
4614 */
4615 public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
4616 return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid());
4617 }
4618
4619 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004620 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
4621 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004622 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004623 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004624 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004625 public int noteOpNoThrow(int op, int uid, String packageName) {
Chad Brubaker9f394312019-02-01 10:29:39 -08004626 logOperationIfNeeded(op, packageName, null);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004627 try {
4628 return mService.noteOperation(op, uid, packageName);
4629 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004630 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004631 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004632 }
4633
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004634 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004635 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004636 public int noteOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07004637 return noteOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004638 }
4639
Dianne Hackborne98f5db2013-07-17 17:23:25 -07004640 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004641 @UnsupportedAppUsage
Dianne Hackborne98f5db2013-07-17 17:23:25 -07004642 public static IBinder getToken(IAppOpsService service) {
4643 synchronized (AppOpsManager.class) {
4644 if (sToken != null) {
4645 return sToken;
4646 }
4647 try {
4648 sToken = service.getToken(new Binder());
4649 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004650 throw e.rethrowFromSystemServer();
Dianne Hackborne98f5db2013-07-17 17:23:25 -07004651 }
4652 return sToken;
4653 }
4654 }
4655
Svet Ganovf7b47252018-02-26 11:11:27 -08004656 /** @hide */
4657 public int startOp(int op) {
4658 return startOp(op, Process.myUid(), mContext.getOpPackageName());
4659 }
4660
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004661 /**
4662 * Report that an application has started executing a long-running operation. Note that you
4663 * must pass in both the uid and name of the application to be checked; this function will
4664 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
4665 * succeeds, the last execution time of the operation for this app will be updated to
4666 * the current time and the operation will be marked as "running". In this case you must
4667 * later call {@link #finishOp(int, int, String)} to report when the application is no
4668 * longer performing the operation.
Svet Ganovf7b47252018-02-26 11:11:27 -08004669 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004670 * @param op The operation to start. One of the OP_* constants.
4671 * @param uid The user id of the application attempting to perform the operation.
4672 * @param packageName The name of the application attempting to perform the operation.
4673 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4674 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4675 * causing the app to crash).
4676 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004677 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004678 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004679 public int startOp(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08004680 return startOp(op, uid, packageName, false);
4681 }
4682
4683 /**
4684 * Report that an application has started executing a long-running operation. Similar
4685 * to {@link #startOp(String, int, String) except that if the mode is {@link #MODE_DEFAULT}
4686 * the operation should succeed since the caller has performed its standard permission
4687 * checks which passed and would perform the protected operation for this mode.
4688 *
4689 * @param op The operation to start. One of the OP_* constants.
4690 * @param uid The user id of the application attempting to perform the operation.
4691 * @param packageName The name of the application attempting to perform the operation.
4692 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4693 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4694 * causing the app to crash).
4695 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
4696 *
4697 * @throws SecurityException If the app has been configured to crash on this op or
4698 * the package is not in the passed in UID.
4699 *
4700 * @hide
4701 */
4702 public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
4703 final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault);
4704 if (mode == MODE_ERRORED) {
4705 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004706 }
Svet Ganovf7b47252018-02-26 11:11:27 -08004707 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004708 }
4709
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004710 /**
4711 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
4712 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004713 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004714 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004715 public int startOpNoThrow(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08004716 return startOpNoThrow(op, uid, packageName, false);
4717 }
4718
4719 /**
4720 * Like {@link #startOp(int, int, String, boolean)} but instead of throwing a
4721 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
4722 *
4723 * @param op The operation to start. One of the OP_* constants.
4724 * @param uid The user id of the application attempting to perform the operation.
4725 * @param packageName The name of the application attempting to perform the operation.
4726 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4727 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4728 * causing the app to crash).
4729 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
4730 *
4731 * @hide
4732 */
4733 public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
Chad Brubaker9f394312019-02-01 10:29:39 -08004734 logOperationIfNeeded(op, packageName, null);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004735 try {
Svet Ganovf7b47252018-02-26 11:11:27 -08004736 return mService.startOperation(getToken(mService), op, uid, packageName,
4737 startIfModeDefault);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004738 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004739 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004740 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004741 }
4742
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004743 /**
4744 * Report that an application is no longer performing an operation that had previously
4745 * been started with {@link #startOp(int, int, String)}. There is no validation of input
4746 * or result; the parameters supplied here must be the exact same ones previously passed
4747 * in when starting the operation.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004748 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004749 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004750 public void finishOp(int op, int uid, String packageName) {
Chad Brubaker9f394312019-02-01 10:29:39 -08004751 logOperationIfNeeded(op, packageName, null);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004752 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07004753 mService.finishOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004754 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004755 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004756 }
4757 }
4758
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004759 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004760 public void finishOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07004761 finishOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004762 }
Jeff Sharkey35e46d22017-06-09 10:01:20 -06004763
Svet Ganovf7b47252018-02-26 11:11:27 -08004764 /**
4765 * Checks whether the given op for a UID and package is active.
4766 *
4767 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4768 * you can query only for your UID.
4769 *
4770 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
4771 * @see #stopWatchingMode(OnOpChangedListener)
4772 * @see #finishOp(int)
4773 * @see #startOp(int)
4774 *
4775 * @hide */
4776 @TestApi
4777 // TODO: Uncomment below annotation once b/73559440 is fixed
4778 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey35e46d22017-06-09 10:01:20 -06004779 public boolean isOperationActive(int code, int uid, String packageName) {
4780 try {
4781 return mService.isOperationActive(code, uid, packageName);
4782 } catch (RemoteException e) {
4783 throw e.rethrowFromSystemServer();
4784 }
4785 }
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00004786
4787 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004788 * Configures the app ops persistence for testing.
4789 *
4790 * @param mode The mode in which the historical registry operates.
4791 * @param baseSnapshotInterval The base interval on which we would be persisting a snapshot of
4792 * the historical data. The history is recursive where every subsequent step encompasses
4793 * {@code compressionStep} longer interval with {@code compressionStep} distance between
4794 * snapshots.
4795 * @param compressionStep The compression step in every iteration.
4796 *
4797 * @see #HISTORICAL_MODE_DISABLED
4798 * @see #HISTORICAL_MODE_ENABLED_ACTIVE
4799 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
4800 *
4801 * @hide
4802 */
4803 @TestApi
4804 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
4805 public void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval,
4806 int compressionStep) {
4807 try {
4808 mService.setHistoryParameters(mode, baseSnapshotInterval, compressionStep);
4809 } catch (RemoteException e) {
4810 throw e.rethrowFromSystemServer();
4811 }
4812 }
4813
4814 /**
4815 * Offsets the history by the given duration.
4816 *
4817 * @param offsetMillis The offset duration.
4818 *
4819 * @hide
4820 */
4821 @TestApi
4822 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
4823 public void offsetHistory(long offsetMillis) {
4824 try {
4825 mService.offsetHistory(offsetMillis);
4826 } catch (RemoteException e) {
4827 throw e.rethrowFromSystemServer();
4828 }
4829 }
4830
4831 /**
4832 * Adds ops to the history directly. This could be useful for testing especially
4833 * when the historical registry operates in {@link #HISTORICAL_MODE_ENABLED_PASSIVE}
4834 * mode.
4835 *
4836 * @param ops The ops to add to the history.
4837 *
4838 * @see #setHistoryParameters(int, long, int)
4839 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
4840 *
4841 * @hide
4842 */
4843 @TestApi
4844 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
4845 public void addHistoricalOps(@NonNull HistoricalOps ops) {
4846 try {
4847 mService.addHistoricalOps(ops);
4848 } catch (RemoteException e) {
4849 throw e.rethrowFromSystemServer();
4850 }
4851 }
4852
4853 /**
4854 * Resets the app ops persistence for testing.
4855 *
4856 * @see #setHistoryParameters(int, long, int)
4857 *
4858 * @hide
4859 */
4860 @TestApi
4861 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
4862 public void resetHistoryParameters() {
4863 try {
4864 mService.resetHistoryParameters();
4865 } catch (RemoteException e) {
4866 throw e.rethrowFromSystemServer();
4867 }
4868 }
4869
4870 /**
4871 * Clears all app ops history.
4872 *
4873 * @hide
4874 */
4875 @TestApi
4876 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
4877 public void clearHistory() {
4878 try {
4879 mService.clearHistory();
4880 } catch (RemoteException e) {
4881 throw e.rethrowFromSystemServer();
4882 }
4883 }
4884
4885 /**
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00004886 * Returns all supported operation names.
4887 * @hide
4888 */
4889 @SystemApi
4890 @TestApi
4891 public static String[] getOpStrs() {
4892 return Arrays.copyOf(sOpToString, sOpToString.length);
4893 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07004894
Philip P. Moltmann24576812018-05-07 10:42:05 -07004895
4896 /**
4897 * @return number of App ops
4898 * @hide
4899 */
4900 @TestApi
4901 public static int getNumOps() {
4902 return _NUM_OP;
4903 }
4904
Dianne Hackbornc216a262018-04-26 13:46:22 -07004905 /**
4906 * @hide
4907 */
4908 public static long maxTime(long[] times, int start, int end) {
4909 long time = 0;
4910 for (int i = start; i < end; i++) {
4911 if (times[i] > time) {
4912 time = times[i];
4913 }
4914 }
4915 return time;
4916 }
Svet Ganov8455ba22019-01-02 13:05:56 -08004917
4918 /** @hide */
4919 public static String uidStateToString(@UidState int uidState) {
4920 switch (uidState) {
4921 case UID_STATE_PERSISTENT: {
4922 return "UID_STATE_PERSISTENT";
4923 }
4924 case UID_STATE_TOP: {
4925 return "UID_STATE_TOP";
4926 }
Amith Yamasania0a30a12019-01-22 11:38:06 -08004927 case UID_STATE_FOREGROUND_SERVICE_LOCATION: {
4928 return "UID_STATE_FOREGROUND_SERVICE_LOCATION";
4929 }
Svet Ganov8455ba22019-01-02 13:05:56 -08004930 case UID_STATE_FOREGROUND_SERVICE: {
4931 return "UID_STATE_FOREGROUND_SERVICE";
4932 }
4933 case UID_STATE_FOREGROUND: {
4934 return "UID_STATE_FOREGROUND";
4935 }
4936 case UID_STATE_BACKGROUND: {
4937 return "UID_STATE_BACKGROUND";
4938 }
4939 case UID_STATE_CACHED: {
4940 return "UID_STATE_CACHED";
4941 }
4942 default: {
4943 return "UNKNOWN";
4944 }
4945 }
4946 }
4947
4948 /** @hide */
4949 public static int parseHistoricalMode(@NonNull String mode) {
4950 switch (mode) {
4951 case "HISTORICAL_MODE_ENABLED_ACTIVE": {
4952 return HISTORICAL_MODE_ENABLED_ACTIVE;
4953 }
4954 case "HISTORICAL_MODE_ENABLED_PASSIVE": {
4955 return HISTORICAL_MODE_ENABLED_PASSIVE;
4956 }
4957 default: {
4958 return HISTORICAL_MODE_DISABLED;
4959 }
4960 }
4961 }
4962
4963 /** @hide */
4964 public static String historicalModeToString(@HistoricalMode int mode) {
4965 switch (mode) {
4966 case HISTORICAL_MODE_DISABLED: {
4967 return "HISTORICAL_MODE_DISABLED";
4968 }
4969 case HISTORICAL_MODE_ENABLED_ACTIVE: {
4970 return "HISTORICAL_MODE_ENABLED_ACTIVE";
4971 }
4972 case HISTORICAL_MODE_ENABLED_PASSIVE: {
4973 return "HISTORICAL_MODE_ENABLED_PASSIVE";
4974 }
4975 default: {
4976 return "UNKNOWN";
4977 }
4978 }
4979 }
Ng Zhi An65a99b62018-10-01 11:57:53 -07004980
4981 private static int getSystemAlertWindowDefault() {
4982 final Context context = ActivityThread.currentApplication();
4983 if (context == null) {
4984 return AppOpsManager.MODE_DEFAULT;
4985 }
4986
4987 // system alert window is disable on low ram phones starting from Q
4988 final PackageManager pm = context.getPackageManager();
4989 // TVs are constantly plugged in and has less concern for memory/power
4990 if (ActivityManager.isLowRamDeviceStatic()
4991 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) {
4992 return AppOpsManager.MODE_IGNORED;
4993 }
4994
4995 return AppOpsManager.MODE_DEFAULT;
4996 }
Chad Brubaker7c6dba62019-01-23 15:51:43 -08004997
Chad Brubaker9f394312019-02-01 10:29:39 -08004998 private static void logOperationIfNeeded(int op, String callingPackage, String proxiedPackage) {
Chad Brubaker7c6dba62019-01-23 15:51:43 -08004999 // Check if debug logging propety is enabled.
5000 if (!SystemProperties.getBoolean(DEBUG_LOGGING_ENABLE_PROP, false)) {
5001 return;
5002 }
5003 // Check if this package should be logged.
5004 String packages = SystemProperties.get(DEBUG_LOGGING_PACKAGES_PROP, "");
5005 if (!"".equals(packages) && callingPackage != null) {
5006 boolean found = false;
5007 for (String pkg : packages.split(",")) {
5008 if (callingPackage.equals(pkg)) {
5009 found = true;
5010 break;
5011 }
5012 }
5013 if (!found) {
5014 return;
5015 }
5016 }
5017 String opStr = opToName(op);
5018 // Check if this app op should be logged
5019 String logOps = SystemProperties.get(DEBUG_LOGGING_OPS_PROP, "");
5020 if (!"".equals(logOps)) {
5021 boolean found = false;
5022 for (String logOp : logOps.split(",")) {
5023 if (opStr.equals(logOp)) {
5024 found = true;
5025 break;
5026 }
5027 }
5028 if (!found) {
5029 return;
5030 }
5031 }
5032
5033 // Log a stack trace
5034 Exception here = new Exception("HERE!");
5035 android.util.Log.i(DEBUG_LOGGING_TAG, "Note operation package= " + callingPackage
Chad Brubaker9f394312019-02-01 10:29:39 -08005036 + " proxied= " + proxiedPackage + " op= " + opStr, here);
Chad Brubaker7c6dba62019-01-23 15:51:43 -08005037 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005038}