blob: 91df05f35295115c2b0c4dadfc278ad3947e1138 [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;
Svet Ganovaf189e32019-02-15 18:45:29 -080046import android.util.LongSparseArray;
47import android.util.LongSparseLongArray;
Ng Zhi An65a99b62018-10-01 11:57:53 -070048import android.util.SparseArray;
Jeff Davidson05542602014-08-11 14:07:27 -070049
Svet Ganovb3d2ae22018-12-17 22:06:15 -080050import com.android.internal.annotations.GuardedBy;
Svet Ganov23c88db2019-01-22 20:38:11 -080051
52import com.android.internal.annotations.Immutable;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080053import com.android.internal.app.IAppOpsActiveCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070054import com.android.internal.app.IAppOpsCallback;
Svet Ganovb3d2ae22018-12-17 22:06:15 -080055import com.android.internal.app.IAppOpsNotedCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070056import com.android.internal.app.IAppOpsService;
Svet Ganov8455ba22019-01-02 13:05:56 -080057import com.android.internal.util.ArrayUtils;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080058import com.android.internal.util.Preconditions;
Jeff Davidson05542602014-08-11 14:07:27 -070059
Svet Ganovaf189e32019-02-15 18:45:29 -080060import java.lang.annotation.ElementType;
Svet Ganovad0a49b2018-10-29 10:07:08 -070061import java.lang.annotation.Retention;
62import java.lang.annotation.RetentionPolicy;
Svet Ganovaf189e32019-02-15 18:45:29 -080063import java.lang.annotation.Target;
Svet Ganov8455ba22019-01-02 13:05:56 -080064import java.math.BigDecimal;
65import java.math.RoundingMode;
Jeff Davidson05542602014-08-11 14:07:27 -070066import java.util.ArrayList;
Peter Visontay5a2a1ef2017-12-18 20:34:03 +000067import java.util.Arrays;
Svet Ganovad0a49b2018-10-29 10:07:08 -070068import java.util.Collections;
Jeff Davidson05542602014-08-11 14:07:27 -070069import java.util.HashMap;
70import java.util.List;
Svet Ganovaf189e32019-02-15 18:45:29 -080071import java.util.Objects;
Svet Ganov8455ba22019-01-02 13:05:56 -080072import java.util.concurrent.Executor;
Ng Zhi An65a99b62018-10-01 11:57:53 -070073import java.util.concurrent.atomic.AtomicInteger;
Svet Ganov8455ba22019-01-02 13:05:56 -080074import java.util.function.Consumer;
Svet Ganovaf189e32019-02-15 18:45:29 -080075import java.util.function.Supplier;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080076
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080077/**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070078 * API for interacting with "application operation" tracking.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080079 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070080 * <p>This API is not generally intended for third party application developers; most
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060081 * features are only available to system applications.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080082 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060083@SystemService(Context.APP_OPS_SERVICE)
Dianne Hackborna06de0f2012-12-11 16:34:47 -080084public class AppOpsManager {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070085 /**
86 * <p>App ops allows callers to:</p>
87 *
88 * <ul>
89 * <li> Note when operations are happening, and find out if they are allowed for the current
90 * caller.</li>
91 * <li> Disallow specific apps from doing specific operations.</li>
92 * <li> Collect all of the current information about operations that have been executed or
93 * are not being allowed.</li>
94 * <li> Monitor for changes in whether an operation is allowed.</li>
95 * </ul>
96 *
97 * <p>Each operation is identified by a single integer; these integers are a fixed set of
98 * operations, enumerated by the OP_* constants.
99 *
100 * <p></p>When checking operations, the result is a "mode" integer indicating the current
101 * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
102 * the operation but fake its behavior enough so that the caller doesn't crash),
103 * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
104 * will do this for you).
105 */
106
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800107 final Context mContext;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800108
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100109 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800110 final IAppOpsService mService;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800111
112 @GuardedBy("mModeWatchers")
113 private final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers =
114 new ArrayMap<>();
115
116 @GuardedBy("mActiveWatchers")
117 private final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers =
118 new ArrayMap<>();
119
120 @GuardedBy("mNotedWatchers")
121 private final ArrayMap<OnOpNotedListener, IAppOpsNotedCallback> mNotedWatchers =
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -0800122 new ArrayMap<>();
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800123
Dianne Hackborne98f5db2013-07-17 17:23:25 -0700124 static IBinder sToken;
125
Svet Ganov8455ba22019-01-02 13:05:56 -0800126 /** @hide */
127 @Retention(RetentionPolicy.SOURCE)
128 @IntDef(flag = true, prefix = { "HISTORICAL_MODE_" }, value = {
129 HISTORICAL_MODE_DISABLED,
130 HISTORICAL_MODE_ENABLED_ACTIVE,
131 HISTORICAL_MODE_ENABLED_PASSIVE
132 })
133 public @interface HistoricalMode {}
134
135 /**
136 * Mode in which app op history is completely disabled.
137 * @hide
138 */
139 @TestApi
140 public static final int HISTORICAL_MODE_DISABLED = 0;
141
142 /**
143 * Mode in which app op history is enabled and app ops performed by apps would
144 * be tracked. This is the mode in which the feature is completely enabled.
145 * @hide
146 */
147 @TestApi
148 public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1;
149
150 /**
151 * Mode in which app op history is enabled but app ops performed by apps would
152 * not be tracked and the only way to add ops to the history is via explicit calls
153 * to dedicated APIs. This mode is useful for testing to allow full control of
154 * the historical content.
155 * @hide
156 */
157 @TestApi
158 public static final int HISTORICAL_MODE_ENABLED_PASSIVE = 2;
159
160 /** @hide */
161 @Retention(RetentionPolicy.SOURCE)
162 @IntDef(flag = true, prefix = { "MODE_" }, value = {
163 MODE_ALLOWED,
164 MODE_IGNORED,
165 MODE_ERRORED,
166 MODE_DEFAULT,
167 MODE_FOREGROUND
168 })
169 public @interface Mode {}
170
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700171 /**
172 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
173 * allowed to perform the given operation.
174 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800175 public static final int MODE_ALLOWED = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700176
177 /**
178 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
179 * not allowed to perform the given operation, and this attempt should
180 * <em>silently fail</em> (it should not cause the app to crash).
181 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800182 public static final int MODE_IGNORED = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700183
184 /**
185 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
186 * given caller is not allowed to perform the given operation, and this attempt should
187 * cause it to have a fatal error, typically a {@link SecurityException}.
188 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800189 public static final int MODE_ERRORED = 2;
190
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -0700191 /**
192 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
193 * use its default security check. This mode is not normally used; it should only be used
194 * with appop permissions, and callers must explicitly check for it and deal with it.
195 */
196 public static final int MODE_DEFAULT = 3;
197
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700198 /**
Dianne Hackbornc216a262018-04-26 13:46:22 -0700199 * Special mode that means "allow only when app is in foreground." This is <b>not</b>
Dianne Hackbornf8709f52019-02-04 16:31:24 -0800200 * returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}. Rather,
201 * {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always
202 * possible for it to be ultimately allowed, depending on the app's background state),
203 * and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app
204 * being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}.
205 *
206 * <p>The only place you will this normally see this value is through
207 * {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op. Note that because
208 * you can't know the current state of the app being checked (and it can change at any
209 * point), you can only treat the result here as an indication that it will vary between
210 * {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background
211 * state of the app. You thus must always use {@link #noteOp} or {@link #startOp} to do
212 * the actual check for access to the op.</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -0700213 */
214 public static final int MODE_FOREGROUND = 4;
215
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700216 /**
217 * Flag for {@link #startWatchingMode(String, String, int, OnOpChangedListener)}:
218 * Also get reports if the foreground state of an op's uid changes. This only works
219 * when watching a particular op, not when watching a package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700220 */
221 public static final int WATCH_FOREGROUND_CHANGES = 1 << 0;
Dianne Hackbornc216a262018-04-26 13:46:22 -0700222
223 /**
224 * @hide
225 */
226 public static final String[] MODE_NAMES = new String[] {
227 "allow", // MODE_ALLOWED
228 "ignore", // MODE_IGNORED
229 "deny", // MODE_ERRORED
230 "default", // MODE_DEFAULT
231 "foreground", // MODE_FOREGROUND
232 };
233
Svet Ganovad0a49b2018-10-29 10:07:08 -0700234 /** @hide */
235 @Retention(RetentionPolicy.SOURCE)
Svet Ganovaf189e32019-02-15 18:45:29 -0800236 @IntDef(prefix = { "UID_STATE_" }, value = {
Svet Ganovad0a49b2018-10-29 10:07:08 -0700237 UID_STATE_PERSISTENT,
238 UID_STATE_TOP,
Amith Yamasania0a30a12019-01-22 11:38:06 -0800239 UID_STATE_FOREGROUND_SERVICE_LOCATION,
Svet Ganovad0a49b2018-10-29 10:07:08 -0700240 UID_STATE_FOREGROUND_SERVICE,
241 UID_STATE_FOREGROUND,
242 UID_STATE_BACKGROUND,
243 UID_STATE_CACHED
244 })
245 public @interface UidState {}
246
Dianne Hackbornc216a262018-04-26 13:46:22 -0700247 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800248 * Uid state: The UID is a foreground persistent app.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700249 * @hide
250 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800251 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700252 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800253 public static final int UID_STATE_PERSISTENT = 100;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700254
255 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800256 * Uid state: The UID is top foreground app.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700257 * @hide
258 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800259 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700260 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800261 public static final int UID_STATE_TOP = 200;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700262
263 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800264 * Uid state: The UID is running a foreground service of location type.
Amith Yamasania0a30a12019-01-22 11:38:06 -0800265 * @hide
266 */
267 @TestApi
268 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800269 public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800270
271 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800272 * Uid state: The UID is running a foreground service.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700273 * @hide
274 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800275 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700276 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800277 public static final int UID_STATE_FOREGROUND_SERVICE = 400;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700278
279 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800280 * The max, which is min priority, UID state for which any app op
281 * would be considered as performed in the foreground.
Dianne Hackborne93ab412018-05-14 17:52:30 -0700282 * @hide
283 */
Svet Ganovaf189e32019-02-15 18:45:29 -0800284 public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE;
Dianne Hackborne93ab412018-05-14 17:52:30 -0700285
286 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800287 * Uid state: The UID is a foreground app.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700288 * @hide
289 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800290 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700291 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800292 public static final int UID_STATE_FOREGROUND = 500;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700293
294 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800295 * Uid state: The UID is a background app.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700296 * @hide
297 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800298 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700299 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800300 public static final int UID_STATE_BACKGROUND = 600;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700301
302 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800303 * Uid state: The UID is a cached app.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700304 * @hide
305 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800306 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700307 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800308 public static final int UID_STATE_CACHED = 700;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700309
310 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800311 * Uid state: The UID state with the highest priority.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700312 * @hide
313 */
Svet Ganovaf189e32019-02-15 18:45:29 -0800314 public static final int MAX_PRIORITY_UID_STATE = UID_STATE_PERSISTENT;
315
316 /**
317 * Uid state: The UID state with the lowest priority.
318 * @hide
319 */
320 public static final int MIN_PRIORITY_UID_STATE = UID_STATE_CACHED;
321
322 /**
323 * Resolves the first unrestricted state given an app op. Location is
324 * special as we want to allow its access only if a dedicated location
325 * foreground service is running. For other ops we consider any foreground
326 * service as a foreground state.
327 *
328 * @param op The op to resolve.
329 * @return The last restricted UID state.
330 *
331 * @hide
332 */
333 public static int resolveFirstUnrestrictedUidState(int op) {
334 switch (op) {
335 case OP_FINE_LOCATION:
336 case OP_COARSE_LOCATION: {
337 return UID_STATE_FOREGROUND_SERVICE_LOCATION;
338 }
339 }
340 return UID_STATE_FOREGROUND_SERVICE;
341 }
342
343 /**
344 * Resolves the last restricted state given an app op. Location is
345 * special as we want to allow its access only if a dedicated location
346 * foreground service is running. For other ops we consider any foreground
347 * service as a foreground state.
348 *
349 * @param op The op to resolve.
350 * @return The last restricted UID state.
351 *
352 * @hide
353 */
354 public static int resolveLastRestrictedUidState(int op) {
355 switch (op) {
356 case OP_FINE_LOCATION:
357 case OP_COARSE_LOCATION: {
358 return UID_STATE_FOREGROUND_SERVICE;
359 }
360 }
361 return UID_STATE_FOREGROUND;
362 }
363
364 /** @hide Note: Keep these sorted */
365 public static final int[] UID_STATES = {
366 UID_STATE_PERSISTENT,
367 UID_STATE_TOP,
368 UID_STATE_FOREGROUND_SERVICE_LOCATION,
369 UID_STATE_FOREGROUND_SERVICE,
370 UID_STATE_FOREGROUND,
371 UID_STATE_BACKGROUND,
372 UID_STATE_CACHED
373 };
374
375 /** @hide */
376 public static String getUidStateName(@UidState int uidState) {
377 switch (uidState) {
378 case UID_STATE_PERSISTENT:
379 return "pers";
380 case UID_STATE_TOP:
381 return "top";
382 case UID_STATE_FOREGROUND_SERVICE_LOCATION:
383 return "fgsvcl";
384 case UID_STATE_FOREGROUND_SERVICE:
385 return "fgsvc";
386 case UID_STATE_FOREGROUND:
387 return "fg";
388 case UID_STATE_BACKGROUND:
389 return "bg";
390 case UID_STATE_CACHED:
391 return "cch";
392 default:
393 return "unknown";
394 }
395 }
396
397 /**
398 * Flag: non proxy operations. These are operations
399 * performed on behalf of the app itself and not on behalf of
400 * another one.
401 *
402 * @hide
403 */
404 @TestApi
405 @SystemApi
406 public static final int OP_FLAG_SELF = 0x1;
407
408 /**
409 * Flag: trusted proxy operations. These are operations
410 * performed on behalf of another app by a trusted app.
411 * Which is work a trusted app blames on another app.
412 *
413 * @hide
414 */
415 @TestApi
416 @SystemApi
417 public static final int OP_FLAG_TRUSTED_PROXY = 0x2;
418
419 /**
420 * Flag: untrusted proxy operations. These are operations
421 * performed on behalf of another app by an untrusted app.
422 * Which is work an untrusted app blames on another app.
423 *
424 * @hide
425 */
426 @TestApi
427 @SystemApi
428 public static final int OP_FLAG_UNTRUSTED_PROXY = 0x4;
429
430 /**
431 * Flag: trusted proxied operations. These are operations
432 * performed by a trusted other app on behalf of an app.
433 * Which is work an app was blamed for by a trusted app.
434 *
435 * @hide
436 */
437 @TestApi
438 @SystemApi
439 public static final int OP_FLAG_TRUSTED_PROXIED = 0x8;
440
441 /**
442 * Flag: untrusted proxied operations. These are operations
443 * performed by an untrusted other app on behalf of an app.
444 * Which is work an app was blamed for by an untrusted app.
445 *
446 * @hide
447 */
448 @TestApi
449 @SystemApi
450 public static final int OP_FLAG_UNTRUSTED_PROXIED = 0x10;
451
452 /**
453 * Flags: all operations. These include operations matched
454 * by {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXIED},
455 * {@link #OP_FLAG_UNTRUSTED_PROXIED}, {@link #OP_FLAG_TRUSTED_PROXIED},
456 * {@link #OP_FLAG_UNTRUSTED_PROXIED}.
457 *
458 * @hide
459 */
460 @TestApi
461 @SystemApi
462 public static final int OP_FLAGS_ALL =
463 OP_FLAG_SELF
464 | OP_FLAG_TRUSTED_PROXY
465 | OP_FLAG_UNTRUSTED_PROXY
466 | OP_FLAG_TRUSTED_PROXIED
467 | OP_FLAG_UNTRUSTED_PROXIED;
468
469 /**
470 * Flags: all trusted operations which is ones either the app did {@link #OP_FLAG_SELF},
471 * or it was blamed for by a trusted app {@link #OP_FLAG_TRUSTED_PROXIED}, or ones the
472 * app if untrusted blamed on other apps {@link #OP_FLAG_UNTRUSTED_PROXY}.
473 *
474 * @hide
475 */
476 @SystemApi
477 public static final int OP_FLAGS_ALL_TRUSTED = AppOpsManager.OP_FLAG_SELF
478 | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY
479 | AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
480
481 /** @hide */
482 @Retention(RetentionPolicy.SOURCE)
483 @IntDef(flag = true, prefix = { "FLAG_" }, value = {
484 OP_FLAG_SELF,
485 OP_FLAG_TRUSTED_PROXY,
486 OP_FLAG_UNTRUSTED_PROXY,
487 OP_FLAG_TRUSTED_PROXIED,
488 OP_FLAG_UNTRUSTED_PROXIED
489 })
490 public @interface OpFlags {}
491
492
493 /** @hide */
494 public static final String getFlagName(@OpFlags int flag) {
495 switch (flag) {
496 case OP_FLAG_SELF:
497 return "s";
498 case OP_FLAG_TRUSTED_PROXY:
499 return "tp";
500 case OP_FLAG_UNTRUSTED_PROXY:
501 return "up";
502 case OP_FLAG_TRUSTED_PROXIED:
503 return "tpd";
504 case OP_FLAG_UNTRUSTED_PROXIED:
505 return "upd";
506 default:
507 return "unknown";
508 }
509 }
510
511 private static final int UID_STATE_OFFSET = 31;
512 private static final int FLAGS_MASK = 0xFFFFFFFF;
513
514 /**
515 * Key for a data bucket storing app op state. The bucket
516 * is composed of the uid state and state flags. This way
517 * we can query data for given uid state and a set of flags where
518 * the flags control which type of data to get. For example,
519 * one can get the ops an app did on behalf of other apps
520 * while in the background.
521 *
522 * @hide
523 */
524 @Retention(RetentionPolicy.SOURCE)
525 @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
526 public @interface DataBucketKey {
527 }
528
529 /** @hide */
530 public static String keyToString(@DataBucketKey long key) {
531 final int uidState = extractUidStateFromKey(key);
532 final int flags = extractFlagsFromKey(key);
533 return "[" + getUidStateName(uidState) + "-" + flagsToString(flags) + "]";
534 }
535
536 /** @hide */
537 public static @DataBucketKey long makeKey(@UidState int uidState, @OpFlags int flags) {
538 return ((long) uidState << UID_STATE_OFFSET) | flags;
539 }
540
541 /** @hide */
542 public static int extractUidStateFromKey(@DataBucketKey long key) {
543 return (int) (key >> UID_STATE_OFFSET);
544 }
545
546 /** @hide */
547 public static int extractFlagsFromKey(@DataBucketKey long key) {
548 return (int) (key & FLAGS_MASK);
549 }
550
551 /** @hide */
552 public static String flagsToString(@OpFlags int flags) {
553 final StringBuilder flagsBuilder = new StringBuilder();
554 while (flags != 0) {
555 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
556 flags &= ~flag;
557 if (flagsBuilder.length() > 0) {
558 flagsBuilder.append('|');
559 }
560 flagsBuilder.append(getFlagName(flag));
561 }
562 return flagsBuilder.toString();
563 }
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700564
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500565 // when adding one of these:
566 // - increment _NUM_OP
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000567 // - define an OPSTR_* constant (marked as @SystemApi)
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700568 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500569 // - add descriptive strings to Settings/res/values/arrays.xml
David Christie0b837452013-07-29 16:02:13 -0700570 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700571
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700572 /** @hide No operation specified. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100573 @UnsupportedAppUsage
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800574 public static final int OP_NONE = -1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700575 /** @hide Access to coarse location information. */
Svet Ganov8455ba22019-01-02 13:05:56 -0800576 @TestApi
Dianne Hackborn35654b62013-01-14 17:38:02 -0800577 public static final int OP_COARSE_LOCATION = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700578 /** @hide Access to fine location information. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100579 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800580 public static final int OP_FINE_LOCATION = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700581 /** @hide Causing GPS to run. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100582 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800583 public static final int OP_GPS = 2;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800584 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100585 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700586 public static final int OP_VIBRATE = 3;
587 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100588 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700589 public static final int OP_READ_CONTACTS = 4;
590 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100591 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700592 public static final int OP_WRITE_CONTACTS = 5;
593 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100594 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700595 public static final int OP_READ_CALL_LOG = 6;
596 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100597 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700598 public static final int OP_WRITE_CALL_LOG = 7;
599 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100600 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700601 public static final int OP_READ_CALENDAR = 8;
602 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100603 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700604 public static final int OP_WRITE_CALENDAR = 9;
605 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100606 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700607 public static final int OP_WIFI_SCAN = 10;
608 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100609 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700610 public static final int OP_POST_NOTIFICATION = 11;
611 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100612 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700613 public static final int OP_NEIGHBORING_CELLS = 12;
614 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100615 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700616 public static final int OP_CALL_PHONE = 13;
617 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100618 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700619 public static final int OP_READ_SMS = 14;
620 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100621 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700622 public static final int OP_WRITE_SMS = 15;
623 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100624 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700625 public static final int OP_RECEIVE_SMS = 16;
626 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100627 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700628 public static final int OP_RECEIVE_EMERGECY_SMS = 17;
629 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100630 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700631 public static final int OP_RECEIVE_MMS = 18;
632 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100633 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700634 public static final int OP_RECEIVE_WAP_PUSH = 19;
635 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100636 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700637 public static final int OP_SEND_SMS = 20;
638 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100639 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700640 public static final int OP_READ_ICC_SMS = 21;
641 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100642 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700643 public static final int OP_WRITE_ICC_SMS = 22;
644 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100645 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700646 public static final int OP_WRITE_SETTINGS = 23;
Peter Visontay96449f62017-12-11 18:50:03 +0000647 /** @hide Required to draw on top of other apps. */
Svet Ganovf7b47252018-02-26 11:11:27 -0800648 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700649 public static final int OP_SYSTEM_ALERT_WINDOW = 24;
650 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100651 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700652 public static final int OP_ACCESS_NOTIFICATIONS = 25;
653 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100654 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700655 public static final int OP_CAMERA = 26;
656 /** @hide */
Svet Ganova7a0db62018-02-27 20:08:01 -0800657 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700658 public static final int OP_RECORD_AUDIO = 27;
659 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100660 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700661 public static final int OP_PLAY_AUDIO = 28;
662 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100663 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700664 public static final int OP_READ_CLIPBOARD = 29;
665 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100666 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700667 public static final int OP_WRITE_CLIPBOARD = 30;
668 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100669 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700670 public static final int OP_TAKE_MEDIA_BUTTONS = 31;
671 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100672 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700673 public static final int OP_TAKE_AUDIO_FOCUS = 32;
674 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100675 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700676 public static final int OP_AUDIO_MASTER_VOLUME = 33;
677 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100678 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700679 public static final int OP_AUDIO_VOICE_VOLUME = 34;
680 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100681 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700682 public static final int OP_AUDIO_RING_VOLUME = 35;
683 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100684 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700685 public static final int OP_AUDIO_MEDIA_VOLUME = 36;
686 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100687 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700688 public static final int OP_AUDIO_ALARM_VOLUME = 37;
689 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100690 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700691 public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
692 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100693 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700694 public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
695 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100696 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700697 public static final int OP_WAKE_LOCK = 40;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700698 /** @hide Continually monitoring location data. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100699 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700700 public static final int OP_MONITOR_LOCATION = 41;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700701 /** @hide Continually monitoring location data with a relatively high power request. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100702 @UnsupportedAppUsage
David Christie0b837452013-07-29 16:02:13 -0700703 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700704 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100705 @UnsupportedAppUsage
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700706 public static final int OP_GET_USAGE_STATS = 43;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700707 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100708 @UnsupportedAppUsage
Emily Bernier22c921a2014-05-28 11:01:32 -0400709 public static final int OP_MUTE_MICROPHONE = 44;
710 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100711 @UnsupportedAppUsage
Jason Monk1c7c3192014-06-26 12:52:18 -0400712 public static final int OP_TOAST_WINDOW = 45;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700713 /** @hide Capture the device's display contents and/or audio */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100714 @UnsupportedAppUsage
Michael Wrightc39d47a2014-07-08 18:07:36 -0700715 public static final int OP_PROJECT_MEDIA = 46;
Jeff Davidson05542602014-08-11 14:07:27 -0700716 /** @hide Activate a VPN connection without user intervention. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100717 @UnsupportedAppUsage
Jeff Davidson05542602014-08-11 14:07:27 -0700718 public static final int OP_ACTIVATE_VPN = 47;
Benjamin Franzf3ece362015-02-11 10:51:10 +0000719 /** @hide Access the WallpaperManagerAPI to write wallpapers. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100720 @UnsupportedAppUsage
Benjamin Franzf3ece362015-02-11 10:51:10 +0000721 public static final int OP_WRITE_WALLPAPER = 48;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700722 /** @hide Received the assist structure from an app. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100723 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700724 public static final int OP_ASSIST_STRUCTURE = 49;
725 /** @hide Received a screenshot from assist. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100726 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700727 public static final int OP_ASSIST_SCREENSHOT = 50;
Svet Ganov16a16892015-04-16 10:32:04 -0700728 /** @hide Read the phone state. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100729 @UnsupportedAppUsage
Svet Ganov16a16892015-04-16 10:32:04 -0700730 public static final int OP_READ_PHONE_STATE = 51;
Svet Ganovc3300092015-04-17 09:07:22 -0700731 /** @hide Add voicemail messages to the voicemail content provider. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100732 @UnsupportedAppUsage
Svet Ganovc3300092015-04-17 09:07:22 -0700733 public static final int OP_ADD_VOICEMAIL = 52;
Svetoslav5335b672015-04-29 12:00:51 -0700734 /** @hide Access APIs for SIP calling over VOIP or WiFi. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100735 @UnsupportedAppUsage
Svetoslav5335b672015-04-29 12:00:51 -0700736 public static final int OP_USE_SIP = 53;
Svetoslavc656e6f2015-04-29 14:08:16 -0700737 /** @hide Intercept outgoing calls. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100738 @UnsupportedAppUsage
Svetoslavc656e6f2015-04-29 14:08:16 -0700739 public static final int OP_PROCESS_OUTGOING_CALLS = 54;
Svetoslav4af76a52015-04-29 15:29:46 -0700740 /** @hide User the fingerprint API. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100741 @UnsupportedAppUsage
Svetoslav4af76a52015-04-29 15:29:46 -0700742 public static final int OP_USE_FINGERPRINT = 55;
Svet Ganovb9d71a62015-04-30 10:38:13 -0700743 /** @hide Access to body sensors such as heart rate, etc. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100744 @UnsupportedAppUsage
Svet Ganovb9d71a62015-04-30 10:38:13 -0700745 public static final int OP_BODY_SENSORS = 56;
Svet Ganovede43162015-05-02 17:42:44 -0700746 /** @hide Read previously received cell broadcast messages. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100747 @UnsupportedAppUsage
Svet Ganovede43162015-05-02 17:42:44 -0700748 public static final int OP_READ_CELL_BROADCASTS = 57;
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700749 /** @hide Inject mock location into the system. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100750 @UnsupportedAppUsage
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700751 public static final int OP_MOCK_LOCATION = 58;
Svet Ganov921c7df2015-06-29 21:51:41 -0700752 /** @hide Read external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100753 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700754 public static final int OP_READ_EXTERNAL_STORAGE = 59;
755 /** @hide Write external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100756 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700757 public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700758 /** @hide Turned on the screen. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100759 @UnsupportedAppUsage
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700760 public static final int OP_TURN_SCREEN_ON = 61;
Svetoslavf3f02ac2015-09-08 14:36:35 -0700761 /** @hide Get device accounts. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100762 @UnsupportedAppUsage
Svetoslavf3f02ac2015-09-08 14:36:35 -0700763 public static final int OP_GET_ACCOUNTS = 62;
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700764 /** @hide Control whether an application is allowed to run in the background. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100765 @UnsupportedAppUsage
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700766 public static final int OP_RUN_IN_BACKGROUND = 63;
Jason Monk1c7c3192014-06-26 12:52:18 -0400767 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100768 @UnsupportedAppUsage
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800769 public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800770 /** @hide Read the phone number. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100771 @UnsupportedAppUsage
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700772 public static final int OP_READ_PHONE_NUMBERS = 65;
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800773 /** @hide Request package installs through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100774 @UnsupportedAppUsage
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800775 public static final int OP_REQUEST_INSTALL_PACKAGES = 66;
Winson Chungf4ac0632017-03-17 12:34:12 -0700776 /** @hide Enter picture-in-picture. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100777 @UnsupportedAppUsage
Winson Chungf4ac0632017-03-17 12:34:12 -0700778 public static final int OP_PICTURE_IN_PICTURE = 67;
Chad Brubaker97b383f2017-02-02 15:04:35 -0800779 /** @hide Instant app start foreground service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100780 @UnsupportedAppUsage
Chad Brubaker97b383f2017-02-02 15:04:35 -0800781 public static final int OP_INSTANT_APP_START_FOREGROUND = 68;
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800782 /** @hide Answer incoming phone calls */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100783 @UnsupportedAppUsage
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800784 public static final int OP_ANSWER_PHONE_CALLS = 69;
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700785 /** @hide Run jobs when in background */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100786 @UnsupportedAppUsage
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700787 public static final int OP_RUN_ANY_IN_BACKGROUND = 70;
Peter Visontay1246d9e2017-10-17 17:02:45 +0100788 /** @hide Change Wi-Fi connectivity state */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100789 @UnsupportedAppUsage
Peter Visontay1246d9e2017-10-17 17:02:45 +0100790 public static final int OP_CHANGE_WIFI_STATE = 71;
Peter Visontayf2e38362017-11-27 15:27:16 +0000791 /** @hide Request package deletion through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100792 @UnsupportedAppUsage
Peter Visontayf2e38362017-11-27 15:27:16 +0000793 public static final int OP_REQUEST_DELETE_PACKAGES = 72;
Peter Visontay11950832017-11-14 19:34:59 +0000794 /** @hide Bind an accessibility service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100795 @UnsupportedAppUsage
Peter Visontay11950832017-11-14 19:34:59 +0000796 public static final int OP_BIND_ACCESSIBILITY_SERVICE = 73;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800797 /** @hide Continue handover of a call from another app */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100798 @UnsupportedAppUsage
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800799 public static final int OP_ACCEPT_HANDOVER = 74;
Nathan Harold1bb420672018-03-14 17:08:53 -0700800 /** @hide Create and Manage IPsec Tunnels */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100801 @UnsupportedAppUsage
Nathan Harold1bb420672018-03-14 17:08:53 -0700802 public static final int OP_MANAGE_IPSEC_TUNNELS = 75;
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700803 /** @hide Any app start foreground service. */
Svet Ganovaf189e32019-02-15 18:45:29 -0800804 @TestApi
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700805 public static final int OP_START_FOREGROUND = 76;
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800806 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100807 @UnsupportedAppUsage
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700808 public static final int OP_BLUETOOTH_SCAN = 77;
Kevin Chynb3c05aa2018-09-21 16:50:32 -0700809 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
810 public static final int OP_USE_BIOMETRIC = 78;
Zimuzo6cbf9cc2018-10-05 12:05:58 +0100811 /** @hide Physical activity recognition. */
812 public static final int OP_ACTIVITY_RECOGNITION = 79;
Hongming Jin228cd012018-11-09 14:47:50 -0800813 /** @hide Financial app sms read. */
814 public static final int OP_SMS_FINANCIAL_TRANSACTIONS = 80;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -0700815 /** @hide Read media of audio type. */
816 public static final int OP_READ_MEDIA_AUDIO = 81;
817 /** @hide Write media of audio type. */
818 public static final int OP_WRITE_MEDIA_AUDIO = 82;
819 /** @hide Read media of video type. */
820 public static final int OP_READ_MEDIA_VIDEO = 83;
821 /** @hide Write media of video type. */
822 public static final int OP_WRITE_MEDIA_VIDEO = 84;
823 /** @hide Read media of image type. */
824 public static final int OP_READ_MEDIA_IMAGES = 85;
825 /** @hide Write media of image type. */
826 public static final int OP_WRITE_MEDIA_IMAGES = 86;
Jeff Sharkeye82cbb12018-12-06 15:53:11 -0700827 /** @hide Has a legacy (non-isolated) view of storage. */
828 public static final int OP_LEGACY_STORAGE = 87;
Jackal Guo8dc791e2019-01-14 10:26:42 +0800829 /** @hide Accessing accessibility features */
830 public static final int OP_ACCESS_ACCESSIBILITY = 88;
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700831 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100832 @UnsupportedAppUsage
Jackal Guo8dc791e2019-01-14 10:26:42 +0800833 public static final int _NUM_OP = 89;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800834
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700835 /** Access to coarse location information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700836 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700837 /** Access to fine location information. */
838 public static final String OPSTR_FINE_LOCATION =
839 "android:fine_location";
840 /** Continually monitoring location data. */
841 public static final String OPSTR_MONITOR_LOCATION
842 = "android:monitor_location";
843 /** Continually monitoring location data with a relatively high power request. */
844 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
845 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700846 /** Access to {@link android.app.usage.UsageStatsManager}. */
847 public static final String OPSTR_GET_USAGE_STATS
848 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700849 /** Activate a VPN connection without user intervention. @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000850 @SystemApi @TestApi
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700851 public static final String OPSTR_ACTIVATE_VPN
852 = "android:activate_vpn";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700853 /** Allows an application to read the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700854 public static final String OPSTR_READ_CONTACTS
855 = "android:read_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700856 /** Allows an application to write to the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700857 public static final String OPSTR_WRITE_CONTACTS
858 = "android:write_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700859 /** Allows an application to read the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700860 public static final String OPSTR_READ_CALL_LOG
861 = "android:read_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700862 /** Allows an application to write to the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700863 public static final String OPSTR_WRITE_CALL_LOG
864 = "android:write_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700865 /** Allows an application to read the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700866 public static final String OPSTR_READ_CALENDAR
867 = "android:read_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700868 /** Allows an application to write to the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700869 public static final String OPSTR_WRITE_CALENDAR
870 = "android:write_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700871 /** Allows an application to initiate a phone call. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700872 public static final String OPSTR_CALL_PHONE
873 = "android:call_phone";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700874 /** Allows an application to read SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700875 public static final String OPSTR_READ_SMS
876 = "android:read_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700877 /** Allows an application to receive SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700878 public static final String OPSTR_RECEIVE_SMS
879 = "android:receive_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700880 /** Allows an application to receive MMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700881 public static final String OPSTR_RECEIVE_MMS
882 = "android:receive_mms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700883 /** Allows an application to receive WAP push messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700884 public static final String OPSTR_RECEIVE_WAP_PUSH
885 = "android:receive_wap_push";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700886 /** Allows an application to send SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700887 public static final String OPSTR_SEND_SMS
888 = "android:send_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700889 /** Required to be able to access the camera device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700890 public static final String OPSTR_CAMERA
891 = "android:camera";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700892 /** Required to be able to access the microphone device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700893 public static final String OPSTR_RECORD_AUDIO
894 = "android:record_audio";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700895 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700896 public static final String OPSTR_READ_PHONE_STATE
897 = "android:read_phone_state";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700898 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700899 public static final String OPSTR_ADD_VOICEMAIL
900 = "android:add_voicemail";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700901 /** Access APIs for SIP calling over VOIP or WiFi */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700902 public static final String OPSTR_USE_SIP
903 = "android:use_sip";
Svet Ganove8e89422016-09-22 19:56:50 -0700904 /** Access APIs for diverting outgoing calls */
Svet Ganov824ad6e2016-09-22 19:36:53 -0700905 public static final String OPSTR_PROCESS_OUTGOING_CALLS
906 = "android:process_outgoing_calls";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700907 /** Use the fingerprint API. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700908 public static final String OPSTR_USE_FINGERPRINT
909 = "android:use_fingerprint";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700910 /** Access to body sensors such as heart rate, etc. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700911 public static final String OPSTR_BODY_SENSORS
912 = "android:body_sensors";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700913 /** Read previously received cell broadcast messages. */
Svet Ganovede43162015-05-02 17:42:44 -0700914 public static final String OPSTR_READ_CELL_BROADCASTS
915 = "android:read_cell_broadcasts";
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700916 /** Inject mock location into the system. */
917 public static final String OPSTR_MOCK_LOCATION
918 = "android:mock_location";
Svet Ganov921c7df2015-06-29 21:51:41 -0700919 /** Read external storage. */
920 public static final String OPSTR_READ_EXTERNAL_STORAGE
921 = "android:read_external_storage";
922 /** Write external storage. */
923 public static final String OPSTR_WRITE_EXTERNAL_STORAGE
924 = "android:write_external_storage";
Billy Lau24b9c832015-07-20 17:34:09 +0100925 /** Required to draw on top of other apps. */
926 public static final String OPSTR_SYSTEM_ALERT_WINDOW
927 = "android:system_alert_window";
928 /** Required to write/modify/update system settingss. */
929 public static final String OPSTR_WRITE_SETTINGS
930 = "android:write_settings";
Svetoslavf3f02ac2015-09-08 14:36:35 -0700931 /** @hide Get device accounts. */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000932 @SystemApi @TestApi
Svetoslavf3f02ac2015-09-08 14:36:35 -0700933 public static final String OPSTR_GET_ACCOUNTS
934 = "android:get_accounts";
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700935 public static final String OPSTR_READ_PHONE_NUMBERS
936 = "android:read_phone_numbers";
Winson Chungf4ac0632017-03-17 12:34:12 -0700937 /** Access to picture-in-picture. */
938 public static final String OPSTR_PICTURE_IN_PICTURE
939 = "android:picture_in_picture";
Chad Brubaker97b383f2017-02-02 15:04:35 -0800940 /** @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000941 @SystemApi @TestApi
Chad Brubaker97b383f2017-02-02 15:04:35 -0800942 public static final String OPSTR_INSTANT_APP_START_FOREGROUND
943 = "android:instant_app_start_foreground";
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800944 /** Answer incoming phone calls */
945 public static final String OPSTR_ANSWER_PHONE_CALLS
946 = "android:answer_phone_calls";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800947 /**
948 * Accept call handover
949 * @hide
950 */
951 @SystemApi @TestApi
952 public static final String OPSTR_ACCEPT_HANDOVER
953 = "android:accept_handover";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000954 /** @hide */
955 @SystemApi @TestApi
956 public static final String OPSTR_GPS = "android:gps";
957 /** @hide */
958 @SystemApi @TestApi
959 public static final String OPSTR_VIBRATE = "android:vibrate";
960 /** @hide */
961 @SystemApi @TestApi
962 public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
963 /** @hide */
964 @SystemApi @TestApi
965 public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
966 /** @hide */
967 @SystemApi @TestApi
968 public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
969 /** @hide */
970 @SystemApi @TestApi
971 public static final String OPSTR_WRITE_SMS = "android:write_sms";
972 /** @hide */
973 @SystemApi @TestApi
974 public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST =
975 "android:receive_emergency_broadcast";
976 /** @hide */
977 @SystemApi @TestApi
978 public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
979 /** @hide */
980 @SystemApi @TestApi
981 public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
982 /** @hide */
983 @SystemApi @TestApi
984 public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
985 /** @hide */
986 @SystemApi @TestApi
987 public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
988 /** @hide */
989 @SystemApi @TestApi
990 public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
991 /** @hide */
992 @SystemApi @TestApi
993 public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
994 /** @hide */
995 @SystemApi @TestApi
996 public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
997 /** @hide */
998 @SystemApi @TestApi
999 public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
1000 /** @hide */
1001 @SystemApi @TestApi
1002 public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
1003 /** @hide */
1004 @SystemApi @TestApi
1005 public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
1006 /** @hide */
1007 @SystemApi @TestApi
1008 public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
1009 /** @hide */
1010 @SystemApi @TestApi
1011 public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
1012 /** @hide */
1013 @SystemApi @TestApi
1014 public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
1015 /** @hide */
1016 @SystemApi @TestApi
1017 public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME =
1018 "android:audio_notification_volume";
1019 /** @hide */
1020 @SystemApi @TestApi
1021 public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
1022 /** @hide */
1023 @SystemApi @TestApi
1024 public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
1025 /** @hide */
1026 @SystemApi @TestApi
1027 public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
1028 /** @hide */
1029 @SystemApi @TestApi
1030 public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
1031 /** @hide */
1032 @SystemApi @TestApi
1033 public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
1034 /** @hide */
1035 @SystemApi @TestApi
1036 public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
1037 /** @hide */
1038 @SystemApi @TestApi
1039 public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
1040 /** @hide */
1041 @SystemApi @TestApi
1042 public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
1043 /** @hide */
1044 @SystemApi @TestApi
1045 public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
1046 /** @hide */
1047 @SystemApi @TestApi
1048 public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
1049 /** @hide */
1050 @SystemApi @TestApi
1051 public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME =
1052 "android:audio_accessibility_volume";
1053 /** @hide */
1054 @SystemApi @TestApi
1055 public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
1056 /** @hide */
1057 @SystemApi @TestApi
1058 public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
1059 /** @hide */
1060 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001061 public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001062 /** @hide */
1063 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001064 public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001065 /** @hide */
1066 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001067 public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE =
1068 "android:bind_accessibility_service";
Nathan Harold1bb420672018-03-14 17:08:53 -07001069 /** @hide */
1070 @SystemApi @TestApi
1071 public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001072 /** @hide */
1073 @SystemApi @TestApi
1074 public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001075 /** @hide */
1076 public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001077
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001078 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
1079 public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001080
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001081 /** @hide Recognize physical activity. */
1082 public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition";
1083
Hongming Jin228cd012018-11-09 14:47:50 -08001084 /** @hide Financial app read sms. */
1085 public static final String OPSTR_SMS_FINANCIAL_TRANSACTIONS =
1086 "android:sms_financial_transactions";
1087
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001088 /** @hide Read media of audio type. */
1089 public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
1090 /** @hide Write media of audio type. */
1091 public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
1092 /** @hide Read media of video type. */
1093 public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
1094 /** @hide Write media of video type. */
1095 public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
1096 /** @hide Read media of image type. */
1097 public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
1098 /** @hide Write media of image type. */
1099 public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001100 /** @hide Has a legacy (non-isolated) view of storage. */
1101 public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
Jackal Guo8dc791e2019-01-14 10:26:42 +08001102 /** @hide Interact with accessibility. */
Joel Galensonff4fe202019-02-06 14:43:58 -08001103 @SystemApi
Jackal Guo8dc791e2019-01-14 10:26:42 +08001104 public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001105
Philip P. Moltmanne56c08e2017-03-15 12:46:04 -07001106 // Warning: If an permission is added here it also has to be added to
1107 // com.android.packageinstaller.permission.utils.EventLogger
Svet Ganovda0acdf2017-02-15 10:28:51 -08001108 private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
1109 // RUNTIME PERMISSIONS
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001110 // Contacts
1111 OP_READ_CONTACTS,
1112 OP_WRITE_CONTACTS,
1113 OP_GET_ACCOUNTS,
1114 // Calendar
1115 OP_READ_CALENDAR,
1116 OP_WRITE_CALENDAR,
1117 // SMS
1118 OP_SEND_SMS,
1119 OP_RECEIVE_SMS,
1120 OP_READ_SMS,
1121 OP_RECEIVE_WAP_PUSH,
1122 OP_RECEIVE_MMS,
1123 OP_READ_CELL_BROADCASTS,
1124 // Storage
1125 OP_READ_EXTERNAL_STORAGE,
1126 OP_WRITE_EXTERNAL_STORAGE,
1127 // Location
1128 OP_COARSE_LOCATION,
1129 OP_FINE_LOCATION,
1130 // Phone
1131 OP_READ_PHONE_STATE,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001132 OP_READ_PHONE_NUMBERS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001133 OP_CALL_PHONE,
1134 OP_READ_CALL_LOG,
1135 OP_WRITE_CALL_LOG,
1136 OP_ADD_VOICEMAIL,
1137 OP_USE_SIP,
1138 OP_PROCESS_OUTGOING_CALLS,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001139 OP_ANSWER_PHONE_CALLS,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001140 OP_ACCEPT_HANDOVER,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001141 // Microphone
1142 OP_RECORD_AUDIO,
1143 // Camera
1144 OP_CAMERA,
1145 // Body sensors
Svet Ganovda0acdf2017-02-15 10:28:51 -08001146 OP_BODY_SENSORS,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001147 // Activity recognition
1148 OP_ACTIVITY_RECOGNITION,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001149 // Aural
1150 OP_READ_MEDIA_AUDIO,
1151 OP_WRITE_MEDIA_AUDIO,
1152 // Visual
1153 OP_READ_MEDIA_VIDEO,
1154 OP_WRITE_MEDIA_VIDEO,
1155 OP_READ_MEDIA_IMAGES,
1156 OP_WRITE_MEDIA_IMAGES,
Svet Ganovda0acdf2017-02-15 10:28:51 -08001157
1158 // APPOP PERMISSIONS
1159 OP_ACCESS_NOTIFICATIONS,
1160 OP_SYSTEM_ALERT_WINDOW,
1161 OP_WRITE_SETTINGS,
1162 OP_REQUEST_INSTALL_PACKAGES,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001163 OP_START_FOREGROUND,
Hongming Jin228cd012018-11-09 14:47:50 -08001164 OP_SMS_FINANCIAL_TRANSACTIONS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001165 };
1166
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001167 /**
1168 * This maps each operation to the operation that serves as the
1169 * switch to determine whether it is allowed. Generally this is
1170 * a 1:1 mapping, but for some things (like location) that have
1171 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -07001172 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001173 * make them all controlled by the same single operation.
1174 */
1175 private static int[] sOpToSwitch = new int[] {
Dianne Hackbornc216a262018-04-26 13:46:22 -07001176 OP_COARSE_LOCATION, // COARSE_LOCATION
1177 OP_COARSE_LOCATION, // FINE_LOCATION
1178 OP_COARSE_LOCATION, // GPS
1179 OP_VIBRATE, // VIBRATE
1180 OP_READ_CONTACTS, // READ_CONTACTS
1181 OP_WRITE_CONTACTS, // WRITE_CONTACTS
1182 OP_READ_CALL_LOG, // READ_CALL_LOG
1183 OP_WRITE_CALL_LOG, // WRITE_CALL_LOG
1184 OP_READ_CALENDAR, // READ_CALENDAR
1185 OP_WRITE_CALENDAR, // WRITE_CALENDAR
1186 OP_COARSE_LOCATION, // WIFI_SCAN
1187 OP_POST_NOTIFICATION, // POST_NOTIFICATION
1188 OP_COARSE_LOCATION, // NEIGHBORING_CELLS
1189 OP_CALL_PHONE, // CALL_PHONE
1190 OP_READ_SMS, // READ_SMS
1191 OP_WRITE_SMS, // WRITE_SMS
1192 OP_RECEIVE_SMS, // RECEIVE_SMS
1193 OP_RECEIVE_SMS, // RECEIVE_EMERGECY_SMS
1194 OP_RECEIVE_MMS, // RECEIVE_MMS
1195 OP_RECEIVE_WAP_PUSH, // RECEIVE_WAP_PUSH
1196 OP_SEND_SMS, // SEND_SMS
1197 OP_READ_SMS, // READ_ICC_SMS
1198 OP_WRITE_SMS, // WRITE_ICC_SMS
1199 OP_WRITE_SETTINGS, // WRITE_SETTINGS
1200 OP_SYSTEM_ALERT_WINDOW, // SYSTEM_ALERT_WINDOW
1201 OP_ACCESS_NOTIFICATIONS, // ACCESS_NOTIFICATIONS
1202 OP_CAMERA, // CAMERA
1203 OP_RECORD_AUDIO, // RECORD_AUDIO
1204 OP_PLAY_AUDIO, // PLAY_AUDIO
1205 OP_READ_CLIPBOARD, // READ_CLIPBOARD
1206 OP_WRITE_CLIPBOARD, // WRITE_CLIPBOARD
1207 OP_TAKE_MEDIA_BUTTONS, // TAKE_MEDIA_BUTTONS
1208 OP_TAKE_AUDIO_FOCUS, // TAKE_AUDIO_FOCUS
1209 OP_AUDIO_MASTER_VOLUME, // AUDIO_MASTER_VOLUME
1210 OP_AUDIO_VOICE_VOLUME, // AUDIO_VOICE_VOLUME
1211 OP_AUDIO_RING_VOLUME, // AUDIO_RING_VOLUME
1212 OP_AUDIO_MEDIA_VOLUME, // AUDIO_MEDIA_VOLUME
1213 OP_AUDIO_ALARM_VOLUME, // AUDIO_ALARM_VOLUME
1214 OP_AUDIO_NOTIFICATION_VOLUME, // AUDIO_NOTIFICATION_VOLUME
1215 OP_AUDIO_BLUETOOTH_VOLUME, // AUDIO_BLUETOOTH_VOLUME
1216 OP_WAKE_LOCK, // WAKE_LOCK
1217 OP_COARSE_LOCATION, // MONITOR_LOCATION
1218 OP_COARSE_LOCATION, // MONITOR_HIGH_POWER_LOCATION
1219 OP_GET_USAGE_STATS, // GET_USAGE_STATS
1220 OP_MUTE_MICROPHONE, // MUTE_MICROPHONE
1221 OP_TOAST_WINDOW, // TOAST_WINDOW
1222 OP_PROJECT_MEDIA, // PROJECT_MEDIA
1223 OP_ACTIVATE_VPN, // ACTIVATE_VPN
1224 OP_WRITE_WALLPAPER, // WRITE_WALLPAPER
1225 OP_ASSIST_STRUCTURE, // ASSIST_STRUCTURE
1226 OP_ASSIST_SCREENSHOT, // ASSIST_SCREENSHOT
1227 OP_READ_PHONE_STATE, // READ_PHONE_STATE
1228 OP_ADD_VOICEMAIL, // ADD_VOICEMAIL
1229 OP_USE_SIP, // USE_SIP
1230 OP_PROCESS_OUTGOING_CALLS, // PROCESS_OUTGOING_CALLS
1231 OP_USE_FINGERPRINT, // USE_FINGERPRINT
1232 OP_BODY_SENSORS, // BODY_SENSORS
1233 OP_READ_CELL_BROADCASTS, // READ_CELL_BROADCASTS
1234 OP_MOCK_LOCATION, // MOCK_LOCATION
1235 OP_READ_EXTERNAL_STORAGE, // READ_EXTERNAL_STORAGE
1236 OP_WRITE_EXTERNAL_STORAGE, // WRITE_EXTERNAL_STORAGE
1237 OP_TURN_SCREEN_ON, // TURN_SCREEN_ON
1238 OP_GET_ACCOUNTS, // GET_ACCOUNTS
1239 OP_RUN_IN_BACKGROUND, // RUN_IN_BACKGROUND
1240 OP_AUDIO_ACCESSIBILITY_VOLUME, // AUDIO_ACCESSIBILITY_VOLUME
1241 OP_READ_PHONE_NUMBERS, // READ_PHONE_NUMBERS
1242 OP_REQUEST_INSTALL_PACKAGES, // REQUEST_INSTALL_PACKAGES
1243 OP_PICTURE_IN_PICTURE, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
1244 OP_INSTANT_APP_START_FOREGROUND, // INSTANT_APP_START_FOREGROUND
1245 OP_ANSWER_PHONE_CALLS, // ANSWER_PHONE_CALLS
1246 OP_RUN_ANY_IN_BACKGROUND, // OP_RUN_ANY_IN_BACKGROUND
1247 OP_CHANGE_WIFI_STATE, // OP_CHANGE_WIFI_STATE
1248 OP_REQUEST_DELETE_PACKAGES, // OP_REQUEST_DELETE_PACKAGES
1249 OP_BIND_ACCESSIBILITY_SERVICE, // OP_BIND_ACCESSIBILITY_SERVICE
1250 OP_ACCEPT_HANDOVER, // ACCEPT_HANDOVER
1251 OP_MANAGE_IPSEC_TUNNELS, // MANAGE_IPSEC_HANDOVERS
1252 OP_START_FOREGROUND, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001253 OP_COARSE_LOCATION, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001254 OP_USE_BIOMETRIC, // BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001255 OP_ACTIVITY_RECOGNITION, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001256 OP_SMS_FINANCIAL_TRANSACTIONS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001257 OP_READ_MEDIA_AUDIO, // READ_MEDIA_AUDIO
1258 OP_WRITE_MEDIA_AUDIO, // WRITE_MEDIA_AUDIO
1259 OP_READ_MEDIA_VIDEO, // READ_MEDIA_VIDEO
1260 OP_WRITE_MEDIA_VIDEO, // WRITE_MEDIA_VIDEO
1261 OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES
1262 OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001263 OP_LEGACY_STORAGE, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001264 OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001265 };
1266
1267 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001268 * This maps each operation to the public string constant for it.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001269 */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001270 private static String[] sOpToString = new String[]{
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001271 OPSTR_COARSE_LOCATION,
1272 OPSTR_FINE_LOCATION,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001273 OPSTR_GPS,
1274 OPSTR_VIBRATE,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001275 OPSTR_READ_CONTACTS,
1276 OPSTR_WRITE_CONTACTS,
1277 OPSTR_READ_CALL_LOG,
1278 OPSTR_WRITE_CALL_LOG,
1279 OPSTR_READ_CALENDAR,
1280 OPSTR_WRITE_CALENDAR,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001281 OPSTR_WIFI_SCAN,
1282 OPSTR_POST_NOTIFICATION,
1283 OPSTR_NEIGHBORING_CELLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001284 OPSTR_CALL_PHONE,
1285 OPSTR_READ_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001286 OPSTR_WRITE_SMS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001287 OPSTR_RECEIVE_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001288 OPSTR_RECEIVE_EMERGENCY_BROADCAST,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001289 OPSTR_RECEIVE_MMS,
1290 OPSTR_RECEIVE_WAP_PUSH,
1291 OPSTR_SEND_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001292 OPSTR_READ_ICC_SMS,
1293 OPSTR_WRITE_ICC_SMS,
Billy Lau24b9c832015-07-20 17:34:09 +01001294 OPSTR_WRITE_SETTINGS,
1295 OPSTR_SYSTEM_ALERT_WINDOW,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001296 OPSTR_ACCESS_NOTIFICATIONS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001297 OPSTR_CAMERA,
1298 OPSTR_RECORD_AUDIO,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001299 OPSTR_PLAY_AUDIO,
1300 OPSTR_READ_CLIPBOARD,
1301 OPSTR_WRITE_CLIPBOARD,
1302 OPSTR_TAKE_MEDIA_BUTTONS,
1303 OPSTR_TAKE_AUDIO_FOCUS,
1304 OPSTR_AUDIO_MASTER_VOLUME,
1305 OPSTR_AUDIO_VOICE_VOLUME,
1306 OPSTR_AUDIO_RING_VOLUME,
1307 OPSTR_AUDIO_MEDIA_VOLUME,
1308 OPSTR_AUDIO_ALARM_VOLUME,
1309 OPSTR_AUDIO_NOTIFICATION_VOLUME,
1310 OPSTR_AUDIO_BLUETOOTH_VOLUME,
1311 OPSTR_WAKE_LOCK,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001312 OPSTR_MONITOR_LOCATION,
1313 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -07001314 OPSTR_GET_USAGE_STATS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001315 OPSTR_MUTE_MICROPHONE,
1316 OPSTR_TOAST_WINDOW,
1317 OPSTR_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -07001318 OPSTR_ACTIVATE_VPN,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001319 OPSTR_WRITE_WALLPAPER,
1320 OPSTR_ASSIST_STRUCTURE,
1321 OPSTR_ASSIST_SCREENSHOT,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001322 OPSTR_READ_PHONE_STATE,
1323 OPSTR_ADD_VOICEMAIL,
1324 OPSTR_USE_SIP,
Svet Ganov824ad6e2016-09-22 19:36:53 -07001325 OPSTR_PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001326 OPSTR_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001327 OPSTR_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001328 OPSTR_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001329 OPSTR_MOCK_LOCATION,
1330 OPSTR_READ_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001331 OPSTR_WRITE_EXTERNAL_STORAGE,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001332 OPSTR_TURN_SCREEN_ON,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001333 OPSTR_GET_ACCOUNTS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001334 OPSTR_RUN_IN_BACKGROUND,
1335 OPSTR_AUDIO_ACCESSIBILITY_VOLUME,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001336 OPSTR_READ_PHONE_NUMBERS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001337 OPSTR_REQUEST_INSTALL_PACKAGES,
Winson Chungf4ac0632017-03-17 12:34:12 -07001338 OPSTR_PICTURE_IN_PICTURE,
Chad Brubaker97b383f2017-02-02 15:04:35 -08001339 OPSTR_INSTANT_APP_START_FOREGROUND,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001340 OPSTR_ANSWER_PHONE_CALLS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001341 OPSTR_RUN_ANY_IN_BACKGROUND,
1342 OPSTR_CHANGE_WIFI_STATE,
1343 OPSTR_REQUEST_DELETE_PACKAGES,
1344 OPSTR_BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001345 OPSTR_ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001346 OPSTR_MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001347 OPSTR_START_FOREGROUND,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001348 OPSTR_BLUETOOTH_SCAN,
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001349 OPSTR_USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001350 OPSTR_ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001351 OPSTR_SMS_FINANCIAL_TRANSACTIONS,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001352 OPSTR_READ_MEDIA_AUDIO,
1353 OPSTR_WRITE_MEDIA_AUDIO,
1354 OPSTR_READ_MEDIA_VIDEO,
1355 OPSTR_WRITE_MEDIA_VIDEO,
1356 OPSTR_READ_MEDIA_IMAGES,
1357 OPSTR_WRITE_MEDIA_IMAGES,
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001358 OPSTR_LEGACY_STORAGE,
Jackal Guo8dc791e2019-01-14 10:26:42 +08001359 OPSTR_ACCESS_ACCESSIBILITY,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001360 };
1361
1362 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001363 * This provides a simple name for each operation to be used
1364 * in debug output.
1365 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001366 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001367 "COARSE_LOCATION",
1368 "FINE_LOCATION",
1369 "GPS",
1370 "VIBRATE",
1371 "READ_CONTACTS",
1372 "WRITE_CONTACTS",
1373 "READ_CALL_LOG",
1374 "WRITE_CALL_LOG",
1375 "READ_CALENDAR",
1376 "WRITE_CALENDAR",
1377 "WIFI_SCAN",
1378 "POST_NOTIFICATION",
1379 "NEIGHBORING_CELLS",
1380 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001381 "READ_SMS",
1382 "WRITE_SMS",
1383 "RECEIVE_SMS",
1384 "RECEIVE_EMERGECY_SMS",
1385 "RECEIVE_MMS",
1386 "RECEIVE_WAP_PUSH",
1387 "SEND_SMS",
1388 "READ_ICC_SMS",
1389 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -08001390 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -08001391 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001392 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001393 "CAMERA",
1394 "RECORD_AUDIO",
1395 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001396 "READ_CLIPBOARD",
1397 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001398 "TAKE_MEDIA_BUTTONS",
1399 "TAKE_AUDIO_FOCUS",
1400 "AUDIO_MASTER_VOLUME",
1401 "AUDIO_VOICE_VOLUME",
1402 "AUDIO_RING_VOLUME",
1403 "AUDIO_MEDIA_VOLUME",
1404 "AUDIO_ALARM_VOLUME",
1405 "AUDIO_NOTIFICATION_VOLUME",
1406 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -07001407 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001408 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -07001409 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -04001410 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001411 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -04001412 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001413 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -07001414 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +00001415 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001416 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -07001417 "ASSIST_SCREENSHOT",
Eugene Suslae4ee2c22018-11-05 12:23:30 -08001418 "READ_PHONE_STATE",
Svetoslav5335b672015-04-29 12:00:51 -07001419 "ADD_VOICEMAIL",
Svetoslavc656e6f2015-04-29 14:08:16 -07001420 "USE_SIP",
Svetoslav4af76a52015-04-29 15:29:46 -07001421 "PROCESS_OUTGOING_CALLS",
Svet Ganovb9d71a62015-04-30 10:38:13 -07001422 "USE_FINGERPRINT",
Svet Ganovede43162015-05-02 17:42:44 -07001423 "BODY_SENSORS",
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001424 "READ_CELL_BROADCASTS",
Svet Ganov921c7df2015-06-29 21:51:41 -07001425 "MOCK_LOCATION",
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001426 "READ_EXTERNAL_STORAGE",
1427 "WRITE_EXTERNAL_STORAGE",
1428 "TURN_ON_SCREEN",
Svetoslavf3f02ac2015-09-08 14:36:35 -07001429 "GET_ACCOUNTS",
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001430 "RUN_IN_BACKGROUND",
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001431 "AUDIO_ACCESSIBILITY_VOLUME",
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001432 "READ_PHONE_NUMBERS",
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001433 "REQUEST_INSTALL_PACKAGES",
Winson Chungf4ac0632017-03-17 12:34:12 -07001434 "PICTURE_IN_PICTURE",
Chad Brubaker97b383f2017-02-02 15:04:35 -08001435 "INSTANT_APP_START_FOREGROUND",
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001436 "ANSWER_PHONE_CALLS",
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001437 "RUN_ANY_IN_BACKGROUND",
Peter Visontay1246d9e2017-10-17 17:02:45 +01001438 "CHANGE_WIFI_STATE",
Peter Visontayf2e38362017-11-27 15:27:16 +00001439 "REQUEST_DELETE_PACKAGES",
Peter Visontay11950832017-11-14 19:34:59 +00001440 "BIND_ACCESSIBILITY_SERVICE",
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001441 "ACCEPT_HANDOVER",
Nathan Harold1bb420672018-03-14 17:08:53 -07001442 "MANAGE_IPSEC_TUNNELS",
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001443 "START_FOREGROUND",
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001444 "BLUETOOTH_SCAN",
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001445 "USE_BIOMETRIC",
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001446 "ACTIVITY_RECOGNITION",
Hongming Jin228cd012018-11-09 14:47:50 -08001447 "SMS_FINANCIAL_TRANSACTIONS",
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001448 "READ_MEDIA_AUDIO",
1449 "WRITE_MEDIA_AUDIO",
1450 "READ_MEDIA_VIDEO",
1451 "WRITE_MEDIA_VIDEO",
1452 "READ_MEDIA_IMAGES",
1453 "WRITE_MEDIA_IMAGES",
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001454 "LEGACY_STORAGE",
Jackal Guo8dc791e2019-01-14 10:26:42 +08001455 "ACCESS_ACCESSIBILITY",
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001456 };
1457
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001458 /**
1459 * This optionally maps a permission to an operation. If there
1460 * is no permission associated with an operation, it is null.
1461 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001462 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001463 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001464 android.Manifest.permission.ACCESS_COARSE_LOCATION,
1465 android.Manifest.permission.ACCESS_FINE_LOCATION,
1466 null,
1467 android.Manifest.permission.VIBRATE,
1468 android.Manifest.permission.READ_CONTACTS,
1469 android.Manifest.permission.WRITE_CONTACTS,
1470 android.Manifest.permission.READ_CALL_LOG,
1471 android.Manifest.permission.WRITE_CALL_LOG,
1472 android.Manifest.permission.READ_CALENDAR,
1473 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001474 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -04001475 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001476 null, // neighboring cells shares the coarse location perm
1477 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001478 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001479 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001480 android.Manifest.permission.RECEIVE_SMS,
1481 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
1482 android.Manifest.permission.RECEIVE_MMS,
1483 android.Manifest.permission.RECEIVE_WAP_PUSH,
1484 android.Manifest.permission.SEND_SMS,
1485 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001486 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -08001487 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -08001488 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001489 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001490 android.Manifest.permission.CAMERA,
1491 android.Manifest.permission.RECORD_AUDIO,
1492 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001493 null, // no permission for reading clipboard
1494 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001495 null, // no permission for taking media buttons
1496 null, // no permission for taking audio focus
1497 null, // no permission for changing master volume
1498 null, // no permission for changing voice volume
1499 null, // no permission for changing ring volume
1500 null, // no permission for changing media volume
1501 null, // no permission for changing alarm volume
1502 null, // no permission for changing notification volume
1503 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -07001504 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001505 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -07001506 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -07001507 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -04001508 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -04001509 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -07001510 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -07001511 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +00001512 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001513 null, // no permission for receiving assist structure
1514 null, // no permission for receiving assist screenshot
Svet Ganovc3300092015-04-17 09:07:22 -07001515 Manifest.permission.READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -07001516 Manifest.permission.ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -07001517 Manifest.permission.USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -07001518 Manifest.permission.PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001519 Manifest.permission.USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001520 Manifest.permission.BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001521 Manifest.permission.READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001522 null,
1523 Manifest.permission.READ_EXTERNAL_STORAGE,
1524 Manifest.permission.WRITE_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001525 null, // no permission for turning the screen on
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001526 Manifest.permission.GET_ACCOUNTS,
1527 null, // no permission for running in background
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001528 null, // no permission for changing accessibility volume
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001529 Manifest.permission.READ_PHONE_NUMBERS,
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001530 Manifest.permission.REQUEST_INSTALL_PACKAGES,
Winson Chung59fda9e2017-01-20 16:14:51 -08001531 null, // no permission for entering picture-in-picture on hide
Chad Brubaker97b383f2017-02-02 15:04:35 -08001532 Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001533 Manifest.permission.ANSWER_PHONE_CALLS,
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001534 null, // no permission for OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001535 Manifest.permission.CHANGE_WIFI_STATE,
Peter Visontayf2e38362017-11-27 15:27:16 +00001536 Manifest.permission.REQUEST_DELETE_PACKAGES,
Peter Visontay11950832017-11-14 19:34:59 +00001537 Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001538 Manifest.permission.ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001539 null, // no permission for OP_MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001540 Manifest.permission.FOREGROUND_SERVICE,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001541 null, // no permission for OP_BLUETOOTH_SCAN
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001542 Manifest.permission.USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001543 Manifest.permission.ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001544 Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001545 Manifest.permission.READ_MEDIA_AUDIO,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001546 null, // no permission for OP_WRITE_MEDIA_AUDIO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001547 Manifest.permission.READ_MEDIA_VIDEO,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001548 null, // no permission for OP_WRITE_MEDIA_VIDEO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001549 Manifest.permission.READ_MEDIA_IMAGES,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001550 null, // no permission for OP_WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001551 null, // no permission for OP_LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001552 null, // no permission for OP_ACCESS_ACCESSIBILITY
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001553 };
1554
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001555 /**
Jason Monk62062992014-05-06 09:55:28 -04001556 * Specifies whether an Op should be restricted by a user restriction.
1557 * Each Op should be filled with a restriction string from UserManager or
1558 * null to specify it is not affected by any user restriction.
1559 */
1560 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -04001561 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
1562 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
1563 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -04001564 null, //VIBRATE
1565 null, //READ_CONTACTS
1566 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -07001567 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
1568 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -04001569 null, //READ_CALENDAR
1570 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001571 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -04001572 null, //POST_NOTIFICATION
1573 null, //NEIGHBORING_CELLS
1574 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001575 UserManager.DISALLOW_SMS, //READ_SMS
1576 UserManager.DISALLOW_SMS, //WRITE_SMS
1577 UserManager.DISALLOW_SMS, //RECEIVE_SMS
1578 null, //RECEIVE_EMERGENCY_SMS
1579 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -04001580 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001581 UserManager.DISALLOW_SMS, //SEND_SMS
1582 UserManager.DISALLOW_SMS, //READ_ICC_SMS
1583 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -04001584 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -04001585 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -04001586 null, //ACCESS_NOTIFICATIONS
Makoto Onuki759a7632015-10-28 16:43:10 -07001587 UserManager.DISALLOW_CAMERA, //CAMERA
Fyodor Kupolovb5013302015-04-17 17:59:14 -07001588 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
Jason Monk62062992014-05-06 09:55:28 -04001589 null, //PLAY_AUDIO
1590 null, //READ_CLIPBOARD
1591 null, //WRITE_CLIPBOARD
1592 null, //TAKE_MEDIA_BUTTONS
1593 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -04001594 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
1595 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
1596 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
1597 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
1598 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
1599 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
1600 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -04001601 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -04001602 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
1603 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -04001604 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -04001605 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -04001606 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -07001607 null, //PROJECT_MEDIA
Tony Mak33d03a92016-06-02 15:01:16 +01001608 null, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001609 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001610 null, // ASSIST_STRUCTURE
1611 null, // ASSIST_SCREENSHOT
Svet Ganovc3300092015-04-17 09:07:22 -07001612 null, // READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001613 null, // ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001614 null, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001615 null, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001616 null, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001617 null, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001618 null, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001619 null, // MOCK_LOCATION
1620 null, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001621 null, // WRITE_EXTERNAL_STORAGE
1622 null, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001623 null, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001624 null, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001625 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001626 null, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001627 null, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001628 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001629 null, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001630 null, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001631 null, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001632 null, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001633 null, // REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001634 null, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001635 null, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001636 null, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001637 null, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001638 null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001639 null, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001640 null, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001641 UserManager.DISALLOW_SMS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001642 null, // READ_MEDIA_AUDIO
1643 null, // WRITE_MEDIA_AUDIO
1644 null, // READ_MEDIA_VIDEO
1645 null, // WRITE_MEDIA_VIDEO
1646 null, // READ_MEDIA_IMAGES
1647 null, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001648 null, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001649 null, // ACCESS_ACCESSIBILITY
Jason Monk1c7c3192014-06-26 12:52:18 -04001650 };
1651
1652 /**
1653 * This specifies whether each option should allow the system
1654 * (and system ui) to bypass the user restriction when active.
1655 */
1656 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
Fyodor Kupolov639e73d2016-02-25 11:58:21 -08001657 true, //COARSE_LOCATION
1658 true, //FINE_LOCATION
Jason Monk1c7c3192014-06-26 12:52:18 -04001659 false, //GPS
1660 false, //VIBRATE
1661 false, //READ_CONTACTS
1662 false, //WRITE_CONTACTS
1663 false, //READ_CALL_LOG
1664 false, //WRITE_CALL_LOG
1665 false, //READ_CALENDAR
1666 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001667 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -04001668 false, //POST_NOTIFICATION
1669 false, //NEIGHBORING_CELLS
1670 false, //CALL_PHONE
1671 false, //READ_SMS
1672 false, //WRITE_SMS
1673 false, //RECEIVE_SMS
1674 false, //RECEIVE_EMERGECY_SMS
1675 false, //RECEIVE_MMS
1676 false, //RECEIVE_WAP_PUSH
1677 false, //SEND_SMS
1678 false, //READ_ICC_SMS
1679 false, //WRITE_ICC_SMS
1680 false, //WRITE_SETTINGS
1681 true, //SYSTEM_ALERT_WINDOW
1682 false, //ACCESS_NOTIFICATIONS
1683 false, //CAMERA
1684 false, //RECORD_AUDIO
1685 false, //PLAY_AUDIO
1686 false, //READ_CLIPBOARD
1687 false, //WRITE_CLIPBOARD
1688 false, //TAKE_MEDIA_BUTTONS
1689 false, //TAKE_AUDIO_FOCUS
1690 false, //AUDIO_MASTER_VOLUME
1691 false, //AUDIO_VOICE_VOLUME
1692 false, //AUDIO_RING_VOLUME
1693 false, //AUDIO_MEDIA_VOLUME
1694 false, //AUDIO_ALARM_VOLUME
1695 false, //AUDIO_NOTIFICATION_VOLUME
1696 false, //AUDIO_BLUETOOTH_VOLUME
1697 false, //WAKE_LOCK
1698 false, //MONITOR_LOCATION
1699 false, //MONITOR_HIGH_POWER_LOCATION
1700 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -07001701 false, //MUTE_MICROPHONE
1702 true, //TOAST_WINDOW
1703 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -07001704 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001705 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001706 false, //ASSIST_STRUCTURE
1707 false, //ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -07001708 false, //READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001709 false, //ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001710 false, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001711 false, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001712 false, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001713 false, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001714 false, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001715 false, // MOCK_LOCATION
1716 false, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001717 false, // WRITE_EXTERNAL_STORAGE
1718 false, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001719 false, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001720 false, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001721 false, // AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001722 false, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001723 false, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001724 false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001725 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001726 false, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001727 false, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001728 false, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001729 false, // OP_REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001730 false, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001731 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001732 false, // MANAGE_IPSEC_HANDOVERS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001733 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001734 true, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001735 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001736 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001737 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001738 false, // READ_MEDIA_AUDIO
1739 false, // WRITE_MEDIA_AUDIO
1740 false, // READ_MEDIA_VIDEO
1741 false, // WRITE_MEDIA_VIDEO
1742 false, // READ_MEDIA_IMAGES
1743 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001744 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001745 false, // ACCESS_ACCESSIBILITY
Jason Monk62062992014-05-06 09:55:28 -04001746 };
1747
1748 /**
David Braunf5d83192013-09-16 13:43:51 -07001749 * This specifies the default mode for each operation.
1750 */
1751 private static int[] sOpDefaultMode = new int[] {
Eugene Susla93519852018-06-13 16:44:31 -07001752 AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION
1753 AppOpsManager.MODE_ALLOWED, // FINE_LOCATION
1754 AppOpsManager.MODE_ALLOWED, // GPS
1755 AppOpsManager.MODE_ALLOWED, // VIBRATE
1756 AppOpsManager.MODE_ALLOWED, // READ_CONTACTS
1757 AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS
1758 AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG
1759 AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG
1760 AppOpsManager.MODE_ALLOWED, // READ_CALENDAR
1761 AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR
1762 AppOpsManager.MODE_ALLOWED, // WIFI_SCAN
1763 AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION
1764 AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS
1765 AppOpsManager.MODE_ALLOWED, // CALL_PHONE
Eugene Suslaaaff0072018-10-30 13:35:03 -07001766 AppOpsManager.MODE_ALLOWED, // READ_SMS
1767 AppOpsManager.MODE_IGNORED, // WRITE_SMS
1768 AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001769 AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST
1770 AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS
Eugene Suslaaaff0072018-10-30 13:35:03 -07001771 AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH
1772 AppOpsManager.MODE_ALLOWED, // SEND_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001773 AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS
1774 AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS
1775 AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS
Ng Zhi An65a99b62018-10-01 11:57:53 -07001776 getSystemAlertWindowDefault(), // SYSTEM_ALERT_WINDOW
Eugene Susla93519852018-06-13 16:44:31 -07001777 AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS
1778 AppOpsManager.MODE_ALLOWED, // CAMERA
1779 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO
1780 AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO
1781 AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD
1782 AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD
1783 AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS
1784 AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS
1785 AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME
1786 AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME
1787 AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME
1788 AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME
1789 AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME
1790 AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME
1791 AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME
1792 AppOpsManager.MODE_ALLOWED, // WAKE_LOCK
1793 AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION
1794 AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION
1795 AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS
1796 AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE
1797 AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW
1798 AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA
1799 AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN
1800 AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER
1801 AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE
1802 AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT
1803 AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE
1804 AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL
1805 AppOpsManager.MODE_ALLOWED, // USE_SIP
1806 AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS
1807 AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT
1808 AppOpsManager.MODE_ALLOWED, // BODY_SENSORS
Eugene Suslaaaff0072018-10-30 13:35:03 -07001809 AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS
Eugene Susla93519852018-06-13 16:44:31 -07001810 AppOpsManager.MODE_ERRORED, // MOCK_LOCATION
1811 AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE
1812 AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE
1813 AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON
1814 AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS
1815 AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND
1816 AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME
1817 AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS
1818 AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES
1819 AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE
1820 AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND
1821 AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
1822 AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND
1823 AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE
1824 AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES
1825 AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE
1826 AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER
1827 AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS
1828 AppOpsManager.MODE_ALLOWED, // START_FOREGROUND
1829 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN
1830 AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001831 AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001832 AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001833 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001834 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001835 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001836 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001837 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001838 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001839 AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001840 AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY
David Braunf5d83192013-09-16 13:43:51 -07001841 };
1842
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001843 /**
1844 * This specifies whether each option is allowed to be reset
1845 * when resetting all app preferences. Disable reset for
1846 * app ops that are under strong control of some part of the
1847 * system (such as OP_WRITE_SMS, which should be allowed only
1848 * for whichever app is selected as the current SMS app).
1849 */
1850 private static boolean[] sOpDisableReset = new boolean[] {
Eugene Susla93519852018-06-13 16:44:31 -07001851 false, // COARSE_LOCATION
1852 false, // FINE_LOCATION
1853 false, // GPS
1854 false, // VIBRATE
1855 false, // READ_CONTACTS
1856 false, // WRITE_CONTACTS
1857 false, // READ_CALL_LOG
1858 false, // WRITE_CALL_LOG
1859 false, // READ_CALENDAR
1860 false, // WRITE_CALENDAR
1861 false, // WIFI_SCAN
1862 false, // POST_NOTIFICATION
1863 false, // NEIGHBORING_CELLS
1864 false, // CALL_PHONE
1865 true, // READ_SMS
1866 true, // WRITE_SMS
1867 true, // RECEIVE_SMS
1868 false, // RECEIVE_EMERGENCY_BROADCAST
1869 false, // RECEIVE_MMS
1870 true, // RECEIVE_WAP_PUSH
1871 true, // SEND_SMS
1872 false, // READ_ICC_SMS
1873 false, // WRITE_ICC_SMS
1874 false, // WRITE_SETTINGS
1875 false, // SYSTEM_ALERT_WINDOW
1876 false, // ACCESS_NOTIFICATIONS
1877 false, // CAMERA
1878 false, // RECORD_AUDIO
1879 false, // PLAY_AUDIO
1880 false, // READ_CLIPBOARD
1881 false, // WRITE_CLIPBOARD
1882 false, // TAKE_MEDIA_BUTTONS
1883 false, // TAKE_AUDIO_FOCUS
1884 false, // AUDIO_MASTER_VOLUME
1885 false, // AUDIO_VOICE_VOLUME
1886 false, // AUDIO_RING_VOLUME
1887 false, // AUDIO_MEDIA_VOLUME
1888 false, // AUDIO_ALARM_VOLUME
1889 false, // AUDIO_NOTIFICATION_VOLUME
1890 false, // AUDIO_BLUETOOTH_VOLUME
1891 false, // WAKE_LOCK
1892 false, // MONITOR_LOCATION
1893 false, // MONITOR_HIGH_POWER_LOCATION
1894 false, // GET_USAGE_STATS
1895 false, // MUTE_MICROPHONE
1896 false, // TOAST_WINDOW
1897 false, // PROJECT_MEDIA
1898 false, // ACTIVATE_VPN
1899 false, // WRITE_WALLPAPER
1900 false, // ASSIST_STRUCTURE
1901 false, // ASSIST_SCREENSHOT
1902 false, // READ_PHONE_STATE
1903 false, // ADD_VOICEMAIL
1904 false, // USE_SIP
1905 false, // PROCESS_OUTGOING_CALLS
1906 false, // USE_FINGERPRINT
1907 false, // BODY_SENSORS
1908 true, // READ_CELL_BROADCASTS
1909 false, // MOCK_LOCATION
1910 false, // READ_EXTERNAL_STORAGE
1911 false, // WRITE_EXTERNAL_STORAGE
1912 false, // TURN_SCREEN_ON
1913 false, // GET_ACCOUNTS
1914 false, // RUN_IN_BACKGROUND
1915 false, // AUDIO_ACCESSIBILITY_VOLUME
1916 false, // READ_PHONE_NUMBERS
1917 false, // REQUEST_INSTALL_PACKAGES
1918 false, // PICTURE_IN_PICTURE
1919 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001920 false, // ANSWER_PHONE_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07001921 false, // RUN_ANY_IN_BACKGROUND
1922 false, // CHANGE_WIFI_STATE
1923 false, // REQUEST_DELETE_PACKAGES
1924 false, // BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001925 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001926 false, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001927 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001928 false, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001929 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001930 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001931 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001932 false, // READ_MEDIA_AUDIO
1933 false, // WRITE_MEDIA_AUDIO
1934 false, // READ_MEDIA_VIDEO
1935 false, // WRITE_MEDIA_VIDEO
1936 false, // READ_MEDIA_IMAGES
1937 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001938 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001939 false, // ACCESS_ACCESSIBILITY
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001940 };
1941
Svet Ganovfbf01f72015-04-28 18:39:06 -07001942 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07001943 * Mapping from an app op name to the app op code.
Svet Ganovfbf01f72015-04-28 18:39:06 -07001944 */
Svet Ganovb9d71a62015-04-30 10:38:13 -07001945 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
Svet Ganovfbf01f72015-04-28 18:39:06 -07001946
Svet Ganovb9d71a62015-04-30 10:38:13 -07001947 /**
1948 * Mapping from a permission to the corresponding app op.
1949 */
Svet Ganovda0acdf2017-02-15 10:28:51 -08001950 private static HashMap<String, Integer> sPermToOp = new HashMap<>();
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001951
1952 static {
1953 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001954 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001955 + " should be " + _NUM_OP);
1956 }
1957 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001958 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001959 + " should be " + _NUM_OP);
1960 }
1961 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001962 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001963 + " should be " + _NUM_OP);
1964 }
1965 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001966 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001967 + " should be " + _NUM_OP);
1968 }
1969 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001970 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
1971 + " should be " + _NUM_OP);
1972 }
1973 if (sOpDisableReset.length != _NUM_OP) {
1974 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001975 + " should be " + _NUM_OP);
1976 }
Jason Monk62062992014-05-06 09:55:28 -04001977 if (sOpRestrictions.length != _NUM_OP) {
1978 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
1979 + " should be " + _NUM_OP);
1980 }
Jason Monk1c7c3192014-06-26 12:52:18 -04001981 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
1982 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
1983 + sOpRestrictions.length + " should be " + _NUM_OP);
1984 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001985 for (int i=0; i<_NUM_OP; i++) {
1986 if (sOpToString[i] != null) {
1987 sOpStrToOp.put(sOpToString[i], i);
1988 }
1989 }
Svet Ganovda0acdf2017-02-15 10:28:51 -08001990 for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001991 if (sOpPerms[op] != null) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08001992 sPermToOp.put(sOpPerms[op], op);
Svet Ganovb9d71a62015-04-30 10:38:13 -07001993 }
1994 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001995 }
1996
Svet Ganov8455ba22019-01-02 13:05:56 -08001997 /** @hide */
1998 public static final String KEY_HISTORICAL_OPS = "historical_ops";
1999
Chad Brubaker7c6dba62019-01-23 15:51:43 -08002000 /** System properties for debug logging of noteOp call sites */
2001 private static final String DEBUG_LOGGING_ENABLE_PROP = "appops.logging_enabled";
2002 private static final String DEBUG_LOGGING_PACKAGES_PROP = "appops.logging_packages";
2003 private static final String DEBUG_LOGGING_OPS_PROP = "appops.logging_ops";
2004 private static final String DEBUG_LOGGING_TAG = "AppOpsManager";
2005
David Braunf5d83192013-09-16 13:43:51 -07002006 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002007 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002008 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002009 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002010 @UnsupportedAppUsage
Dianne Hackbornf265ea92013-01-31 15:00:51 -08002011 public static int opToSwitch(int op) {
2012 return sOpToSwitch[op];
2013 }
2014
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002015 /**
2016 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002017 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002018 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002019 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002020 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08002021 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002022 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
2023 }
2024
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002025 /**
Svet Ganov65f1b9e2019-01-17 19:19:40 -08002026 * Retrieve a non-localized public name for the operation.
2027 *
2028 * @hide
2029 */
2030 public static @NonNull String opToPublicName(int op) {
2031 return sOpToString[op];
2032 }
2033
2034 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08002035 * @hide
2036 */
2037 public static int strDebugOpToOp(String op) {
2038 for (int i=0; i<sOpNames.length; i++) {
2039 if (sOpNames[i].equals(op)) {
2040 return i;
2041 }
2042 }
2043 throw new IllegalArgumentException("Unknown operation string: " + op);
2044 }
2045
2046 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002047 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002048 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002049 */
Philip P. Moltmann33115152018-04-11 13:39:36 -07002050 @TestApi
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002051 public static String opToPermission(int op) {
2052 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002053 }
2054
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002055 /**
Hai Zhangb7776682018-09-25 15:10:57 -07002056 * Retrieve the permission associated with an operation, or null if there is not one.
2057 *
2058 * @param op The operation name.
2059 *
2060 * @hide
2061 */
2062 @Nullable
2063 @SystemApi
2064 public static String opToPermission(@NonNull String op) {
2065 return opToPermission(strOpToOp(op));
2066 }
2067
2068 /**
Jason Monk62062992014-05-06 09:55:28 -04002069 * Retrieve the user restriction associated with an operation, or null if there is not one.
2070 * @hide
2071 */
2072 public static String opToRestriction(int op) {
2073 return sOpRestrictions[op];
2074 }
2075
2076 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07002077 * Retrieve the app op code for a permission, or null if there is not one.
Svet Ganovda0acdf2017-02-15 10:28:51 -08002078 * This API is intended to be used for mapping runtime or appop permissions
2079 * to the corresponding app op.
Svet Ganovb9d71a62015-04-30 10:38:13 -07002080 * @hide
2081 */
Philip P. Moltmann33115152018-04-11 13:39:36 -07002082 @TestApi
Svet Ganovb9d71a62015-04-30 10:38:13 -07002083 public static int permissionToOpCode(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002084 Integer boxedOpCode = sPermToOp.get(permission);
Svet Ganov019d2302015-05-04 11:07:38 -07002085 return boxedOpCode != null ? boxedOpCode : OP_NONE;
Svet Ganovb9d71a62015-04-30 10:38:13 -07002086 }
2087
2088 /**
Jason Monk1c7c3192014-06-26 12:52:18 -04002089 * Retrieve whether the op allows the system (and system ui) to
2090 * bypass the user restriction.
2091 * @hide
2092 */
2093 public static boolean opAllowSystemBypassRestriction(int op) {
2094 return sOpAllowSystemRestrictionBypass[op];
2095 }
2096
2097 /**
David Braunf5d83192013-09-16 13:43:51 -07002098 * Retrieve the default mode for the operation.
2099 * @hide
2100 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002101 public static @Mode int opToDefaultMode(int op) {
Svet Ganov55203682018-11-02 22:34:52 -07002102 // STOPSHIP b/118520006: Hardcode the default values once the feature is stable.
2103 switch (op) {
2104 // SMS permissions
2105 case AppOpsManager.OP_SEND_SMS:
2106 case AppOpsManager.OP_RECEIVE_SMS:
2107 case AppOpsManager.OP_READ_SMS:
2108 case AppOpsManager.OP_RECEIVE_WAP_PUSH:
2109 case AppOpsManager.OP_RECEIVE_MMS:
2110 case AppOpsManager.OP_READ_CELL_BROADCASTS:
2111 // CallLog permissions
2112 case AppOpsManager.OP_READ_CALL_LOG:
2113 case AppOpsManager.OP_WRITE_CALL_LOG:
2114 case AppOpsManager.OP_PROCESS_OUTGOING_CALLS: {
Svet Ganov55203682018-11-02 22:34:52 -07002115 if (sSmsAndCallLogRestrictionEnabled.get() == 1) {
2116 return AppOpsManager.MODE_DEFAULT;
2117 }
2118 }
2119 }
David Braunf5d83192013-09-16 13:43:51 -07002120 return sOpDefaultMode[op];
2121 }
2122
Svet Ganov55203682018-11-02 22:34:52 -07002123 // STOPSHIP b/118520006: Hardcode the default values once the feature is stable.
2124 private static final AtomicInteger sSmsAndCallLogRestrictionEnabled = new AtomicInteger(-1);
2125
2126 // STOPSHIP b/118520006: Hardcode the default values once the feature is stable.
Todd Kennedye4a8dbd2018-11-14 09:22:05 -08002127 static {
Svet Ganov55203682018-11-02 22:34:52 -07002128 final Context context = ActivityThread.currentApplication();
Todd Kennedye4a8dbd2018-11-14 09:22:05 -08002129 if (context != null) {
2130 sSmsAndCallLogRestrictionEnabled.set(ActivityThread.currentActivityThread()
2131 .getIntCoreSetting(Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0));
2132
2133 final Uri uri =
2134 Settings.Global.getUriFor(Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED);
2135 context.getContentResolver().registerContentObserver(uri, false, new ContentObserver(
2136 context.getMainThreadHandler()) {
2137 @Override
2138 public void onChange(boolean selfChange) {
2139 sSmsAndCallLogRestrictionEnabled.set(Settings.Global.getInt(
2140 context.getContentResolver(),
2141 Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0));
2142 }
2143 });
Svet Ganov55203682018-11-02 22:34:52 -07002144 }
Svet Ganov55203682018-11-02 22:34:52 -07002145 }
2146
David Braunf5d83192013-09-16 13:43:51 -07002147 /**
Hai Zhangc595f112018-11-06 14:20:38 -08002148 * Retrieve the default mode for the app op.
2149 *
2150 * @param appOp The app op name
2151 *
2152 * @return the default mode for the app op
2153 *
2154 * @hide
2155 */
2156 @SystemApi
2157 public static int opToDefaultMode(@NonNull String appOp) {
2158 return opToDefaultMode(strOpToOp(appOp));
2159 }
2160
2161 /**
Svet Ganov82f09bc2018-01-12 22:08:40 -08002162 * Retrieve the human readable mode.
2163 * @hide
2164 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002165 public static String modeToName(@Mode int mode) {
Dianne Hackbornc216a262018-04-26 13:46:22 -07002166 if (mode >= 0 && mode < MODE_NAMES.length) {
2167 return MODE_NAMES[mode];
Svet Ganov82f09bc2018-01-12 22:08:40 -08002168 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07002169 return "mode=" + mode;
Svet Ganov82f09bc2018-01-12 22:08:40 -08002170 }
2171
2172 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002173 * Retrieve whether the op allows itself to be reset.
2174 * @hide
2175 */
2176 public static boolean opAllowsReset(int op) {
2177 return !sOpDisableReset[op];
2178 }
2179
2180 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002181 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002182 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002183 */
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002184 @SystemApi
2185 public static final class PackageOps implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002186 private final String mPackageName;
2187 private final int mUid;
2188 private final List<OpEntry> mEntries;
2189
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002190 /**
2191 * @hide
2192 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002193 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002194 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
2195 mPackageName = packageName;
2196 mUid = uid;
2197 mEntries = entries;
2198 }
2199
Svet Ganovaf189e32019-02-15 18:45:29 -08002200 /**
2201 * @return The name of the package.
2202 */
2203 public @NonNull String getPackageName() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002204 return mPackageName;
2205 }
2206
Svet Ganovaf189e32019-02-15 18:45:29 -08002207 /**
2208 * @return The uid of the package.
2209 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002210 public int getUid() {
2211 return mUid;
2212 }
2213
Svet Ganovaf189e32019-02-15 18:45:29 -08002214 /**
2215 * @return The ops of the package.
2216 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002217 public List<OpEntry> getOps() {
2218 return mEntries;
2219 }
2220
2221 @Override
2222 public int describeContents() {
2223 return 0;
2224 }
2225
2226 @Override
2227 public void writeToParcel(Parcel dest, int flags) {
2228 dest.writeString(mPackageName);
2229 dest.writeInt(mUid);
2230 dest.writeInt(mEntries.size());
2231 for (int i=0; i<mEntries.size(); i++) {
2232 mEntries.get(i).writeToParcel(dest, flags);
2233 }
2234 }
2235
2236 PackageOps(Parcel source) {
2237 mPackageName = source.readString();
2238 mUid = source.readInt();
2239 mEntries = new ArrayList<OpEntry>();
2240 final int N = source.readInt();
2241 for (int i=0; i<N; i++) {
2242 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
2243 }
2244 }
2245
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07002246 public static final @android.annotation.NonNull Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002247 @Override public PackageOps createFromParcel(Parcel source) {
2248 return new PackageOps(source);
2249 }
2250
2251 @Override public PackageOps[] newArray(int size) {
2252 return new PackageOps[size];
2253 }
2254 };
2255 }
2256
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002257 /**
2258 * Class holding the information about one unique operation of an application.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002259 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002260 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002261 @TestApi
2262 @Immutable
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002263 @SystemApi
2264 public static final class OpEntry implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002265 private final int mOp;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002266 private final boolean mRunning;
Svet Ganovaf189e32019-02-15 18:45:29 -08002267 private final @Mode int mMode;
2268 private final @Nullable LongSparseLongArray mAccessTimes;
2269 private final @Nullable LongSparseLongArray mRejectTimes;
2270 private final @Nullable LongSparseLongArray mDurations;
2271 private final @Nullable LongSparseLongArray mProxyUids;
2272 private final @Nullable LongSparseArray<String> mProxyPackageNames;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002273
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002274 /**
2275 * @hide
2276 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002277 public OpEntry(int op, boolean running, @Mode int mode,
2278 @Nullable LongSparseLongArray accessTimes, @Nullable LongSparseLongArray rejectTimes,
2279 @Nullable LongSparseLongArray durations, @Nullable LongSparseLongArray proxyUids,
2280 @Nullable LongSparseArray<String> proxyPackageNames) {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002281 mOp = op;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002282 mRunning = running;
Svet Ganovaf189e32019-02-15 18:45:29 -08002283 mMode = mode;
2284 mAccessTimes = accessTimes;
2285 mRejectTimes = rejectTimes;
2286 mDurations = durations;
2287 mProxyUids = proxyUids;
2288 mProxyPackageNames = proxyPackageNames;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002289 }
2290
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002291 /**
2292 * @hide
2293 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002294 public OpEntry(int op, @Mode int mode) {
2295 mOp = op;
2296 mMode = mode;
2297 mRunning = false;
2298 mAccessTimes = null;
2299 mRejectTimes = null;
2300 mDurations = null;
2301 mProxyUids = null;
2302 mProxyPackageNames = null;
2303 }
2304
2305 /**
2306 * Returns all keys for which we have mapped state in any of the data buckets -
2307 * access time, reject time, duration.
2308 * @hide */
2309 public @Nullable LongSparseArray<Object> collectKeys() {
2310 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessTimes, null);
2311 result = AppOpsManager.collectKeys(mRejectTimes, result);
2312 result = AppOpsManager.collectKeys(mDurations, result);
2313 return result;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002314 }
2315
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002316 /**
2317 * @hide
2318 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002319 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002320 public int getOp() {
2321 return mOp;
2322 }
2323
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002324 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002325 * @return This entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}.
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002326 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002327 public @NonNull String getOpStr() {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002328 return sOpToString[mOp];
2329 }
2330
2331 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002332 * @return this entry's current mode, such as {@link #MODE_ALLOWED}.
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002333 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002334 public @Mode int getMode() {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002335 return mMode;
2336 }
2337
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002338 /**
2339 * @hide
2340 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002341 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002342 public long getTime() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002343 return getLastAccessTime(OP_FLAGS_ALL);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002344 }
2345
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002346 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002347 * Return the last wall clock time in milliseconds this op was accessed.
2348 *
2349 * @param flags The flags which are any combination of
2350 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2351 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2352 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2353 * for any flag.
2354 * @return the last access time in milliseconds since
2355 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2356 *
2357 * @see #getLastAccessForegroundTime(int)
2358 * @see #getLastAccessBackgroundTime(int)
2359 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002360 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002361 public long getLastAccessTime(@OpFlags int flags) {
2362 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
2363 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002364 }
2365
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002366 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002367 * Return the last wall clock time in milliseconds this op was accessed
2368 * by the app while in the foreground.
2369 *
2370 * @param flags The flags which are any combination of
2371 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2372 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2373 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2374 * for any flag.
2375 * @return the last foreground access time in milliseconds since
2376 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2377 *
2378 * @see #getLastAccessBackgroundTime(int)
2379 * @see #getLastAccessTime(int)
2380 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002381 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002382 public long getLastAccessForegroundTime(@OpFlags int flags) {
2383 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
2384 resolveFirstUnrestrictedUidState(mOp), flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002385 }
2386
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002387 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002388 * Return the last wall clock time in milliseconds this op was accessed
2389 * by the app while in the background.
2390 *
2391 * @param flags The flags which are any combination of
2392 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2393 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2394 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2395 * for any flag.
2396 * @return the last foreground access time in milliseconds since
2397 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2398 *
2399 * @see #getLastAccessForegroundTime(int)
2400 * @see #getLastAccessTime(int)
2401 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002402 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002403 public long getLastAccessBackgroundTime(@OpFlags int flags) {
2404 return maxForFlagsInStates(mAccessTimes, resolveLastRestrictedUidState(mOp),
2405 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002406 }
2407
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002408 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002409 * Return the last wall clock time in milliseconds this op was accessed
2410 * by the app for a given range of UID states.
2411 *
2412 * @param fromUidState The UID state for which to query. Could be one of
2413 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2414 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2415 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2416 * @param toUidState The UID state for which to query.
2417 * @param flags The flags which are any combination of
2418 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2419 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2420 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2421 * for any flag.
2422 *
2423 * @return the last foreground access time in milliseconds since
2424 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2425 *
2426 * @see #getLastAccessForegroundTime(int)
2427 * @see #getLastAccessBackgroundTime(int)
2428 * @see #getLastAccessTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002429 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002430 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
2431 @OpFlags int flags) {
2432 return maxForFlagsInStates(mAccessTimes, fromUidState, toUidState, flags);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002433 }
2434
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002435 /**
2436 * @hide
2437 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002438 public long getRejectTime() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002439 return getLastRejectTime(OP_FLAGS_ALL);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002440 }
2441
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002442 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002443 * Return the last wall clock time in milliseconds the app made an attempt
2444 * to access this op but was rejected.
2445 *
2446 * @param flags The flags which are any combination of
2447 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2448 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2449 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2450 * for any flag.
2451 * @return the last reject time in milliseconds since
2452 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2453 *
2454 * @see #getLastRejectBackgroundTime(int)
2455 * @see #getLastRejectForegroundTime(int)
2456 * @see #getLastRejectTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002457 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002458 public long getLastRejectTime(@OpFlags int flags) {
2459 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
2460 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002461 }
2462
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002463 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002464 * Return the last wall clock time in milliseconds the app made an attempt
2465 * to access this op while in the foreground but was rejected.
2466 *
2467 * @param flags The flags which are any combination of
2468 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2469 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2470 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2471 * for any flag.
2472 * @return the last foreground reject time in milliseconds since
2473 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2474 *
2475 * @see #getLastRejectBackgroundTime(int)
2476 * @see #getLastRejectTime(int, int, int)
2477 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002478 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002479 public long getLastRejectForegroundTime(@OpFlags int flags) {
2480 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
2481 resolveFirstUnrestrictedUidState(mOp), flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002482 }
2483
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002484 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002485 * Return the last wall clock time in milliseconds the app made an attempt
2486 * to access this op while in the background but was rejected.
2487 *
2488 * @param flags The flags which are any combination of
2489 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2490 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2491 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2492 * for any flag.
2493 * @return the last background reject time in milliseconds since
2494 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2495 *
2496 * @see #getLastRejectForegroundTime(int)
2497 * @see #getLastRejectTime(int, int, int)
2498 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002499 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002500 public long getLastRejectBackgroundTime(@OpFlags int flags) {
2501 return maxForFlagsInStates(mRejectTimes, resolveLastRestrictedUidState(mOp),
2502 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002503 }
2504
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002505 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002506 * Return the last wall clock time state in milliseconds the app made an
2507 * attempt to access this op for a given range of UID states.
2508 *
2509 * @param fromUidState The UID state from which to query. Could be one of
2510 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2511 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2512 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2513 * @param toUidState The UID state to which to query.
2514 * @param flags The flags which are any combination of
2515 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2516 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2517 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2518 * for any flag.
2519 * @return the last foreground access time in milliseconds since
2520 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2521 *
2522 * @see #getLastRejectForegroundTime(int)
2523 * @see #getLastRejectBackgroundTime(int)
2524 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002525 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002526 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
2527 @OpFlags int flags) {
2528 return maxForFlagsInStates(mRejectTimes, fromUidState, toUidState, flags);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002529 }
2530
Svet Ganovaf189e32019-02-15 18:45:29 -08002531 /**
2532 * @return Whether the operation is running.
2533 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002534 public boolean isRunning() {
Amith Yamasania1ce9632018-05-28 20:50:48 -07002535 return mRunning;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002536 }
2537
Svet Ganovaf189e32019-02-15 18:45:29 -08002538 /**
2539 * @return The duration of the operation in milliseconds.
2540 */
2541 public long getDuration() {
2542 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002543 }
2544
Svet Ganovaf189e32019-02-15 18:45:29 -08002545 /**
2546 * Return the duration in milliseconds the app accessed this op while
2547 * in the foreground.
2548 *
2549 * @param flags The flags which are any combination of
2550 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2551 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2552 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2553 * for any flag.
2554 * @return the foreground access duration in milliseconds.
2555 *
2556 * @see #getLastBackgroundDuration(int)
2557 * @see #getLastDuration(int, int, int)
2558 */
2559 public long getLastForegroundDuration(@OpFlags int flags) {
2560 return sumForFlagsInStates(mDurations, MAX_PRIORITY_UID_STATE,
2561 resolveFirstUnrestrictedUidState(mOp), flags);
2562 }
2563
2564 /**
2565 * Return the duration in milliseconds the app accessed this op while
2566 * in the background.
2567 *
2568 * @param flags The flags which are any combination of
2569 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2570 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2571 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2572 * for any flag.
2573 * @return the background access duration in milliseconds.
2574 *
2575 * @see #getLastForegroundDuration(int)
2576 * @see #getLastDuration(int, int, int)
2577 */
2578 public long getLastBackgroundDuration(@OpFlags int flags) {
2579 return sumForFlagsInStates(mDurations, resolveLastRestrictedUidState(mOp),
2580 MIN_PRIORITY_UID_STATE, flags);
2581 }
2582
2583 /**
2584 * Return the duration in milliseconds the app accessed this op for
2585 * a given range of UID states.
2586 *
2587 * @param fromUidState The UID state for which to query. Could be one of
2588 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2589 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2590 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2591 * @param toUidState The UID state for which to query.
2592 * @param flags The flags which are any combination of
2593 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2594 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2595 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2596 * for any flag.
2597 * @return the access duration in milliseconds.
2598 */
2599 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
2600 @OpFlags int flags) {
2601 return sumForFlagsInStates(mDurations, fromUidState, toUidState, flags);
2602 }
2603
2604 /**
2605 * Gets the UID of the app that performed the op on behalf of this app and
2606 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2607 * there is no proxy.
2608 *
2609 * @return The proxy UID.
2610 */
Svet Ganov99b60432015-06-27 13:15:22 -07002611 public int getProxyUid() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002612 return (int) findFirstNonNegativeForFlagsInStates(mDurations,
2613 MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
Svet Ganov99b60432015-06-27 13:15:22 -07002614 }
2615
Svet Ganovaf189e32019-02-15 18:45:29 -08002616 /**
2617 * Gets the UID of the app that performed the op on behalf of this app and
2618 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2619 * there is no proxy.
2620 *
2621 * @param uidState The UID state for which to query. Could be one of
2622 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2623 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2624 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2625 * @param flags The flags which are any combination of
2626 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2627 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2628 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2629 * for any flag.
2630 *
2631 * @return The proxy UID.
2632 */
2633 public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
2634 return (int) findFirstNonNegativeForFlagsInStates(mDurations,
2635 uidState, uidState, flags);
2636 }
2637
2638 /**
2639 * Gets the package name of the app that performed the op on behalf of this
2640 * app and as a result blamed the op on this app or {@code null}
2641 * if there is no proxy.
2642 *
2643 * @return The proxy package name.
2644 */
2645 public @Nullable String getProxyPackageName() {
2646 return findFirstNonNullForFlagsInStates(mProxyPackageNames, MAX_PRIORITY_UID_STATE,
2647 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
2648 }
2649
2650 /**
2651 * Gets the package name of the app that performed the op on behalf of this
2652 * app and as a result blamed the op on this app for a UID state or
2653 * {@code null} if there is no proxy.
2654 *
2655 * @param uidState The UID state for which to query. Could be one of
2656 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2657 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2658 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2659 * @param flags The flags which are any combination of
2660 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2661 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2662 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2663 * for any flag.
2664 * @return The proxy package name.
2665 */
2666 public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
2667 return findFirstNonNullForFlagsInStates(mProxyPackageNames, uidState, uidState, flags);
Svet Ganov99b60432015-06-27 13:15:22 -07002668 }
2669
Dianne Hackborn35654b62013-01-14 17:38:02 -08002670 @Override
2671 public int describeContents() {
2672 return 0;
2673 }
2674
2675 @Override
2676 public void writeToParcel(Parcel dest, int flags) {
2677 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002678 dest.writeInt(mMode);
Amith Yamasania1ce9632018-05-28 20:50:48 -07002679 dest.writeBoolean(mRunning);
Svet Ganovaf189e32019-02-15 18:45:29 -08002680 writeLongSparseLongArrayToParcel(mAccessTimes, dest);
2681 writeLongSparseLongArrayToParcel(mRejectTimes, dest);
2682 writeLongSparseLongArrayToParcel(mDurations, dest);
2683 writeLongSparseLongArrayToParcel(mProxyUids, dest);
2684 writeLongSparseStringArrayToParcel(mProxyPackageNames, dest);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002685 }
2686
2687 OpEntry(Parcel source) {
2688 mOp = source.readInt();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002689 mMode = source.readInt();
Amith Yamasania1ce9632018-05-28 20:50:48 -07002690 mRunning = source.readBoolean();
Svet Ganovaf189e32019-02-15 18:45:29 -08002691 mAccessTimes = readLongSparseLongArrayFromParcel(source);
2692 mRejectTimes = readLongSparseLongArrayFromParcel(source);
2693 mDurations = readLongSparseLongArrayFromParcel(source);
2694 mProxyUids = readLongSparseLongArrayFromParcel(source);
2695 mProxyPackageNames = readLongSparseStringArrayFromParcel(source);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002696 }
2697
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07002698 public static final @android.annotation.NonNull Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002699 @Override public OpEntry createFromParcel(Parcel source) {
2700 return new OpEntry(source);
2701 }
2702
2703 @Override public OpEntry[] newArray(int size) {
2704 return new OpEntry[size];
2705 }
2706 };
2707 }
2708
Svet Ganov8455ba22019-01-02 13:05:56 -08002709 /** @hide */
2710 public interface HistoricalOpsVisitor {
2711 void visitHistoricalOps(@NonNull HistoricalOps ops);
2712 void visitHistoricalUidOps(@NonNull HistoricalUidOps ops);
2713 void visitHistoricalPackageOps(@NonNull HistoricalPackageOps ops);
2714 void visitHistoricalOp(@NonNull HistoricalOp ops);
2715 }
2716
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002717 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08002718 * Request for getting historical app op usage. The request acts
2719 * as a filtering criteria when querying historical op usage.
2720 *
2721 * @hide
2722 */
2723 @Immutable
2724 @TestApi
2725 @SystemApi
2726 public static final class HistoricalOpsRequest {
2727 private final int mUid;
2728 private final @Nullable String mPackageName;
2729 private final @Nullable List<String> mOpNames;
2730 private final long mBeginTimeMillis;
2731 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08002732 private final @OpFlags int mFlags;
Svet Ganov23c88db2019-01-22 20:38:11 -08002733
2734 private HistoricalOpsRequest(int uid, @Nullable String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08002735 @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
2736 @OpFlags int flags) {
Svet Ganov23c88db2019-01-22 20:38:11 -08002737 mUid = uid;
2738 mPackageName = packageName;
2739 mOpNames = opNames;
2740 mBeginTimeMillis = beginTimeMillis;
2741 mEndTimeMillis = endTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08002742 mFlags = flags;
Svet Ganov23c88db2019-01-22 20:38:11 -08002743 }
2744
2745 /**
2746 * Builder for creating a {@link HistoricalOpsRequest}.
2747 *
2748 * @hide
2749 */
2750 @TestApi
2751 @SystemApi
2752 public static final class Builder {
2753 private int mUid = Process.INVALID_UID;
2754 private @Nullable String mPackageName;
2755 private @Nullable List<String> mOpNames;
2756 private final long mBeginTimeMillis;
2757 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08002758 private @OpFlags int mFlags = OP_FLAGS_ALL;
Svet Ganov23c88db2019-01-22 20:38:11 -08002759
2760 /**
2761 * Creates a new builder.
2762 *
2763 * @param beginTimeMillis The beginning of the interval in milliseconds since
2764 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non
2765 * negative.
2766 * @param endTimeMillis The end of the interval in milliseconds since
2767 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after
2768 * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent
2769 * history including ops that happen while this call is in flight.
2770 */
2771 public Builder(long beginTimeMillis, long endTimeMillis) {
2772 Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
2773 "beginTimeMillis must be non negative and lesser than endTimeMillis");
2774 mBeginTimeMillis = beginTimeMillis;
2775 mEndTimeMillis = endTimeMillis;
2776 }
2777
2778 /**
2779 * Sets the UID to query for.
2780 *
2781 * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid.
2782 * @return This builder.
2783 */
2784 public @NonNull Builder setUid(int uid) {
2785 Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
2786 "uid must be " + Process.INVALID_UID + " or non negative");
2787 mUid = uid;
2788 return this;
2789 }
2790
2791 /**
2792 * Sets the package to query for.
2793 *
2794 * @param packageName The package name. <code>Null</code> for any package.
2795 * @return This builder.
2796 */
2797 public @NonNull Builder setPackageName(@Nullable String packageName) {
2798 mPackageName = packageName;
2799 return this;
2800 }
2801
2802 /**
2803 * Sets the op names to query for.
2804 *
2805 * @param opNames The op names. <code>Null</code> for any op.
2806 * @return This builder.
2807 */
2808 public @NonNull Builder setOpNames(@Nullable List<String> opNames) {
2809 if (opNames != null) {
2810 final int opCount = opNames.size();
2811 for (int i = 0; i < opCount; i++) {
2812 Preconditions.checkArgument(AppOpsManager.strOpToOp(
2813 opNames.get(i)) != AppOpsManager.OP_NONE);
2814 }
2815 }
2816 mOpNames = opNames;
2817 return this;
2818 }
2819
2820 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002821 * Sets the op flags to query for. The flags specify the type of
2822 * op data being queried.
2823 *
2824 * @param flags The flags which are any combination of
2825 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2826 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2827 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2828 * for any flag.
2829 * @return This builder.
2830 */
2831 public @NonNull Builder setFlags(@OpFlags int flags) {
2832 Preconditions.checkFlagsArgument(flags, OP_FLAGS_ALL);
2833 mFlags = flags;
2834 return this;
2835 }
2836
2837 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08002838 * @return a new {@link HistoricalOpsRequest}.
2839 */
2840 public @NonNull HistoricalOpsRequest build() {
2841 return new HistoricalOpsRequest(mUid, mPackageName, mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08002842 mBeginTimeMillis, mEndTimeMillis, mFlags);
Svet Ganov23c88db2019-01-22 20:38:11 -08002843 }
2844 }
2845 }
2846
2847 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08002848 * This class represents historical app op state of all UIDs for a given time interval.
2849 *
2850 * @hide
2851 */
2852 @TestApi
2853 @SystemApi
2854 public static final class HistoricalOps implements Parcelable {
2855 private long mBeginTimeMillis;
2856 private long mEndTimeMillis;
2857 private @Nullable SparseArray<HistoricalUidOps> mHistoricalUidOps;
2858
2859 /** @hide */
2860 @TestApi
2861 public HistoricalOps(long beginTimeMillis, long endTimeMillis) {
2862 Preconditions.checkState(beginTimeMillis <= endTimeMillis);
2863 mBeginTimeMillis = beginTimeMillis;
2864 mEndTimeMillis = endTimeMillis;
2865 }
2866
2867 /** @hide */
2868 public HistoricalOps(@NonNull HistoricalOps other) {
2869 mBeginTimeMillis = other.mBeginTimeMillis;
2870 mEndTimeMillis = other.mEndTimeMillis;
2871 Preconditions.checkState(mBeginTimeMillis <= mEndTimeMillis);
2872 if (other.mHistoricalUidOps != null) {
2873 final int opCount = other.getUidCount();
2874 for (int i = 0; i < opCount; i++) {
2875 final HistoricalUidOps origOps = other.getUidOpsAt(i);
2876 final HistoricalUidOps clonedOps = new HistoricalUidOps(origOps);
2877 if (mHistoricalUidOps == null) {
2878 mHistoricalUidOps = new SparseArray<>(opCount);
2879 }
2880 mHistoricalUidOps.put(clonedOps.getUid(), clonedOps);
2881 }
2882 }
2883 }
2884
2885 private HistoricalOps(Parcel parcel) {
2886 mBeginTimeMillis = parcel.readLong();
2887 mEndTimeMillis = parcel.readLong();
2888 final int[] uids = parcel.createIntArray();
2889 if (!ArrayUtils.isEmpty(uids)) {
2890 final ParceledListSlice<HistoricalUidOps> listSlice = parcel.readParcelable(
2891 HistoricalOps.class.getClassLoader());
2892 final List<HistoricalUidOps> uidOps = (listSlice != null)
2893 ? listSlice.getList() : null;
2894 if (uidOps == null) {
2895 return;
2896 }
2897 for (int i = 0; i < uids.length; i++) {
2898 if (mHistoricalUidOps == null) {
2899 mHistoricalUidOps = new SparseArray<>();
2900 }
2901 mHistoricalUidOps.put(uids[i], uidOps.get(i));
2902 }
2903 }
2904 }
2905
2906 /**
2907 * Splice a piece from the beginning of these ops.
2908 *
2909 * @param splicePoint The fraction of the data to be spliced off.
2910 *
2911 * @hide
2912 */
2913 public @NonNull HistoricalOps spliceFromBeginning(double splicePoint) {
2914 return splice(splicePoint, true);
2915 }
2916
2917 /**
2918 * Splice a piece from the end of these ops.
2919 *
2920 * @param fractionToRemove The fraction of the data to be spliced off.
2921 *
2922 * @hide
2923 */
2924 public @NonNull HistoricalOps spliceFromEnd(double fractionToRemove) {
2925 return splice(fractionToRemove, false);
2926 }
2927
2928 /**
2929 * Splice a piece from the beginning or end of these ops.
2930 *
2931 * @param fractionToRemove The fraction of the data to be spliced off.
2932 * @param beginning Whether to splice off the beginning or the end.
2933 *
2934 * @return The spliced off part.
2935 *
2936 * @hide
2937 */
2938 private @Nullable HistoricalOps splice(double fractionToRemove, boolean beginning) {
2939 final long spliceBeginTimeMills;
2940 final long spliceEndTimeMills;
2941 if (beginning) {
2942 spliceBeginTimeMills = mBeginTimeMillis;
2943 spliceEndTimeMills = (long) (mBeginTimeMillis
2944 + getDurationMillis() * fractionToRemove);
2945 mBeginTimeMillis = spliceEndTimeMills;
2946 } else {
2947 spliceBeginTimeMills = (long) (mEndTimeMillis
2948 - getDurationMillis() * fractionToRemove);
2949 spliceEndTimeMills = mEndTimeMillis;
2950 mEndTimeMillis = spliceBeginTimeMills;
2951 }
2952
2953 HistoricalOps splice = null;
2954 final int uidCount = getUidCount();
2955 for (int i = 0; i < uidCount; i++) {
2956 final HistoricalUidOps origOps = getUidOpsAt(i);
2957 final HistoricalUidOps spliceOps = origOps.splice(fractionToRemove);
2958 if (spliceOps != null) {
2959 if (splice == null) {
2960 splice = new HistoricalOps(spliceBeginTimeMills, spliceEndTimeMills);
2961 }
2962 if (splice.mHistoricalUidOps == null) {
2963 splice.mHistoricalUidOps = new SparseArray<>();
2964 }
2965 splice.mHistoricalUidOps.put(spliceOps.getUid(), spliceOps);
2966 }
2967 }
2968 return splice;
2969 }
2970
2971 /**
2972 * Merge the passed ops into the current ones. The time interval is a
2973 * union of the current and passed in one and the passed in data is
2974 * folded into the data of this instance.
2975 *
2976 * @hide
2977 */
2978 public void merge(@NonNull HistoricalOps other) {
2979 mBeginTimeMillis = Math.min(mBeginTimeMillis, other.mBeginTimeMillis);
2980 mEndTimeMillis = Math.max(mEndTimeMillis, other.mEndTimeMillis);
2981 final int uidCount = other.getUidCount();
2982 for (int i = 0; i < uidCount; i++) {
2983 final HistoricalUidOps otherUidOps = other.getUidOpsAt(i);
2984 final HistoricalUidOps thisUidOps = getUidOps(otherUidOps.getUid());
2985 if (thisUidOps != null) {
2986 thisUidOps.merge(otherUidOps);
2987 } else {
2988 if (mHistoricalUidOps == null) {
2989 mHistoricalUidOps = new SparseArray<>();
2990 }
2991 mHistoricalUidOps.put(otherUidOps.getUid(), otherUidOps);
2992 }
2993 }
2994 }
2995
2996 /**
2997 * AppPermissionUsage the ops to leave only the data we filter for.
2998 *
2999 * @param uid Uid to filter for or {@link android.os.Process#INCIDENTD_UID} for all.
3000 * @param packageName Package to filter for or null for all.
3001 * @param opNames Ops to filter for or null for all.
3002 * @param beginTimeMillis The begin time to filter for or {@link Long#MIN_VALUE} for all.
3003 * @param endTimeMillis The end time to filter for or {@link Long#MAX_VALUE} for all.
3004 *
3005 * @hide
3006 */
3007 public void filter(int uid, @Nullable String packageName, @Nullable String[] opNames,
3008 long beginTimeMillis, long endTimeMillis) {
3009 final long durationMillis = getDurationMillis();
3010 mBeginTimeMillis = Math.max(mBeginTimeMillis, beginTimeMillis);
3011 mEndTimeMillis = Math.min(mEndTimeMillis, endTimeMillis);
3012 final double scaleFactor = Math.min((double) (endTimeMillis - beginTimeMillis)
3013 / (double) durationMillis, 1);
3014 final int uidCount = getUidCount();
3015 for (int i = uidCount - 1; i >= 0; i--) {
3016 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
3017 if (uid != Process.INVALID_UID && uid != uidOp.getUid()) {
3018 mHistoricalUidOps.removeAt(i);
3019 } else {
3020 uidOp.filter(packageName, opNames, scaleFactor);
3021 }
3022 }
3023 }
3024
3025 /** @hide */
3026 public boolean isEmpty() {
3027 if (getBeginTimeMillis() >= getEndTimeMillis()) {
3028 return true;
3029 }
3030 final int uidCount = getUidCount();
3031 for (int i = uidCount - 1; i >= 0; i--) {
3032 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
3033 if (!uidOp.isEmpty()) {
3034 return false;
3035 }
3036 }
3037 return true;
3038 }
3039
3040 /** @hide */
3041 public long getDurationMillis() {
3042 return mEndTimeMillis - mBeginTimeMillis;
3043 }
3044
3045 /** @hide */
3046 @TestApi
3047 public void increaseAccessCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003048 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003049 getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003050 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003051 }
3052
3053 /** @hide */
3054 @TestApi
3055 public void increaseRejectCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003056 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003057 getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003058 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003059 }
3060
3061 /** @hide */
3062 @TestApi
3063 public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003064 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003065 getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003066 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003067 }
3068
3069 /** @hide */
3070 @TestApi
3071 public void offsetBeginAndEndTime(long offsetMillis) {
3072 mBeginTimeMillis += offsetMillis;
3073 mEndTimeMillis += offsetMillis;
3074 }
3075
3076 /** @hide */
3077 public void setBeginAndEndTime(long beginTimeMillis, long endTimeMillis) {
3078 mBeginTimeMillis = beginTimeMillis;
3079 mEndTimeMillis = endTimeMillis;
3080 }
3081
3082 /** @hide */
3083 public void setBeginTime(long beginTimeMillis) {
3084 mBeginTimeMillis = beginTimeMillis;
3085 }
3086
3087 /** @hide */
3088 public void setEndTime(long endTimeMillis) {
3089 mEndTimeMillis = endTimeMillis;
3090 }
3091
3092 /**
3093 * @return The beginning of the interval in milliseconds since
3094 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3095 */
3096 public long getBeginTimeMillis() {
3097 return mBeginTimeMillis;
3098 }
3099
3100 /**
3101 * @return The end of the interval in milliseconds since
3102 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3103 */
3104 public long getEndTimeMillis() {
3105 return mEndTimeMillis;
3106 }
3107
3108 /**
3109 * Gets number of UIDs with historical ops.
3110 *
3111 * @return The number of UIDs with historical ops.
3112 *
3113 * @see #getUidOpsAt(int)
3114 */
3115 public int getUidCount() {
3116 if (mHistoricalUidOps == null) {
3117 return 0;
3118 }
3119 return mHistoricalUidOps.size();
3120 }
3121
3122 /**
3123 * Gets the historical UID ops at a given index.
3124 *
3125 * @param index The index.
3126 *
3127 * @return The historical UID ops at the given index.
3128 *
3129 * @see #getUidCount()
3130 */
3131 public @NonNull HistoricalUidOps getUidOpsAt(int index) {
3132 if (mHistoricalUidOps == null) {
3133 throw new IndexOutOfBoundsException();
3134 }
3135 return mHistoricalUidOps.valueAt(index);
3136 }
3137
3138 /**
3139 * Gets the historical UID ops for a given UID.
3140 *
3141 * @param uid The UID.
3142 *
3143 * @return The historical ops for the UID.
3144 */
3145 public @Nullable HistoricalUidOps getUidOps(int uid) {
3146 if (mHistoricalUidOps == null) {
3147 return null;
3148 }
3149 return mHistoricalUidOps.get(uid);
3150 }
3151
3152 @Override
3153 public int describeContents() {
3154 return 0;
3155 }
3156
3157 @Override
3158 public void writeToParcel(Parcel parcel, int flags) {
3159 parcel.writeLong(mBeginTimeMillis);
3160 parcel.writeLong(mEndTimeMillis);
3161 if (mHistoricalUidOps != null) {
3162 final int uidCount = mHistoricalUidOps.size();
3163 parcel.writeInt(uidCount);
3164 for (int i = 0; i < uidCount; i++) {
3165 parcel.writeInt(mHistoricalUidOps.keyAt(i));
3166 }
3167 final List<HistoricalUidOps> opsList = new ArrayList<>(uidCount);
3168 for (int i = 0; i < uidCount; i++) {
3169 opsList.add(mHistoricalUidOps.valueAt(i));
3170 }
3171 parcel.writeParcelable(new ParceledListSlice<>(opsList), flags);
3172 } else {
3173 parcel.writeInt(-1);
3174 }
3175 }
3176
3177 /**
3178 * Accepts a visitor to traverse the ops tree.
3179 *
3180 * @param visitor The visitor.
3181 *
3182 * @hide
3183 */
3184 public void accept(@NonNull HistoricalOpsVisitor visitor) {
3185 visitor.visitHistoricalOps(this);
3186 final int uidCount = getUidCount();
3187 for (int i = 0; i < uidCount; i++) {
3188 getUidOpsAt(i).accept(visitor);
3189 }
3190 }
3191
3192 private @NonNull HistoricalUidOps getOrCreateHistoricalUidOps(int uid) {
3193 if (mHistoricalUidOps == null) {
3194 mHistoricalUidOps = new SparseArray<>();
3195 }
3196 HistoricalUidOps historicalUidOp = mHistoricalUidOps.get(uid);
3197 if (historicalUidOp == null) {
3198 historicalUidOp = new HistoricalUidOps(uid);
3199 mHistoricalUidOps.put(uid, historicalUidOp);
3200 }
3201 return historicalUidOp;
3202 }
3203
3204 /**
3205 * @return Rounded value up at the 0.5 boundary.
3206 *
3207 * @hide
3208 */
3209 public static double round(double value) {
3210 final BigDecimal decimalScale = new BigDecimal(value);
3211 return decimalScale.setScale(0, RoundingMode.HALF_UP).doubleValue();
3212 }
3213
3214 @Override
3215 public boolean equals(Object obj) {
3216 if (this == obj) {
3217 return true;
3218 }
3219 if (obj == null || getClass() != obj.getClass()) {
3220 return false;
3221 }
3222 final HistoricalOps other = (HistoricalOps) obj;
3223 if (mBeginTimeMillis != other.mBeginTimeMillis) {
3224 return false;
3225 }
3226 if (mEndTimeMillis != other.mEndTimeMillis) {
3227 return false;
3228 }
3229 if (mHistoricalUidOps == null) {
3230 if (other.mHistoricalUidOps != null) {
3231 return false;
3232 }
3233 } else if (!mHistoricalUidOps.equals(other.mHistoricalUidOps)) {
3234 return false;
3235 }
3236 return true;
3237 }
3238
3239 @Override
3240 public int hashCode() {
3241 int result = (int) (mBeginTimeMillis ^ (mBeginTimeMillis >>> 32));
3242 result = 31 * result + mHistoricalUidOps.hashCode();
3243 return result;
3244 }
3245
3246 @Override
3247 public String toString() {
3248 return getClass().getSimpleName() + "[from:"
3249 + mBeginTimeMillis + " to:" + mEndTimeMillis + "]";
3250 }
3251
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07003252 public static final @android.annotation.NonNull Creator<HistoricalOps> CREATOR = new Creator<HistoricalOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003253 @Override
3254 public @NonNull HistoricalOps createFromParcel(@NonNull Parcel parcel) {
3255 return new HistoricalOps(parcel);
3256 }
3257
3258 @Override
3259 public @NonNull HistoricalOps[] newArray(int size) {
3260 return new HistoricalOps[size];
3261 }
3262 };
3263 }
3264
3265 /**
3266 * This class represents historical app op state for a UID.
3267 *
3268 * @hide
3269 */
3270 @TestApi
3271 @SystemApi
3272 public static final class HistoricalUidOps implements Parcelable {
3273 private final int mUid;
3274 private @Nullable ArrayMap<String, HistoricalPackageOps> mHistoricalPackageOps;
3275
3276 /** @hide */
3277 public HistoricalUidOps(int uid) {
3278 mUid = uid;
3279 }
3280
3281 private HistoricalUidOps(@NonNull HistoricalUidOps other) {
3282 mUid = other.mUid;
3283 final int opCount = other.getPackageCount();
3284 for (int i = 0; i < opCount; i++) {
3285 final HistoricalPackageOps origOps = other.getPackageOpsAt(i);
3286 final HistoricalPackageOps cloneOps = new HistoricalPackageOps(origOps);
3287 if (mHistoricalPackageOps == null) {
3288 mHistoricalPackageOps = new ArrayMap<>(opCount);
3289 }
3290 mHistoricalPackageOps.put(cloneOps.getPackageName(), cloneOps);
3291 }
3292 }
3293
3294 private HistoricalUidOps(@NonNull Parcel parcel) {
3295 // No arg check since we always read from a trusted source.
3296 mUid = parcel.readInt();
3297 mHistoricalPackageOps = parcel.createTypedArrayMap(HistoricalPackageOps.CREATOR);
3298 }
3299
3300 private @Nullable HistoricalUidOps splice(double fractionToRemove) {
3301 HistoricalUidOps splice = null;
3302 final int packageCount = getPackageCount();
3303 for (int i = 0; i < packageCount; i++) {
3304 final HistoricalPackageOps origOps = getPackageOpsAt(i);
3305 final HistoricalPackageOps spliceOps = origOps.splice(fractionToRemove);
3306 if (spliceOps != null) {
3307 if (splice == null) {
3308 splice = new HistoricalUidOps(mUid);
3309 }
3310 if (splice.mHistoricalPackageOps == null) {
3311 splice.mHistoricalPackageOps = new ArrayMap<>();
3312 }
3313 splice.mHistoricalPackageOps.put(spliceOps.getPackageName(), spliceOps);
3314 }
3315 }
3316 return splice;
3317 }
3318
3319 private void merge(@NonNull HistoricalUidOps other) {
3320 final int packageCount = other.getPackageCount();
3321 for (int i = 0; i < packageCount; i++) {
3322 final HistoricalPackageOps otherPackageOps = other.getPackageOpsAt(i);
3323 final HistoricalPackageOps thisPackageOps = getPackageOps(
3324 otherPackageOps.getPackageName());
3325 if (thisPackageOps != null) {
3326 thisPackageOps.merge(otherPackageOps);
3327 } else {
3328 if (mHistoricalPackageOps == null) {
3329 mHistoricalPackageOps = new ArrayMap<>();
3330 }
3331 mHistoricalPackageOps.put(otherPackageOps.getPackageName(), otherPackageOps);
3332 }
3333 }
3334 }
3335
3336 private void filter(@Nullable String packageName, @Nullable String[] opNames,
3337 double fractionToRemove) {
3338 final int packageCount = getPackageCount();
3339 for (int i = packageCount - 1; i >= 0; i--) {
3340 final HistoricalPackageOps packageOps = getPackageOpsAt(i);
3341 if (packageName != null && !packageName.equals(packageOps.getPackageName())) {
3342 mHistoricalPackageOps.removeAt(i);
3343 } else {
3344 packageOps.filter(opNames, fractionToRemove);
3345 }
3346 }
3347 }
3348
3349 private boolean isEmpty() {
3350 final int packageCount = getPackageCount();
3351 for (int i = packageCount - 1; i >= 0; i--) {
3352 final HistoricalPackageOps packageOps = mHistoricalPackageOps.valueAt(i);
3353 if (!packageOps.isEmpty()) {
3354 return false;
3355 }
3356 }
3357 return true;
3358 }
3359
3360 private void increaseAccessCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003361 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003362 getOrCreateHistoricalPackageOps(packageName).increaseAccessCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08003363 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003364 }
3365
3366 private void increaseRejectCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003367 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003368 getOrCreateHistoricalPackageOps(packageName).increaseRejectCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08003369 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003370 }
3371
3372 private void increaseAccessDuration(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003373 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003374 getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration(
Svet Ganovaf189e32019-02-15 18:45:29 -08003375 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003376 }
3377
3378 /**
3379 * @return The UID for which the data is related.
3380 */
3381 public int getUid() {
3382 return mUid;
3383 }
3384
3385 /**
3386 * Gets number of packages with historical ops.
3387 *
3388 * @return The number of packages with historical ops.
3389 *
3390 * @see #getPackageOpsAt(int)
3391 */
3392 public int getPackageCount() {
3393 if (mHistoricalPackageOps == null) {
3394 return 0;
3395 }
3396 return mHistoricalPackageOps.size();
3397 }
3398
3399 /**
3400 * Gets the historical package ops at a given index.
3401 *
3402 * @param index The index.
3403 *
3404 * @return The historical package ops at the given index.
3405 *
3406 * @see #getPackageCount()
3407 */
3408 public @NonNull HistoricalPackageOps getPackageOpsAt(int index) {
3409 if (mHistoricalPackageOps == null) {
3410 throw new IndexOutOfBoundsException();
3411 }
3412 return mHistoricalPackageOps.valueAt(index);
3413 }
3414
3415 /**
3416 * Gets the historical package ops for a given package.
3417 *
3418 * @param packageName The package.
3419 *
3420 * @return The historical ops for the package.
3421 */
3422 public @Nullable HistoricalPackageOps getPackageOps(@NonNull String packageName) {
3423 if (mHistoricalPackageOps == null) {
3424 return null;
3425 }
3426 return mHistoricalPackageOps.get(packageName);
3427 }
3428
3429 @Override
3430 public int describeContents() {
3431 return 0;
3432 }
3433
3434 @Override
3435 public void writeToParcel(Parcel parcel, int flags) {
3436 parcel.writeInt(mUid);
3437 parcel.writeTypedArrayMap(mHistoricalPackageOps, flags);
3438 }
3439
3440 private void accept(@NonNull HistoricalOpsVisitor visitor) {
3441 visitor.visitHistoricalUidOps(this);
3442 final int packageCount = getPackageCount();
3443 for (int i = 0; i < packageCount; i++) {
3444 getPackageOpsAt(i).accept(visitor);
3445 }
3446 }
3447
3448 private @NonNull HistoricalPackageOps getOrCreateHistoricalPackageOps(
3449 @NonNull String packageName) {
3450 if (mHistoricalPackageOps == null) {
3451 mHistoricalPackageOps = new ArrayMap<>();
3452 }
3453 HistoricalPackageOps historicalPackageOp = mHistoricalPackageOps.get(packageName);
3454 if (historicalPackageOp == null) {
3455 historicalPackageOp = new HistoricalPackageOps(packageName);
3456 mHistoricalPackageOps.put(packageName, historicalPackageOp);
3457 }
3458 return historicalPackageOp;
3459 }
3460
3461
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07003462 public static final @android.annotation.NonNull Creator<HistoricalUidOps> CREATOR = new Creator<HistoricalUidOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003463 @Override
3464 public @NonNull HistoricalUidOps createFromParcel(@NonNull Parcel parcel) {
3465 return new HistoricalUidOps(parcel);
3466 }
3467
3468 @Override
3469 public @NonNull HistoricalUidOps[] newArray(int size) {
3470 return new HistoricalUidOps[size];
3471 }
3472 };
3473
3474 @Override
3475 public boolean equals(Object obj) {
3476 if (this == obj) {
3477 return true;
3478 }
3479 if (obj == null || getClass() != obj.getClass()) {
3480 return false;
3481 }
3482 final HistoricalUidOps other = (HistoricalUidOps) obj;
3483 if (mUid != other.mUid) {
3484 return false;
3485 }
3486 if (mHistoricalPackageOps == null) {
3487 if (other.mHistoricalPackageOps != null) {
3488 return false;
3489 }
3490 } else if (!mHistoricalPackageOps.equals(other.mHistoricalPackageOps)) {
3491 return false;
3492 }
3493 return true;
3494 }
3495
3496 @Override
3497 public int hashCode() {
3498 int result = mUid;
3499 result = 31 * result + (mHistoricalPackageOps != null
3500 ? mHistoricalPackageOps.hashCode() : 0);
3501 return result;
3502 }
3503 }
3504
3505 /**
3506 * This class represents historical app op information about a package.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003507 *
3508 * @hide
3509 */
3510 @TestApi
3511 @SystemApi
3512 public static final class HistoricalPackageOps implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003513 private final @NonNull String mPackageName;
Svet Ganov8455ba22019-01-02 13:05:56 -08003514 private @Nullable ArrayMap<String, HistoricalOp> mHistoricalOps;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003515
Svet Ganov8455ba22019-01-02 13:05:56 -08003516 /** @hide */
3517 public HistoricalPackageOps(@NonNull String packageName) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003518 mPackageName = packageName;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003519 }
3520
Svet Ganov8455ba22019-01-02 13:05:56 -08003521 private HistoricalPackageOps(@NonNull HistoricalPackageOps other) {
3522 mPackageName = other.mPackageName;
3523 final int opCount = other.getOpCount();
3524 for (int i = 0; i < opCount; i++) {
3525 final HistoricalOp origOp = other.getOpAt(i);
3526 final HistoricalOp cloneOp = new HistoricalOp(origOp);
3527 if (mHistoricalOps == null) {
3528 mHistoricalOps = new ArrayMap<>(opCount);
3529 }
3530 mHistoricalOps.put(cloneOp.getOpName(), cloneOp);
3531 }
3532 }
3533
3534 private HistoricalPackageOps(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003535 mPackageName = parcel.readString();
Svet Ganov8455ba22019-01-02 13:05:56 -08003536 mHistoricalOps = parcel.createTypedArrayMap(HistoricalOp.CREATOR);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003537 }
3538
Svet Ganov8455ba22019-01-02 13:05:56 -08003539 private @Nullable HistoricalPackageOps splice(double fractionToRemove) {
3540 HistoricalPackageOps splice = null;
3541 final int opCount = getOpCount();
3542 for (int i = 0; i < opCount; i++) {
3543 final HistoricalOp origOps = getOpAt(i);
3544 final HistoricalOp spliceOps = origOps.splice(fractionToRemove);
3545 if (spliceOps != null) {
3546 if (splice == null) {
3547 splice = new HistoricalPackageOps(mPackageName);
3548 }
3549 if (splice.mHistoricalOps == null) {
3550 splice.mHistoricalOps = new ArrayMap<>();
3551 }
3552 splice.mHistoricalOps.put(spliceOps.getOpName(), spliceOps);
3553 }
3554 }
3555 return splice;
3556 }
3557
3558 private void merge(@NonNull HistoricalPackageOps other) {
3559 final int opCount = other.getOpCount();
3560 for (int i = 0; i < opCount; i++) {
3561 final HistoricalOp otherOp = other.getOpAt(i);
3562 final HistoricalOp thisOp = getOp(otherOp.getOpName());
3563 if (thisOp != null) {
3564 thisOp.merge(otherOp);
3565 } else {
3566 if (mHistoricalOps == null) {
3567 mHistoricalOps = new ArrayMap<>();
3568 }
3569 mHistoricalOps.put(otherOp.getOpName(), otherOp);
3570 }
3571 }
3572 }
3573
3574 private void filter(@Nullable String[] opNames, double scaleFactor) {
3575 final int opCount = getOpCount();
3576 for (int i = opCount - 1; i >= 0; i--) {
3577 final HistoricalOp op = mHistoricalOps.valueAt(i);
3578 if (opNames != null && !ArrayUtils.contains(opNames, op.getOpName())) {
3579 mHistoricalOps.removeAt(i);
3580 } else {
3581 op.filter(scaleFactor);
3582 }
3583 }
3584 }
3585
3586 private boolean isEmpty() {
3587 final int opCount = getOpCount();
3588 for (int i = opCount - 1; i >= 0; i--) {
3589 final HistoricalOp op = mHistoricalOps.valueAt(i);
3590 if (!op.isEmpty()) {
3591 return false;
3592 }
3593 }
3594 return true;
3595 }
3596
Svet Ganovaf189e32019-02-15 18:45:29 -08003597 private void increaseAccessCount(int opCode, @UidState int uidState,
3598 @OpFlags int flags, long increment) {
3599 getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003600 }
3601
Svet Ganovaf189e32019-02-15 18:45:29 -08003602 private void increaseRejectCount(int opCode, @UidState int uidState,
3603 @OpFlags int flags, long increment) {
3604 getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003605 }
3606
Svet Ganovaf189e32019-02-15 18:45:29 -08003607 private void increaseAccessDuration(int opCode, @UidState int uidState,
3608 @OpFlags int flags, long increment) {
3609 getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, flags, increment);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003610 }
3611
3612 /**
3613 * Gets the package name which the data represents.
3614 *
3615 * @return The package name which the data represents.
3616 */
3617 public @NonNull String getPackageName() {
3618 return mPackageName;
3619 }
3620
3621 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003622 * Gets number historical app ops.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003623 *
Svet Ganov8455ba22019-01-02 13:05:56 -08003624 * @return The number historical app ops.
Svet Ganov8455ba22019-01-02 13:05:56 -08003625 * @see #getOpAt(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003626 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003627 public int getOpCount() {
3628 if (mHistoricalOps == null) {
3629 return 0;
3630 }
3631 return mHistoricalOps.size();
Svet Ganovad0a49b2018-10-29 10:07:08 -07003632 }
3633
3634 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003635 * Gets the historical op at a given index.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003636 *
3637 * @param index The index to lookup.
Svet Ganov8455ba22019-01-02 13:05:56 -08003638 * @return The op at the given index.
Svet Ganov8455ba22019-01-02 13:05:56 -08003639 * @see #getOpCount()
Svet Ganovad0a49b2018-10-29 10:07:08 -07003640 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003641 public @NonNull HistoricalOp getOpAt(int index) {
3642 if (mHistoricalOps == null) {
3643 throw new IndexOutOfBoundsException();
3644 }
3645 return mHistoricalOps.valueAt(index);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003646 }
3647
3648 /**
3649 * Gets the historical entry for a given op name.
3650 *
3651 * @param opName The op name.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003652 * @return The historical entry for that op name.
3653 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003654 public @Nullable HistoricalOp getOp(@NonNull String opName) {
3655 if (mHistoricalOps == null) {
3656 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003657 }
Svet Ganov8455ba22019-01-02 13:05:56 -08003658 return mHistoricalOps.get(opName);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003659 }
3660
3661 @Override
3662 public int describeContents() {
3663 return 0;
3664 }
3665
3666 @Override
3667 public void writeToParcel(@NonNull Parcel parcel, int flags) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003668 parcel.writeString(mPackageName);
Svet Ganov8455ba22019-01-02 13:05:56 -08003669 parcel.writeTypedArrayMap(mHistoricalOps, flags);
3670 }
3671
3672 private void accept(@NonNull HistoricalOpsVisitor visitor) {
3673 visitor.visitHistoricalPackageOps(this);
3674 final int opCount = getOpCount();
3675 for (int i = 0; i < opCount; i++) {
3676 getOpAt(i).accept(visitor);
3677 }
3678 }
3679
3680 private @NonNull HistoricalOp getOrCreateHistoricalOp(int opCode) {
3681 if (mHistoricalOps == null) {
3682 mHistoricalOps = new ArrayMap<>();
3683 }
3684 final String opStr = sOpToString[opCode];
3685 HistoricalOp op = mHistoricalOps.get(opStr);
3686 if (op == null) {
3687 op = new HistoricalOp(opCode);
3688 mHistoricalOps.put(opStr, op);
3689 }
3690 return op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003691 }
3692
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07003693 public static final @android.annotation.NonNull Creator<HistoricalPackageOps> CREATOR =
Svet Ganovad0a49b2018-10-29 10:07:08 -07003694 new Creator<HistoricalPackageOps>() {
3695 @Override
3696 public @NonNull HistoricalPackageOps createFromParcel(@NonNull Parcel parcel) {
3697 return new HistoricalPackageOps(parcel);
3698 }
3699
3700 @Override
3701 public @NonNull HistoricalPackageOps[] newArray(int size) {
3702 return new HistoricalPackageOps[size];
3703 }
3704 };
Svet Ganov8455ba22019-01-02 13:05:56 -08003705
3706 @Override
3707 public boolean equals(Object obj) {
3708 if (this == obj) {
3709 return true;
3710 }
3711 if (obj == null || getClass() != obj.getClass()) {
3712 return false;
3713 }
3714 final HistoricalPackageOps other = (HistoricalPackageOps) obj;
3715 if (!mPackageName.equals(other.mPackageName)) {
3716 return false;
3717 }
3718 if (mHistoricalOps == null) {
3719 if (other.mHistoricalOps != null) {
3720 return false;
3721 }
3722 } else if (!mHistoricalOps.equals(other.mHistoricalOps)) {
3723 return false;
3724 }
3725 return true;
3726 }
3727
3728 @Override
3729 public int hashCode() {
3730 int result = mPackageName != null ? mPackageName.hashCode() : 0;
3731 result = 31 * result + (mHistoricalOps != null ? mHistoricalOps.hashCode() : 0);
3732 return result;
3733 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003734 }
3735
3736 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003737 * This class represents historical information about an app op.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003738 *
3739 * @hide
3740 */
3741 @TestApi
3742 @SystemApi
Svet Ganov8455ba22019-01-02 13:05:56 -08003743 public static final class HistoricalOp implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003744 private final int mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08003745 private @Nullable LongSparseLongArray mAccessCount;
3746 private @Nullable LongSparseLongArray mRejectCount;
3747 private @Nullable LongSparseLongArray mAccessDuration;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003748
Svet Ganov8455ba22019-01-02 13:05:56 -08003749 /** @hide */
3750 public HistoricalOp(int op) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003751 mOp = op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003752 }
3753
Svet Ganov8455ba22019-01-02 13:05:56 -08003754 private HistoricalOp(@NonNull HistoricalOp other) {
3755 mOp = other.mOp;
3756 if (other.mAccessCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003757 mAccessCount = other.mAccessCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08003758 }
3759 if (other.mRejectCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003760 mRejectCount = other.mRejectCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08003761 }
3762 if (other.mAccessDuration != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003763 mAccessDuration = other.mAccessDuration.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08003764 }
3765 }
3766
3767 private HistoricalOp(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003768 mOp = parcel.readInt();
Svet Ganovaf189e32019-02-15 18:45:29 -08003769 mAccessCount = readLongSparseLongArrayFromParcel(parcel);
3770 mRejectCount = readLongSparseLongArrayFromParcel(parcel);
3771 mAccessDuration = readLongSparseLongArrayFromParcel(parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003772 }
3773
Svet Ganov8455ba22019-01-02 13:05:56 -08003774 private void filter(double scaleFactor) {
3775 scale(mAccessCount, scaleFactor);
3776 scale(mRejectCount, scaleFactor);
3777 scale(mAccessDuration, scaleFactor);
3778 }
3779
3780 private boolean isEmpty() {
3781 return !hasData(mAccessCount)
3782 && !hasData(mRejectCount)
3783 && !hasData(mAccessDuration);
3784 }
3785
Svet Ganovaf189e32019-02-15 18:45:29 -08003786 private boolean hasData(@NonNull LongSparseLongArray array) {
3787 return (array != null && array.size() > 0);
Svet Ganov8455ba22019-01-02 13:05:56 -08003788 }
3789
3790 private @Nullable HistoricalOp splice(double fractionToRemove) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003791 final HistoricalOp splice = new HistoricalOp(mOp);
3792 splice(mAccessCount, splice::getOrCreateAccessCount, fractionToRemove);
3793 splice(mRejectCount, splice::getOrCreateRejectCount, fractionToRemove);
3794 splice(mAccessDuration, splice::getOrCreateAccessDuration, fractionToRemove);
Svet Ganov8455ba22019-01-02 13:05:56 -08003795 return splice;
3796 }
3797
Svet Ganovaf189e32019-02-15 18:45:29 -08003798 private static void splice(@Nullable LongSparseLongArray sourceContainer,
3799 @NonNull Supplier<LongSparseLongArray> destContainerProvider,
3800 double fractionToRemove) {
3801 if (sourceContainer != null) {
3802 final int size = sourceContainer.size();
3803 for (int i = 0; i < size; i++) {
3804 final long key = sourceContainer.keyAt(i);
3805 final long value = sourceContainer.valueAt(i);
3806 final long removedFraction = Math.round(value * fractionToRemove);
3807 if (removedFraction > 0) {
3808 destContainerProvider.get().put(key, removedFraction);
3809 sourceContainer.put(key, value - removedFraction);
3810 }
3811 }
3812 }
3813 }
3814
Svet Ganov8455ba22019-01-02 13:05:56 -08003815 private void merge(@NonNull HistoricalOp other) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003816 merge(this::getOrCreateAccessCount, other.mAccessCount);
3817 merge(this::getOrCreateRejectCount, other.mRejectCount);
3818 merge(this::getOrCreateAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08003819 }
3820
Svet Ganovaf189e32019-02-15 18:45:29 -08003821 private void increaseAccessCount(@UidState int uidState, @OpFlags int flags,
3822 long increment) {
3823 increaseCount(getOrCreateAccessCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003824 }
3825
Svet Ganovaf189e32019-02-15 18:45:29 -08003826 private void increaseRejectCount(@UidState int uidState, @OpFlags int flags,
3827 long increment) {
3828 increaseCount(getOrCreateRejectCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003829 }
3830
Svet Ganovaf189e32019-02-15 18:45:29 -08003831 private void increaseAccessDuration(@UidState int uidState, @OpFlags int flags,
3832 long increment) {
3833 increaseCount(getOrCreateAccessDuration(), uidState, flags, increment);
3834 }
3835
3836 private void increaseCount(@NonNull LongSparseLongArray counts,
3837 @UidState int uidState, @OpFlags int flags, long increment) {
3838 while (flags != 0) {
3839 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
3840 flags &= ~flag;
3841 final long key = makeKey(uidState, flag);
3842 counts.put(key, counts.get(key) + increment);
3843 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003844 }
3845
3846 /**
3847 * Gets the op name.
3848 *
3849 * @return The op name.
3850 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003851 public @NonNull String getOpName() {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003852 return sOpToString[mOp];
3853 }
3854
Svet Ganov8455ba22019-01-02 13:05:56 -08003855 /** @hide */
3856 public int getOpCode() {
3857 return mOp;
3858 }
3859
Svet Ganovad0a49b2018-10-29 10:07:08 -07003860 /**
3861 * Gets the number times the op was accessed (performed) in the foreground.
3862 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003863 * @param flags The flags which are any combination of
3864 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3865 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3866 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3867 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003868 * @return The times the op was accessed in the foreground.
3869 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003870 * @see #getBackgroundAccessCount(int)
3871 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003872 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003873 public long getForegroundAccessCount(@OpFlags int flags) {
3874 return sumForFlagsInStates(mAccessCount, MAX_PRIORITY_UID_STATE,
3875 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003876 }
3877
3878 /**
3879 * Gets the number times the op was accessed (performed) in the background.
3880 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003881 * @param flags The flags which are any combination of
3882 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3883 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3884 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3885 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003886 * @return The times the op was accessed in the background.
3887 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003888 * @see #getForegroundAccessCount(int)
3889 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003890 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003891 public long getBackgroundAccessCount(@OpFlags int flags) {
3892 return sumForFlagsInStates(mAccessCount, resolveLastRestrictedUidState(mOp),
3893 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003894 }
3895
3896 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08003897 * Gets the number times the op was accessed (performed) for a
3898 * range of uid states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003899 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003900 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07003901 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08003902 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07003903 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3904 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08003905 * @param toUidState The UID state to which to query.
3906 * @param flags The flags which are any combination of
3907 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3908 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3909 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3910 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003911 *
3912 * @return The times the op was accessed for the given UID state.
3913 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003914 * @see #getForegroundAccessCount(int)
3915 * @see #getBackgroundAccessCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003916 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003917 public long getAccessCount(@UidState int fromUidState, @UidState int toUidState,
3918 @OpFlags int flags) {
3919 return sumForFlagsInStates(mAccessCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003920 }
3921
3922 /**
3923 * Gets the number times the op was rejected in the foreground.
3924 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003925 * @param flags The flags which are any combination of
3926 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3927 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3928 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3929 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003930 * @return The times the op was rejected in the foreground.
3931 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003932 * @see #getBackgroundRejectCount(int)
3933 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003934 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003935 public long getForegroundRejectCount(@OpFlags int flags) {
3936 return sumForFlagsInStates(mRejectCount, MAX_PRIORITY_UID_STATE,
3937 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003938 }
3939
3940 /**
3941 * Gets the number times the op was rejected in the background.
3942 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003943 * @param flags The flags which are any combination of
3944 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3945 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3946 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3947 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003948 * @return The times the op was rejected in the background.
3949 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003950 * @see #getForegroundRejectCount(int)
3951 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003952 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003953 public long getBackgroundRejectCount(@OpFlags int flags) {
3954 return sumForFlagsInStates(mRejectCount, resolveLastRestrictedUidState(mOp),
3955 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003956 }
3957
3958 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08003959 * Gets the number times the op was rejected for a given range of UID states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003960 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003961 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07003962 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08003963 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07003964 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3965 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08003966 * @param toUidState The UID state to which to query.
3967 * @param flags The flags which are any combination of
3968 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3969 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3970 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3971 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003972 *
3973 * @return The times the op was rejected for the given UID state.
3974 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003975 * @see #getForegroundRejectCount(int)
3976 * @see #getBackgroundRejectCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003977 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003978 public long getRejectCount(@UidState int fromUidState, @UidState int toUidState,
3979 @OpFlags int flags) {
3980 return sumForFlagsInStates(mRejectCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003981 }
3982
3983 /**
3984 * Gets the total duration the app op was accessed (performed) in the foreground.
3985 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003986 * @param flags The flags which are any combination of
3987 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3988 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3989 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3990 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003991 * @return The total duration the app op was accessed in the foreground.
3992 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003993 * @see #getBackgroundAccessDuration(int)
3994 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003995 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003996 public long getForegroundAccessDuration(@OpFlags int flags) {
3997 return sumForFlagsInStates(mAccessDuration, MAX_PRIORITY_UID_STATE,
3998 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003999 }
4000
4001 /**
4002 * Gets the total duration the app op was accessed (performed) in the background.
4003 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004004 * @param flags The flags which are any combination of
4005 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4006 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4007 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4008 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004009 * @return The total duration the app op was accessed in the background.
4010 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004011 * @see #getForegroundAccessDuration(int)
4012 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004013 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004014 public long getBackgroundAccessDuration(@OpFlags int flags) {
4015 return sumForFlagsInStates(mAccessDuration, resolveLastRestrictedUidState(mOp),
4016 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004017 }
4018
4019 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08004020 * Gets the total duration the app op was accessed (performed) for a given
4021 * range of UID states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004022 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004023 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07004024 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08004025 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07004026 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
4027 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08004028 * @param toUidState The UID state from which to query.
4029 * @param flags The flags which are any combination of
4030 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4031 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4032 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4033 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004034 *
4035 * @return The total duration the app op was accessed for the given UID state.
4036 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004037 * @see #getForegroundAccessDuration(int)
4038 * @see #getBackgroundAccessDuration(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004039 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004040 public long getAccessDuration(@UidState int fromUidState, @UidState int toUidState,
4041 @OpFlags int flags) {
4042 return sumForFlagsInStates(mAccessDuration, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004043 }
4044
4045 @Override
4046 public int describeContents() {
4047 return 0;
4048 }
4049
4050 @Override
4051 public void writeToParcel(Parcel parcel, int flags) {
4052 parcel.writeInt(mOp);
Svet Ganovaf189e32019-02-15 18:45:29 -08004053 writeLongSparseLongArrayToParcel(mAccessCount, parcel);
4054 writeLongSparseLongArrayToParcel(mRejectCount, parcel);
4055 writeLongSparseLongArrayToParcel(mAccessDuration, parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004056 }
4057
Svet Ganov8455ba22019-01-02 13:05:56 -08004058 @Override
4059 public boolean equals(Object obj) {
4060 if (this == obj) {
4061 return true;
4062 }
4063 if (obj == null || getClass() != obj.getClass()) {
4064 return false;
4065 }
4066 final HistoricalOp other = (HistoricalOp) obj;
4067 if (mOp != other.mOp) {
4068 return false;
4069 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004070 if (!Objects.equals(mAccessCount, other.mAccessCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004071 return false;
4072 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004073 if (!Objects.equals(mRejectCount, other.mRejectCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004074 return false;
4075 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004076 return Objects.equals(mAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004077 }
4078
4079 @Override
4080 public int hashCode() {
4081 int result = mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08004082 result = 31 * result + Objects.hashCode(mAccessCount);
4083 result = 31 * result + Objects.hashCode(mRejectCount);
4084 result = 31 * result + Objects.hashCode(mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004085 return result;
4086 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004087
4088 private void accept(@NonNull HistoricalOpsVisitor visitor) {
4089 visitor.visitHistoricalOp(this);
4090 }
4091
4092 private @NonNull LongSparseLongArray getOrCreateAccessCount() {
4093 if (mAccessCount == null) {
4094 mAccessCount = new LongSparseLongArray();
4095 }
4096 return mAccessCount;
4097 }
4098
4099 private @NonNull LongSparseLongArray getOrCreateRejectCount() {
4100 if (mRejectCount == null) {
4101 mRejectCount = new LongSparseLongArray();
4102 }
4103 return mRejectCount;
4104 }
4105
4106 private @NonNull LongSparseLongArray getOrCreateAccessDuration() {
4107 if (mAccessDuration == null) {
4108 mAccessDuration = new LongSparseLongArray();
4109 }
4110 return mAccessDuration;
4111 }
4112
4113 /**
4114 * Multiplies the entries in the array with the passed in scale factor and
4115 * rounds the result at up 0.5 boundary.
4116 *
4117 * @param data The data to scale.
4118 * @param scaleFactor The scale factor.
4119 */
4120 private static void scale(@NonNull LongSparseLongArray data, double scaleFactor) {
4121 if (data != null) {
4122 final int size = data.size();
4123 for (int i = 0; i < size; i++) {
4124 data.put(data.keyAt(i), (long) HistoricalOps.round(
4125 (double) data.valueAt(i) * scaleFactor));
4126 }
4127 }
4128 }
4129
4130 /**
4131 * Merges two arrays while lazily acquiring the destination.
4132 *
4133 * @param thisSupplier The destination supplier.
4134 * @param other The array to merge in.
4135 */
4136 private static void merge(@NonNull Supplier<LongSparseLongArray> thisSupplier,
4137 @Nullable LongSparseLongArray other) {
4138 if (other != null) {
4139 final int otherSize = other.size();
4140 for (int i = 0; i < otherSize; i++) {
4141 final LongSparseLongArray that = thisSupplier.get();
4142 final long otherKey = other.keyAt(i);
4143 final long otherValue = other.valueAt(i);
4144 that.put(otherKey, that.get(otherKey) + otherValue);
4145 }
4146 }
4147 }
4148
4149 /** @hide */
4150 public @Nullable LongSparseArray<Object> collectKeys() {
4151 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessCount,
4152 null /*result*/);
4153 result = AppOpsManager.collectKeys(mRejectCount, result);
4154 result = AppOpsManager.collectKeys(mAccessDuration, result);
4155 return result;
4156 }
4157
4158 public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR =
4159 new Creator<HistoricalOp>() {
4160 @Override
4161 public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) {
4162 return new HistoricalOp(source);
4163 }
4164
4165 @Override
4166 public @NonNull HistoricalOp[] newArray(int size) {
4167 return new HistoricalOp[size];
4168 }
4169 };
4170 }
4171
4172 /**
4173 * Computes the sum of the counts for the given flags in between the begin and
4174 * end UID states.
4175 *
4176 * @param counts The data array.
4177 * @param beginUidState The beginning UID state (exclusive).
4178 * @param endUidState The end UID state.
4179 * @param flags The UID flags.
4180 * @return The sum.
4181 */
4182 private static long sumForFlagsInStates(@Nullable LongSparseLongArray counts,
4183 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
4184 if (counts == null) {
4185 return 0;
4186 }
4187 long sum = 0;
4188 while (flags != 0) {
4189 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4190 flags &= ~flag;
4191 for (int uidState : UID_STATES) {
4192 if (uidState < beginUidState || uidState > endUidState) {
4193 continue;
4194 }
4195 final long key = makeKey(uidState, flag);
4196 sum += counts.get(key);
4197 }
4198 }
4199 return sum;
4200 }
4201
4202 /**
4203 * Finds the first non-negative value for the given flags in between the begin and
4204 * end UID states.
4205 *
4206 * @param counts The data array.
4207 * @param flags The UID flags.
4208 * @param beginUidState The beginning UID state (exclusive).
4209 * @param endUidState The end UID state.
4210 * @return The non-negative value or -1.
4211 */
4212 private static long findFirstNonNegativeForFlagsInStates(@Nullable LongSparseLongArray counts,
4213 @OpFlags int flags, @UidState int beginUidState, @UidState int endUidState) {
4214 if (counts == null) {
4215 return -1;
4216 }
4217 while (flags != 0) {
4218 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4219 flags &= ~flag;
4220 for (int uidState : UID_STATES) {
4221 if (uidState < beginUidState || uidState > endUidState) {
4222 continue;
4223 }
4224 final long key = makeKey(uidState, flag);
4225 final long value = counts.get(key);
4226 if (value >= 0) {
4227 return value;
4228 }
4229 }
4230 }
4231 return -1;
4232 }
4233
4234 /**
4235 * Finds the first non-null value for the given flags in between the begin and
4236 * end UID states.
4237 *
4238 * @param counts The data array.
4239 * @param flags The UID flags.
4240 * @param beginUidState The beginning UID state (exclusive).
4241 * @param endUidState The end UID state.
4242 * @return The non-negative value or -1.
4243 */
4244 private static @Nullable String findFirstNonNullForFlagsInStates(
4245 @Nullable LongSparseArray<String> counts, @OpFlags int flags,
4246 @UidState int beginUidState, @UidState int endUidState) {
4247 if (counts == null) {
4248 return null;
4249 }
4250 while (flags != 0) {
4251 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4252 flags &= ~flag;
4253 for (int uidState : UID_STATES) {
4254 if (uidState < beginUidState || uidState > endUidState) {
4255 continue;
4256 }
4257 final long key = makeKey(uidState, flag);
4258 final String value = counts.get(key);
4259 if (value != null) {
4260 return value;
4261 }
4262 }
4263 }
4264 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004265 }
4266
4267 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004268 * Callback for notification of changes to operation state.
4269 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004270 public interface OnOpChangedListener {
4271 public void onOpChanged(String op, String packageName);
4272 }
4273
4274 /**
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004275 * Callback for notification of changes to operation active state.
4276 *
4277 * @hide
4278 */
Svet Ganovf7b47252018-02-26 11:11:27 -08004279 @TestApi
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004280 public interface OnOpActiveChangedListener {
4281 /**
4282 * Called when the active state of an app op changes.
4283 *
4284 * @param code The op code.
4285 * @param uid The UID performing the operation.
4286 * @param packageName The package performing the operation.
4287 * @param active Whether the operation became active or inactive.
4288 */
4289 void onOpActiveChanged(int code, int uid, String packageName, boolean active);
4290 }
4291
4292 /**
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004293 * Callback for notification of an op being noted.
4294 *
4295 * @hide
4296 */
4297 public interface OnOpNotedListener {
4298 /**
4299 * Called when an op was noted.
4300 *
4301 * @param code The op code.
4302 * @param uid The UID performing the operation.
4303 * @param packageName The package performing the operation.
4304 * @param result The result of the note.
4305 */
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004306 void onOpNoted(int code, int uid, String packageName, int result);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004307 }
4308
4309 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004310 * Callback for notification of changes to operation state.
4311 * This allows you to see the raw op codes instead of strings.
4312 * @hide
4313 */
4314 public static class OnOpChangedInternalListener implements OnOpChangedListener {
4315 public void onOpChanged(String op, String packageName) { }
4316 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -08004317 }
4318
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004319 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004320 mContext = context;
4321 mService = service;
4322 }
4323
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004324 /**
4325 * Retrieve current operation state for all applications.
4326 *
4327 * @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 -07004328 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004329 */
Svet Ganov8455ba22019-01-02 13:05:56 -08004330 @SystemApi
4331 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
4332 public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops) {
4333 final int opCount = ops.length;
4334 final int[] opCodes = new int[opCount];
4335 for (int i = 0; i < opCount; i++) {
4336 opCodes[i] = sOpStrToOp.get(ops[i]);
4337 }
4338 final List<AppOpsManager.PackageOps> result = getPackagesForOps(opCodes);
4339 return (result != null) ? result : Collections.emptyList();
4340 }
4341
4342 /**
4343 * Retrieve current operation state for all applications.
4344 *
4345 * @param ops The set of operations you are interested in, or null if you want all of them.
4346 * @hide
4347 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07004348 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004349 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08004350 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
4351 try {
4352 return mService.getPackagesForOps(ops);
4353 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004354 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08004355 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08004356 }
4357
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004358 /**
4359 * Retrieve current operation state for one application.
4360 *
4361 * @param uid The uid of the application of interest.
4362 * @param packageName The name of the application of interest.
4363 * @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 -08004364 *
4365 * @deprecated The int op codes are not stable and you should use the string based op
4366 * names which are stable and namespaced. Use
4367 * {@link #getOpsForPackage(int, String, String...)})}.
4368 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004369 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004370 */
Svet Ganov8455ba22019-01-02 13:05:56 -08004371 @Deprecated
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07004372 @SystemApi
Dianne Hackbornc216a262018-04-26 13:46:22 -07004373 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov8455ba22019-01-02 13:05:56 -08004374 public List<PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
Dianne Hackborn72e39832013-01-18 18:36:09 -08004375 try {
4376 return mService.getOpsForPackage(uid, packageName, ops);
4377 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004378 throw e.rethrowFromSystemServer();
Dianne Hackborn72e39832013-01-18 18:36:09 -08004379 }
Dianne Hackborn72e39832013-01-18 18:36:09 -08004380 }
4381
Svet Ganovae0e03a2016-02-25 18:22:10 -08004382 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004383 * Retrieve current operation state for one application. The UID and the
4384 * package must match.
4385 *
4386 * @param uid The uid of the application of interest.
4387 * @param packageName The name of the application of interest.
4388 * @param ops The set of operations you are interested in, or null if you want all of them.
4389 *
4390 * @hide
4391 */
4392 @SystemApi
4393 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
4394 public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid,
4395 @NonNull String packageName, @Nullable String... ops) {
4396 int[] opCodes = null;
4397 if (ops != null) {
4398 opCodes = new int[ops.length];
4399 for (int i = 0; i < ops.length; i++) {
4400 opCodes[i] = strOpToOp(ops[i]);
4401 }
4402 }
4403 try {
4404 final List<PackageOps> result = mService.getOpsForPackage(uid, packageName, opCodes);
4405 if (result == null) {
4406 return Collections.emptyList();
4407 }
4408 return result;
4409 } catch (RemoteException e) {
4410 throw e.rethrowFromSystemServer();
4411 }
4412 }
4413
4414 /**
4415 * Retrieve historical app op stats for a period.
4416 *
Svet Ganov23c88db2019-01-22 20:38:11 -08004417 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08004418 * @param executor Executor on which to run the callback. If <code>null</code>
4419 * the callback is executed on the default executor running on the main thread.
4420 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004421 *
4422 * @throws IllegalArgumentException If any of the argument contracts is violated.
4423 *
4424 * @hide
4425 */
4426 @TestApi
4427 @SystemApi
4428 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov23c88db2019-01-22 20:38:11 -08004429 public void getHistoricalOps(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08004430 @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) {
4431 Preconditions.checkNotNull(executor, "executor cannot be null");
4432 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07004433 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08004434 mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08004435 request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags,
Svet Ganov8455ba22019-01-02 13:05:56 -08004436 new RemoteCallback((result) -> {
4437 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
4438 final long identity = Binder.clearCallingIdentity();
4439 try {
4440 executor.execute(() -> callback.accept(ops));
4441 } finally {
4442 Binder.restoreCallingIdentity(identity);
4443 }
4444 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07004445 } catch (RemoteException e) {
4446 throw e.rethrowFromSystemServer();
4447 }
4448 }
4449
4450 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004451 * Retrieve historical app op stats for a period.
Svet Ganov8455ba22019-01-02 13:05:56 -08004452 * <p>
4453 * This method queries only the on disk state and the returned ops are raw,
4454 * which is their times are relative to the history start as opposed to the
4455 * epoch start.
4456 *
Svet Ganov23c88db2019-01-22 20:38:11 -08004457 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08004458 * @param executor Executor on which to run the callback. If <code>null</code>
4459 * the callback is executed on the default executor running on the main thread.
4460 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004461 *
4462 * @throws IllegalArgumentException If any of the argument contracts is violated.
4463 *
4464 * @hide
4465 */
4466 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -07004467 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov23c88db2019-01-22 20:38:11 -08004468 public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08004469 @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) {
4470 Preconditions.checkNotNull(executor, "executor cannot be null");
4471 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07004472 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08004473 mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName,
4474 request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis,
Svet Ganovaf189e32019-02-15 18:45:29 -08004475 request.mFlags, new RemoteCallback((result) -> {
Svet Ganov23c88db2019-01-22 20:38:11 -08004476 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
Svet Ganov8455ba22019-01-02 13:05:56 -08004477 final long identity = Binder.clearCallingIdentity();
4478 try {
4479 executor.execute(() -> callback.accept(ops));
4480 } finally {
4481 Binder.restoreCallingIdentity(identity);
4482 }
4483 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07004484 } catch (RemoteException e) {
4485 throw e.rethrowFromSystemServer();
4486 }
4487 }
4488
4489 /**
Svet Ganovae0e03a2016-02-25 18:22:10 -08004490 * Sets given app op in the specified mode for app ops in the UID.
4491 * This applies to all apps currently in the UID or installed in
4492 * this UID in the future.
4493 *
4494 * @param code The app op.
4495 * @param uid The UID for which to set the app.
4496 * @param mode The app op mode to set.
4497 * @hide
4498 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004499 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004500 public void setUidMode(int code, int uid, @Mode int mode) {
Svet Ganov2af57082015-07-30 08:44:20 -07004501 try {
4502 mService.setUidMode(code, uid, mode);
4503 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004504 throw e.rethrowFromSystemServer();
Svet Ganov2af57082015-07-30 08:44:20 -07004505 }
4506 }
4507
Svet Ganovae0e03a2016-02-25 18:22:10 -08004508 /**
4509 * Sets given app op in the specified mode for app ops in the UID.
4510 * This applies to all apps currently in the UID or installed in
4511 * this UID in the future.
4512 *
4513 * @param appOp The app op.
4514 * @param uid The UID for which to set the app.
4515 * @param mode The app op mode to set.
4516 * @hide
4517 */
4518 @SystemApi
Eugene Susla93519852018-06-13 16:44:31 -07004519 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004520 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004521 public void setUidMode(String appOp, int uid, @Mode int mode) {
Svet Ganovae0e03a2016-02-25 18:22:10 -08004522 try {
4523 mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
4524 } catch (RemoteException e) {
4525 throw e.rethrowFromSystemServer();
4526 }
4527 }
4528
Svet Ganov2af57082015-07-30 08:44:20 -07004529 /** @hide */
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004530 public void setUserRestriction(int code, boolean restricted, IBinder token) {
Ruben Brunk29931bc2016-03-11 00:24:26 -08004531 setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
4532 }
4533
4534 /** @hide */
4535 public void setUserRestriction(int code, boolean restricted, IBinder token,
4536 String[] exceptionPackages) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07004537 setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
4538 }
4539
4540 /** @hide */
4541 public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
4542 String[] exceptionPackages, int userId) {
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004543 try {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07004544 mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004545 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004546 throw e.rethrowFromSystemServer();
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004547 }
4548 }
4549
4550 /** @hide */
Peter Visontayb97fbc82017-12-21 16:23:55 +00004551 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004552 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004553 public void setMode(int code, int uid, String packageName, @Mode int mode) {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08004554 try {
4555 mService.setMode(code, uid, packageName, mode);
4556 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004557 throw e.rethrowFromSystemServer();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08004558 }
4559 }
4560
John Spurlock1af30c72014-03-10 08:33:35 -04004561 /**
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004562 * Change the operating mode for the given op in the given app package. You must pass
4563 * in both the uid and name of the application whose mode is being modified; if these
4564 * do not match, the modification will not be applied.
4565 *
4566 * @param op The operation to modify. One of the OPSTR_* constants.
4567 * @param uid The user id of the application whose mode will be changed.
4568 * @param packageName The name of the application package name whose mode will
4569 * be changed.
4570 * @hide
4571 */
4572 @SystemApi
4573 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004574 public void setMode(String op, int uid, String packageName, @Mode int mode) {
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004575 try {
4576 mService.setMode(strOpToOp(op), uid, packageName, mode);
4577 } catch (RemoteException e) {
4578 throw e.rethrowFromSystemServer();
4579 }
4580 }
4581
4582 /**
John Spurlock1af30c72014-03-10 08:33:35 -04004583 * Set a non-persisted restriction on an audio operation at a stream-level.
4584 * Restrictions are temporary additional constraints imposed on top of the persisted rules
4585 * defined by {@link #setMode}.
4586 *
4587 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04004588 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04004589 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
4590 * @param exceptionPackages Optional list of packages to exclude from the restriction.
4591 * @hide
4592 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004593 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004594 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -08004595 public void setRestriction(int code, @AttributeUsage int usage, @Mode int mode,
John Spurlock7b414672014-07-18 13:02:39 -04004596 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04004597 try {
4598 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04004599 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04004600 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004601 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04004602 }
4603 }
4604
Dianne Hackborn607b4142013-08-02 18:10:10 -07004605 /** @hide */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004606 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004607 @UnsupportedAppUsage
Dianne Hackborn607b4142013-08-02 18:10:10 -07004608 public void resetAllModes() {
4609 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -07004610 mService.resetAllModes(mContext.getUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07004611 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004612 throw e.rethrowFromSystemServer();
Dianne Hackborn607b4142013-08-02 18:10:10 -07004613 }
4614 }
4615
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004616 /**
Svet Ganovfbf01f72015-04-28 18:39:06 -07004617 * Gets the app op name associated with a given permission.
4618 * The app op name is one of the public constants defined
4619 * in this class such as {@link #OPSTR_COARSE_LOCATION}.
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07004620 * This API is intended to be used for mapping runtime
4621 * permissions to the corresponding app op.
Svet Ganovfbf01f72015-04-28 18:39:06 -07004622 *
4623 * @param permission The permission.
4624 * @return The app op associated with the permission or null.
Svet Ganovfbf01f72015-04-28 18:39:06 -07004625 */
Svet Ganovfbf01f72015-04-28 18:39:06 -07004626 public static String permissionToOp(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08004627 final Integer opCode = sPermToOp.get(permission);
Svet Ganovb9d71a62015-04-30 10:38:13 -07004628 if (opCode == null) {
4629 return null;
4630 }
4631 return sOpToString[opCode];
Svet Ganovfbf01f72015-04-28 18:39:06 -07004632 }
4633
4634 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004635 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004636 * You can watch op changes only for your UID.
4637 *
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07004638 * @param op The operation to monitor, one of OPSTR_*.
4639 * @param packageName The name of the application to monitor.
4640 * @param callback Where to report changes.
4641 */
4642 public void startWatchingMode(String op, String packageName,
4643 final OnOpChangedListener callback) {
4644 startWatchingMode(strOpToOp(op), packageName, callback);
4645 }
4646
4647 /**
4648 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004649 * You can watch op changes only for your UID.
4650 *
4651 * @param op The operation to monitor, one of OPSTR_*.
4652 * @param packageName The name of the application to monitor.
4653 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
4654 * @param callback Where to report changes.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004655 */
4656 public void startWatchingMode(String op, String packageName, int flags,
4657 final OnOpChangedListener callback) {
4658 startWatchingMode(strOpToOp(op), packageName, flags, callback);
4659 }
4660
4661 /**
4662 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004663 *
4664 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08004665 * you can watch changes only for your UID.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004666 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004667 * @param op The operation to monitor, one of OP_*.
4668 * @param packageName The name of the application to monitor.
4669 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07004670 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004671 */
Jeff Sharkeybf6b2132018-02-27 11:16:37 -07004672 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004673 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004674 startWatchingMode(op, packageName, 0, callback);
4675 }
4676
4677 /**
4678 * Monitor for changes to the operating mode for the given op in the given app package.
4679 *
4680 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4681 * you can watch changes only for your UID.
4682 *
4683 * @param op The operation to monitor, one of OP_*.
4684 * @param packageName The name of the application to monitor.
4685 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
4686 * @param callback Where to report changes.
4687 * @hide
4688 */
4689 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
4690 public void startWatchingMode(int op, String packageName, int flags,
4691 final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08004692 synchronized (mModeWatchers) {
4693 IAppOpsCallback cb = mModeWatchers.get(callback);
4694 if (cb == null) {
4695 cb = new IAppOpsCallback.Stub() {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07004696 public void opChanged(int op, int uid, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004697 if (callback instanceof OnOpChangedInternalListener) {
4698 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
4699 }
4700 if (sOpToString[op] != null) {
4701 callback.onOpChanged(sOpToString[op], packageName);
4702 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08004703 }
4704 };
4705 mModeWatchers.put(callback, cb);
4706 }
4707 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004708 mService.startWatchingModeWithFlags(op, packageName, flags, cb);
Dianne Hackbornc2293022013-02-06 23:14:49 -08004709 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004710 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08004711 }
4712 }
4713 }
4714
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004715 /**
4716 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
4717 * monitoring associated with this callback will be removed.
4718 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004719 public void stopWatchingMode(OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08004720 synchronized (mModeWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004721 IAppOpsCallback cb = mModeWatchers.remove(callback);
Dianne Hackbornc2293022013-02-06 23:14:49 -08004722 if (cb != null) {
4723 try {
4724 mService.stopWatchingMode(cb);
4725 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004726 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08004727 }
4728 }
4729 }
4730 }
4731
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004732 /**
4733 * Start watching for changes to the active state of app ops. An app op may be
4734 * long running and it has a clear start and stop delimiters. If an op is being
4735 * started or stopped by any package you will get a callback. To change the
4736 * watched ops for a registered callback you need to unregister and register it
4737 * again.
4738 *
Svet Ganovf7b47252018-02-26 11:11:27 -08004739 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4740 * you can watch changes only for your UID.
4741 *
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004742 * @param ops The ops to watch.
4743 * @param callback Where to report changes.
4744 *
4745 * @see #isOperationActive(int, int, String)
4746 * @see #stopWatchingActive(OnOpActiveChangedListener)
4747 * @see #startOp(int, int, String)
4748 * @see #finishOp(int, int, String)
4749 *
4750 * @hide
4751 */
Svet Ganovf7b47252018-02-26 11:11:27 -08004752 @TestApi
4753 // TODO: Uncomment below annotation once b/73559440 is fixed
4754 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004755 public void startWatchingActive(@NonNull int[] ops,
4756 @NonNull OnOpActiveChangedListener callback) {
4757 Preconditions.checkNotNull(ops, "ops cannot be null");
4758 Preconditions.checkNotNull(callback, "callback cannot be null");
4759 IAppOpsActiveCallback cb;
4760 synchronized (mActiveWatchers) {
4761 cb = mActiveWatchers.get(callback);
4762 if (cb != null) {
4763 return;
4764 }
4765 cb = new IAppOpsActiveCallback.Stub() {
4766 @Override
4767 public void opActiveChanged(int op, int uid, String packageName, boolean active) {
4768 callback.onOpActiveChanged(op, uid, packageName, active);
4769 }
4770 };
4771 mActiveWatchers.put(callback, cb);
4772 }
4773 try {
4774 mService.startWatchingActive(ops, cb);
4775 } catch (RemoteException e) {
4776 throw e.rethrowFromSystemServer();
4777 }
4778 }
4779
4780 /**
4781 * Stop watching for changes to the active state of an app op. An app op may be
4782 * long running and it has a clear start and stop delimiters. Unregistering a
4783 * non-registered callback has no effect.
4784 *
4785 * @see #isOperationActive#(int, int, String)
4786 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
4787 * @see #startOp(int, int, String)
4788 * @see #finishOp(int, int, String)
4789 *
4790 * @hide
4791 */
Svet Ganovf7b47252018-02-26 11:11:27 -08004792 @TestApi
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004793 public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
4794 synchronized (mActiveWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004795 final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004796 if (cb != null) {
4797 try {
4798 mService.stopWatchingActive(cb);
4799 } catch (RemoteException e) {
4800 throw e.rethrowFromSystemServer();
4801 }
4802 }
4803 }
4804 }
4805
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004806 /**
4807 * Start watching for noted app ops. An app op may be immediate or long running.
4808 * Immediate ops are noted while long running ones are started and stopped. This
4809 * method allows registering a listener to be notified when an app op is noted. If
4810 * an op is being noted by any package you will get a callback. To change the
4811 * watched ops for a registered callback you need to unregister and register it again.
4812 *
4813 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4814 * you can watch changes only for your UID.
4815 *
4816 * @param ops The ops to watch.
4817 * @param callback Where to report changes.
4818 *
4819 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
4820 * @see #stopWatchingNoted(OnOpNotedListener)
4821 * @see #noteOp(String, int, String)
4822 *
4823 * @hide
4824 */
4825 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004826 public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004827 IAppOpsNotedCallback cb;
4828 synchronized (mNotedWatchers) {
4829 cb = mNotedWatchers.get(callback);
4830 if (cb != null) {
4831 return;
4832 }
4833 cb = new IAppOpsNotedCallback.Stub() {
4834 @Override
4835 public void opNoted(int op, int uid, String packageName, int mode) {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004836 callback.onOpNoted(op, uid, packageName, mode);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004837 }
4838 };
4839 mNotedWatchers.put(callback, cb);
4840 }
4841 try {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004842 mService.startWatchingNoted(ops, cb);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004843 } catch (RemoteException e) {
4844 throw e.rethrowFromSystemServer();
4845 }
4846 }
4847
4848 /**
4849 * Stop watching for noted app ops. An app op may be immediate or long running.
4850 * Unregistering a non-registered callback has no effect.
4851 *
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004852 * @see #startWatchingNoted(int[], OnOpNotedListener)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004853 * @see #noteOp(String, int, String)
4854 *
4855 * @hide
4856 */
4857 public void stopWatchingNoted(@NonNull OnOpNotedListener callback) {
4858 synchronized (mNotedWatchers) {
4859 final IAppOpsNotedCallback cb = mNotedWatchers.get(callback);
4860 if (cb != null) {
4861 try {
4862 mService.stopWatchingNoted(cb);
4863 } catch (RemoteException e) {
4864 throw e.rethrowFromSystemServer();
4865 }
4866 }
4867 }
4868 }
4869
Dianne Hackborn95d78532013-09-11 09:51:14 -07004870 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
4871 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
4872 }
4873
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07004874 /**
4875 * {@hide}
4876 */
Philip P. Moltmann33115152018-04-11 13:39:36 -07004877 @TestApi
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07004878 public static int strOpToOp(String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004879 Integer val = sOpStrToOp.get(op);
4880 if (val == null) {
4881 throw new IllegalArgumentException("Unknown operation string: " + op);
4882 }
4883 return val;
4884 }
4885
4886 /**
4887 * Do a quick check for whether an application might be able to perform an operation.
4888 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
4889 * or {@link #startOp(String, int, String)} for your actual security checks, which also
4890 * ensure that the given uid and package name are consistent. This function can just be
4891 * used for a quick check to see if an operation has been disabled for the application,
4892 * as an early reject of some work. This does not modify the time stamp or other data
4893 * about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07004894 *
4895 * <p>Important things this will not do (which you need to ultimate use
4896 * {@link #noteOp(String, int, String)} or {@link #startOp(String, int, String)} to cover):</p>
4897 * <ul>
4898 * <li>Verifying the uid and package are consistent, so callers can't spoof
4899 * their identity.</li>
4900 * <li>Taking into account the current foreground/background state of the
4901 * app; apps whose mode varies by this state will always be reported
4902 * as {@link #MODE_ALLOWED}.</li>
4903 * </ul>
4904 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004905 * @param op The operation to check. One of the OPSTR_* constants.
4906 * @param uid The user id of the application attempting to perform the operation.
4907 * @param packageName The name of the application attempting to perform the operation.
4908 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4909 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4910 * causing the app to crash).
4911 * @throws SecurityException If the app has been configured to crash on this op.
4912 */
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07004913 public int unsafeCheckOp(String op, int uid, String packageName) {
4914 return checkOp(strOpToOp(op), uid, packageName);
4915 }
4916
4917 /**
4918 * @deprecated Renamed to {@link #unsafeCheckOp(String, int, String)}.
4919 */
4920 @Deprecated
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004921 public int checkOp(String op, int uid, String packageName) {
4922 return checkOp(strOpToOp(op), uid, packageName);
4923 }
4924
4925 /**
John Spurlock925b85e2014-03-10 16:52:11 -04004926 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004927 * returns {@link #MODE_ERRORED}.
4928 */
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07004929 public int unsafeCheckOpNoThrow(String op, int uid, String packageName) {
4930 return checkOpNoThrow(strOpToOp(op), uid, packageName);
4931 }
4932
4933 /**
4934 * @deprecated Renamed to {@link #unsafeCheckOpNoThrow(String, int, String)}.
4935 */
4936 @Deprecated
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004937 public int checkOpNoThrow(String op, int uid, String packageName) {
4938 return checkOpNoThrow(strOpToOp(op), uid, packageName);
4939 }
4940
4941 /**
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004942 * Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op.
4943 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004944 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004945 public int unsafeCheckOpRaw(@NonNull String op, int uid, String packageName) {
4946 try {
4947 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
4948 } catch (RemoteException e) {
4949 throw e.rethrowFromSystemServer();
4950 }
4951 }
4952
4953 /**
4954 * Like {@link #unsafeCheckOpNoThrow(String, int, String)} but returns the <em>raw</em>
4955 * mode associated with the op. Does not throw a security exception, does not translate
4956 * {@link #MODE_FOREGROUND}.
4957 */
4958 public int unsafeCheckOpRawNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004959 try {
Svet Ganov9d528a12018-12-19 17:23:11 -08004960 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004961 } catch (RemoteException e) {
4962 throw e.rethrowFromSystemServer();
4963 }
4964 }
4965
4966 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004967 * Make note of an application performing an operation. Note that you must pass
4968 * in both the uid and name of the application to be checked; this function will verify
4969 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
4970 * succeeds, the last execution time of the operation for this app will be updated to
4971 * the current time.
4972 * @param op The operation to note. One of the OPSTR_* constants.
4973 * @param uid The user id of the application attempting to perform the operation.
4974 * @param packageName The name of the application attempting to perform the operation.
4975 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4976 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4977 * causing the app to crash).
4978 * @throws SecurityException If the app has been configured to crash on this op.
4979 */
4980 public int noteOp(String op, int uid, String packageName) {
4981 return noteOp(strOpToOp(op), uid, packageName);
4982 }
4983
4984 /**
4985 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
4986 * returns {@link #MODE_ERRORED}.
4987 */
4988 public int noteOpNoThrow(String op, int uid, String packageName) {
4989 return noteOpNoThrow(strOpToOp(op), uid, packageName);
4990 }
4991
4992 /**
Svet Ganov99b60432015-06-27 13:15:22 -07004993 * Make note of an application performing an operation on behalf of another
4994 * application when handling an IPC. Note that you must pass the package name
4995 * of the application that is being proxied while its UID will be inferred from
4996 * the IPC state; this function will verify that the calling uid and proxied
4997 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
4998 * succeeds, the last execution time of the operation for the proxied app and
4999 * your app will be updated to the current time.
5000 * @param op The operation to note. One of the OPSTR_* constants.
5001 * @param proxiedPackageName The name of the application calling into the proxy application.
5002 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5003 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5004 * causing the app to crash).
5005 * @throws SecurityException If the app has been configured to crash on this op.
5006 */
5007 public int noteProxyOp(String op, String proxiedPackageName) {
5008 return noteProxyOp(strOpToOp(op), proxiedPackageName);
5009 }
5010
5011 /**
5012 * Like {@link #noteProxyOp(String, String)} but instead
5013 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005014 *
5015 * <p>This API requires the package with the {@code proxiedPackageName} to belongs to
5016 * {@link Binder#getCallingUid()}.
Svet Ganov99b60432015-06-27 13:15:22 -07005017 */
5018 public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
5019 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
5020 }
5021
5022 /**
Philip P. Moltmann78219312019-03-01 17:04:19 -08005023 * Like {@link #noteProxyOpNoThrow(String, String)} but allows to specify the proxied uid.
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005024 *
5025 * <p>This API requires package with the {@code proxiedPackageName} to belong to
5026 * {@code proxiedUid}.
5027 *
5028 * @param op The op to note
5029 * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
5030 * noted for the "android" package
5031 * @param proxiedUid The uid the package belongs to
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005032 */
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005033 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
5034 int proxiedUid) {
5035 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid);
5036 }
5037
5038 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005039 * Report that an application has started executing a long-running operation. Note that you
5040 * must pass in both the uid and name of the application to be checked; this function will
5041 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5042 * succeeds, the last execution time of the operation for this app will be updated to
5043 * the current time and the operation will be marked as "running". In this case you must
5044 * later call {@link #finishOp(String, int, String)} to report when the application is no
5045 * longer performing the operation.
5046 * @param op The operation to start. One of the OPSTR_* constants.
5047 * @param uid The user id of the application attempting to perform the operation.
5048 * @param packageName The name of the application attempting to perform the operation.
5049 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5050 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5051 * causing the app to crash).
5052 * @throws SecurityException If the app has been configured to crash on this op.
5053 */
5054 public int startOp(String op, int uid, String packageName) {
5055 return startOp(strOpToOp(op), uid, packageName);
5056 }
5057
5058 /**
5059 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
5060 * returns {@link #MODE_ERRORED}.
5061 */
5062 public int startOpNoThrow(String op, int uid, String packageName) {
5063 return startOpNoThrow(strOpToOp(op), uid, packageName);
5064 }
5065
5066 /**
5067 * Report that an application is no longer performing an operation that had previously
5068 * been started with {@link #startOp(String, int, String)}. There is no validation of input
5069 * or result; the parameters supplied here must be the exact same ones previously passed
5070 * in when starting the operation.
5071 */
5072 public void finishOp(String op, int uid, String packageName) {
5073 finishOp(strOpToOp(op), uid, packageName);
5074 }
5075
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005076 /**
5077 * Do a quick check for whether an application might be able to perform an operation.
5078 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
5079 * or {@link #startOp(int, int, String)} for your actual security checks, which also
5080 * ensure that the given uid and package name are consistent. This function can just be
5081 * used for a quick check to see if an operation has been disabled for the application,
5082 * as an early reject of some work. This does not modify the time stamp or other data
5083 * about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07005084 *
5085 * <p>Important things this will not do (which you need to ultimate use
5086 * {@link #noteOp(int, int, String)} or {@link #startOp(int, int, String)} to cover):</p>
5087 * <ul>
5088 * <li>Verifying the uid and package are consistent, so callers can't spoof
5089 * their identity.</li>
5090 * <li>Taking into account the current foreground/background state of the
5091 * app; apps whose mode varies by this state will always be reported
5092 * as {@link #MODE_ALLOWED}.</li>
5093 * </ul>
5094 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005095 * @param op The operation to check. One of the OP_* constants.
5096 * @param uid The user id of the application attempting to perform the operation.
5097 * @param packageName The name of the application attempting to perform the operation.
5098 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5099 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5100 * causing the app to crash).
5101 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005102 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005103 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005104 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08005105 public int checkOp(int op, int uid, String packageName) {
5106 try {
5107 int mode = mService.checkOperation(op, uid, packageName);
5108 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07005109 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08005110 }
5111 return mode;
5112 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005113 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08005114 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08005115 }
5116
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005117 /**
5118 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
5119 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005120 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005121 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005122 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08005123 public int checkOpNoThrow(int op, int uid, String packageName) {
5124 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005125 int mode = mService.checkOperation(op, uid, packageName);
5126 return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08005127 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005128 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08005129 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08005130 }
5131
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005132 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07005133 * Do a quick check to validate if a package name belongs to a UID.
5134 *
5135 * @throws SecurityException if the package name doesn't belong to the given
5136 * UID, or if ownership cannot be verified.
5137 */
5138 public void checkPackage(int uid, String packageName) {
5139 try {
5140 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
5141 throw new SecurityException(
5142 "Package " + packageName + " does not belong to " + uid);
5143 }
5144 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005145 throw e.rethrowFromSystemServer();
Jeff Sharkey911d7f42013-09-05 18:11:45 -07005146 }
5147 }
5148
5149 /**
John Spurlock1af30c72014-03-10 08:33:35 -04005150 * Like {@link #checkOp} but at a stream-level for audio operations.
5151 * @hide
5152 */
5153 public int checkAudioOp(int op, int stream, int uid, String packageName) {
5154 try {
5155 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
5156 if (mode == MODE_ERRORED) {
5157 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
5158 }
5159 return mode;
5160 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005161 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04005162 }
John Spurlock1af30c72014-03-10 08:33:35 -04005163 }
5164
5165 /**
5166 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
5167 * returns {@link #MODE_ERRORED}.
5168 * @hide
5169 */
5170 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
5171 try {
5172 return mService.checkAudioOperation(op, stream, uid, packageName);
5173 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005174 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04005175 }
John Spurlock1af30c72014-03-10 08:33:35 -04005176 }
5177
5178 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005179 * Make note of an application performing an operation. Note that you must pass
5180 * in both the uid and name of the application to be checked; this function will verify
5181 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5182 * succeeds, the last execution time of the operation for this app will be updated to
5183 * the current time.
5184 * @param op The operation to note. One of the OP_* constants.
5185 * @param uid The user id of the application attempting to perform the operation.
5186 * @param packageName The name of the application attempting to perform the operation.
5187 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5188 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5189 * causing the app to crash).
5190 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005191 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005192 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005193 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005194 public int noteOp(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08005195 final int mode = noteOpNoThrow(op, uid, packageName);
5196 if (mode == MODE_ERRORED) {
5197 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005198 }
Svet Ganovf7b47252018-02-26 11:11:27 -08005199 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005200 }
5201
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005202 /**
Svet Ganov99b60432015-06-27 13:15:22 -07005203 * Make note of an application performing an operation on behalf of another
5204 * application when handling an IPC. Note that you must pass the package name
5205 * of the application that is being proxied while its UID will be inferred from
5206 * the IPC state; this function will verify that the calling uid and proxied
5207 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
5208 * succeeds, the last execution time of the operation for the proxied app and
5209 * your app will be updated to the current time.
5210 * @param op The operation to note. One of the OPSTR_* constants.
5211 * @param proxiedPackageName The name of the application calling into the proxy application.
5212 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5213 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5214 * causing the app to crash).
5215 * @throws SecurityException If the proxy or proxied app has been configured to
5216 * crash on this op.
5217 *
5218 * @hide
5219 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005220 @UnsupportedAppUsage
Svet Ganov99b60432015-06-27 13:15:22 -07005221 public int noteProxyOp(int op, String proxiedPackageName) {
5222 int mode = noteProxyOpNoThrow(op, proxiedPackageName);
5223 if (mode == MODE_ERRORED) {
5224 throw new SecurityException("Proxy package " + mContext.getOpPackageName()
5225 + " from uid " + Process.myUid() + " or calling package "
5226 + proxiedPackageName + " from uid " + Binder.getCallingUid()
5227 + " not allowed to perform " + sOpNames[op]);
5228 }
5229 return mode;
5230 }
5231
5232 /**
5233 * Like {@link #noteProxyOp(int, String)} but instead
5234 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
5235 * @hide
5236 */
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005237 public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) {
Chad Brubaker9f394312019-02-01 10:29:39 -08005238 logOperationIfNeeded(op, mContext.getOpPackageName(), proxiedPackageName);
Svet Ganov99b60432015-06-27 13:15:22 -07005239 try {
Svet Ganovd873ae62018-06-25 16:39:23 -07005240 return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005241 proxiedUid, proxiedPackageName);
Svet Ganov99b60432015-06-27 13:15:22 -07005242 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005243 throw e.rethrowFromSystemServer();
Svet Ganov99b60432015-06-27 13:15:22 -07005244 }
Svet Ganov99b60432015-06-27 13:15:22 -07005245 }
5246
5247 /**
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005248 * Like {@link #noteProxyOp(int, String)} but instead
5249 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
5250 *
5251 * <p>This API requires the package with {@code proxiedPackageName} to belongs to
5252 * {@link Binder#getCallingUid()}.
5253 *
5254 * @hide
5255 */
5256 public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
5257 return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid());
5258 }
5259
5260 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005261 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
5262 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005263 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005264 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005265 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005266 public int noteOpNoThrow(int op, int uid, String packageName) {
Chad Brubaker9f394312019-02-01 10:29:39 -08005267 logOperationIfNeeded(op, packageName, null);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005268 try {
5269 return mService.noteOperation(op, uid, packageName);
5270 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005271 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005272 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005273 }
5274
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005275 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005276 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005277 public int noteOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07005278 return noteOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005279 }
5280
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005281 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005282 @UnsupportedAppUsage
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005283 public static IBinder getToken(IAppOpsService service) {
5284 synchronized (AppOpsManager.class) {
5285 if (sToken != null) {
5286 return sToken;
5287 }
5288 try {
5289 sToken = service.getToken(new Binder());
5290 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005291 throw e.rethrowFromSystemServer();
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005292 }
5293 return sToken;
5294 }
5295 }
5296
Svet Ganovf7b47252018-02-26 11:11:27 -08005297 /** @hide */
5298 public int startOp(int op) {
5299 return startOp(op, Process.myUid(), mContext.getOpPackageName());
5300 }
5301
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005302 /**
5303 * Report that an application has started executing a long-running operation. Note that you
5304 * must pass in both the uid and name of the application to be checked; this function will
5305 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5306 * succeeds, the last execution time of the operation for this app will be updated to
5307 * the current time and the operation will be marked as "running". In this case you must
5308 * later call {@link #finishOp(int, int, String)} to report when the application is no
5309 * longer performing the operation.
Svet Ganovf7b47252018-02-26 11:11:27 -08005310 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005311 * @param op The operation to start. One of the OP_* constants.
5312 * @param uid The user id of the application attempting to perform the operation.
5313 * @param packageName The name of the application attempting to perform the operation.
5314 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5315 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5316 * causing the app to crash).
5317 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005318 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005319 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005320 public int startOp(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08005321 return startOp(op, uid, packageName, false);
5322 }
5323
5324 /**
5325 * Report that an application has started executing a long-running operation. Similar
5326 * to {@link #startOp(String, int, String) except that if the mode is {@link #MODE_DEFAULT}
5327 * the operation should succeed since the caller has performed its standard permission
5328 * checks which passed and would perform the protected operation for this mode.
5329 *
5330 * @param op The operation to start. One of the OP_* constants.
5331 * @param uid The user id of the application attempting to perform the operation.
5332 * @param packageName The name of the application attempting to perform the operation.
5333 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5334 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5335 * causing the app to crash).
5336 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
5337 *
5338 * @throws SecurityException If the app has been configured to crash on this op or
5339 * the package is not in the passed in UID.
5340 *
5341 * @hide
5342 */
5343 public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
5344 final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault);
5345 if (mode == MODE_ERRORED) {
5346 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005347 }
Svet Ganovf7b47252018-02-26 11:11:27 -08005348 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005349 }
5350
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005351 /**
5352 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
5353 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005354 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005355 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005356 public int startOpNoThrow(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08005357 return startOpNoThrow(op, uid, packageName, false);
5358 }
5359
5360 /**
5361 * Like {@link #startOp(int, int, String, boolean)} but instead of throwing a
5362 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
5363 *
5364 * @param op The operation to start. One of the OP_* constants.
5365 * @param uid The user id of the application attempting to perform the operation.
5366 * @param packageName The name of the application attempting to perform the operation.
5367 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5368 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5369 * causing the app to crash).
5370 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
5371 *
5372 * @hide
5373 */
5374 public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
Chad Brubaker9f394312019-02-01 10:29:39 -08005375 logOperationIfNeeded(op, packageName, null);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005376 try {
Svet Ganovf7b47252018-02-26 11:11:27 -08005377 return mService.startOperation(getToken(mService), op, uid, packageName,
5378 startIfModeDefault);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005379 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005380 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005381 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005382 }
5383
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005384 /**
5385 * Report that an application is no longer performing an operation that had previously
5386 * been started with {@link #startOp(int, int, String)}. There is no validation of input
5387 * or result; the parameters supplied here must be the exact same ones previously passed
5388 * in when starting the operation.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005389 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005390 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005391 public void finishOp(int op, int uid, String packageName) {
Chad Brubaker9f394312019-02-01 10:29:39 -08005392 logOperationIfNeeded(op, packageName, null);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005393 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005394 mService.finishOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005395 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005396 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005397 }
5398 }
5399
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005400 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005401 public void finishOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07005402 finishOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005403 }
Jeff Sharkey35e46d22017-06-09 10:01:20 -06005404
Svet Ganovf7b47252018-02-26 11:11:27 -08005405 /**
5406 * Checks whether the given op for a UID and package is active.
5407 *
5408 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
5409 * you can query only for your UID.
5410 *
5411 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
5412 * @see #stopWatchingMode(OnOpChangedListener)
5413 * @see #finishOp(int)
5414 * @see #startOp(int)
5415 *
5416 * @hide */
5417 @TestApi
5418 // TODO: Uncomment below annotation once b/73559440 is fixed
5419 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey35e46d22017-06-09 10:01:20 -06005420 public boolean isOperationActive(int code, int uid, String packageName) {
5421 try {
5422 return mService.isOperationActive(code, uid, packageName);
5423 } catch (RemoteException e) {
5424 throw e.rethrowFromSystemServer();
5425 }
5426 }
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00005427
5428 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005429 * Configures the app ops persistence for testing.
5430 *
5431 * @param mode The mode in which the historical registry operates.
5432 * @param baseSnapshotInterval The base interval on which we would be persisting a snapshot of
5433 * the historical data. The history is recursive where every subsequent step encompasses
5434 * {@code compressionStep} longer interval with {@code compressionStep} distance between
5435 * snapshots.
5436 * @param compressionStep The compression step in every iteration.
5437 *
5438 * @see #HISTORICAL_MODE_DISABLED
5439 * @see #HISTORICAL_MODE_ENABLED_ACTIVE
5440 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
5441 *
5442 * @hide
5443 */
5444 @TestApi
5445 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5446 public void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval,
5447 int compressionStep) {
5448 try {
5449 mService.setHistoryParameters(mode, baseSnapshotInterval, compressionStep);
5450 } catch (RemoteException e) {
5451 throw e.rethrowFromSystemServer();
5452 }
5453 }
5454
5455 /**
5456 * Offsets the history by the given duration.
5457 *
5458 * @param offsetMillis The offset duration.
5459 *
5460 * @hide
5461 */
5462 @TestApi
5463 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5464 public void offsetHistory(long offsetMillis) {
5465 try {
5466 mService.offsetHistory(offsetMillis);
5467 } catch (RemoteException e) {
5468 throw e.rethrowFromSystemServer();
5469 }
5470 }
5471
5472 /**
5473 * Adds ops to the history directly. This could be useful for testing especially
5474 * when the historical registry operates in {@link #HISTORICAL_MODE_ENABLED_PASSIVE}
5475 * mode.
5476 *
5477 * @param ops The ops to add to the history.
5478 *
5479 * @see #setHistoryParameters(int, long, int)
5480 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
5481 *
5482 * @hide
5483 */
5484 @TestApi
5485 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5486 public void addHistoricalOps(@NonNull HistoricalOps ops) {
5487 try {
5488 mService.addHistoricalOps(ops);
5489 } catch (RemoteException e) {
5490 throw e.rethrowFromSystemServer();
5491 }
5492 }
5493
5494 /**
5495 * Resets the app ops persistence for testing.
5496 *
5497 * @see #setHistoryParameters(int, long, int)
5498 *
5499 * @hide
5500 */
5501 @TestApi
5502 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5503 public void resetHistoryParameters() {
5504 try {
5505 mService.resetHistoryParameters();
5506 } catch (RemoteException e) {
5507 throw e.rethrowFromSystemServer();
5508 }
5509 }
5510
5511 /**
5512 * Clears all app ops history.
5513 *
5514 * @hide
5515 */
5516 @TestApi
5517 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5518 public void clearHistory() {
5519 try {
5520 mService.clearHistory();
5521 } catch (RemoteException e) {
5522 throw e.rethrowFromSystemServer();
5523 }
5524 }
5525
5526 /**
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00005527 * Returns all supported operation names.
5528 * @hide
5529 */
5530 @SystemApi
5531 @TestApi
5532 public static String[] getOpStrs() {
5533 return Arrays.copyOf(sOpToString, sOpToString.length);
5534 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07005535
Philip P. Moltmann24576812018-05-07 10:42:05 -07005536
5537 /**
5538 * @return number of App ops
5539 * @hide
5540 */
5541 @TestApi
5542 public static int getNumOps() {
5543 return _NUM_OP;
5544 }
5545
Dianne Hackbornc216a262018-04-26 13:46:22 -07005546 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08005547 * Computes the max for the given flags in between the begin and
5548 * end UID states.
5549 *
5550 * @param counts The data array.
5551 * @param flags The UID flags.
5552 * @param beginUidState The beginning UID state (exclusive).
5553 * @param endUidState The end UID state.
5554 * @return The sum.
Dianne Hackbornc216a262018-04-26 13:46:22 -07005555 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005556 private static long maxForFlagsInStates(@Nullable LongSparseLongArray counts,
5557 @UidState int beginUidState, @UidState int endUidState,
5558 @OpFlags int flags) {
5559 if (counts == null) {
5560 return 0;
5561 }
5562 long max = 0;
5563 while (flags != 0) {
5564 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
5565 flags &= ~flag;
5566 for (int uidState : UID_STATES) {
5567 if (uidState < beginUidState || uidState > endUidState) {
5568 continue;
5569 }
5570 final long key = makeKey(uidState, flag);
5571 max = Math.max(max, counts.get(key));
Dianne Hackbornc216a262018-04-26 13:46:22 -07005572 }
5573 }
Svet Ganovaf189e32019-02-15 18:45:29 -08005574 return max;
5575 }
5576
5577
5578 private static void writeLongSparseLongArrayToParcel(
5579 @Nullable LongSparseLongArray array, @NonNull Parcel parcel) {
5580 if (array != null) {
5581 final int size = array.size();
5582 parcel.writeInt(size);
5583 for (int i = 0; i < size; i++) {
5584 parcel.writeLong(array.keyAt(i));
5585 parcel.writeLong(array.valueAt(i));
5586 }
5587 } else {
5588 parcel.writeInt(-1);
5589 }
5590 }
5591
5592 private static @Nullable LongSparseLongArray readLongSparseLongArrayFromParcel(
5593 @NonNull Parcel parcel) {
5594 final int size = parcel.readInt();
5595 if (size < 0) {
5596 return null;
5597 }
5598 final LongSparseLongArray array = new LongSparseLongArray(size);
5599 for (int i = 0; i < size; i++) {
5600 array.append(parcel.readLong(), parcel.readLong());
5601 }
5602 return array;
5603 }
5604
5605 private static void writeLongSparseStringArrayToParcel(
5606 @Nullable LongSparseArray<String> array, @NonNull Parcel parcel) {
5607 if (array != null) {
5608 final int size = array.size();
5609 parcel.writeInt(size);
5610 for (int i = 0; i < size; i++) {
5611 parcel.writeLong(array.keyAt(i));
5612 parcel.writeString(array.valueAt(i));
5613 }
5614 } else {
5615 parcel.writeInt(-1);
5616 }
5617 }
5618
5619 private static @Nullable LongSparseArray<String> readLongSparseStringArrayFromParcel(
5620 @NonNull Parcel parcel) {
5621 final int size = parcel.readInt();
5622 if (size < 0) {
5623 return null;
5624 }
5625 final LongSparseArray<String> array = new LongSparseArray<>(size);
5626 for (int i = 0; i < size; i++) {
5627 array.append(parcel.readLong(), parcel.readString());
5628 }
5629 return array;
5630 }
5631
5632 /**
5633 * Collects the keys from an array to the result creating the result if needed.
5634 *
5635 * @param array The array whose keys to collect.
5636 * @param result The optional result store collected keys.
5637 * @return The result collected keys array.
5638 */
5639 private static LongSparseArray<Object> collectKeys(@Nullable LongSparseLongArray array,
5640 @Nullable LongSparseArray<Object> result) {
5641 if (array != null) {
5642 if (result == null) {
5643 result = new LongSparseArray<>();
5644 }
5645 final int accessSize = array.size();
5646 for (int i = 0; i < accessSize; i++) {
5647 result.put(array.keyAt(i), null);
5648 }
5649 }
5650 return result;
Dianne Hackbornc216a262018-04-26 13:46:22 -07005651 }
Svet Ganov8455ba22019-01-02 13:05:56 -08005652
5653 /** @hide */
5654 public static String uidStateToString(@UidState int uidState) {
5655 switch (uidState) {
5656 case UID_STATE_PERSISTENT: {
5657 return "UID_STATE_PERSISTENT";
5658 }
5659 case UID_STATE_TOP: {
5660 return "UID_STATE_TOP";
5661 }
Amith Yamasania0a30a12019-01-22 11:38:06 -08005662 case UID_STATE_FOREGROUND_SERVICE_LOCATION: {
5663 return "UID_STATE_FOREGROUND_SERVICE_LOCATION";
5664 }
Svet Ganov8455ba22019-01-02 13:05:56 -08005665 case UID_STATE_FOREGROUND_SERVICE: {
5666 return "UID_STATE_FOREGROUND_SERVICE";
5667 }
5668 case UID_STATE_FOREGROUND: {
5669 return "UID_STATE_FOREGROUND";
5670 }
5671 case UID_STATE_BACKGROUND: {
5672 return "UID_STATE_BACKGROUND";
5673 }
5674 case UID_STATE_CACHED: {
5675 return "UID_STATE_CACHED";
5676 }
5677 default: {
5678 return "UNKNOWN";
5679 }
5680 }
5681 }
5682
5683 /** @hide */
5684 public static int parseHistoricalMode(@NonNull String mode) {
5685 switch (mode) {
5686 case "HISTORICAL_MODE_ENABLED_ACTIVE": {
5687 return HISTORICAL_MODE_ENABLED_ACTIVE;
5688 }
5689 case "HISTORICAL_MODE_ENABLED_PASSIVE": {
5690 return HISTORICAL_MODE_ENABLED_PASSIVE;
5691 }
5692 default: {
5693 return HISTORICAL_MODE_DISABLED;
5694 }
5695 }
5696 }
5697
5698 /** @hide */
5699 public static String historicalModeToString(@HistoricalMode int mode) {
5700 switch (mode) {
5701 case HISTORICAL_MODE_DISABLED: {
5702 return "HISTORICAL_MODE_DISABLED";
5703 }
5704 case HISTORICAL_MODE_ENABLED_ACTIVE: {
5705 return "HISTORICAL_MODE_ENABLED_ACTIVE";
5706 }
5707 case HISTORICAL_MODE_ENABLED_PASSIVE: {
5708 return "HISTORICAL_MODE_ENABLED_PASSIVE";
5709 }
5710 default: {
5711 return "UNKNOWN";
5712 }
5713 }
5714 }
Ng Zhi An65a99b62018-10-01 11:57:53 -07005715
5716 private static int getSystemAlertWindowDefault() {
5717 final Context context = ActivityThread.currentApplication();
5718 if (context == null) {
5719 return AppOpsManager.MODE_DEFAULT;
5720 }
5721
5722 // system alert window is disable on low ram phones starting from Q
5723 final PackageManager pm = context.getPackageManager();
5724 // TVs are constantly plugged in and has less concern for memory/power
5725 if (ActivityManager.isLowRamDeviceStatic()
5726 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) {
5727 return AppOpsManager.MODE_IGNORED;
5728 }
5729
5730 return AppOpsManager.MODE_DEFAULT;
5731 }
Chad Brubaker7c6dba62019-01-23 15:51:43 -08005732
Chad Brubaker9f394312019-02-01 10:29:39 -08005733 private static void logOperationIfNeeded(int op, String callingPackage, String proxiedPackage) {
Chad Brubaker7c6dba62019-01-23 15:51:43 -08005734 // Check if debug logging propety is enabled.
5735 if (!SystemProperties.getBoolean(DEBUG_LOGGING_ENABLE_PROP, false)) {
5736 return;
5737 }
5738 // Check if this package should be logged.
5739 String packages = SystemProperties.get(DEBUG_LOGGING_PACKAGES_PROP, "");
5740 if (!"".equals(packages) && callingPackage != null) {
5741 boolean found = false;
5742 for (String pkg : packages.split(",")) {
5743 if (callingPackage.equals(pkg)) {
5744 found = true;
5745 break;
5746 }
5747 }
5748 if (!found) {
5749 return;
5750 }
5751 }
5752 String opStr = opToName(op);
5753 // Check if this app op should be logged
5754 String logOps = SystemProperties.get(DEBUG_LOGGING_OPS_PROP, "");
5755 if (!"".equals(logOps)) {
5756 boolean found = false;
5757 for (String logOp : logOps.split(",")) {
5758 if (opStr.equals(logOp)) {
5759 found = true;
5760 break;
5761 }
5762 }
5763 if (!found) {
5764 return;
5765 }
5766 }
5767
5768 // Log a stack trace
5769 Exception here = new Exception("HERE!");
5770 android.util.Log.i(DEBUG_LOGGING_TAG, "Note operation package= " + callingPackage
Chad Brubaker9f394312019-02-01 10:29:39 -08005771 + " proxied= " + proxiedPackage + " op= " + opStr, here);
Chad Brubaker7c6dba62019-01-23 15:51:43 -08005772 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005773}