blob: aedf4b54fd3f3d030cc538065bb03d31a79ab0e4 [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;
Svet Ganov00a46ef2019-03-29 21:13:03 -070021import android.annotation.IntRange;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080022import android.annotation.NonNull;
Hai Zhangb7776682018-09-25 15:10:57 -070023import android.annotation.Nullable;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060024import android.annotation.RequiresPermission;
Jeff Davidson05542602014-08-11 14:07:27 -070025import android.annotation.SystemApi;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060026import android.annotation.SystemService;
Peter Visontay5a2a1ef2017-12-18 20:34:03 +000027import android.annotation.TestApi;
Mathew Inwood61e8ae62018-08-14 14:17:44 +010028import android.annotation.UnsupportedAppUsage;
Jeff Davidson05542602014-08-11 14:07:27 -070029import android.app.usage.UsageStatsManager;
30import android.content.Context;
Ng Zhi An65a99b62018-10-01 11:57:53 -070031import android.content.pm.PackageManager;
Svet Ganovad0a49b2018-10-29 10:07:08 -070032import android.content.pm.ParceledListSlice;
John Spurlock7b414672014-07-18 13:02:39 -040033import android.media.AudioAttributes.AttributeUsage;
Dianne Hackborne98f5db2013-07-17 17:23:25 -070034import android.os.Binder;
35import android.os.IBinder;
Dianne Hackborn35654b62013-01-14 17:38:02 -080036import android.os.Parcel;
37import android.os.Parcelable;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080038import android.os.Process;
Svet Ganov8455ba22019-01-02 13:05:56 -080039import android.os.RemoteCallback;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080040import android.os.RemoteException;
Jeff Davidson05542602014-08-11 14:07:27 -070041import android.os.UserManager;
42import android.util.ArrayMap;
Svet Ganovaf189e32019-02-15 18:45:29 -080043import android.util.LongSparseArray;
44import android.util.LongSparseLongArray;
Ng Zhi An65a99b62018-10-01 11:57:53 -070045import android.util.SparseArray;
Jeff Davidson05542602014-08-11 14:07:27 -070046
Svet Ganovb3d2ae22018-12-17 22:06:15 -080047import com.android.internal.annotations.GuardedBy;
Svet Ganov23c88db2019-01-22 20:38:11 -080048import com.android.internal.annotations.Immutable;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080049import com.android.internal.app.IAppOpsActiveCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070050import com.android.internal.app.IAppOpsCallback;
Svet Ganovb3d2ae22018-12-17 22:06:15 -080051import com.android.internal.app.IAppOpsNotedCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070052import com.android.internal.app.IAppOpsService;
Svet Ganov8455ba22019-01-02 13:05:56 -080053import com.android.internal.util.ArrayUtils;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080054import com.android.internal.util.Preconditions;
Jeff Davidson05542602014-08-11 14:07:27 -070055
Svet Ganovaf189e32019-02-15 18:45:29 -080056import java.lang.annotation.ElementType;
Svet Ganovad0a49b2018-10-29 10:07:08 -070057import java.lang.annotation.Retention;
58import java.lang.annotation.RetentionPolicy;
Svet Ganovaf189e32019-02-15 18:45:29 -080059import java.lang.annotation.Target;
Svet Ganov8455ba22019-01-02 13:05:56 -080060import java.math.BigDecimal;
61import java.math.RoundingMode;
Jeff Davidson05542602014-08-11 14:07:27 -070062import java.util.ArrayList;
Peter Visontay5a2a1ef2017-12-18 20:34:03 +000063import java.util.Arrays;
Svet Ganovad0a49b2018-10-29 10:07:08 -070064import java.util.Collections;
Jeff Davidson05542602014-08-11 14:07:27 -070065import java.util.HashMap;
66import java.util.List;
Svet Ganovaf189e32019-02-15 18:45:29 -080067import java.util.Objects;
Svet Ganov8455ba22019-01-02 13:05:56 -080068import java.util.concurrent.Executor;
69import java.util.function.Consumer;
Svet Ganovaf189e32019-02-15 18:45:29 -080070import java.util.function.Supplier;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080071
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080072/**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070073 * API for interacting with "application operation" tracking.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080074 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070075 * <p>This API is not generally intended for third party application developers; most
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060076 * features are only available to system applications.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080077 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060078@SystemService(Context.APP_OPS_SERVICE)
Dianne Hackborna06de0f2012-12-11 16:34:47 -080079public class AppOpsManager {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070080 /**
81 * <p>App ops allows callers to:</p>
82 *
83 * <ul>
84 * <li> Note when operations are happening, and find out if they are allowed for the current
85 * caller.</li>
86 * <li> Disallow specific apps from doing specific operations.</li>
87 * <li> Collect all of the current information about operations that have been executed or
88 * are not being allowed.</li>
89 * <li> Monitor for changes in whether an operation is allowed.</li>
90 * </ul>
91 *
92 * <p>Each operation is identified by a single integer; these integers are a fixed set of
93 * operations, enumerated by the OP_* constants.
94 *
95 * <p></p>When checking operations, the result is a "mode" integer indicating the current
96 * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
97 * the operation but fake its behavior enough so that the caller doesn't crash),
98 * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
99 * will do this for you).
100 */
101
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800102 final Context mContext;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800103
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100104 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800105 final IAppOpsService mService;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800106
107 @GuardedBy("mModeWatchers")
108 private final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers =
109 new ArrayMap<>();
110
111 @GuardedBy("mActiveWatchers")
112 private final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers =
113 new ArrayMap<>();
114
115 @GuardedBy("mNotedWatchers")
116 private final ArrayMap<OnOpNotedListener, IAppOpsNotedCallback> mNotedWatchers =
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -0800117 new ArrayMap<>();
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800118
Dianne Hackborne98f5db2013-07-17 17:23:25 -0700119 static IBinder sToken;
120
Svet Ganov8455ba22019-01-02 13:05:56 -0800121 /** @hide */
122 @Retention(RetentionPolicy.SOURCE)
123 @IntDef(flag = true, prefix = { "HISTORICAL_MODE_" }, value = {
124 HISTORICAL_MODE_DISABLED,
125 HISTORICAL_MODE_ENABLED_ACTIVE,
126 HISTORICAL_MODE_ENABLED_PASSIVE
127 })
128 public @interface HistoricalMode {}
129
130 /**
131 * Mode in which app op history is completely disabled.
132 * @hide
133 */
134 @TestApi
135 public static final int HISTORICAL_MODE_DISABLED = 0;
136
137 /**
138 * Mode in which app op history is enabled and app ops performed by apps would
139 * be tracked. This is the mode in which the feature is completely enabled.
140 * @hide
141 */
142 @TestApi
143 public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1;
144
145 /**
146 * Mode in which app op history is enabled but app ops performed by apps would
147 * not be tracked and the only way to add ops to the history is via explicit calls
148 * to dedicated APIs. This mode is useful for testing to allow full control of
149 * the historical content.
150 * @hide
151 */
152 @TestApi
153 public static final int HISTORICAL_MODE_ENABLED_PASSIVE = 2;
154
155 /** @hide */
156 @Retention(RetentionPolicy.SOURCE)
157 @IntDef(flag = true, prefix = { "MODE_" }, value = {
158 MODE_ALLOWED,
159 MODE_IGNORED,
160 MODE_ERRORED,
161 MODE_DEFAULT,
162 MODE_FOREGROUND
163 })
164 public @interface Mode {}
165
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700166 /**
167 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
168 * allowed to perform the given operation.
169 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800170 public static final int MODE_ALLOWED = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700171
172 /**
173 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
174 * not allowed to perform the given operation, and this attempt should
175 * <em>silently fail</em> (it should not cause the app to crash).
176 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800177 public static final int MODE_IGNORED = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700178
179 /**
180 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
181 * given caller is not allowed to perform the given operation, and this attempt should
182 * cause it to have a fatal error, typically a {@link SecurityException}.
183 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800184 public static final int MODE_ERRORED = 2;
185
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -0700186 /**
187 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
188 * use its default security check. This mode is not normally used; it should only be used
189 * with appop permissions, and callers must explicitly check for it and deal with it.
190 */
191 public static final int MODE_DEFAULT = 3;
192
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700193 /**
Dianne Hackbornc216a262018-04-26 13:46:22 -0700194 * Special mode that means "allow only when app is in foreground." This is <b>not</b>
Dianne Hackbornf8709f52019-02-04 16:31:24 -0800195 * returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}. Rather,
196 * {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always
197 * possible for it to be ultimately allowed, depending on the app's background state),
198 * and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app
199 * being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}.
200 *
201 * <p>The only place you will this normally see this value is through
202 * {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op. Note that because
203 * you can't know the current state of the app being checked (and it can change at any
204 * point), you can only treat the result here as an indication that it will vary between
205 * {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background
206 * state of the app. You thus must always use {@link #noteOp} or {@link #startOp} to do
207 * the actual check for access to the op.</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -0700208 */
209 public static final int MODE_FOREGROUND = 4;
210
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700211 /**
212 * Flag for {@link #startWatchingMode(String, String, int, OnOpChangedListener)}:
213 * Also get reports if the foreground state of an op's uid changes. This only works
214 * when watching a particular op, not when watching a package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700215 */
216 public static final int WATCH_FOREGROUND_CHANGES = 1 << 0;
Dianne Hackbornc216a262018-04-26 13:46:22 -0700217
218 /**
219 * @hide
220 */
221 public static final String[] MODE_NAMES = new String[] {
222 "allow", // MODE_ALLOWED
223 "ignore", // MODE_IGNORED
224 "deny", // MODE_ERRORED
225 "default", // MODE_DEFAULT
226 "foreground", // MODE_FOREGROUND
227 };
228
Svet Ganovad0a49b2018-10-29 10:07:08 -0700229 /** @hide */
230 @Retention(RetentionPolicy.SOURCE)
Svet Ganovaf189e32019-02-15 18:45:29 -0800231 @IntDef(prefix = { "UID_STATE_" }, value = {
Svet Ganovad0a49b2018-10-29 10:07:08 -0700232 UID_STATE_PERSISTENT,
233 UID_STATE_TOP,
Amith Yamasania0a30a12019-01-22 11:38:06 -0800234 UID_STATE_FOREGROUND_SERVICE_LOCATION,
Svet Ganovad0a49b2018-10-29 10:07:08 -0700235 UID_STATE_FOREGROUND_SERVICE,
236 UID_STATE_FOREGROUND,
237 UID_STATE_BACKGROUND,
238 UID_STATE_CACHED
239 })
240 public @interface UidState {}
241
Dianne Hackbornc216a262018-04-26 13:46:22 -0700242 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800243 * Uid state: The UID is a foreground persistent app.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700244 * @hide
245 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800246 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700247 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800248 public static final int UID_STATE_PERSISTENT = 100;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700249
250 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800251 * Uid state: The UID is top foreground app.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700252 * @hide
253 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800254 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700255 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800256 public static final int UID_STATE_TOP = 200;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700257
258 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800259 * Uid state: The UID is running a foreground service of location type.
Amith Yamasania0a30a12019-01-22 11:38:06 -0800260 * @hide
261 */
262 @TestApi
263 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800264 public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800265
266 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800267 * Uid state: The UID is running a foreground service.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700268 * @hide
269 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800270 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700271 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800272 public static final int UID_STATE_FOREGROUND_SERVICE = 400;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700273
274 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800275 * The max, which is min priority, UID state for which any app op
276 * would be considered as performed in the foreground.
Dianne Hackborne93ab412018-05-14 17:52:30 -0700277 * @hide
278 */
Svet Ganovaf189e32019-02-15 18:45:29 -0800279 public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE;
Dianne Hackborne93ab412018-05-14 17:52:30 -0700280
281 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800282 * Uid state: The UID is a foreground app.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700283 * @hide
284 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800285 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700286 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800287 public static final int UID_STATE_FOREGROUND = 500;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700288
289 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800290 * Uid state: The UID is a background app.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700291 * @hide
292 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800293 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700294 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800295 public static final int UID_STATE_BACKGROUND = 600;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700296
297 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800298 * Uid state: The UID is a cached app.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700299 * @hide
300 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800301 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700302 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800303 public static final int UID_STATE_CACHED = 700;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700304
305 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800306 * Uid state: The UID state with the highest priority.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700307 * @hide
308 */
Svet Ganovaf189e32019-02-15 18:45:29 -0800309 public static final int MAX_PRIORITY_UID_STATE = UID_STATE_PERSISTENT;
310
311 /**
312 * Uid state: The UID state with the lowest priority.
313 * @hide
314 */
315 public static final int MIN_PRIORITY_UID_STATE = UID_STATE_CACHED;
316
317 /**
318 * Resolves the first unrestricted state given an app op. Location is
319 * special as we want to allow its access only if a dedicated location
320 * foreground service is running. For other ops we consider any foreground
321 * service as a foreground state.
322 *
323 * @param op The op to resolve.
324 * @return The last restricted UID state.
325 *
326 * @hide
327 */
328 public static int resolveFirstUnrestrictedUidState(int op) {
329 switch (op) {
330 case OP_FINE_LOCATION:
Wei Wange1f864e2019-03-28 18:12:18 -0700331 case OP_COARSE_LOCATION:
332 case OP_MONITOR_LOCATION:
333 case OP_MONITOR_HIGH_POWER_LOCATION: {
Svet Ganovaf189e32019-02-15 18:45:29 -0800334 return UID_STATE_FOREGROUND_SERVICE_LOCATION;
335 }
336 }
337 return UID_STATE_FOREGROUND_SERVICE;
338 }
339
340 /**
341 * Resolves the last restricted state given an app op. Location is
342 * special as we want to allow its access only if a dedicated location
343 * foreground service is running. For other ops we consider any foreground
344 * service as a foreground state.
345 *
346 * @param op The op to resolve.
347 * @return The last restricted UID state.
348 *
349 * @hide
350 */
351 public static int resolveLastRestrictedUidState(int op) {
352 switch (op) {
353 case OP_FINE_LOCATION:
354 case OP_COARSE_LOCATION: {
355 return UID_STATE_FOREGROUND_SERVICE;
356 }
357 }
358 return UID_STATE_FOREGROUND;
359 }
360
361 /** @hide Note: Keep these sorted */
362 public static final int[] UID_STATES = {
363 UID_STATE_PERSISTENT,
364 UID_STATE_TOP,
365 UID_STATE_FOREGROUND_SERVICE_LOCATION,
366 UID_STATE_FOREGROUND_SERVICE,
367 UID_STATE_FOREGROUND,
368 UID_STATE_BACKGROUND,
369 UID_STATE_CACHED
370 };
371
372 /** @hide */
373 public static String getUidStateName(@UidState int uidState) {
374 switch (uidState) {
375 case UID_STATE_PERSISTENT:
376 return "pers";
377 case UID_STATE_TOP:
378 return "top";
379 case UID_STATE_FOREGROUND_SERVICE_LOCATION:
380 return "fgsvcl";
381 case UID_STATE_FOREGROUND_SERVICE:
382 return "fgsvc";
383 case UID_STATE_FOREGROUND:
384 return "fg";
385 case UID_STATE_BACKGROUND:
386 return "bg";
387 case UID_STATE_CACHED:
388 return "cch";
389 default:
390 return "unknown";
391 }
392 }
393
394 /**
395 * Flag: non proxy operations. These are operations
396 * performed on behalf of the app itself and not on behalf of
397 * another one.
398 *
399 * @hide
400 */
401 @TestApi
402 @SystemApi
403 public static final int OP_FLAG_SELF = 0x1;
404
405 /**
406 * Flag: trusted proxy operations. These are operations
407 * performed on behalf of another app by a trusted app.
408 * Which is work a trusted app blames on another app.
409 *
410 * @hide
411 */
412 @TestApi
413 @SystemApi
414 public static final int OP_FLAG_TRUSTED_PROXY = 0x2;
415
416 /**
417 * Flag: untrusted proxy operations. These are operations
418 * performed on behalf of another app by an untrusted app.
419 * Which is work an untrusted app blames on another app.
420 *
421 * @hide
422 */
423 @TestApi
424 @SystemApi
425 public static final int OP_FLAG_UNTRUSTED_PROXY = 0x4;
426
427 /**
428 * Flag: trusted proxied operations. These are operations
429 * performed by a trusted other app on behalf of an app.
430 * Which is work an app was blamed for by a trusted app.
431 *
432 * @hide
433 */
434 @TestApi
435 @SystemApi
436 public static final int OP_FLAG_TRUSTED_PROXIED = 0x8;
437
438 /**
439 * Flag: untrusted proxied operations. These are operations
440 * performed by an untrusted other app on behalf of an app.
441 * Which is work an app was blamed for by an untrusted app.
442 *
443 * @hide
444 */
445 @TestApi
446 @SystemApi
447 public static final int OP_FLAG_UNTRUSTED_PROXIED = 0x10;
448
449 /**
450 * Flags: all operations. These include operations matched
451 * by {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXIED},
452 * {@link #OP_FLAG_UNTRUSTED_PROXIED}, {@link #OP_FLAG_TRUSTED_PROXIED},
453 * {@link #OP_FLAG_UNTRUSTED_PROXIED}.
454 *
455 * @hide
456 */
457 @TestApi
458 @SystemApi
459 public static final int OP_FLAGS_ALL =
460 OP_FLAG_SELF
461 | OP_FLAG_TRUSTED_PROXY
462 | OP_FLAG_UNTRUSTED_PROXY
463 | OP_FLAG_TRUSTED_PROXIED
464 | OP_FLAG_UNTRUSTED_PROXIED;
465
466 /**
467 * Flags: all trusted operations which is ones either the app did {@link #OP_FLAG_SELF},
468 * or it was blamed for by a trusted app {@link #OP_FLAG_TRUSTED_PROXIED}, or ones the
469 * app if untrusted blamed on other apps {@link #OP_FLAG_UNTRUSTED_PROXY}.
470 *
471 * @hide
472 */
473 @SystemApi
474 public static final int OP_FLAGS_ALL_TRUSTED = AppOpsManager.OP_FLAG_SELF
475 | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY
476 | AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
477
478 /** @hide */
479 @Retention(RetentionPolicy.SOURCE)
480 @IntDef(flag = true, prefix = { "FLAG_" }, value = {
481 OP_FLAG_SELF,
482 OP_FLAG_TRUSTED_PROXY,
483 OP_FLAG_UNTRUSTED_PROXY,
484 OP_FLAG_TRUSTED_PROXIED,
485 OP_FLAG_UNTRUSTED_PROXIED
486 })
487 public @interface OpFlags {}
488
489
490 /** @hide */
491 public static final String getFlagName(@OpFlags int flag) {
492 switch (flag) {
493 case OP_FLAG_SELF:
494 return "s";
495 case OP_FLAG_TRUSTED_PROXY:
496 return "tp";
497 case OP_FLAG_UNTRUSTED_PROXY:
498 return "up";
499 case OP_FLAG_TRUSTED_PROXIED:
500 return "tpd";
501 case OP_FLAG_UNTRUSTED_PROXIED:
502 return "upd";
503 default:
504 return "unknown";
505 }
506 }
507
508 private static final int UID_STATE_OFFSET = 31;
509 private static final int FLAGS_MASK = 0xFFFFFFFF;
510
511 /**
512 * Key for a data bucket storing app op state. The bucket
513 * is composed of the uid state and state flags. This way
514 * we can query data for given uid state and a set of flags where
515 * the flags control which type of data to get. For example,
516 * one can get the ops an app did on behalf of other apps
517 * while in the background.
518 *
519 * @hide
520 */
521 @Retention(RetentionPolicy.SOURCE)
522 @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
523 public @interface DataBucketKey {
524 }
525
526 /** @hide */
527 public static String keyToString(@DataBucketKey long key) {
528 final int uidState = extractUidStateFromKey(key);
529 final int flags = extractFlagsFromKey(key);
530 return "[" + getUidStateName(uidState) + "-" + flagsToString(flags) + "]";
531 }
532
533 /** @hide */
534 public static @DataBucketKey long makeKey(@UidState int uidState, @OpFlags int flags) {
535 return ((long) uidState << UID_STATE_OFFSET) | flags;
536 }
537
538 /** @hide */
539 public static int extractUidStateFromKey(@DataBucketKey long key) {
540 return (int) (key >> UID_STATE_OFFSET);
541 }
542
543 /** @hide */
544 public static int extractFlagsFromKey(@DataBucketKey long key) {
545 return (int) (key & FLAGS_MASK);
546 }
547
548 /** @hide */
549 public static String flagsToString(@OpFlags int flags) {
550 final StringBuilder flagsBuilder = new StringBuilder();
551 while (flags != 0) {
552 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
553 flags &= ~flag;
554 if (flagsBuilder.length() > 0) {
555 flagsBuilder.append('|');
556 }
557 flagsBuilder.append(getFlagName(flag));
558 }
559 return flagsBuilder.toString();
560 }
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700561
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500562 // when adding one of these:
563 // - increment _NUM_OP
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000564 // - define an OPSTR_* constant (marked as @SystemApi)
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700565 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500566 // - add descriptive strings to Settings/res/values/arrays.xml
David Christie0b837452013-07-29 16:02:13 -0700567 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700568
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700569 /** @hide No operation specified. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100570 @UnsupportedAppUsage
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800571 public static final int OP_NONE = -1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700572 /** @hide Access to coarse location information. */
Artur Satayev5a525852019-10-31 15:15:50 +0000573 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -0800574 @TestApi
Dianne Hackborn35654b62013-01-14 17:38:02 -0800575 public static final int OP_COARSE_LOCATION = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700576 /** @hide Access to fine location information. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100577 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800578 public static final int OP_FINE_LOCATION = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700579 /** @hide Causing GPS to run. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100580 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800581 public static final int OP_GPS = 2;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800582 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100583 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700584 public static final int OP_VIBRATE = 3;
585 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100586 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700587 public static final int OP_READ_CONTACTS = 4;
588 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100589 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700590 public static final int OP_WRITE_CONTACTS = 5;
591 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100592 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700593 public static final int OP_READ_CALL_LOG = 6;
594 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100595 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700596 public static final int OP_WRITE_CALL_LOG = 7;
597 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100598 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700599 public static final int OP_READ_CALENDAR = 8;
600 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100601 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700602 public static final int OP_WRITE_CALENDAR = 9;
603 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100604 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700605 public static final int OP_WIFI_SCAN = 10;
606 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100607 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700608 public static final int OP_POST_NOTIFICATION = 11;
609 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100610 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700611 public static final int OP_NEIGHBORING_CELLS = 12;
612 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100613 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700614 public static final int OP_CALL_PHONE = 13;
615 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100616 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700617 public static final int OP_READ_SMS = 14;
618 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100619 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700620 public static final int OP_WRITE_SMS = 15;
621 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100622 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700623 public static final int OP_RECEIVE_SMS = 16;
624 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100625 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700626 public static final int OP_RECEIVE_EMERGECY_SMS = 17;
627 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100628 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700629 public static final int OP_RECEIVE_MMS = 18;
630 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100631 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700632 public static final int OP_RECEIVE_WAP_PUSH = 19;
633 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100634 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700635 public static final int OP_SEND_SMS = 20;
636 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100637 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700638 public static final int OP_READ_ICC_SMS = 21;
639 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100640 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700641 public static final int OP_WRITE_ICC_SMS = 22;
642 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100643 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700644 public static final int OP_WRITE_SETTINGS = 23;
Peter Visontay96449f62017-12-11 18:50:03 +0000645 /** @hide Required to draw on top of other apps. */
Artur Satayev5a525852019-10-31 15:15:50 +0000646 @UnsupportedAppUsage
Svet Ganovf7b47252018-02-26 11:11:27 -0800647 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700648 public static final int OP_SYSTEM_ALERT_WINDOW = 24;
649 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100650 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700651 public static final int OP_ACCESS_NOTIFICATIONS = 25;
652 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100653 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700654 public static final int OP_CAMERA = 26;
655 /** @hide */
Artur Satayev5a525852019-10-31 15:15:50 +0000656 @UnsupportedAppUsage
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. */
Artur Satayev5a525852019-10-31 15:15:50 +0000804 @UnsupportedAppUsage
Svet Ganovaf189e32019-02-15 18:45:29 -0800805 @TestApi
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700806 public static final int OP_START_FOREGROUND = 76;
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800807 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100808 @UnsupportedAppUsage
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700809 public static final int OP_BLUETOOTH_SCAN = 77;
Kevin Chynb3c05aa2018-09-21 16:50:32 -0700810 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
811 public static final int OP_USE_BIOMETRIC = 78;
Zimuzo6cbf9cc2018-10-05 12:05:58 +0100812 /** @hide Physical activity recognition. */
813 public static final int OP_ACTIVITY_RECOGNITION = 79;
Hongming Jin228cd012018-11-09 14:47:50 -0800814 /** @hide Financial app sms read. */
815 public static final int OP_SMS_FINANCIAL_TRANSACTIONS = 80;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -0700816 /** @hide Read media of audio type. */
817 public static final int OP_READ_MEDIA_AUDIO = 81;
818 /** @hide Write media of audio type. */
819 public static final int OP_WRITE_MEDIA_AUDIO = 82;
820 /** @hide Read media of video type. */
821 public static final int OP_READ_MEDIA_VIDEO = 83;
822 /** @hide Write media of video type. */
823 public static final int OP_WRITE_MEDIA_VIDEO = 84;
824 /** @hide Read media of image type. */
825 public static final int OP_READ_MEDIA_IMAGES = 85;
826 /** @hide Write media of image type. */
827 public static final int OP_WRITE_MEDIA_IMAGES = 86;
Jeff Sharkeye82cbb12018-12-06 15:53:11 -0700828 /** @hide Has a legacy (non-isolated) view of storage. */
829 public static final int OP_LEGACY_STORAGE = 87;
Jackal Guo8dc791e2019-01-14 10:26:42 +0800830 /** @hide Accessing accessibility features */
831 public static final int OP_ACCESS_ACCESSIBILITY = 88;
Michael Groover656ef912019-04-09 17:09:57 -0700832 /** @hide Read the device identifiers (IMEI / MEID, IMSI, SIM / Build serial) */
833 public static final int OP_READ_DEVICE_IDENTIFIERS = 89;
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700834 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100835 @UnsupportedAppUsage
Michael Groover656ef912019-04-09 17:09:57 -0700836 public static final int _NUM_OP = 90;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800837
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700838 /** Access to coarse location information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700839 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700840 /** Access to fine location information. */
841 public static final String OPSTR_FINE_LOCATION =
842 "android:fine_location";
843 /** Continually monitoring location data. */
844 public static final String OPSTR_MONITOR_LOCATION
845 = "android:monitor_location";
846 /** Continually monitoring location data with a relatively high power request. */
847 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
848 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700849 /** Access to {@link android.app.usage.UsageStatsManager}. */
850 public static final String OPSTR_GET_USAGE_STATS
851 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700852 /** Activate a VPN connection without user intervention. @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000853 @SystemApi @TestApi
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700854 public static final String OPSTR_ACTIVATE_VPN
855 = "android:activate_vpn";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700856 /** Allows an application to read the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700857 public static final String OPSTR_READ_CONTACTS
858 = "android:read_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700859 /** Allows an application to write to the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700860 public static final String OPSTR_WRITE_CONTACTS
861 = "android:write_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700862 /** Allows an application to read the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700863 public static final String OPSTR_READ_CALL_LOG
864 = "android:read_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700865 /** Allows an application to write to the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700866 public static final String OPSTR_WRITE_CALL_LOG
867 = "android:write_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700868 /** Allows an application to read the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700869 public static final String OPSTR_READ_CALENDAR
870 = "android:read_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700871 /** Allows an application to write to the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700872 public static final String OPSTR_WRITE_CALENDAR
873 = "android:write_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700874 /** Allows an application to initiate a phone call. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700875 public static final String OPSTR_CALL_PHONE
876 = "android:call_phone";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700877 /** Allows an application to read SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700878 public static final String OPSTR_READ_SMS
879 = "android:read_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700880 /** Allows an application to receive SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700881 public static final String OPSTR_RECEIVE_SMS
882 = "android:receive_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700883 /** Allows an application to receive MMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700884 public static final String OPSTR_RECEIVE_MMS
885 = "android:receive_mms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700886 /** Allows an application to receive WAP push messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700887 public static final String OPSTR_RECEIVE_WAP_PUSH
888 = "android:receive_wap_push";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700889 /** Allows an application to send SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700890 public static final String OPSTR_SEND_SMS
891 = "android:send_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700892 /** Required to be able to access the camera device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700893 public static final String OPSTR_CAMERA
894 = "android:camera";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700895 /** Required to be able to access the microphone device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700896 public static final String OPSTR_RECORD_AUDIO
897 = "android:record_audio";
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_READ_PHONE_STATE
900 = "android:read_phone_state";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700901 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700902 public static final String OPSTR_ADD_VOICEMAIL
903 = "android:add_voicemail";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700904 /** Access APIs for SIP calling over VOIP or WiFi */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700905 public static final String OPSTR_USE_SIP
906 = "android:use_sip";
Svet Ganove8e89422016-09-22 19:56:50 -0700907 /** Access APIs for diverting outgoing calls */
Svet Ganov824ad6e2016-09-22 19:36:53 -0700908 public static final String OPSTR_PROCESS_OUTGOING_CALLS
909 = "android:process_outgoing_calls";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700910 /** Use the fingerprint API. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700911 public static final String OPSTR_USE_FINGERPRINT
912 = "android:use_fingerprint";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700913 /** Access to body sensors such as heart rate, etc. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700914 public static final String OPSTR_BODY_SENSORS
915 = "android:body_sensors";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700916 /** Read previously received cell broadcast messages. */
Svet Ganovede43162015-05-02 17:42:44 -0700917 public static final String OPSTR_READ_CELL_BROADCASTS
918 = "android:read_cell_broadcasts";
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700919 /** Inject mock location into the system. */
920 public static final String OPSTR_MOCK_LOCATION
921 = "android:mock_location";
Svet Ganov921c7df2015-06-29 21:51:41 -0700922 /** Read external storage. */
923 public static final String OPSTR_READ_EXTERNAL_STORAGE
924 = "android:read_external_storage";
925 /** Write external storage. */
926 public static final String OPSTR_WRITE_EXTERNAL_STORAGE
927 = "android:write_external_storage";
Billy Lau24b9c832015-07-20 17:34:09 +0100928 /** Required to draw on top of other apps. */
929 public static final String OPSTR_SYSTEM_ALERT_WINDOW
930 = "android:system_alert_window";
931 /** Required to write/modify/update system settingss. */
932 public static final String OPSTR_WRITE_SETTINGS
933 = "android:write_settings";
Svetoslavf3f02ac2015-09-08 14:36:35 -0700934 /** @hide Get device accounts. */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000935 @SystemApi @TestApi
Svetoslavf3f02ac2015-09-08 14:36:35 -0700936 public static final String OPSTR_GET_ACCOUNTS
937 = "android:get_accounts";
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700938 public static final String OPSTR_READ_PHONE_NUMBERS
939 = "android:read_phone_numbers";
Winson Chungf4ac0632017-03-17 12:34:12 -0700940 /** Access to picture-in-picture. */
941 public static final String OPSTR_PICTURE_IN_PICTURE
942 = "android:picture_in_picture";
Chad Brubaker97b383f2017-02-02 15:04:35 -0800943 /** @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000944 @SystemApi @TestApi
Chad Brubaker97b383f2017-02-02 15:04:35 -0800945 public static final String OPSTR_INSTANT_APP_START_FOREGROUND
946 = "android:instant_app_start_foreground";
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800947 /** Answer incoming phone calls */
948 public static final String OPSTR_ANSWER_PHONE_CALLS
949 = "android:answer_phone_calls";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800950 /**
951 * Accept call handover
952 * @hide
953 */
954 @SystemApi @TestApi
955 public static final String OPSTR_ACCEPT_HANDOVER
956 = "android:accept_handover";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000957 /** @hide */
958 @SystemApi @TestApi
959 public static final String OPSTR_GPS = "android:gps";
960 /** @hide */
961 @SystemApi @TestApi
962 public static final String OPSTR_VIBRATE = "android:vibrate";
963 /** @hide */
964 @SystemApi @TestApi
965 public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
966 /** @hide */
967 @SystemApi @TestApi
968 public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
969 /** @hide */
970 @SystemApi @TestApi
971 public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
972 /** @hide */
973 @SystemApi @TestApi
974 public static final String OPSTR_WRITE_SMS = "android:write_sms";
975 /** @hide */
976 @SystemApi @TestApi
977 public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST =
978 "android:receive_emergency_broadcast";
979 /** @hide */
980 @SystemApi @TestApi
981 public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
982 /** @hide */
983 @SystemApi @TestApi
984 public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
985 /** @hide */
986 @SystemApi @TestApi
987 public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
988 /** @hide */
989 @SystemApi @TestApi
990 public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
991 /** @hide */
992 @SystemApi @TestApi
993 public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
994 /** @hide */
995 @SystemApi @TestApi
996 public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
997 /** @hide */
998 @SystemApi @TestApi
999 public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
1000 /** @hide */
1001 @SystemApi @TestApi
1002 public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
1003 /** @hide */
1004 @SystemApi @TestApi
1005 public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
1006 /** @hide */
1007 @SystemApi @TestApi
1008 public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
1009 /** @hide */
1010 @SystemApi @TestApi
1011 public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
1012 /** @hide */
1013 @SystemApi @TestApi
1014 public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
1015 /** @hide */
1016 @SystemApi @TestApi
1017 public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
1018 /** @hide */
1019 @SystemApi @TestApi
1020 public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME =
1021 "android:audio_notification_volume";
1022 /** @hide */
1023 @SystemApi @TestApi
1024 public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
1025 /** @hide */
1026 @SystemApi @TestApi
1027 public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
1028 /** @hide */
1029 @SystemApi @TestApi
1030 public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
1031 /** @hide */
1032 @SystemApi @TestApi
1033 public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
1034 /** @hide */
1035 @SystemApi @TestApi
1036 public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
1037 /** @hide */
1038 @SystemApi @TestApi
1039 public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
1040 /** @hide */
1041 @SystemApi @TestApi
1042 public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
1043 /** @hide */
1044 @SystemApi @TestApi
1045 public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
1046 /** @hide */
1047 @SystemApi @TestApi
1048 public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
1049 /** @hide */
1050 @SystemApi @TestApi
1051 public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
1052 /** @hide */
1053 @SystemApi @TestApi
1054 public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME =
1055 "android:audio_accessibility_volume";
1056 /** @hide */
1057 @SystemApi @TestApi
1058 public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
1059 /** @hide */
1060 @SystemApi @TestApi
1061 public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
1062 /** @hide */
1063 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001064 public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
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_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001068 /** @hide */
1069 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001070 public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE =
1071 "android:bind_accessibility_service";
Nathan Harold1bb420672018-03-14 17:08:53 -07001072 /** @hide */
1073 @SystemApi @TestApi
1074 public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001075 /** @hide */
1076 @SystemApi @TestApi
1077 public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001078 /** @hide */
1079 public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001080
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001081 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
1082 public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001083
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001084 /** @hide Recognize physical activity. */
1085 public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition";
1086
Hongming Jin228cd012018-11-09 14:47:50 -08001087 /** @hide Financial app read sms. */
1088 public static final String OPSTR_SMS_FINANCIAL_TRANSACTIONS =
1089 "android:sms_financial_transactions";
1090
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001091 /** @hide Read media of audio type. */
1092 public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
1093 /** @hide Write media of audio type. */
1094 public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
1095 /** @hide Read media of video type. */
1096 public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
1097 /** @hide Write media of video type. */
1098 public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
1099 /** @hide Read media of image type. */
1100 public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
1101 /** @hide Write media of image type. */
1102 public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001103 /** @hide Has a legacy (non-isolated) view of storage. */
Philip P. Moltmannc94ba822019-03-04 16:48:22 -08001104 @TestApi
1105 @SystemApi
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001106 public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
Jackal Guo8dc791e2019-01-14 10:26:42 +08001107 /** @hide Interact with accessibility. */
Joel Galensonff4fe202019-02-06 14:43:58 -08001108 @SystemApi
Jackal Guo8dc791e2019-01-14 10:26:42 +08001109 public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
Michael Groover656ef912019-04-09 17:09:57 -07001110 /** @hide Read device identifiers */
1111 public static final String OPSTR_READ_DEVICE_IDENTIFIERS = "android:read_device_identifiers";
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001112
Philip P. Moltmanne56c08e2017-03-15 12:46:04 -07001113 // Warning: If an permission is added here it also has to be added to
1114 // com.android.packageinstaller.permission.utils.EventLogger
Svet Ganovda0acdf2017-02-15 10:28:51 -08001115 private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
1116 // RUNTIME PERMISSIONS
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001117 // Contacts
1118 OP_READ_CONTACTS,
1119 OP_WRITE_CONTACTS,
1120 OP_GET_ACCOUNTS,
1121 // Calendar
1122 OP_READ_CALENDAR,
1123 OP_WRITE_CALENDAR,
1124 // SMS
1125 OP_SEND_SMS,
1126 OP_RECEIVE_SMS,
1127 OP_READ_SMS,
1128 OP_RECEIVE_WAP_PUSH,
1129 OP_RECEIVE_MMS,
1130 OP_READ_CELL_BROADCASTS,
1131 // Storage
1132 OP_READ_EXTERNAL_STORAGE,
1133 OP_WRITE_EXTERNAL_STORAGE,
1134 // Location
1135 OP_COARSE_LOCATION,
1136 OP_FINE_LOCATION,
1137 // Phone
1138 OP_READ_PHONE_STATE,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001139 OP_READ_PHONE_NUMBERS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001140 OP_CALL_PHONE,
1141 OP_READ_CALL_LOG,
1142 OP_WRITE_CALL_LOG,
1143 OP_ADD_VOICEMAIL,
1144 OP_USE_SIP,
1145 OP_PROCESS_OUTGOING_CALLS,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001146 OP_ANSWER_PHONE_CALLS,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001147 OP_ACCEPT_HANDOVER,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001148 // Microphone
1149 OP_RECORD_AUDIO,
1150 // Camera
1151 OP_CAMERA,
1152 // Body sensors
Svet Ganovda0acdf2017-02-15 10:28:51 -08001153 OP_BODY_SENSORS,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001154 // Activity recognition
1155 OP_ACTIVITY_RECOGNITION,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001156 // Aural
1157 OP_READ_MEDIA_AUDIO,
1158 OP_WRITE_MEDIA_AUDIO,
1159 // Visual
1160 OP_READ_MEDIA_VIDEO,
1161 OP_WRITE_MEDIA_VIDEO,
1162 OP_READ_MEDIA_IMAGES,
1163 OP_WRITE_MEDIA_IMAGES,
Svet Ganovda0acdf2017-02-15 10:28:51 -08001164
1165 // APPOP PERMISSIONS
1166 OP_ACCESS_NOTIFICATIONS,
1167 OP_SYSTEM_ALERT_WINDOW,
1168 OP_WRITE_SETTINGS,
1169 OP_REQUEST_INSTALL_PACKAGES,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001170 OP_START_FOREGROUND,
Hongming Jin228cd012018-11-09 14:47:50 -08001171 OP_SMS_FINANCIAL_TRANSACTIONS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001172 };
1173
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001174 /**
1175 * This maps each operation to the operation that serves as the
1176 * switch to determine whether it is allowed. Generally this is
1177 * a 1:1 mapping, but for some things (like location) that have
1178 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -07001179 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001180 * make them all controlled by the same single operation.
1181 */
1182 private static int[] sOpToSwitch = new int[] {
Dianne Hackbornc216a262018-04-26 13:46:22 -07001183 OP_COARSE_LOCATION, // COARSE_LOCATION
1184 OP_COARSE_LOCATION, // FINE_LOCATION
1185 OP_COARSE_LOCATION, // GPS
1186 OP_VIBRATE, // VIBRATE
1187 OP_READ_CONTACTS, // READ_CONTACTS
1188 OP_WRITE_CONTACTS, // WRITE_CONTACTS
1189 OP_READ_CALL_LOG, // READ_CALL_LOG
1190 OP_WRITE_CALL_LOG, // WRITE_CALL_LOG
1191 OP_READ_CALENDAR, // READ_CALENDAR
1192 OP_WRITE_CALENDAR, // WRITE_CALENDAR
1193 OP_COARSE_LOCATION, // WIFI_SCAN
1194 OP_POST_NOTIFICATION, // POST_NOTIFICATION
1195 OP_COARSE_LOCATION, // NEIGHBORING_CELLS
1196 OP_CALL_PHONE, // CALL_PHONE
1197 OP_READ_SMS, // READ_SMS
1198 OP_WRITE_SMS, // WRITE_SMS
1199 OP_RECEIVE_SMS, // RECEIVE_SMS
1200 OP_RECEIVE_SMS, // RECEIVE_EMERGECY_SMS
1201 OP_RECEIVE_MMS, // RECEIVE_MMS
1202 OP_RECEIVE_WAP_PUSH, // RECEIVE_WAP_PUSH
1203 OP_SEND_SMS, // SEND_SMS
1204 OP_READ_SMS, // READ_ICC_SMS
1205 OP_WRITE_SMS, // WRITE_ICC_SMS
1206 OP_WRITE_SETTINGS, // WRITE_SETTINGS
1207 OP_SYSTEM_ALERT_WINDOW, // SYSTEM_ALERT_WINDOW
1208 OP_ACCESS_NOTIFICATIONS, // ACCESS_NOTIFICATIONS
1209 OP_CAMERA, // CAMERA
1210 OP_RECORD_AUDIO, // RECORD_AUDIO
1211 OP_PLAY_AUDIO, // PLAY_AUDIO
1212 OP_READ_CLIPBOARD, // READ_CLIPBOARD
1213 OP_WRITE_CLIPBOARD, // WRITE_CLIPBOARD
1214 OP_TAKE_MEDIA_BUTTONS, // TAKE_MEDIA_BUTTONS
1215 OP_TAKE_AUDIO_FOCUS, // TAKE_AUDIO_FOCUS
1216 OP_AUDIO_MASTER_VOLUME, // AUDIO_MASTER_VOLUME
1217 OP_AUDIO_VOICE_VOLUME, // AUDIO_VOICE_VOLUME
1218 OP_AUDIO_RING_VOLUME, // AUDIO_RING_VOLUME
1219 OP_AUDIO_MEDIA_VOLUME, // AUDIO_MEDIA_VOLUME
1220 OP_AUDIO_ALARM_VOLUME, // AUDIO_ALARM_VOLUME
1221 OP_AUDIO_NOTIFICATION_VOLUME, // AUDIO_NOTIFICATION_VOLUME
1222 OP_AUDIO_BLUETOOTH_VOLUME, // AUDIO_BLUETOOTH_VOLUME
1223 OP_WAKE_LOCK, // WAKE_LOCK
1224 OP_COARSE_LOCATION, // MONITOR_LOCATION
1225 OP_COARSE_LOCATION, // MONITOR_HIGH_POWER_LOCATION
1226 OP_GET_USAGE_STATS, // GET_USAGE_STATS
1227 OP_MUTE_MICROPHONE, // MUTE_MICROPHONE
1228 OP_TOAST_WINDOW, // TOAST_WINDOW
1229 OP_PROJECT_MEDIA, // PROJECT_MEDIA
1230 OP_ACTIVATE_VPN, // ACTIVATE_VPN
1231 OP_WRITE_WALLPAPER, // WRITE_WALLPAPER
1232 OP_ASSIST_STRUCTURE, // ASSIST_STRUCTURE
1233 OP_ASSIST_SCREENSHOT, // ASSIST_SCREENSHOT
1234 OP_READ_PHONE_STATE, // READ_PHONE_STATE
1235 OP_ADD_VOICEMAIL, // ADD_VOICEMAIL
1236 OP_USE_SIP, // USE_SIP
1237 OP_PROCESS_OUTGOING_CALLS, // PROCESS_OUTGOING_CALLS
1238 OP_USE_FINGERPRINT, // USE_FINGERPRINT
1239 OP_BODY_SENSORS, // BODY_SENSORS
1240 OP_READ_CELL_BROADCASTS, // READ_CELL_BROADCASTS
1241 OP_MOCK_LOCATION, // MOCK_LOCATION
1242 OP_READ_EXTERNAL_STORAGE, // READ_EXTERNAL_STORAGE
1243 OP_WRITE_EXTERNAL_STORAGE, // WRITE_EXTERNAL_STORAGE
1244 OP_TURN_SCREEN_ON, // TURN_SCREEN_ON
1245 OP_GET_ACCOUNTS, // GET_ACCOUNTS
1246 OP_RUN_IN_BACKGROUND, // RUN_IN_BACKGROUND
1247 OP_AUDIO_ACCESSIBILITY_VOLUME, // AUDIO_ACCESSIBILITY_VOLUME
1248 OP_READ_PHONE_NUMBERS, // READ_PHONE_NUMBERS
1249 OP_REQUEST_INSTALL_PACKAGES, // REQUEST_INSTALL_PACKAGES
1250 OP_PICTURE_IN_PICTURE, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
1251 OP_INSTANT_APP_START_FOREGROUND, // INSTANT_APP_START_FOREGROUND
1252 OP_ANSWER_PHONE_CALLS, // ANSWER_PHONE_CALLS
1253 OP_RUN_ANY_IN_BACKGROUND, // OP_RUN_ANY_IN_BACKGROUND
1254 OP_CHANGE_WIFI_STATE, // OP_CHANGE_WIFI_STATE
1255 OP_REQUEST_DELETE_PACKAGES, // OP_REQUEST_DELETE_PACKAGES
1256 OP_BIND_ACCESSIBILITY_SERVICE, // OP_BIND_ACCESSIBILITY_SERVICE
1257 OP_ACCEPT_HANDOVER, // ACCEPT_HANDOVER
1258 OP_MANAGE_IPSEC_TUNNELS, // MANAGE_IPSEC_HANDOVERS
1259 OP_START_FOREGROUND, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001260 OP_COARSE_LOCATION, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001261 OP_USE_BIOMETRIC, // BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001262 OP_ACTIVITY_RECOGNITION, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001263 OP_SMS_FINANCIAL_TRANSACTIONS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001264 OP_READ_MEDIA_AUDIO, // READ_MEDIA_AUDIO
1265 OP_WRITE_MEDIA_AUDIO, // WRITE_MEDIA_AUDIO
1266 OP_READ_MEDIA_VIDEO, // READ_MEDIA_VIDEO
1267 OP_WRITE_MEDIA_VIDEO, // WRITE_MEDIA_VIDEO
1268 OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES
1269 OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001270 OP_LEGACY_STORAGE, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001271 OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001272 OP_READ_DEVICE_IDENTIFIERS, // READ_DEVICE_IDENTIFIERS
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001273 };
1274
1275 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001276 * This maps each operation to the public string constant for it.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001277 */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001278 private static String[] sOpToString = new String[]{
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001279 OPSTR_COARSE_LOCATION,
1280 OPSTR_FINE_LOCATION,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001281 OPSTR_GPS,
1282 OPSTR_VIBRATE,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001283 OPSTR_READ_CONTACTS,
1284 OPSTR_WRITE_CONTACTS,
1285 OPSTR_READ_CALL_LOG,
1286 OPSTR_WRITE_CALL_LOG,
1287 OPSTR_READ_CALENDAR,
1288 OPSTR_WRITE_CALENDAR,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001289 OPSTR_WIFI_SCAN,
1290 OPSTR_POST_NOTIFICATION,
1291 OPSTR_NEIGHBORING_CELLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001292 OPSTR_CALL_PHONE,
1293 OPSTR_READ_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001294 OPSTR_WRITE_SMS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001295 OPSTR_RECEIVE_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001296 OPSTR_RECEIVE_EMERGENCY_BROADCAST,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001297 OPSTR_RECEIVE_MMS,
1298 OPSTR_RECEIVE_WAP_PUSH,
1299 OPSTR_SEND_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001300 OPSTR_READ_ICC_SMS,
1301 OPSTR_WRITE_ICC_SMS,
Billy Lau24b9c832015-07-20 17:34:09 +01001302 OPSTR_WRITE_SETTINGS,
1303 OPSTR_SYSTEM_ALERT_WINDOW,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001304 OPSTR_ACCESS_NOTIFICATIONS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001305 OPSTR_CAMERA,
1306 OPSTR_RECORD_AUDIO,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001307 OPSTR_PLAY_AUDIO,
1308 OPSTR_READ_CLIPBOARD,
1309 OPSTR_WRITE_CLIPBOARD,
1310 OPSTR_TAKE_MEDIA_BUTTONS,
1311 OPSTR_TAKE_AUDIO_FOCUS,
1312 OPSTR_AUDIO_MASTER_VOLUME,
1313 OPSTR_AUDIO_VOICE_VOLUME,
1314 OPSTR_AUDIO_RING_VOLUME,
1315 OPSTR_AUDIO_MEDIA_VOLUME,
1316 OPSTR_AUDIO_ALARM_VOLUME,
1317 OPSTR_AUDIO_NOTIFICATION_VOLUME,
1318 OPSTR_AUDIO_BLUETOOTH_VOLUME,
1319 OPSTR_WAKE_LOCK,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001320 OPSTR_MONITOR_LOCATION,
1321 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -07001322 OPSTR_GET_USAGE_STATS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001323 OPSTR_MUTE_MICROPHONE,
1324 OPSTR_TOAST_WINDOW,
1325 OPSTR_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -07001326 OPSTR_ACTIVATE_VPN,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001327 OPSTR_WRITE_WALLPAPER,
1328 OPSTR_ASSIST_STRUCTURE,
1329 OPSTR_ASSIST_SCREENSHOT,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001330 OPSTR_READ_PHONE_STATE,
1331 OPSTR_ADD_VOICEMAIL,
1332 OPSTR_USE_SIP,
Svet Ganov824ad6e2016-09-22 19:36:53 -07001333 OPSTR_PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001334 OPSTR_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001335 OPSTR_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001336 OPSTR_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001337 OPSTR_MOCK_LOCATION,
1338 OPSTR_READ_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001339 OPSTR_WRITE_EXTERNAL_STORAGE,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001340 OPSTR_TURN_SCREEN_ON,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001341 OPSTR_GET_ACCOUNTS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001342 OPSTR_RUN_IN_BACKGROUND,
1343 OPSTR_AUDIO_ACCESSIBILITY_VOLUME,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001344 OPSTR_READ_PHONE_NUMBERS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001345 OPSTR_REQUEST_INSTALL_PACKAGES,
Winson Chungf4ac0632017-03-17 12:34:12 -07001346 OPSTR_PICTURE_IN_PICTURE,
Chad Brubaker97b383f2017-02-02 15:04:35 -08001347 OPSTR_INSTANT_APP_START_FOREGROUND,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001348 OPSTR_ANSWER_PHONE_CALLS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001349 OPSTR_RUN_ANY_IN_BACKGROUND,
1350 OPSTR_CHANGE_WIFI_STATE,
1351 OPSTR_REQUEST_DELETE_PACKAGES,
1352 OPSTR_BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001353 OPSTR_ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001354 OPSTR_MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001355 OPSTR_START_FOREGROUND,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001356 OPSTR_BLUETOOTH_SCAN,
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001357 OPSTR_USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001358 OPSTR_ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001359 OPSTR_SMS_FINANCIAL_TRANSACTIONS,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001360 OPSTR_READ_MEDIA_AUDIO,
1361 OPSTR_WRITE_MEDIA_AUDIO,
1362 OPSTR_READ_MEDIA_VIDEO,
1363 OPSTR_WRITE_MEDIA_VIDEO,
1364 OPSTR_READ_MEDIA_IMAGES,
1365 OPSTR_WRITE_MEDIA_IMAGES,
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001366 OPSTR_LEGACY_STORAGE,
Jackal Guo8dc791e2019-01-14 10:26:42 +08001367 OPSTR_ACCESS_ACCESSIBILITY,
Michael Groover656ef912019-04-09 17:09:57 -07001368 OPSTR_READ_DEVICE_IDENTIFIERS,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001369 };
1370
1371 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001372 * This provides a simple name for each operation to be used
1373 * in debug output.
1374 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001375 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001376 "COARSE_LOCATION",
1377 "FINE_LOCATION",
1378 "GPS",
1379 "VIBRATE",
1380 "READ_CONTACTS",
1381 "WRITE_CONTACTS",
1382 "READ_CALL_LOG",
1383 "WRITE_CALL_LOG",
1384 "READ_CALENDAR",
1385 "WRITE_CALENDAR",
1386 "WIFI_SCAN",
1387 "POST_NOTIFICATION",
1388 "NEIGHBORING_CELLS",
1389 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001390 "READ_SMS",
1391 "WRITE_SMS",
1392 "RECEIVE_SMS",
1393 "RECEIVE_EMERGECY_SMS",
1394 "RECEIVE_MMS",
1395 "RECEIVE_WAP_PUSH",
1396 "SEND_SMS",
1397 "READ_ICC_SMS",
1398 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -08001399 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -08001400 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001401 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001402 "CAMERA",
1403 "RECORD_AUDIO",
1404 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001405 "READ_CLIPBOARD",
1406 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001407 "TAKE_MEDIA_BUTTONS",
1408 "TAKE_AUDIO_FOCUS",
1409 "AUDIO_MASTER_VOLUME",
1410 "AUDIO_VOICE_VOLUME",
1411 "AUDIO_RING_VOLUME",
1412 "AUDIO_MEDIA_VOLUME",
1413 "AUDIO_ALARM_VOLUME",
1414 "AUDIO_NOTIFICATION_VOLUME",
1415 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -07001416 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001417 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -07001418 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -04001419 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001420 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -04001421 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001422 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -07001423 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +00001424 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001425 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -07001426 "ASSIST_SCREENSHOT",
Eugene Suslae4ee2c22018-11-05 12:23:30 -08001427 "READ_PHONE_STATE",
Svetoslav5335b672015-04-29 12:00:51 -07001428 "ADD_VOICEMAIL",
Svetoslavc656e6f2015-04-29 14:08:16 -07001429 "USE_SIP",
Svetoslav4af76a52015-04-29 15:29:46 -07001430 "PROCESS_OUTGOING_CALLS",
Svet Ganovb9d71a62015-04-30 10:38:13 -07001431 "USE_FINGERPRINT",
Svet Ganovede43162015-05-02 17:42:44 -07001432 "BODY_SENSORS",
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001433 "READ_CELL_BROADCASTS",
Svet Ganov921c7df2015-06-29 21:51:41 -07001434 "MOCK_LOCATION",
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001435 "READ_EXTERNAL_STORAGE",
1436 "WRITE_EXTERNAL_STORAGE",
1437 "TURN_ON_SCREEN",
Svetoslavf3f02ac2015-09-08 14:36:35 -07001438 "GET_ACCOUNTS",
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001439 "RUN_IN_BACKGROUND",
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001440 "AUDIO_ACCESSIBILITY_VOLUME",
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001441 "READ_PHONE_NUMBERS",
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001442 "REQUEST_INSTALL_PACKAGES",
Winson Chungf4ac0632017-03-17 12:34:12 -07001443 "PICTURE_IN_PICTURE",
Chad Brubaker97b383f2017-02-02 15:04:35 -08001444 "INSTANT_APP_START_FOREGROUND",
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001445 "ANSWER_PHONE_CALLS",
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001446 "RUN_ANY_IN_BACKGROUND",
Peter Visontay1246d9e2017-10-17 17:02:45 +01001447 "CHANGE_WIFI_STATE",
Peter Visontayf2e38362017-11-27 15:27:16 +00001448 "REQUEST_DELETE_PACKAGES",
Peter Visontay11950832017-11-14 19:34:59 +00001449 "BIND_ACCESSIBILITY_SERVICE",
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001450 "ACCEPT_HANDOVER",
Nathan Harold1bb420672018-03-14 17:08:53 -07001451 "MANAGE_IPSEC_TUNNELS",
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001452 "START_FOREGROUND",
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001453 "BLUETOOTH_SCAN",
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001454 "USE_BIOMETRIC",
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001455 "ACTIVITY_RECOGNITION",
Hongming Jin228cd012018-11-09 14:47:50 -08001456 "SMS_FINANCIAL_TRANSACTIONS",
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001457 "READ_MEDIA_AUDIO",
1458 "WRITE_MEDIA_AUDIO",
1459 "READ_MEDIA_VIDEO",
1460 "WRITE_MEDIA_VIDEO",
1461 "READ_MEDIA_IMAGES",
1462 "WRITE_MEDIA_IMAGES",
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001463 "LEGACY_STORAGE",
Jackal Guo8dc791e2019-01-14 10:26:42 +08001464 "ACCESS_ACCESSIBILITY",
Michael Groover656ef912019-04-09 17:09:57 -07001465 "READ_DEVICE_IDENTIFIERS",
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001466 };
1467
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001468 /**
1469 * This optionally maps a permission to an operation. If there
1470 * is no permission associated with an operation, it is null.
1471 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001472 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001473 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001474 android.Manifest.permission.ACCESS_COARSE_LOCATION,
1475 android.Manifest.permission.ACCESS_FINE_LOCATION,
1476 null,
1477 android.Manifest.permission.VIBRATE,
1478 android.Manifest.permission.READ_CONTACTS,
1479 android.Manifest.permission.WRITE_CONTACTS,
1480 android.Manifest.permission.READ_CALL_LOG,
1481 android.Manifest.permission.WRITE_CALL_LOG,
1482 android.Manifest.permission.READ_CALENDAR,
1483 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001484 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -04001485 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001486 null, // neighboring cells shares the coarse location perm
1487 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001488 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001489 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001490 android.Manifest.permission.RECEIVE_SMS,
1491 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
1492 android.Manifest.permission.RECEIVE_MMS,
1493 android.Manifest.permission.RECEIVE_WAP_PUSH,
1494 android.Manifest.permission.SEND_SMS,
1495 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001496 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -08001497 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -08001498 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001499 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001500 android.Manifest.permission.CAMERA,
1501 android.Manifest.permission.RECORD_AUDIO,
1502 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001503 null, // no permission for reading clipboard
1504 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001505 null, // no permission for taking media buttons
1506 null, // no permission for taking audio focus
1507 null, // no permission for changing master volume
1508 null, // no permission for changing voice volume
1509 null, // no permission for changing ring volume
1510 null, // no permission for changing media volume
1511 null, // no permission for changing alarm volume
1512 null, // no permission for changing notification volume
1513 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -07001514 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001515 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -07001516 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -07001517 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -04001518 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -04001519 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -07001520 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -07001521 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +00001522 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001523 null, // no permission for receiving assist structure
1524 null, // no permission for receiving assist screenshot
Svet Ganovc3300092015-04-17 09:07:22 -07001525 Manifest.permission.READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -07001526 Manifest.permission.ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -07001527 Manifest.permission.USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -07001528 Manifest.permission.PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001529 Manifest.permission.USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001530 Manifest.permission.BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001531 Manifest.permission.READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001532 null,
1533 Manifest.permission.READ_EXTERNAL_STORAGE,
1534 Manifest.permission.WRITE_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001535 null, // no permission for turning the screen on
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001536 Manifest.permission.GET_ACCOUNTS,
1537 null, // no permission for running in background
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001538 null, // no permission for changing accessibility volume
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001539 Manifest.permission.READ_PHONE_NUMBERS,
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001540 Manifest.permission.REQUEST_INSTALL_PACKAGES,
Winson Chung59fda9e2017-01-20 16:14:51 -08001541 null, // no permission for entering picture-in-picture on hide
Chad Brubaker97b383f2017-02-02 15:04:35 -08001542 Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001543 Manifest.permission.ANSWER_PHONE_CALLS,
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001544 null, // no permission for OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001545 Manifest.permission.CHANGE_WIFI_STATE,
Peter Visontayf2e38362017-11-27 15:27:16 +00001546 Manifest.permission.REQUEST_DELETE_PACKAGES,
Peter Visontay11950832017-11-14 19:34:59 +00001547 Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001548 Manifest.permission.ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001549 null, // no permission for OP_MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001550 Manifest.permission.FOREGROUND_SERVICE,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001551 null, // no permission for OP_BLUETOOTH_SCAN
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001552 Manifest.permission.USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001553 Manifest.permission.ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001554 Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001555 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001556 null, // no permission for OP_WRITE_MEDIA_AUDIO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001557 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001558 null, // no permission for OP_WRITE_MEDIA_VIDEO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001559 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001560 null, // no permission for OP_WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001561 null, // no permission for OP_LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001562 null, // no permission for OP_ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001563 null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001564 };
1565
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001566 /**
Jason Monk62062992014-05-06 09:55:28 -04001567 * Specifies whether an Op should be restricted by a user restriction.
1568 * Each Op should be filled with a restriction string from UserManager or
1569 * null to specify it is not affected by any user restriction.
1570 */
1571 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -04001572 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
1573 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
1574 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -04001575 null, //VIBRATE
1576 null, //READ_CONTACTS
1577 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -07001578 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
1579 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -04001580 null, //READ_CALENDAR
1581 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001582 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -04001583 null, //POST_NOTIFICATION
1584 null, //NEIGHBORING_CELLS
1585 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001586 UserManager.DISALLOW_SMS, //READ_SMS
1587 UserManager.DISALLOW_SMS, //WRITE_SMS
1588 UserManager.DISALLOW_SMS, //RECEIVE_SMS
1589 null, //RECEIVE_EMERGENCY_SMS
1590 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -04001591 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001592 UserManager.DISALLOW_SMS, //SEND_SMS
1593 UserManager.DISALLOW_SMS, //READ_ICC_SMS
1594 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -04001595 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -04001596 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -04001597 null, //ACCESS_NOTIFICATIONS
Makoto Onuki759a7632015-10-28 16:43:10 -07001598 UserManager.DISALLOW_CAMERA, //CAMERA
Fyodor Kupolovb5013302015-04-17 17:59:14 -07001599 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
Jason Monk62062992014-05-06 09:55:28 -04001600 null, //PLAY_AUDIO
1601 null, //READ_CLIPBOARD
1602 null, //WRITE_CLIPBOARD
1603 null, //TAKE_MEDIA_BUTTONS
1604 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -04001605 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
1606 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
1607 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
1608 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
1609 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
1610 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
1611 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -04001612 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -04001613 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
1614 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -04001615 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -04001616 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -04001617 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -07001618 null, //PROJECT_MEDIA
Tony Mak33d03a92016-06-02 15:01:16 +01001619 null, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001620 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001621 null, // ASSIST_STRUCTURE
1622 null, // ASSIST_SCREENSHOT
Svet Ganovc3300092015-04-17 09:07:22 -07001623 null, // READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001624 null, // ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001625 null, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001626 null, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001627 null, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001628 null, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001629 null, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001630 null, // MOCK_LOCATION
1631 null, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001632 null, // WRITE_EXTERNAL_STORAGE
1633 null, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001634 null, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001635 null, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001636 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001637 null, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001638 null, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001639 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001640 null, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001641 null, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001642 null, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001643 null, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001644 null, // REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001645 null, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001646 null, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001647 null, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001648 null, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001649 null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001650 null, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001651 null, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001652 UserManager.DISALLOW_SMS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001653 null, // READ_MEDIA_AUDIO
1654 null, // WRITE_MEDIA_AUDIO
1655 null, // READ_MEDIA_VIDEO
1656 null, // WRITE_MEDIA_VIDEO
1657 null, // READ_MEDIA_IMAGES
1658 null, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001659 null, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001660 null, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001661 null, // READ_DEVICE_IDENTIFIERS
Jason Monk1c7c3192014-06-26 12:52:18 -04001662 };
1663
1664 /**
1665 * This specifies whether each option should allow the system
1666 * (and system ui) to bypass the user restriction when active.
1667 */
1668 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
Fyodor Kupolov639e73d2016-02-25 11:58:21 -08001669 true, //COARSE_LOCATION
1670 true, //FINE_LOCATION
Jason Monk1c7c3192014-06-26 12:52:18 -04001671 false, //GPS
1672 false, //VIBRATE
1673 false, //READ_CONTACTS
1674 false, //WRITE_CONTACTS
1675 false, //READ_CALL_LOG
1676 false, //WRITE_CALL_LOG
1677 false, //READ_CALENDAR
1678 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001679 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -04001680 false, //POST_NOTIFICATION
1681 false, //NEIGHBORING_CELLS
1682 false, //CALL_PHONE
1683 false, //READ_SMS
1684 false, //WRITE_SMS
1685 false, //RECEIVE_SMS
1686 false, //RECEIVE_EMERGECY_SMS
1687 false, //RECEIVE_MMS
1688 false, //RECEIVE_WAP_PUSH
1689 false, //SEND_SMS
1690 false, //READ_ICC_SMS
1691 false, //WRITE_ICC_SMS
1692 false, //WRITE_SETTINGS
1693 true, //SYSTEM_ALERT_WINDOW
1694 false, //ACCESS_NOTIFICATIONS
1695 false, //CAMERA
1696 false, //RECORD_AUDIO
1697 false, //PLAY_AUDIO
1698 false, //READ_CLIPBOARD
1699 false, //WRITE_CLIPBOARD
1700 false, //TAKE_MEDIA_BUTTONS
1701 false, //TAKE_AUDIO_FOCUS
1702 false, //AUDIO_MASTER_VOLUME
1703 false, //AUDIO_VOICE_VOLUME
1704 false, //AUDIO_RING_VOLUME
1705 false, //AUDIO_MEDIA_VOLUME
1706 false, //AUDIO_ALARM_VOLUME
1707 false, //AUDIO_NOTIFICATION_VOLUME
1708 false, //AUDIO_BLUETOOTH_VOLUME
1709 false, //WAKE_LOCK
1710 false, //MONITOR_LOCATION
1711 false, //MONITOR_HIGH_POWER_LOCATION
1712 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -07001713 false, //MUTE_MICROPHONE
1714 true, //TOAST_WINDOW
1715 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -07001716 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001717 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001718 false, //ASSIST_STRUCTURE
1719 false, //ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -07001720 false, //READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001721 false, //ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001722 false, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001723 false, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001724 false, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001725 false, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001726 false, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001727 false, // MOCK_LOCATION
1728 false, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001729 false, // WRITE_EXTERNAL_STORAGE
1730 false, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001731 false, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001732 false, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001733 false, // AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001734 false, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001735 false, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001736 false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001737 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001738 false, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001739 false, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001740 false, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001741 false, // OP_REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001742 false, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001743 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001744 false, // MANAGE_IPSEC_HANDOVERS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001745 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001746 true, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001747 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001748 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001749 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001750 false, // READ_MEDIA_AUDIO
1751 false, // WRITE_MEDIA_AUDIO
1752 false, // READ_MEDIA_VIDEO
1753 false, // WRITE_MEDIA_VIDEO
1754 false, // READ_MEDIA_IMAGES
1755 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001756 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001757 false, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001758 false, // READ_DEVICE_IDENTIFIERS
Jason Monk62062992014-05-06 09:55:28 -04001759 };
1760
1761 /**
David Braunf5d83192013-09-16 13:43:51 -07001762 * This specifies the default mode for each operation.
1763 */
1764 private static int[] sOpDefaultMode = new int[] {
Eugene Susla93519852018-06-13 16:44:31 -07001765 AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION
1766 AppOpsManager.MODE_ALLOWED, // FINE_LOCATION
1767 AppOpsManager.MODE_ALLOWED, // GPS
1768 AppOpsManager.MODE_ALLOWED, // VIBRATE
1769 AppOpsManager.MODE_ALLOWED, // READ_CONTACTS
1770 AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS
Svet Ganovd563e932019-04-14 13:07:41 -07001771 AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG
1772 AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG
Eugene Susla93519852018-06-13 16:44:31 -07001773 AppOpsManager.MODE_ALLOWED, // READ_CALENDAR
1774 AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR
1775 AppOpsManager.MODE_ALLOWED, // WIFI_SCAN
1776 AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION
1777 AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS
1778 AppOpsManager.MODE_ALLOWED, // CALL_PHONE
Svet Ganovd563e932019-04-14 13:07:41 -07001779 AppOpsManager.MODE_ALLOWED, // READ_SMS
Eugene Suslaaaff0072018-10-30 13:35:03 -07001780 AppOpsManager.MODE_IGNORED, // WRITE_SMS
Svet Ganovd563e932019-04-14 13:07:41 -07001781 AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001782 AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST
Svet Ganovd563e932019-04-14 13:07:41 -07001783 AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS
1784 AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH
1785 AppOpsManager.MODE_ALLOWED, // SEND_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001786 AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS
1787 AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS
1788 AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS
Ng Zhi An65a99b62018-10-01 11:57:53 -07001789 getSystemAlertWindowDefault(), // SYSTEM_ALERT_WINDOW
Eugene Susla93519852018-06-13 16:44:31 -07001790 AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS
1791 AppOpsManager.MODE_ALLOWED, // CAMERA
1792 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO
1793 AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO
1794 AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD
1795 AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD
1796 AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS
1797 AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS
1798 AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME
1799 AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME
1800 AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME
1801 AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME
1802 AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME
1803 AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME
1804 AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME
1805 AppOpsManager.MODE_ALLOWED, // WAKE_LOCK
1806 AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION
1807 AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION
1808 AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS
1809 AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE
1810 AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW
1811 AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA
1812 AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN
1813 AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER
1814 AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE
1815 AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT
1816 AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE
1817 AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL
1818 AppOpsManager.MODE_ALLOWED, // USE_SIP
Svet Ganovd563e932019-04-14 13:07:41 -07001819 AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07001820 AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT
1821 AppOpsManager.MODE_ALLOWED, // BODY_SENSORS
Svet Ganovd563e932019-04-14 13:07:41 -07001822 AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS
Eugene Susla93519852018-06-13 16:44:31 -07001823 AppOpsManager.MODE_ERRORED, // MOCK_LOCATION
1824 AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE
1825 AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE
1826 AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON
1827 AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS
1828 AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND
1829 AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME
1830 AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS
1831 AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES
1832 AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE
1833 AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND
1834 AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
1835 AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND
1836 AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE
1837 AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES
1838 AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE
1839 AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER
1840 AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS
1841 AppOpsManager.MODE_ALLOWED, // START_FOREGROUND
1842 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN
1843 AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001844 AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001845 AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001846 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001847 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001848 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001849 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001850 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001851 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001852 AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001853 AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001854 AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS
David Braunf5d83192013-09-16 13:43:51 -07001855 };
1856
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001857 /**
1858 * This specifies whether each option is allowed to be reset
1859 * when resetting all app preferences. Disable reset for
1860 * app ops that are under strong control of some part of the
1861 * system (such as OP_WRITE_SMS, which should be allowed only
1862 * for whichever app is selected as the current SMS app).
1863 */
1864 private static boolean[] sOpDisableReset = new boolean[] {
Eugene Susla93519852018-06-13 16:44:31 -07001865 false, // COARSE_LOCATION
1866 false, // FINE_LOCATION
1867 false, // GPS
1868 false, // VIBRATE
1869 false, // READ_CONTACTS
1870 false, // WRITE_CONTACTS
1871 false, // READ_CALL_LOG
1872 false, // WRITE_CALL_LOG
1873 false, // READ_CALENDAR
1874 false, // WRITE_CALENDAR
1875 false, // WIFI_SCAN
1876 false, // POST_NOTIFICATION
1877 false, // NEIGHBORING_CELLS
1878 false, // CALL_PHONE
1879 true, // READ_SMS
1880 true, // WRITE_SMS
1881 true, // RECEIVE_SMS
1882 false, // RECEIVE_EMERGENCY_BROADCAST
1883 false, // RECEIVE_MMS
1884 true, // RECEIVE_WAP_PUSH
1885 true, // SEND_SMS
1886 false, // READ_ICC_SMS
1887 false, // WRITE_ICC_SMS
1888 false, // WRITE_SETTINGS
1889 false, // SYSTEM_ALERT_WINDOW
1890 false, // ACCESS_NOTIFICATIONS
1891 false, // CAMERA
1892 false, // RECORD_AUDIO
1893 false, // PLAY_AUDIO
1894 false, // READ_CLIPBOARD
1895 false, // WRITE_CLIPBOARD
1896 false, // TAKE_MEDIA_BUTTONS
1897 false, // TAKE_AUDIO_FOCUS
1898 false, // AUDIO_MASTER_VOLUME
1899 false, // AUDIO_VOICE_VOLUME
1900 false, // AUDIO_RING_VOLUME
1901 false, // AUDIO_MEDIA_VOLUME
1902 false, // AUDIO_ALARM_VOLUME
1903 false, // AUDIO_NOTIFICATION_VOLUME
1904 false, // AUDIO_BLUETOOTH_VOLUME
1905 false, // WAKE_LOCK
1906 false, // MONITOR_LOCATION
1907 false, // MONITOR_HIGH_POWER_LOCATION
1908 false, // GET_USAGE_STATS
1909 false, // MUTE_MICROPHONE
1910 false, // TOAST_WINDOW
1911 false, // PROJECT_MEDIA
1912 false, // ACTIVATE_VPN
1913 false, // WRITE_WALLPAPER
1914 false, // ASSIST_STRUCTURE
1915 false, // ASSIST_SCREENSHOT
1916 false, // READ_PHONE_STATE
1917 false, // ADD_VOICEMAIL
1918 false, // USE_SIP
1919 false, // PROCESS_OUTGOING_CALLS
1920 false, // USE_FINGERPRINT
1921 false, // BODY_SENSORS
1922 true, // READ_CELL_BROADCASTS
1923 false, // MOCK_LOCATION
1924 false, // READ_EXTERNAL_STORAGE
1925 false, // WRITE_EXTERNAL_STORAGE
1926 false, // TURN_SCREEN_ON
1927 false, // GET_ACCOUNTS
1928 false, // RUN_IN_BACKGROUND
1929 false, // AUDIO_ACCESSIBILITY_VOLUME
1930 false, // READ_PHONE_NUMBERS
1931 false, // REQUEST_INSTALL_PACKAGES
1932 false, // PICTURE_IN_PICTURE
1933 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001934 false, // ANSWER_PHONE_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07001935 false, // RUN_ANY_IN_BACKGROUND
1936 false, // CHANGE_WIFI_STATE
1937 false, // REQUEST_DELETE_PACKAGES
1938 false, // BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001939 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001940 false, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001941 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001942 false, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001943 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001944 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001945 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001946 false, // READ_MEDIA_AUDIO
1947 false, // WRITE_MEDIA_AUDIO
1948 false, // READ_MEDIA_VIDEO
1949 false, // WRITE_MEDIA_VIDEO
1950 false, // READ_MEDIA_IMAGES
1951 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001952 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001953 false, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001954 false, // READ_DEVICE_IDENTIFIERS
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001955 };
1956
Svet Ganovfbf01f72015-04-28 18:39:06 -07001957 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07001958 * Mapping from an app op name to the app op code.
Svet Ganovfbf01f72015-04-28 18:39:06 -07001959 */
Svet Ganovb9d71a62015-04-30 10:38:13 -07001960 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
Svet Ganovfbf01f72015-04-28 18:39:06 -07001961
Svet Ganovb9d71a62015-04-30 10:38:13 -07001962 /**
1963 * Mapping from a permission to the corresponding app op.
1964 */
Svet Ganovda0acdf2017-02-15 10:28:51 -08001965 private static HashMap<String, Integer> sPermToOp = new HashMap<>();
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001966
1967 static {
1968 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001969 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001970 + " should be " + _NUM_OP);
1971 }
1972 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001973 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001974 + " should be " + _NUM_OP);
1975 }
1976 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001977 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001978 + " should be " + _NUM_OP);
1979 }
1980 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001981 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001982 + " should be " + _NUM_OP);
1983 }
1984 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001985 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
1986 + " should be " + _NUM_OP);
1987 }
1988 if (sOpDisableReset.length != _NUM_OP) {
1989 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001990 + " should be " + _NUM_OP);
1991 }
Jason Monk62062992014-05-06 09:55:28 -04001992 if (sOpRestrictions.length != _NUM_OP) {
1993 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
1994 + " should be " + _NUM_OP);
1995 }
Jason Monk1c7c3192014-06-26 12:52:18 -04001996 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
1997 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
1998 + sOpRestrictions.length + " should be " + _NUM_OP);
1999 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002000 for (int i=0; i<_NUM_OP; i++) {
2001 if (sOpToString[i] != null) {
2002 sOpStrToOp.put(sOpToString[i], i);
2003 }
2004 }
Svet Ganovda0acdf2017-02-15 10:28:51 -08002005 for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07002006 if (sOpPerms[op] != null) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002007 sPermToOp.put(sOpPerms[op], op);
Svet Ganovb9d71a62015-04-30 10:38:13 -07002008 }
2009 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002010 }
2011
Svet Ganov8455ba22019-01-02 13:05:56 -08002012 /** @hide */
2013 public static final String KEY_HISTORICAL_OPS = "historical_ops";
2014
Chad Brubaker7c6dba62019-01-23 15:51:43 -08002015 /** System properties for debug logging of noteOp call sites */
2016 private static final String DEBUG_LOGGING_ENABLE_PROP = "appops.logging_enabled";
2017 private static final String DEBUG_LOGGING_PACKAGES_PROP = "appops.logging_packages";
2018 private static final String DEBUG_LOGGING_OPS_PROP = "appops.logging_ops";
2019 private static final String DEBUG_LOGGING_TAG = "AppOpsManager";
2020
David Braunf5d83192013-09-16 13:43:51 -07002021 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002022 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002023 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002024 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002025 @UnsupportedAppUsage
Dianne Hackbornf265ea92013-01-31 15:00:51 -08002026 public static int opToSwitch(int op) {
2027 return sOpToSwitch[op];
2028 }
2029
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002030 /**
2031 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002032 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002033 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002034 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002035 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08002036 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002037 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
2038 }
2039
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002040 /**
Svet Ganov65f1b9e2019-01-17 19:19:40 -08002041 * Retrieve a non-localized public name for the operation.
2042 *
2043 * @hide
2044 */
2045 public static @NonNull String opToPublicName(int op) {
2046 return sOpToString[op];
2047 }
2048
2049 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08002050 * @hide
2051 */
2052 public static int strDebugOpToOp(String op) {
2053 for (int i=0; i<sOpNames.length; i++) {
2054 if (sOpNames[i].equals(op)) {
2055 return i;
2056 }
2057 }
2058 throw new IllegalArgumentException("Unknown operation string: " + op);
2059 }
2060
2061 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002062 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002063 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002064 */
Artur Satayev5a525852019-10-31 15:15:50 +00002065 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07002066 @TestApi
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002067 public static String opToPermission(int op) {
2068 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002069 }
2070
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002071 /**
Hai Zhangb7776682018-09-25 15:10:57 -07002072 * Retrieve the permission associated with an operation, or null if there is not one.
2073 *
2074 * @param op The operation name.
2075 *
2076 * @hide
2077 */
2078 @Nullable
2079 @SystemApi
2080 public static String opToPermission(@NonNull String op) {
2081 return opToPermission(strOpToOp(op));
2082 }
2083
2084 /**
Jason Monk62062992014-05-06 09:55:28 -04002085 * Retrieve the user restriction associated with an operation, or null if there is not one.
2086 * @hide
2087 */
2088 public static String opToRestriction(int op) {
2089 return sOpRestrictions[op];
2090 }
2091
2092 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07002093 * Retrieve the app op code for a permission, or null if there is not one.
Svet Ganovda0acdf2017-02-15 10:28:51 -08002094 * This API is intended to be used for mapping runtime or appop permissions
2095 * to the corresponding app op.
Svet Ganovb9d71a62015-04-30 10:38:13 -07002096 * @hide
2097 */
Artur Satayev5a525852019-10-31 15:15:50 +00002098 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07002099 @TestApi
Svet Ganovb9d71a62015-04-30 10:38:13 -07002100 public static int permissionToOpCode(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002101 Integer boxedOpCode = sPermToOp.get(permission);
Svet Ganov019d2302015-05-04 11:07:38 -07002102 return boxedOpCode != null ? boxedOpCode : OP_NONE;
Svet Ganovb9d71a62015-04-30 10:38:13 -07002103 }
2104
2105 /**
Jason Monk1c7c3192014-06-26 12:52:18 -04002106 * Retrieve whether the op allows the system (and system ui) to
2107 * bypass the user restriction.
2108 * @hide
2109 */
2110 public static boolean opAllowSystemBypassRestriction(int op) {
2111 return sOpAllowSystemRestrictionBypass[op];
2112 }
2113
2114 /**
David Braunf5d83192013-09-16 13:43:51 -07002115 * Retrieve the default mode for the operation.
2116 * @hide
2117 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002118 public static @Mode int opToDefaultMode(int op) {
David Braunf5d83192013-09-16 13:43:51 -07002119 return sOpDefaultMode[op];
2120 }
2121
2122 /**
Hai Zhangc595f112018-11-06 14:20:38 -08002123 * Retrieve the default mode for the app op.
2124 *
2125 * @param appOp The app op name
2126 *
2127 * @return the default mode for the app op
2128 *
2129 * @hide
2130 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07002131 @TestApi
Hai Zhangc595f112018-11-06 14:20:38 -08002132 @SystemApi
2133 public static int opToDefaultMode(@NonNull String appOp) {
2134 return opToDefaultMode(strOpToOp(appOp));
2135 }
2136
2137 /**
Svet Ganov82f09bc2018-01-12 22:08:40 -08002138 * Retrieve the human readable mode.
2139 * @hide
2140 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002141 public static String modeToName(@Mode int mode) {
Dianne Hackbornc216a262018-04-26 13:46:22 -07002142 if (mode >= 0 && mode < MODE_NAMES.length) {
2143 return MODE_NAMES[mode];
Svet Ganov82f09bc2018-01-12 22:08:40 -08002144 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07002145 return "mode=" + mode;
Svet Ganov82f09bc2018-01-12 22:08:40 -08002146 }
2147
2148 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002149 * Retrieve whether the op allows itself to be reset.
2150 * @hide
2151 */
2152 public static boolean opAllowsReset(int op) {
2153 return !sOpDisableReset[op];
2154 }
2155
2156 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002157 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002158 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002159 */
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002160 @SystemApi
2161 public static final class PackageOps implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002162 private final String mPackageName;
2163 private final int mUid;
2164 private final List<OpEntry> mEntries;
2165
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002166 /**
2167 * @hide
2168 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002169 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002170 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
2171 mPackageName = packageName;
2172 mUid = uid;
2173 mEntries = entries;
2174 }
2175
Svet Ganovaf189e32019-02-15 18:45:29 -08002176 /**
2177 * @return The name of the package.
2178 */
2179 public @NonNull String getPackageName() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002180 return mPackageName;
2181 }
2182
Svet Ganovaf189e32019-02-15 18:45:29 -08002183 /**
2184 * @return The uid of the package.
2185 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002186 public int getUid() {
2187 return mUid;
2188 }
2189
Svet Ganovaf189e32019-02-15 18:45:29 -08002190 /**
2191 * @return The ops of the package.
2192 */
Dianne Hackborn62878492019-03-11 15:57:07 -07002193 public @NonNull List<OpEntry> getOps() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002194 return mEntries;
2195 }
2196
2197 @Override
2198 public int describeContents() {
2199 return 0;
2200 }
2201
2202 @Override
2203 public void writeToParcel(Parcel dest, int flags) {
2204 dest.writeString(mPackageName);
2205 dest.writeInt(mUid);
2206 dest.writeInt(mEntries.size());
2207 for (int i=0; i<mEntries.size(); i++) {
2208 mEntries.get(i).writeToParcel(dest, flags);
2209 }
2210 }
2211
2212 PackageOps(Parcel source) {
2213 mPackageName = source.readString();
2214 mUid = source.readInt();
2215 mEntries = new ArrayList<OpEntry>();
2216 final int N = source.readInt();
2217 for (int i=0; i<N; i++) {
2218 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
2219 }
2220 }
2221
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07002222 public static final @android.annotation.NonNull Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002223 @Override public PackageOps createFromParcel(Parcel source) {
2224 return new PackageOps(source);
2225 }
2226
2227 @Override public PackageOps[] newArray(int size) {
2228 return new PackageOps[size];
2229 }
2230 };
2231 }
2232
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002233 /**
2234 * Class holding the information about one unique operation of an application.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002235 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002236 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002237 @TestApi
2238 @Immutable
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002239 @SystemApi
2240 public static final class OpEntry implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002241 private final int mOp;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002242 private final boolean mRunning;
Svet Ganovaf189e32019-02-15 18:45:29 -08002243 private final @Mode int mMode;
2244 private final @Nullable LongSparseLongArray mAccessTimes;
2245 private final @Nullable LongSparseLongArray mRejectTimes;
2246 private final @Nullable LongSparseLongArray mDurations;
2247 private final @Nullable LongSparseLongArray mProxyUids;
2248 private final @Nullable LongSparseArray<String> mProxyPackageNames;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002249
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002250 /**
2251 * @hide
2252 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002253 public OpEntry(int op, boolean running, @Mode int mode,
2254 @Nullable LongSparseLongArray accessTimes, @Nullable LongSparseLongArray rejectTimes,
2255 @Nullable LongSparseLongArray durations, @Nullable LongSparseLongArray proxyUids,
2256 @Nullable LongSparseArray<String> proxyPackageNames) {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002257 mOp = op;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002258 mRunning = running;
Svet Ganovaf189e32019-02-15 18:45:29 -08002259 mMode = mode;
2260 mAccessTimes = accessTimes;
2261 mRejectTimes = rejectTimes;
2262 mDurations = durations;
2263 mProxyUids = proxyUids;
2264 mProxyPackageNames = proxyPackageNames;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002265 }
2266
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002267 /**
2268 * @hide
2269 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002270 public OpEntry(int op, @Mode int mode) {
2271 mOp = op;
2272 mMode = mode;
2273 mRunning = false;
2274 mAccessTimes = null;
2275 mRejectTimes = null;
2276 mDurations = null;
2277 mProxyUids = null;
2278 mProxyPackageNames = null;
2279 }
2280
2281 /**
2282 * Returns all keys for which we have mapped state in any of the data buckets -
2283 * access time, reject time, duration.
2284 * @hide */
2285 public @Nullable LongSparseArray<Object> collectKeys() {
2286 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessTimes, null);
2287 result = AppOpsManager.collectKeys(mRejectTimes, result);
2288 result = AppOpsManager.collectKeys(mDurations, result);
2289 return result;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002290 }
2291
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002292 /**
2293 * @hide
2294 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002295 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002296 public int getOp() {
2297 return mOp;
2298 }
2299
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002300 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002301 * @return This entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}.
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002302 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002303 public @NonNull String getOpStr() {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002304 return sOpToString[mOp];
2305 }
2306
2307 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002308 * @return this entry's current mode, such as {@link #MODE_ALLOWED}.
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002309 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002310 public @Mode int getMode() {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002311 return mMode;
2312 }
2313
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002314 /**
2315 * @hide
2316 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002317 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002318 public long getTime() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002319 return getLastAccessTime(OP_FLAGS_ALL);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002320 }
2321
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002322 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002323 * Return the last wall clock time in milliseconds this op was accessed.
2324 *
2325 * @param flags The flags which are any combination of
2326 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2327 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2328 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2329 * for any flag.
2330 * @return the last access time in milliseconds since
2331 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2332 *
2333 * @see #getLastAccessForegroundTime(int)
2334 * @see #getLastAccessBackgroundTime(int)
2335 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002336 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002337 public long getLastAccessTime(@OpFlags int flags) {
2338 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
2339 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002340 }
2341
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002342 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002343 * Return the last wall clock time in milliseconds this op was accessed
2344 * by the app while in the foreground.
2345 *
2346 * @param flags The flags which are any combination of
2347 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2348 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2349 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2350 * for any flag.
2351 * @return the last foreground access time in milliseconds since
2352 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2353 *
2354 * @see #getLastAccessBackgroundTime(int)
2355 * @see #getLastAccessTime(int)
2356 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002357 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002358 public long getLastAccessForegroundTime(@OpFlags int flags) {
2359 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
2360 resolveFirstUnrestrictedUidState(mOp), flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002361 }
2362
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002363 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002364 * Return the last wall clock time in milliseconds this op was accessed
2365 * by the app while in the background.
2366 *
2367 * @param flags The flags which are any combination of
2368 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2369 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2370 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2371 * for any flag.
2372 * @return the last foreground access time in milliseconds since
2373 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2374 *
2375 * @see #getLastAccessForegroundTime(int)
2376 * @see #getLastAccessTime(int)
2377 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002378 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002379 public long getLastAccessBackgroundTime(@OpFlags int flags) {
2380 return maxForFlagsInStates(mAccessTimes, resolveLastRestrictedUidState(mOp),
2381 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002382 }
2383
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002384 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002385 * Return the last wall clock time in milliseconds this op was accessed
2386 * by the app for a given range of UID states.
2387 *
2388 * @param fromUidState The UID state for which to query. Could be one of
2389 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2390 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2391 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2392 * @param toUidState The UID state for which to query.
2393 * @param flags The flags which are any combination of
2394 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2395 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2396 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2397 * for any flag.
2398 *
2399 * @return the last foreground access time in milliseconds since
2400 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2401 *
2402 * @see #getLastAccessForegroundTime(int)
2403 * @see #getLastAccessBackgroundTime(int)
2404 * @see #getLastAccessTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002405 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002406 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
2407 @OpFlags int flags) {
2408 return maxForFlagsInStates(mAccessTimes, fromUidState, toUidState, flags);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002409 }
2410
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002411 /**
2412 * @hide
2413 */
Andrei Onea2bbb6542019-05-21 18:13:26 +01002414 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002415 public long getRejectTime() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002416 return getLastRejectTime(OP_FLAGS_ALL);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002417 }
2418
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002419 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002420 * Return the last wall clock time in milliseconds the app made an attempt
2421 * to access this op but was rejected.
2422 *
2423 * @param flags The flags which are any combination of
2424 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2425 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2426 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2427 * for any flag.
2428 * @return the last reject time in milliseconds since
2429 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2430 *
2431 * @see #getLastRejectBackgroundTime(int)
2432 * @see #getLastRejectForegroundTime(int)
2433 * @see #getLastRejectTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002434 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002435 public long getLastRejectTime(@OpFlags int flags) {
2436 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
2437 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002438 }
2439
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002440 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002441 * Return the last wall clock time in milliseconds the app made an attempt
2442 * to access this op while in the foreground but was rejected.
2443 *
2444 * @param flags The flags which are any combination of
2445 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2446 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2447 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2448 * for any flag.
2449 * @return the last foreground reject time in milliseconds since
2450 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2451 *
2452 * @see #getLastRejectBackgroundTime(int)
2453 * @see #getLastRejectTime(int, int, int)
2454 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002455 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002456 public long getLastRejectForegroundTime(@OpFlags int flags) {
2457 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
2458 resolveFirstUnrestrictedUidState(mOp), flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002459 }
2460
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002461 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002462 * Return the last wall clock time in milliseconds the app made an attempt
2463 * to access this op while in the background but was rejected.
2464 *
2465 * @param flags The flags which are any combination of
2466 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2467 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2468 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2469 * for any flag.
2470 * @return the last background reject time in milliseconds since
2471 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2472 *
2473 * @see #getLastRejectForegroundTime(int)
2474 * @see #getLastRejectTime(int, int, int)
2475 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002476 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002477 public long getLastRejectBackgroundTime(@OpFlags int flags) {
2478 return maxForFlagsInStates(mRejectTimes, resolveLastRestrictedUidState(mOp),
2479 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002480 }
2481
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002482 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002483 * Return the last wall clock time state in milliseconds the app made an
2484 * attempt to access this op for a given range of UID states.
2485 *
2486 * @param fromUidState The UID state from which to query. Could be one of
2487 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2488 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2489 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2490 * @param toUidState The UID state to which to query.
2491 * @param flags The flags which are any combination of
2492 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2493 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2494 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2495 * for any flag.
2496 * @return the last foreground access time in milliseconds since
2497 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2498 *
2499 * @see #getLastRejectForegroundTime(int)
2500 * @see #getLastRejectBackgroundTime(int)
2501 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002502 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002503 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
2504 @OpFlags int flags) {
2505 return maxForFlagsInStates(mRejectTimes, fromUidState, toUidState, flags);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002506 }
2507
Svet Ganovaf189e32019-02-15 18:45:29 -08002508 /**
2509 * @return Whether the operation is running.
2510 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002511 public boolean isRunning() {
Amith Yamasania1ce9632018-05-28 20:50:48 -07002512 return mRunning;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002513 }
2514
Svet Ganovaf189e32019-02-15 18:45:29 -08002515 /**
Svet Ganov6f672a32019-07-08 16:40:42 -07002516 * @return The duration of the operation in milliseconds. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002517 */
2518 public long getDuration() {
2519 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002520 }
2521
Svet Ganovaf189e32019-02-15 18:45:29 -08002522 /**
2523 * Return the duration in milliseconds the app accessed this op while
Svet Ganov6f672a32019-07-08 16:40:42 -07002524 * in the foreground. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002525 *
2526 * @param flags The flags which are any combination of
2527 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2528 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2529 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2530 * for any flag.
2531 * @return the foreground access duration in milliseconds.
2532 *
2533 * @see #getLastBackgroundDuration(int)
2534 * @see #getLastDuration(int, int, int)
2535 */
2536 public long getLastForegroundDuration(@OpFlags int flags) {
2537 return sumForFlagsInStates(mDurations, MAX_PRIORITY_UID_STATE,
2538 resolveFirstUnrestrictedUidState(mOp), flags);
2539 }
2540
2541 /**
2542 * Return the duration in milliseconds the app accessed this op while
Svet Ganov6f672a32019-07-08 16:40:42 -07002543 * in the background. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002544 *
2545 * @param flags The flags which are any combination of
2546 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2547 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2548 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2549 * for any flag.
2550 * @return the background access duration in milliseconds.
2551 *
2552 * @see #getLastForegroundDuration(int)
2553 * @see #getLastDuration(int, int, int)
2554 */
2555 public long getLastBackgroundDuration(@OpFlags int flags) {
2556 return sumForFlagsInStates(mDurations, resolveLastRestrictedUidState(mOp),
2557 MIN_PRIORITY_UID_STATE, flags);
2558 }
2559
2560 /**
2561 * Return the duration in milliseconds the app accessed this op for
Svet Ganov6f672a32019-07-08 16:40:42 -07002562 * a given range of UID states. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002563 *
2564 * @param fromUidState The UID state for which to query. Could be one of
2565 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2566 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2567 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2568 * @param toUidState The UID state for which to query.
2569 * @param flags The flags which are any combination of
2570 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2571 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2572 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2573 * for any flag.
2574 * @return the access duration in milliseconds.
2575 */
2576 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
2577 @OpFlags int flags) {
2578 return sumForFlagsInStates(mDurations, fromUidState, toUidState, flags);
2579 }
2580
2581 /**
2582 * Gets the UID of the app that performed the op on behalf of this app and
2583 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2584 * there is no proxy.
2585 *
2586 * @return The proxy UID.
2587 */
Svet Ganov99b60432015-06-27 13:15:22 -07002588 public int getProxyUid() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002589 return (int) findFirstNonNegativeForFlagsInStates(mDurations,
2590 MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
Svet Ganov99b60432015-06-27 13:15:22 -07002591 }
2592
Svet Ganovaf189e32019-02-15 18:45:29 -08002593 /**
2594 * Gets the UID of the app that performed the op on behalf of this app and
2595 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2596 * there is no proxy.
2597 *
2598 * @param uidState The UID state for which to query. Could be one of
2599 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2600 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2601 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2602 * @param flags The flags which are any combination of
2603 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2604 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2605 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2606 * for any flag.
2607 *
2608 * @return The proxy UID.
2609 */
2610 public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
2611 return (int) findFirstNonNegativeForFlagsInStates(mDurations,
2612 uidState, uidState, flags);
2613 }
2614
2615 /**
2616 * Gets the package name of the app that performed the op on behalf of this
2617 * app and as a result blamed the op on this app or {@code null}
2618 * if there is no proxy.
2619 *
2620 * @return The proxy package name.
2621 */
2622 public @Nullable String getProxyPackageName() {
2623 return findFirstNonNullForFlagsInStates(mProxyPackageNames, MAX_PRIORITY_UID_STATE,
2624 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
2625 }
2626
2627 /**
2628 * Gets the package name of the app that performed the op on behalf of this
2629 * app and as a result blamed the op on this app for a UID state or
2630 * {@code null} if there is no proxy.
2631 *
2632 * @param uidState The UID state for which to query. Could be one of
2633 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2634 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2635 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2636 * @param flags The flags which are any combination of
2637 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2638 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2639 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2640 * for any flag.
2641 * @return The proxy package name.
2642 */
2643 public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
2644 return findFirstNonNullForFlagsInStates(mProxyPackageNames, uidState, uidState, flags);
Svet Ganov99b60432015-06-27 13:15:22 -07002645 }
2646
Dianne Hackborn35654b62013-01-14 17:38:02 -08002647 @Override
2648 public int describeContents() {
2649 return 0;
2650 }
2651
2652 @Override
2653 public void writeToParcel(Parcel dest, int flags) {
2654 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002655 dest.writeInt(mMode);
Amith Yamasania1ce9632018-05-28 20:50:48 -07002656 dest.writeBoolean(mRunning);
Svet Ganovaf189e32019-02-15 18:45:29 -08002657 writeLongSparseLongArrayToParcel(mAccessTimes, dest);
2658 writeLongSparseLongArrayToParcel(mRejectTimes, dest);
2659 writeLongSparseLongArrayToParcel(mDurations, dest);
2660 writeLongSparseLongArrayToParcel(mProxyUids, dest);
2661 writeLongSparseStringArrayToParcel(mProxyPackageNames, dest);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002662 }
2663
2664 OpEntry(Parcel source) {
2665 mOp = source.readInt();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002666 mMode = source.readInt();
Amith Yamasania1ce9632018-05-28 20:50:48 -07002667 mRunning = source.readBoolean();
Svet Ganovaf189e32019-02-15 18:45:29 -08002668 mAccessTimes = readLongSparseLongArrayFromParcel(source);
2669 mRejectTimes = readLongSparseLongArrayFromParcel(source);
2670 mDurations = readLongSparseLongArrayFromParcel(source);
2671 mProxyUids = readLongSparseLongArrayFromParcel(source);
2672 mProxyPackageNames = readLongSparseStringArrayFromParcel(source);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002673 }
2674
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07002675 public static final @android.annotation.NonNull Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002676 @Override public OpEntry createFromParcel(Parcel source) {
2677 return new OpEntry(source);
2678 }
2679
2680 @Override public OpEntry[] newArray(int size) {
2681 return new OpEntry[size];
2682 }
2683 };
2684 }
2685
Svet Ganov8455ba22019-01-02 13:05:56 -08002686 /** @hide */
2687 public interface HistoricalOpsVisitor {
2688 void visitHistoricalOps(@NonNull HistoricalOps ops);
2689 void visitHistoricalUidOps(@NonNull HistoricalUidOps ops);
2690 void visitHistoricalPackageOps(@NonNull HistoricalPackageOps ops);
2691 void visitHistoricalOp(@NonNull HistoricalOp ops);
2692 }
2693
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002694 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08002695 * Request for getting historical app op usage. The request acts
2696 * as a filtering criteria when querying historical op usage.
2697 *
2698 * @hide
2699 */
2700 @Immutable
2701 @TestApi
2702 @SystemApi
2703 public static final class HistoricalOpsRequest {
2704 private final int mUid;
2705 private final @Nullable String mPackageName;
2706 private final @Nullable List<String> mOpNames;
2707 private final long mBeginTimeMillis;
2708 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08002709 private final @OpFlags int mFlags;
Svet Ganov23c88db2019-01-22 20:38:11 -08002710
2711 private HistoricalOpsRequest(int uid, @Nullable String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08002712 @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
2713 @OpFlags int flags) {
Svet Ganov23c88db2019-01-22 20:38:11 -08002714 mUid = uid;
2715 mPackageName = packageName;
2716 mOpNames = opNames;
2717 mBeginTimeMillis = beginTimeMillis;
2718 mEndTimeMillis = endTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08002719 mFlags = flags;
Svet Ganov23c88db2019-01-22 20:38:11 -08002720 }
2721
2722 /**
2723 * Builder for creating a {@link HistoricalOpsRequest}.
2724 *
2725 * @hide
2726 */
2727 @TestApi
2728 @SystemApi
2729 public static final class Builder {
2730 private int mUid = Process.INVALID_UID;
2731 private @Nullable String mPackageName;
2732 private @Nullable List<String> mOpNames;
2733 private final long mBeginTimeMillis;
2734 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08002735 private @OpFlags int mFlags = OP_FLAGS_ALL;
Svet Ganov23c88db2019-01-22 20:38:11 -08002736
2737 /**
2738 * Creates a new builder.
2739 *
2740 * @param beginTimeMillis The beginning of the interval in milliseconds since
2741 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non
2742 * negative.
2743 * @param endTimeMillis The end of the interval in milliseconds since
2744 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after
2745 * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent
2746 * history including ops that happen while this call is in flight.
2747 */
2748 public Builder(long beginTimeMillis, long endTimeMillis) {
2749 Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
2750 "beginTimeMillis must be non negative and lesser than endTimeMillis");
2751 mBeginTimeMillis = beginTimeMillis;
2752 mEndTimeMillis = endTimeMillis;
2753 }
2754
2755 /**
2756 * Sets the UID to query for.
2757 *
2758 * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid.
2759 * @return This builder.
2760 */
2761 public @NonNull Builder setUid(int uid) {
2762 Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
2763 "uid must be " + Process.INVALID_UID + " or non negative");
2764 mUid = uid;
2765 return this;
2766 }
2767
2768 /**
2769 * Sets the package to query for.
2770 *
2771 * @param packageName The package name. <code>Null</code> for any package.
2772 * @return This builder.
2773 */
2774 public @NonNull Builder setPackageName(@Nullable String packageName) {
2775 mPackageName = packageName;
2776 return this;
2777 }
2778
2779 /**
2780 * Sets the op names to query for.
2781 *
2782 * @param opNames The op names. <code>Null</code> for any op.
2783 * @return This builder.
2784 */
2785 public @NonNull Builder setOpNames(@Nullable List<String> opNames) {
2786 if (opNames != null) {
2787 final int opCount = opNames.size();
2788 for (int i = 0; i < opCount; i++) {
2789 Preconditions.checkArgument(AppOpsManager.strOpToOp(
2790 opNames.get(i)) != AppOpsManager.OP_NONE);
2791 }
2792 }
2793 mOpNames = opNames;
2794 return this;
2795 }
2796
2797 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002798 * Sets the op flags to query for. The flags specify the type of
2799 * op data being queried.
2800 *
2801 * @param flags The flags which are any combination of
2802 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2803 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2804 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2805 * for any flag.
2806 * @return This builder.
2807 */
2808 public @NonNull Builder setFlags(@OpFlags int flags) {
2809 Preconditions.checkFlagsArgument(flags, OP_FLAGS_ALL);
2810 mFlags = flags;
2811 return this;
2812 }
2813
2814 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08002815 * @return a new {@link HistoricalOpsRequest}.
2816 */
2817 public @NonNull HistoricalOpsRequest build() {
2818 return new HistoricalOpsRequest(mUid, mPackageName, mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08002819 mBeginTimeMillis, mEndTimeMillis, mFlags);
Svet Ganov23c88db2019-01-22 20:38:11 -08002820 }
2821 }
2822 }
2823
2824 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08002825 * This class represents historical app op state of all UIDs for a given time interval.
2826 *
2827 * @hide
2828 */
2829 @TestApi
2830 @SystemApi
2831 public static final class HistoricalOps implements Parcelable {
2832 private long mBeginTimeMillis;
2833 private long mEndTimeMillis;
2834 private @Nullable SparseArray<HistoricalUidOps> mHistoricalUidOps;
2835
2836 /** @hide */
2837 @TestApi
2838 public HistoricalOps(long beginTimeMillis, long endTimeMillis) {
2839 Preconditions.checkState(beginTimeMillis <= endTimeMillis);
2840 mBeginTimeMillis = beginTimeMillis;
2841 mEndTimeMillis = endTimeMillis;
2842 }
2843
2844 /** @hide */
2845 public HistoricalOps(@NonNull HistoricalOps other) {
2846 mBeginTimeMillis = other.mBeginTimeMillis;
2847 mEndTimeMillis = other.mEndTimeMillis;
2848 Preconditions.checkState(mBeginTimeMillis <= mEndTimeMillis);
2849 if (other.mHistoricalUidOps != null) {
2850 final int opCount = other.getUidCount();
2851 for (int i = 0; i < opCount; i++) {
2852 final HistoricalUidOps origOps = other.getUidOpsAt(i);
2853 final HistoricalUidOps clonedOps = new HistoricalUidOps(origOps);
2854 if (mHistoricalUidOps == null) {
2855 mHistoricalUidOps = new SparseArray<>(opCount);
2856 }
2857 mHistoricalUidOps.put(clonedOps.getUid(), clonedOps);
2858 }
2859 }
2860 }
2861
2862 private HistoricalOps(Parcel parcel) {
2863 mBeginTimeMillis = parcel.readLong();
2864 mEndTimeMillis = parcel.readLong();
2865 final int[] uids = parcel.createIntArray();
2866 if (!ArrayUtils.isEmpty(uids)) {
2867 final ParceledListSlice<HistoricalUidOps> listSlice = parcel.readParcelable(
2868 HistoricalOps.class.getClassLoader());
2869 final List<HistoricalUidOps> uidOps = (listSlice != null)
2870 ? listSlice.getList() : null;
2871 if (uidOps == null) {
2872 return;
2873 }
2874 for (int i = 0; i < uids.length; i++) {
2875 if (mHistoricalUidOps == null) {
2876 mHistoricalUidOps = new SparseArray<>();
2877 }
2878 mHistoricalUidOps.put(uids[i], uidOps.get(i));
2879 }
2880 }
2881 }
2882
2883 /**
2884 * Splice a piece from the beginning of these ops.
2885 *
2886 * @param splicePoint The fraction of the data to be spliced off.
2887 *
2888 * @hide
2889 */
2890 public @NonNull HistoricalOps spliceFromBeginning(double splicePoint) {
2891 return splice(splicePoint, true);
2892 }
2893
2894 /**
2895 * Splice a piece from the end of these ops.
2896 *
2897 * @param fractionToRemove The fraction of the data to be spliced off.
2898 *
2899 * @hide
2900 */
2901 public @NonNull HistoricalOps spliceFromEnd(double fractionToRemove) {
2902 return splice(fractionToRemove, false);
2903 }
2904
2905 /**
2906 * Splice a piece from the beginning or end of these ops.
2907 *
2908 * @param fractionToRemove The fraction of the data to be spliced off.
2909 * @param beginning Whether to splice off the beginning or the end.
2910 *
2911 * @return The spliced off part.
2912 *
2913 * @hide
2914 */
2915 private @Nullable HistoricalOps splice(double fractionToRemove, boolean beginning) {
2916 final long spliceBeginTimeMills;
2917 final long spliceEndTimeMills;
2918 if (beginning) {
2919 spliceBeginTimeMills = mBeginTimeMillis;
2920 spliceEndTimeMills = (long) (mBeginTimeMillis
2921 + getDurationMillis() * fractionToRemove);
2922 mBeginTimeMillis = spliceEndTimeMills;
2923 } else {
2924 spliceBeginTimeMills = (long) (mEndTimeMillis
2925 - getDurationMillis() * fractionToRemove);
2926 spliceEndTimeMills = mEndTimeMillis;
2927 mEndTimeMillis = spliceBeginTimeMills;
2928 }
2929
2930 HistoricalOps splice = null;
2931 final int uidCount = getUidCount();
2932 for (int i = 0; i < uidCount; i++) {
2933 final HistoricalUidOps origOps = getUidOpsAt(i);
2934 final HistoricalUidOps spliceOps = origOps.splice(fractionToRemove);
2935 if (spliceOps != null) {
2936 if (splice == null) {
2937 splice = new HistoricalOps(spliceBeginTimeMills, spliceEndTimeMills);
2938 }
2939 if (splice.mHistoricalUidOps == null) {
2940 splice.mHistoricalUidOps = new SparseArray<>();
2941 }
2942 splice.mHistoricalUidOps.put(spliceOps.getUid(), spliceOps);
2943 }
2944 }
2945 return splice;
2946 }
2947
2948 /**
2949 * Merge the passed ops into the current ones. The time interval is a
2950 * union of the current and passed in one and the passed in data is
2951 * folded into the data of this instance.
2952 *
2953 * @hide
2954 */
2955 public void merge(@NonNull HistoricalOps other) {
2956 mBeginTimeMillis = Math.min(mBeginTimeMillis, other.mBeginTimeMillis);
2957 mEndTimeMillis = Math.max(mEndTimeMillis, other.mEndTimeMillis);
2958 final int uidCount = other.getUidCount();
2959 for (int i = 0; i < uidCount; i++) {
2960 final HistoricalUidOps otherUidOps = other.getUidOpsAt(i);
2961 final HistoricalUidOps thisUidOps = getUidOps(otherUidOps.getUid());
2962 if (thisUidOps != null) {
2963 thisUidOps.merge(otherUidOps);
2964 } else {
2965 if (mHistoricalUidOps == null) {
2966 mHistoricalUidOps = new SparseArray<>();
2967 }
2968 mHistoricalUidOps.put(otherUidOps.getUid(), otherUidOps);
2969 }
2970 }
2971 }
2972
2973 /**
2974 * AppPermissionUsage the ops to leave only the data we filter for.
2975 *
2976 * @param uid Uid to filter for or {@link android.os.Process#INCIDENTD_UID} for all.
2977 * @param packageName Package to filter for or null for all.
2978 * @param opNames Ops to filter for or null for all.
2979 * @param beginTimeMillis The begin time to filter for or {@link Long#MIN_VALUE} for all.
2980 * @param endTimeMillis The end time to filter for or {@link Long#MAX_VALUE} for all.
2981 *
2982 * @hide
2983 */
2984 public void filter(int uid, @Nullable String packageName, @Nullable String[] opNames,
2985 long beginTimeMillis, long endTimeMillis) {
2986 final long durationMillis = getDurationMillis();
2987 mBeginTimeMillis = Math.max(mBeginTimeMillis, beginTimeMillis);
2988 mEndTimeMillis = Math.min(mEndTimeMillis, endTimeMillis);
2989 final double scaleFactor = Math.min((double) (endTimeMillis - beginTimeMillis)
2990 / (double) durationMillis, 1);
2991 final int uidCount = getUidCount();
2992 for (int i = uidCount - 1; i >= 0; i--) {
2993 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
2994 if (uid != Process.INVALID_UID && uid != uidOp.getUid()) {
2995 mHistoricalUidOps.removeAt(i);
2996 } else {
2997 uidOp.filter(packageName, opNames, scaleFactor);
2998 }
2999 }
3000 }
3001
3002 /** @hide */
3003 public boolean isEmpty() {
3004 if (getBeginTimeMillis() >= getEndTimeMillis()) {
3005 return true;
3006 }
3007 final int uidCount = getUidCount();
3008 for (int i = uidCount - 1; i >= 0; i--) {
3009 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
3010 if (!uidOp.isEmpty()) {
3011 return false;
3012 }
3013 }
3014 return true;
3015 }
3016
3017 /** @hide */
3018 public long getDurationMillis() {
3019 return mEndTimeMillis - mBeginTimeMillis;
3020 }
3021
3022 /** @hide */
3023 @TestApi
3024 public void increaseAccessCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003025 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003026 getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003027 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003028 }
3029
3030 /** @hide */
3031 @TestApi
3032 public void increaseRejectCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003033 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003034 getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003035 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003036 }
3037
3038 /** @hide */
3039 @TestApi
3040 public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003041 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003042 getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003043 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003044 }
3045
3046 /** @hide */
3047 @TestApi
3048 public void offsetBeginAndEndTime(long offsetMillis) {
3049 mBeginTimeMillis += offsetMillis;
3050 mEndTimeMillis += offsetMillis;
3051 }
3052
3053 /** @hide */
3054 public void setBeginAndEndTime(long beginTimeMillis, long endTimeMillis) {
3055 mBeginTimeMillis = beginTimeMillis;
3056 mEndTimeMillis = endTimeMillis;
3057 }
3058
3059 /** @hide */
3060 public void setBeginTime(long beginTimeMillis) {
3061 mBeginTimeMillis = beginTimeMillis;
3062 }
3063
3064 /** @hide */
3065 public void setEndTime(long endTimeMillis) {
3066 mEndTimeMillis = endTimeMillis;
3067 }
3068
3069 /**
3070 * @return The beginning of the interval in milliseconds since
3071 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3072 */
3073 public long getBeginTimeMillis() {
3074 return mBeginTimeMillis;
3075 }
3076
3077 /**
3078 * @return The end of the interval in milliseconds since
3079 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3080 */
3081 public long getEndTimeMillis() {
3082 return mEndTimeMillis;
3083 }
3084
3085 /**
3086 * Gets number of UIDs with historical ops.
3087 *
3088 * @return The number of UIDs with historical ops.
3089 *
3090 * @see #getUidOpsAt(int)
3091 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003092 public @IntRange(from = 0) int getUidCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003093 if (mHistoricalUidOps == null) {
3094 return 0;
3095 }
3096 return mHistoricalUidOps.size();
3097 }
3098
3099 /**
3100 * Gets the historical UID ops at a given index.
3101 *
3102 * @param index The index.
3103 *
3104 * @return The historical UID ops at the given index.
3105 *
3106 * @see #getUidCount()
3107 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003108 public @NonNull HistoricalUidOps getUidOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003109 if (mHistoricalUidOps == null) {
3110 throw new IndexOutOfBoundsException();
3111 }
3112 return mHistoricalUidOps.valueAt(index);
3113 }
3114
3115 /**
3116 * Gets the historical UID ops for a given UID.
3117 *
3118 * @param uid The UID.
3119 *
3120 * @return The historical ops for the UID.
3121 */
3122 public @Nullable HistoricalUidOps getUidOps(int uid) {
3123 if (mHistoricalUidOps == null) {
3124 return null;
3125 }
3126 return mHistoricalUidOps.get(uid);
3127 }
3128
Winson4e3b4352019-05-07 16:29:59 -07003129 /** @hide */
3130 public void clearHistory(int uid, @NonNull String packageName) {
3131 HistoricalUidOps historicalUidOps = getOrCreateHistoricalUidOps(uid);
3132 historicalUidOps.clearHistory(packageName);
3133 if (historicalUidOps.isEmpty()) {
3134 mHistoricalUidOps.remove(uid);
3135 }
3136 }
3137
Svet Ganov8455ba22019-01-02 13:05:56 -08003138 @Override
3139 public int describeContents() {
3140 return 0;
3141 }
3142
3143 @Override
3144 public void writeToParcel(Parcel parcel, int flags) {
3145 parcel.writeLong(mBeginTimeMillis);
3146 parcel.writeLong(mEndTimeMillis);
3147 if (mHistoricalUidOps != null) {
3148 final int uidCount = mHistoricalUidOps.size();
3149 parcel.writeInt(uidCount);
3150 for (int i = 0; i < uidCount; i++) {
3151 parcel.writeInt(mHistoricalUidOps.keyAt(i));
3152 }
3153 final List<HistoricalUidOps> opsList = new ArrayList<>(uidCount);
3154 for (int i = 0; i < uidCount; i++) {
3155 opsList.add(mHistoricalUidOps.valueAt(i));
3156 }
3157 parcel.writeParcelable(new ParceledListSlice<>(opsList), flags);
3158 } else {
3159 parcel.writeInt(-1);
3160 }
3161 }
3162
3163 /**
3164 * Accepts a visitor to traverse the ops tree.
3165 *
3166 * @param visitor The visitor.
3167 *
3168 * @hide
3169 */
3170 public void accept(@NonNull HistoricalOpsVisitor visitor) {
3171 visitor.visitHistoricalOps(this);
3172 final int uidCount = getUidCount();
3173 for (int i = 0; i < uidCount; i++) {
3174 getUidOpsAt(i).accept(visitor);
3175 }
3176 }
3177
3178 private @NonNull HistoricalUidOps getOrCreateHistoricalUidOps(int uid) {
3179 if (mHistoricalUidOps == null) {
3180 mHistoricalUidOps = new SparseArray<>();
3181 }
3182 HistoricalUidOps historicalUidOp = mHistoricalUidOps.get(uid);
3183 if (historicalUidOp == null) {
3184 historicalUidOp = new HistoricalUidOps(uid);
3185 mHistoricalUidOps.put(uid, historicalUidOp);
3186 }
3187 return historicalUidOp;
3188 }
3189
3190 /**
3191 * @return Rounded value up at the 0.5 boundary.
3192 *
3193 * @hide
3194 */
3195 public static double round(double value) {
3196 final BigDecimal decimalScale = new BigDecimal(value);
3197 return decimalScale.setScale(0, RoundingMode.HALF_UP).doubleValue();
3198 }
3199
3200 @Override
Aurimas Liutikas00be9512019-08-28 13:01:05 -07003201 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003202 if (this == obj) {
3203 return true;
3204 }
3205 if (obj == null || getClass() != obj.getClass()) {
3206 return false;
3207 }
3208 final HistoricalOps other = (HistoricalOps) obj;
3209 if (mBeginTimeMillis != other.mBeginTimeMillis) {
3210 return false;
3211 }
3212 if (mEndTimeMillis != other.mEndTimeMillis) {
3213 return false;
3214 }
3215 if (mHistoricalUidOps == null) {
3216 if (other.mHistoricalUidOps != null) {
3217 return false;
3218 }
3219 } else if (!mHistoricalUidOps.equals(other.mHistoricalUidOps)) {
3220 return false;
3221 }
3222 return true;
3223 }
3224
3225 @Override
3226 public int hashCode() {
3227 int result = (int) (mBeginTimeMillis ^ (mBeginTimeMillis >>> 32));
3228 result = 31 * result + mHistoricalUidOps.hashCode();
3229 return result;
3230 }
3231
Aurimas Liutikas00be9512019-08-28 13:01:05 -07003232 @NonNull
Svet Ganov8455ba22019-01-02 13:05:56 -08003233 @Override
3234 public String toString() {
3235 return getClass().getSimpleName() + "[from:"
3236 + mBeginTimeMillis + " to:" + mEndTimeMillis + "]";
3237 }
3238
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07003239 public static final @android.annotation.NonNull Creator<HistoricalOps> CREATOR = new Creator<HistoricalOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003240 @Override
3241 public @NonNull HistoricalOps createFromParcel(@NonNull Parcel parcel) {
3242 return new HistoricalOps(parcel);
3243 }
3244
3245 @Override
3246 public @NonNull HistoricalOps[] newArray(int size) {
3247 return new HistoricalOps[size];
3248 }
3249 };
3250 }
3251
3252 /**
3253 * This class represents historical app op state for a UID.
3254 *
3255 * @hide
3256 */
3257 @TestApi
3258 @SystemApi
3259 public static final class HistoricalUidOps implements Parcelable {
3260 private final int mUid;
3261 private @Nullable ArrayMap<String, HistoricalPackageOps> mHistoricalPackageOps;
3262
3263 /** @hide */
3264 public HistoricalUidOps(int uid) {
3265 mUid = uid;
3266 }
3267
3268 private HistoricalUidOps(@NonNull HistoricalUidOps other) {
3269 mUid = other.mUid;
3270 final int opCount = other.getPackageCount();
3271 for (int i = 0; i < opCount; i++) {
3272 final HistoricalPackageOps origOps = other.getPackageOpsAt(i);
3273 final HistoricalPackageOps cloneOps = new HistoricalPackageOps(origOps);
3274 if (mHistoricalPackageOps == null) {
3275 mHistoricalPackageOps = new ArrayMap<>(opCount);
3276 }
3277 mHistoricalPackageOps.put(cloneOps.getPackageName(), cloneOps);
3278 }
3279 }
3280
3281 private HistoricalUidOps(@NonNull Parcel parcel) {
3282 // No arg check since we always read from a trusted source.
3283 mUid = parcel.readInt();
3284 mHistoricalPackageOps = parcel.createTypedArrayMap(HistoricalPackageOps.CREATOR);
3285 }
3286
3287 private @Nullable HistoricalUidOps splice(double fractionToRemove) {
3288 HistoricalUidOps splice = null;
3289 final int packageCount = getPackageCount();
3290 for (int i = 0; i < packageCount; i++) {
3291 final HistoricalPackageOps origOps = getPackageOpsAt(i);
3292 final HistoricalPackageOps spliceOps = origOps.splice(fractionToRemove);
3293 if (spliceOps != null) {
3294 if (splice == null) {
3295 splice = new HistoricalUidOps(mUid);
3296 }
3297 if (splice.mHistoricalPackageOps == null) {
3298 splice.mHistoricalPackageOps = new ArrayMap<>();
3299 }
3300 splice.mHistoricalPackageOps.put(spliceOps.getPackageName(), spliceOps);
3301 }
3302 }
3303 return splice;
3304 }
3305
3306 private void merge(@NonNull HistoricalUidOps other) {
3307 final int packageCount = other.getPackageCount();
3308 for (int i = 0; i < packageCount; i++) {
3309 final HistoricalPackageOps otherPackageOps = other.getPackageOpsAt(i);
3310 final HistoricalPackageOps thisPackageOps = getPackageOps(
3311 otherPackageOps.getPackageName());
3312 if (thisPackageOps != null) {
3313 thisPackageOps.merge(otherPackageOps);
3314 } else {
3315 if (mHistoricalPackageOps == null) {
3316 mHistoricalPackageOps = new ArrayMap<>();
3317 }
3318 mHistoricalPackageOps.put(otherPackageOps.getPackageName(), otherPackageOps);
3319 }
3320 }
3321 }
3322
3323 private void filter(@Nullable String packageName, @Nullable String[] opNames,
3324 double fractionToRemove) {
3325 final int packageCount = getPackageCount();
3326 for (int i = packageCount - 1; i >= 0; i--) {
3327 final HistoricalPackageOps packageOps = getPackageOpsAt(i);
3328 if (packageName != null && !packageName.equals(packageOps.getPackageName())) {
3329 mHistoricalPackageOps.removeAt(i);
3330 } else {
3331 packageOps.filter(opNames, fractionToRemove);
3332 }
3333 }
3334 }
3335
3336 private boolean isEmpty() {
3337 final int packageCount = getPackageCount();
3338 for (int i = packageCount - 1; i >= 0; i--) {
3339 final HistoricalPackageOps packageOps = mHistoricalPackageOps.valueAt(i);
3340 if (!packageOps.isEmpty()) {
3341 return false;
3342 }
3343 }
3344 return true;
3345 }
3346
3347 private void increaseAccessCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003348 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003349 getOrCreateHistoricalPackageOps(packageName).increaseAccessCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08003350 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003351 }
3352
3353 private void increaseRejectCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003354 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003355 getOrCreateHistoricalPackageOps(packageName).increaseRejectCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08003356 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003357 }
3358
3359 private void increaseAccessDuration(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003360 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003361 getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration(
Svet Ganovaf189e32019-02-15 18:45:29 -08003362 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003363 }
3364
3365 /**
3366 * @return The UID for which the data is related.
3367 */
3368 public int getUid() {
3369 return mUid;
3370 }
3371
3372 /**
3373 * Gets number of packages with historical ops.
3374 *
3375 * @return The number of packages with historical ops.
3376 *
3377 * @see #getPackageOpsAt(int)
3378 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003379 public @IntRange(from = 0) int getPackageCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003380 if (mHistoricalPackageOps == null) {
3381 return 0;
3382 }
3383 return mHistoricalPackageOps.size();
3384 }
3385
3386 /**
3387 * Gets the historical package ops at a given index.
3388 *
3389 * @param index The index.
3390 *
3391 * @return The historical package ops at the given index.
3392 *
3393 * @see #getPackageCount()
3394 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003395 public @NonNull HistoricalPackageOps getPackageOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003396 if (mHistoricalPackageOps == null) {
3397 throw new IndexOutOfBoundsException();
3398 }
3399 return mHistoricalPackageOps.valueAt(index);
3400 }
3401
3402 /**
3403 * Gets the historical package ops for a given package.
3404 *
3405 * @param packageName The package.
3406 *
3407 * @return The historical ops for the package.
3408 */
3409 public @Nullable HistoricalPackageOps getPackageOps(@NonNull String packageName) {
3410 if (mHistoricalPackageOps == null) {
3411 return null;
3412 }
3413 return mHistoricalPackageOps.get(packageName);
3414 }
3415
Winson4e3b4352019-05-07 16:29:59 -07003416 private void clearHistory(@NonNull String packageName) {
3417 if (mHistoricalPackageOps != null) {
3418 mHistoricalPackageOps.remove(packageName);
3419 }
3420 }
3421
Svet Ganov8455ba22019-01-02 13:05:56 -08003422 @Override
3423 public int describeContents() {
3424 return 0;
3425 }
3426
3427 @Override
3428 public void writeToParcel(Parcel parcel, int flags) {
3429 parcel.writeInt(mUid);
3430 parcel.writeTypedArrayMap(mHistoricalPackageOps, flags);
3431 }
3432
3433 private void accept(@NonNull HistoricalOpsVisitor visitor) {
3434 visitor.visitHistoricalUidOps(this);
3435 final int packageCount = getPackageCount();
3436 for (int i = 0; i < packageCount; i++) {
3437 getPackageOpsAt(i).accept(visitor);
3438 }
3439 }
3440
3441 private @NonNull HistoricalPackageOps getOrCreateHistoricalPackageOps(
3442 @NonNull String packageName) {
3443 if (mHistoricalPackageOps == null) {
3444 mHistoricalPackageOps = new ArrayMap<>();
3445 }
3446 HistoricalPackageOps historicalPackageOp = mHistoricalPackageOps.get(packageName);
3447 if (historicalPackageOp == null) {
3448 historicalPackageOp = new HistoricalPackageOps(packageName);
3449 mHistoricalPackageOps.put(packageName, historicalPackageOp);
3450 }
3451 return historicalPackageOp;
3452 }
3453
3454
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07003455 public static final @android.annotation.NonNull Creator<HistoricalUidOps> CREATOR = new Creator<HistoricalUidOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003456 @Override
3457 public @NonNull HistoricalUidOps createFromParcel(@NonNull Parcel parcel) {
3458 return new HistoricalUidOps(parcel);
3459 }
3460
3461 @Override
3462 public @NonNull HistoricalUidOps[] newArray(int size) {
3463 return new HistoricalUidOps[size];
3464 }
3465 };
3466
3467 @Override
Aurimas Liutikas00be9512019-08-28 13:01:05 -07003468 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003469 if (this == obj) {
3470 return true;
3471 }
3472 if (obj == null || getClass() != obj.getClass()) {
3473 return false;
3474 }
3475 final HistoricalUidOps other = (HistoricalUidOps) obj;
3476 if (mUid != other.mUid) {
3477 return false;
3478 }
3479 if (mHistoricalPackageOps == null) {
3480 if (other.mHistoricalPackageOps != null) {
3481 return false;
3482 }
3483 } else if (!mHistoricalPackageOps.equals(other.mHistoricalPackageOps)) {
3484 return false;
3485 }
3486 return true;
3487 }
3488
3489 @Override
3490 public int hashCode() {
3491 int result = mUid;
3492 result = 31 * result + (mHistoricalPackageOps != null
3493 ? mHistoricalPackageOps.hashCode() : 0);
3494 return result;
3495 }
3496 }
3497
3498 /**
3499 * This class represents historical app op information about a package.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003500 *
3501 * @hide
3502 */
3503 @TestApi
3504 @SystemApi
3505 public static final class HistoricalPackageOps implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003506 private final @NonNull String mPackageName;
Svet Ganov8455ba22019-01-02 13:05:56 -08003507 private @Nullable ArrayMap<String, HistoricalOp> mHistoricalOps;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003508
Svet Ganov8455ba22019-01-02 13:05:56 -08003509 /** @hide */
3510 public HistoricalPackageOps(@NonNull String packageName) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003511 mPackageName = packageName;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003512 }
3513
Svet Ganov8455ba22019-01-02 13:05:56 -08003514 private HistoricalPackageOps(@NonNull HistoricalPackageOps other) {
3515 mPackageName = other.mPackageName;
3516 final int opCount = other.getOpCount();
3517 for (int i = 0; i < opCount; i++) {
3518 final HistoricalOp origOp = other.getOpAt(i);
3519 final HistoricalOp cloneOp = new HistoricalOp(origOp);
3520 if (mHistoricalOps == null) {
3521 mHistoricalOps = new ArrayMap<>(opCount);
3522 }
3523 mHistoricalOps.put(cloneOp.getOpName(), cloneOp);
3524 }
3525 }
3526
3527 private HistoricalPackageOps(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003528 mPackageName = parcel.readString();
Svet Ganov8455ba22019-01-02 13:05:56 -08003529 mHistoricalOps = parcel.createTypedArrayMap(HistoricalOp.CREATOR);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003530 }
3531
Svet Ganov8455ba22019-01-02 13:05:56 -08003532 private @Nullable HistoricalPackageOps splice(double fractionToRemove) {
3533 HistoricalPackageOps splice = null;
3534 final int opCount = getOpCount();
3535 for (int i = 0; i < opCount; i++) {
3536 final HistoricalOp origOps = getOpAt(i);
3537 final HistoricalOp spliceOps = origOps.splice(fractionToRemove);
3538 if (spliceOps != null) {
3539 if (splice == null) {
3540 splice = new HistoricalPackageOps(mPackageName);
3541 }
3542 if (splice.mHistoricalOps == null) {
3543 splice.mHistoricalOps = new ArrayMap<>();
3544 }
3545 splice.mHistoricalOps.put(spliceOps.getOpName(), spliceOps);
3546 }
3547 }
3548 return splice;
3549 }
3550
3551 private void merge(@NonNull HistoricalPackageOps other) {
3552 final int opCount = other.getOpCount();
3553 for (int i = 0; i < opCount; i++) {
3554 final HistoricalOp otherOp = other.getOpAt(i);
3555 final HistoricalOp thisOp = getOp(otherOp.getOpName());
3556 if (thisOp != null) {
3557 thisOp.merge(otherOp);
3558 } else {
3559 if (mHistoricalOps == null) {
3560 mHistoricalOps = new ArrayMap<>();
3561 }
3562 mHistoricalOps.put(otherOp.getOpName(), otherOp);
3563 }
3564 }
3565 }
3566
3567 private void filter(@Nullable String[] opNames, double scaleFactor) {
3568 final int opCount = getOpCount();
3569 for (int i = opCount - 1; i >= 0; i--) {
3570 final HistoricalOp op = mHistoricalOps.valueAt(i);
3571 if (opNames != null && !ArrayUtils.contains(opNames, op.getOpName())) {
3572 mHistoricalOps.removeAt(i);
3573 } else {
3574 op.filter(scaleFactor);
3575 }
3576 }
3577 }
3578
3579 private boolean isEmpty() {
3580 final int opCount = getOpCount();
3581 for (int i = opCount - 1; i >= 0; i--) {
3582 final HistoricalOp op = mHistoricalOps.valueAt(i);
3583 if (!op.isEmpty()) {
3584 return false;
3585 }
3586 }
3587 return true;
3588 }
3589
Svet Ganovaf189e32019-02-15 18:45:29 -08003590 private void increaseAccessCount(int opCode, @UidState int uidState,
3591 @OpFlags int flags, long increment) {
3592 getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003593 }
3594
Svet Ganovaf189e32019-02-15 18:45:29 -08003595 private void increaseRejectCount(int opCode, @UidState int uidState,
3596 @OpFlags int flags, long increment) {
3597 getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003598 }
3599
Svet Ganovaf189e32019-02-15 18:45:29 -08003600 private void increaseAccessDuration(int opCode, @UidState int uidState,
3601 @OpFlags int flags, long increment) {
3602 getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, flags, increment);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003603 }
3604
3605 /**
3606 * Gets the package name which the data represents.
3607 *
3608 * @return The package name which the data represents.
3609 */
3610 public @NonNull String getPackageName() {
3611 return mPackageName;
3612 }
3613
3614 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003615 * Gets number historical app ops.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003616 *
Svet Ganov8455ba22019-01-02 13:05:56 -08003617 * @return The number historical app ops.
Svet Ganov8455ba22019-01-02 13:05:56 -08003618 * @see #getOpAt(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003619 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003620 public @IntRange(from = 0) int getOpCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003621 if (mHistoricalOps == null) {
3622 return 0;
3623 }
3624 return mHistoricalOps.size();
Svet Ganovad0a49b2018-10-29 10:07:08 -07003625 }
3626
3627 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003628 * Gets the historical op at a given index.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003629 *
3630 * @param index The index to lookup.
Svet Ganov8455ba22019-01-02 13:05:56 -08003631 * @return The op at the given index.
Svet Ganov8455ba22019-01-02 13:05:56 -08003632 * @see #getOpCount()
Svet Ganovad0a49b2018-10-29 10:07:08 -07003633 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003634 public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003635 if (mHistoricalOps == null) {
3636 throw new IndexOutOfBoundsException();
3637 }
3638 return mHistoricalOps.valueAt(index);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003639 }
3640
3641 /**
3642 * Gets the historical entry for a given op name.
3643 *
3644 * @param opName The op name.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003645 * @return The historical entry for that op name.
3646 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003647 public @Nullable HistoricalOp getOp(@NonNull String opName) {
3648 if (mHistoricalOps == null) {
3649 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003650 }
Svet Ganov8455ba22019-01-02 13:05:56 -08003651 return mHistoricalOps.get(opName);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003652 }
3653
3654 @Override
3655 public int describeContents() {
3656 return 0;
3657 }
3658
3659 @Override
3660 public void writeToParcel(@NonNull Parcel parcel, int flags) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003661 parcel.writeString(mPackageName);
Svet Ganov8455ba22019-01-02 13:05:56 -08003662 parcel.writeTypedArrayMap(mHistoricalOps, flags);
3663 }
3664
3665 private void accept(@NonNull HistoricalOpsVisitor visitor) {
3666 visitor.visitHistoricalPackageOps(this);
3667 final int opCount = getOpCount();
3668 for (int i = 0; i < opCount; i++) {
3669 getOpAt(i).accept(visitor);
3670 }
3671 }
3672
3673 private @NonNull HistoricalOp getOrCreateHistoricalOp(int opCode) {
3674 if (mHistoricalOps == null) {
3675 mHistoricalOps = new ArrayMap<>();
3676 }
3677 final String opStr = sOpToString[opCode];
3678 HistoricalOp op = mHistoricalOps.get(opStr);
3679 if (op == null) {
3680 op = new HistoricalOp(opCode);
3681 mHistoricalOps.put(opStr, op);
3682 }
3683 return op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003684 }
3685
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07003686 public static final @android.annotation.NonNull Creator<HistoricalPackageOps> CREATOR =
Svet Ganovad0a49b2018-10-29 10:07:08 -07003687 new Creator<HistoricalPackageOps>() {
3688 @Override
3689 public @NonNull HistoricalPackageOps createFromParcel(@NonNull Parcel parcel) {
3690 return new HistoricalPackageOps(parcel);
3691 }
3692
3693 @Override
3694 public @NonNull HistoricalPackageOps[] newArray(int size) {
3695 return new HistoricalPackageOps[size];
3696 }
3697 };
Svet Ganov8455ba22019-01-02 13:05:56 -08003698
3699 @Override
Aurimas Liutikas00be9512019-08-28 13:01:05 -07003700 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003701 if (this == obj) {
3702 return true;
3703 }
3704 if (obj == null || getClass() != obj.getClass()) {
3705 return false;
3706 }
3707 final HistoricalPackageOps other = (HistoricalPackageOps) obj;
3708 if (!mPackageName.equals(other.mPackageName)) {
3709 return false;
3710 }
3711 if (mHistoricalOps == null) {
3712 if (other.mHistoricalOps != null) {
3713 return false;
3714 }
3715 } else if (!mHistoricalOps.equals(other.mHistoricalOps)) {
3716 return false;
3717 }
3718 return true;
3719 }
3720
3721 @Override
3722 public int hashCode() {
3723 int result = mPackageName != null ? mPackageName.hashCode() : 0;
3724 result = 31 * result + (mHistoricalOps != null ? mHistoricalOps.hashCode() : 0);
3725 return result;
3726 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003727 }
3728
3729 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003730 * This class represents historical information about an app op.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003731 *
3732 * @hide
3733 */
3734 @TestApi
3735 @SystemApi
Svet Ganov8455ba22019-01-02 13:05:56 -08003736 public static final class HistoricalOp implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003737 private final int mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08003738 private @Nullable LongSparseLongArray mAccessCount;
3739 private @Nullable LongSparseLongArray mRejectCount;
3740 private @Nullable LongSparseLongArray mAccessDuration;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003741
Svet Ganov8455ba22019-01-02 13:05:56 -08003742 /** @hide */
3743 public HistoricalOp(int op) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003744 mOp = op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003745 }
3746
Svet Ganov8455ba22019-01-02 13:05:56 -08003747 private HistoricalOp(@NonNull HistoricalOp other) {
3748 mOp = other.mOp;
3749 if (other.mAccessCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003750 mAccessCount = other.mAccessCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08003751 }
3752 if (other.mRejectCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003753 mRejectCount = other.mRejectCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08003754 }
3755 if (other.mAccessDuration != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003756 mAccessDuration = other.mAccessDuration.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08003757 }
3758 }
3759
3760 private HistoricalOp(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003761 mOp = parcel.readInt();
Svet Ganovaf189e32019-02-15 18:45:29 -08003762 mAccessCount = readLongSparseLongArrayFromParcel(parcel);
3763 mRejectCount = readLongSparseLongArrayFromParcel(parcel);
3764 mAccessDuration = readLongSparseLongArrayFromParcel(parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003765 }
3766
Svet Ganov8455ba22019-01-02 13:05:56 -08003767 private void filter(double scaleFactor) {
3768 scale(mAccessCount, scaleFactor);
3769 scale(mRejectCount, scaleFactor);
3770 scale(mAccessDuration, scaleFactor);
3771 }
3772
3773 private boolean isEmpty() {
3774 return !hasData(mAccessCount)
3775 && !hasData(mRejectCount)
3776 && !hasData(mAccessDuration);
3777 }
3778
Svet Ganovaf189e32019-02-15 18:45:29 -08003779 private boolean hasData(@NonNull LongSparseLongArray array) {
3780 return (array != null && array.size() > 0);
Svet Ganov8455ba22019-01-02 13:05:56 -08003781 }
3782
3783 private @Nullable HistoricalOp splice(double fractionToRemove) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003784 final HistoricalOp splice = new HistoricalOp(mOp);
3785 splice(mAccessCount, splice::getOrCreateAccessCount, fractionToRemove);
3786 splice(mRejectCount, splice::getOrCreateRejectCount, fractionToRemove);
3787 splice(mAccessDuration, splice::getOrCreateAccessDuration, fractionToRemove);
Svet Ganov8455ba22019-01-02 13:05:56 -08003788 return splice;
3789 }
3790
Svet Ganovaf189e32019-02-15 18:45:29 -08003791 private static void splice(@Nullable LongSparseLongArray sourceContainer,
3792 @NonNull Supplier<LongSparseLongArray> destContainerProvider,
3793 double fractionToRemove) {
3794 if (sourceContainer != null) {
3795 final int size = sourceContainer.size();
3796 for (int i = 0; i < size; i++) {
3797 final long key = sourceContainer.keyAt(i);
3798 final long value = sourceContainer.valueAt(i);
3799 final long removedFraction = Math.round(value * fractionToRemove);
3800 if (removedFraction > 0) {
3801 destContainerProvider.get().put(key, removedFraction);
3802 sourceContainer.put(key, value - removedFraction);
3803 }
3804 }
3805 }
3806 }
3807
Svet Ganov8455ba22019-01-02 13:05:56 -08003808 private void merge(@NonNull HistoricalOp other) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003809 merge(this::getOrCreateAccessCount, other.mAccessCount);
3810 merge(this::getOrCreateRejectCount, other.mRejectCount);
3811 merge(this::getOrCreateAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08003812 }
3813
Svet Ganovaf189e32019-02-15 18:45:29 -08003814 private void increaseAccessCount(@UidState int uidState, @OpFlags int flags,
3815 long increment) {
3816 increaseCount(getOrCreateAccessCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003817 }
3818
Svet Ganovaf189e32019-02-15 18:45:29 -08003819 private void increaseRejectCount(@UidState int uidState, @OpFlags int flags,
3820 long increment) {
3821 increaseCount(getOrCreateRejectCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003822 }
3823
Svet Ganovaf189e32019-02-15 18:45:29 -08003824 private void increaseAccessDuration(@UidState int uidState, @OpFlags int flags,
3825 long increment) {
3826 increaseCount(getOrCreateAccessDuration(), uidState, flags, increment);
3827 }
3828
3829 private void increaseCount(@NonNull LongSparseLongArray counts,
3830 @UidState int uidState, @OpFlags int flags, long increment) {
3831 while (flags != 0) {
3832 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
3833 flags &= ~flag;
3834 final long key = makeKey(uidState, flag);
3835 counts.put(key, counts.get(key) + increment);
3836 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003837 }
3838
3839 /**
3840 * Gets the op name.
3841 *
3842 * @return The op name.
3843 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003844 public @NonNull String getOpName() {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003845 return sOpToString[mOp];
3846 }
3847
Svet Ganov8455ba22019-01-02 13:05:56 -08003848 /** @hide */
3849 public int getOpCode() {
3850 return mOp;
3851 }
3852
Svet Ganovad0a49b2018-10-29 10:07:08 -07003853 /**
3854 * Gets the number times the op was accessed (performed) in the foreground.
3855 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003856 * @param flags The flags which are any combination of
3857 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3858 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3859 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3860 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003861 * @return The times the op was accessed in the foreground.
3862 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003863 * @see #getBackgroundAccessCount(int)
3864 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003865 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003866 public long getForegroundAccessCount(@OpFlags int flags) {
3867 return sumForFlagsInStates(mAccessCount, MAX_PRIORITY_UID_STATE,
3868 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003869 }
3870
3871 /**
3872 * Gets the number times the op was accessed (performed) in the background.
3873 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003874 * @param flags The flags which are any combination of
3875 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3876 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3877 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3878 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003879 * @return The times the op was accessed in the background.
3880 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003881 * @see #getForegroundAccessCount(int)
3882 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003883 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003884 public long getBackgroundAccessCount(@OpFlags int flags) {
3885 return sumForFlagsInStates(mAccessCount, resolveLastRestrictedUidState(mOp),
3886 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003887 }
3888
3889 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08003890 * Gets the number times the op was accessed (performed) for a
3891 * range of uid states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003892 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003893 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07003894 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08003895 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07003896 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3897 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08003898 * @param toUidState The UID state to which to query.
3899 * @param flags The flags which are any combination of
3900 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3901 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3902 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3903 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003904 *
3905 * @return The times the op was accessed for the given UID state.
3906 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003907 * @see #getForegroundAccessCount(int)
3908 * @see #getBackgroundAccessCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003909 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003910 public long getAccessCount(@UidState int fromUidState, @UidState int toUidState,
3911 @OpFlags int flags) {
3912 return sumForFlagsInStates(mAccessCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003913 }
3914
3915 /**
3916 * Gets the number times the op was rejected in the foreground.
3917 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003918 * @param flags The flags which are any combination of
3919 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3920 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3921 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3922 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003923 * @return The times the op was rejected in the foreground.
3924 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003925 * @see #getBackgroundRejectCount(int)
3926 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003927 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003928 public long getForegroundRejectCount(@OpFlags int flags) {
3929 return sumForFlagsInStates(mRejectCount, MAX_PRIORITY_UID_STATE,
3930 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003931 }
3932
3933 /**
3934 * Gets the number times the op was rejected in the background.
3935 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003936 * @param flags The flags which are any combination of
3937 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3938 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3939 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3940 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003941 * @return The times the op was rejected in the background.
3942 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003943 * @see #getForegroundRejectCount(int)
3944 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003945 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003946 public long getBackgroundRejectCount(@OpFlags int flags) {
3947 return sumForFlagsInStates(mRejectCount, resolveLastRestrictedUidState(mOp),
3948 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003949 }
3950
3951 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08003952 * Gets the number times the op was rejected for a given range of UID states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003953 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003954 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07003955 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08003956 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07003957 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3958 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08003959 * @param toUidState The UID state to which to query.
3960 * @param flags The flags which are any combination of
3961 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3962 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3963 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3964 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003965 *
3966 * @return The times the op was rejected for the given UID state.
3967 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003968 * @see #getForegroundRejectCount(int)
3969 * @see #getBackgroundRejectCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003970 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003971 public long getRejectCount(@UidState int fromUidState, @UidState int toUidState,
3972 @OpFlags int flags) {
3973 return sumForFlagsInStates(mRejectCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003974 }
3975
3976 /**
3977 * Gets the total duration the app op was accessed (performed) in the foreground.
Svet Ganov6f672a32019-07-08 16:40:42 -07003978 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003979 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003980 * @param flags The flags which are any combination of
3981 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3982 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3983 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3984 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003985 * @return The total duration the app op was accessed in the foreground.
3986 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003987 * @see #getBackgroundAccessDuration(int)
3988 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003989 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003990 public long getForegroundAccessDuration(@OpFlags int flags) {
3991 return sumForFlagsInStates(mAccessDuration, MAX_PRIORITY_UID_STATE,
3992 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003993 }
3994
3995 /**
3996 * Gets the total duration the app op was accessed (performed) in the background.
Svet Ganov6f672a32019-07-08 16:40:42 -07003997 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003998 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003999 * @param flags The flags which are any combination of
4000 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4001 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4002 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4003 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004004 * @return The total duration the app op was accessed in the background.
4005 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004006 * @see #getForegroundAccessDuration(int)
4007 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004008 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004009 public long getBackgroundAccessDuration(@OpFlags int flags) {
4010 return sumForFlagsInStates(mAccessDuration, resolveLastRestrictedUidState(mOp),
4011 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004012 }
4013
4014 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08004015 * Gets the total duration the app op was accessed (performed) for a given
Svet Ganov6f672a32019-07-08 16:40:42 -07004016 * range of UID states. The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004017 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004018 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07004019 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08004020 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07004021 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
4022 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08004023 * @param toUidState The UID state from which to query.
4024 * @param flags The flags which are any combination of
4025 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4026 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4027 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4028 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004029 *
4030 * @return The total duration the app op was accessed for the given UID state.
4031 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004032 * @see #getForegroundAccessDuration(int)
4033 * @see #getBackgroundAccessDuration(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004034 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004035 public long getAccessDuration(@UidState int fromUidState, @UidState int toUidState,
4036 @OpFlags int flags) {
4037 return sumForFlagsInStates(mAccessDuration, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004038 }
4039
4040 @Override
4041 public int describeContents() {
4042 return 0;
4043 }
4044
4045 @Override
4046 public void writeToParcel(Parcel parcel, int flags) {
4047 parcel.writeInt(mOp);
Svet Ganovaf189e32019-02-15 18:45:29 -08004048 writeLongSparseLongArrayToParcel(mAccessCount, parcel);
4049 writeLongSparseLongArrayToParcel(mRejectCount, parcel);
4050 writeLongSparseLongArrayToParcel(mAccessDuration, parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004051 }
4052
Svet Ganov8455ba22019-01-02 13:05:56 -08004053 @Override
Aurimas Liutikas00be9512019-08-28 13:01:05 -07004054 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004055 if (this == obj) {
4056 return true;
4057 }
4058 if (obj == null || getClass() != obj.getClass()) {
4059 return false;
4060 }
4061 final HistoricalOp other = (HistoricalOp) obj;
4062 if (mOp != other.mOp) {
4063 return false;
4064 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004065 if (!Objects.equals(mAccessCount, other.mAccessCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004066 return false;
4067 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004068 if (!Objects.equals(mRejectCount, other.mRejectCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004069 return false;
4070 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004071 return Objects.equals(mAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004072 }
4073
4074 @Override
4075 public int hashCode() {
4076 int result = mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08004077 result = 31 * result + Objects.hashCode(mAccessCount);
4078 result = 31 * result + Objects.hashCode(mRejectCount);
4079 result = 31 * result + Objects.hashCode(mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004080 return result;
4081 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004082
4083 private void accept(@NonNull HistoricalOpsVisitor visitor) {
4084 visitor.visitHistoricalOp(this);
4085 }
4086
4087 private @NonNull LongSparseLongArray getOrCreateAccessCount() {
4088 if (mAccessCount == null) {
4089 mAccessCount = new LongSparseLongArray();
4090 }
4091 return mAccessCount;
4092 }
4093
4094 private @NonNull LongSparseLongArray getOrCreateRejectCount() {
4095 if (mRejectCount == null) {
4096 mRejectCount = new LongSparseLongArray();
4097 }
4098 return mRejectCount;
4099 }
4100
4101 private @NonNull LongSparseLongArray getOrCreateAccessDuration() {
4102 if (mAccessDuration == null) {
4103 mAccessDuration = new LongSparseLongArray();
4104 }
4105 return mAccessDuration;
4106 }
4107
4108 /**
4109 * Multiplies the entries in the array with the passed in scale factor and
4110 * rounds the result at up 0.5 boundary.
4111 *
4112 * @param data The data to scale.
4113 * @param scaleFactor The scale factor.
4114 */
4115 private static void scale(@NonNull LongSparseLongArray data, double scaleFactor) {
4116 if (data != null) {
4117 final int size = data.size();
4118 for (int i = 0; i < size; i++) {
4119 data.put(data.keyAt(i), (long) HistoricalOps.round(
4120 (double) data.valueAt(i) * scaleFactor));
4121 }
4122 }
4123 }
4124
4125 /**
4126 * Merges two arrays while lazily acquiring the destination.
4127 *
4128 * @param thisSupplier The destination supplier.
4129 * @param other The array to merge in.
4130 */
4131 private static void merge(@NonNull Supplier<LongSparseLongArray> thisSupplier,
4132 @Nullable LongSparseLongArray other) {
4133 if (other != null) {
4134 final int otherSize = other.size();
4135 for (int i = 0; i < otherSize; i++) {
4136 final LongSparseLongArray that = thisSupplier.get();
4137 final long otherKey = other.keyAt(i);
4138 final long otherValue = other.valueAt(i);
4139 that.put(otherKey, that.get(otherKey) + otherValue);
4140 }
4141 }
4142 }
4143
4144 /** @hide */
4145 public @Nullable LongSparseArray<Object> collectKeys() {
4146 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessCount,
4147 null /*result*/);
4148 result = AppOpsManager.collectKeys(mRejectCount, result);
4149 result = AppOpsManager.collectKeys(mAccessDuration, result);
4150 return result;
4151 }
4152
4153 public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR =
4154 new Creator<HistoricalOp>() {
4155 @Override
4156 public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) {
4157 return new HistoricalOp(source);
4158 }
4159
4160 @Override
4161 public @NonNull HistoricalOp[] newArray(int size) {
4162 return new HistoricalOp[size];
4163 }
4164 };
4165 }
4166
4167 /**
4168 * Computes the sum of the counts for the given flags in between the begin and
4169 * end UID states.
4170 *
4171 * @param counts The data array.
4172 * @param beginUidState The beginning UID state (exclusive).
4173 * @param endUidState The end UID state.
4174 * @param flags The UID flags.
4175 * @return The sum.
4176 */
4177 private static long sumForFlagsInStates(@Nullable LongSparseLongArray counts,
4178 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
4179 if (counts == null) {
4180 return 0;
4181 }
4182 long sum = 0;
4183 while (flags != 0) {
4184 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4185 flags &= ~flag;
4186 for (int uidState : UID_STATES) {
4187 if (uidState < beginUidState || uidState > endUidState) {
4188 continue;
4189 }
4190 final long key = makeKey(uidState, flag);
4191 sum += counts.get(key);
4192 }
4193 }
4194 return sum;
4195 }
4196
4197 /**
4198 * Finds the first non-negative value for the given flags in between the begin and
4199 * end UID states.
4200 *
4201 * @param counts The data array.
4202 * @param flags The UID flags.
4203 * @param beginUidState The beginning UID state (exclusive).
4204 * @param endUidState The end UID state.
4205 * @return The non-negative value or -1.
4206 */
4207 private static long findFirstNonNegativeForFlagsInStates(@Nullable LongSparseLongArray counts,
4208 @OpFlags int flags, @UidState int beginUidState, @UidState int endUidState) {
4209 if (counts == null) {
4210 return -1;
4211 }
4212 while (flags != 0) {
4213 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4214 flags &= ~flag;
4215 for (int uidState : UID_STATES) {
4216 if (uidState < beginUidState || uidState > endUidState) {
4217 continue;
4218 }
4219 final long key = makeKey(uidState, flag);
4220 final long value = counts.get(key);
4221 if (value >= 0) {
4222 return value;
4223 }
4224 }
4225 }
4226 return -1;
4227 }
4228
4229 /**
4230 * Finds the first non-null value for the given flags in between the begin and
4231 * end UID states.
4232 *
4233 * @param counts The data array.
4234 * @param flags The UID flags.
4235 * @param beginUidState The beginning UID state (exclusive).
4236 * @param endUidState The end UID state.
4237 * @return The non-negative value or -1.
4238 */
4239 private static @Nullable String findFirstNonNullForFlagsInStates(
4240 @Nullable LongSparseArray<String> counts, @OpFlags int flags,
4241 @UidState int beginUidState, @UidState int endUidState) {
4242 if (counts == null) {
4243 return null;
4244 }
4245 while (flags != 0) {
4246 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4247 flags &= ~flag;
4248 for (int uidState : UID_STATES) {
4249 if (uidState < beginUidState || uidState > endUidState) {
4250 continue;
4251 }
4252 final long key = makeKey(uidState, flag);
4253 final String value = counts.get(key);
4254 if (value != null) {
4255 return value;
4256 }
4257 }
4258 }
4259 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004260 }
4261
4262 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004263 * Callback for notification of changes to operation state.
4264 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004265 public interface OnOpChangedListener {
4266 public void onOpChanged(String op, String packageName);
4267 }
4268
4269 /**
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004270 * Callback for notification of changes to operation active state.
4271 *
4272 * @hide
4273 */
Svet Ganovf7b47252018-02-26 11:11:27 -08004274 @TestApi
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004275 public interface OnOpActiveChangedListener {
4276 /**
4277 * Called when the active state of an app op changes.
4278 *
4279 * @param code The op code.
4280 * @param uid The UID performing the operation.
4281 * @param packageName The package performing the operation.
4282 * @param active Whether the operation became active or inactive.
4283 */
4284 void onOpActiveChanged(int code, int uid, String packageName, boolean active);
4285 }
4286
4287 /**
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004288 * Callback for notification of an op being noted.
4289 *
4290 * @hide
4291 */
4292 public interface OnOpNotedListener {
4293 /**
4294 * Called when an op was noted.
4295 *
4296 * @param code The op code.
4297 * @param uid The UID performing the operation.
4298 * @param packageName The package performing the operation.
4299 * @param result The result of the note.
4300 */
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004301 void onOpNoted(int code, int uid, String packageName, int result);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004302 }
4303
4304 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004305 * Callback for notification of changes to operation state.
4306 * This allows you to see the raw op codes instead of strings.
4307 * @hide
4308 */
4309 public static class OnOpChangedInternalListener implements OnOpChangedListener {
4310 public void onOpChanged(String op, String packageName) { }
4311 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -08004312 }
4313
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004314 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004315 mContext = context;
4316 mService = service;
4317 }
4318
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004319 /**
4320 * Retrieve current operation state for all applications.
4321 *
Winson6a864b52019-05-10 10:34:14 -07004322 * The mode of the ops returned are set for the package but may not reflect their effective
4323 * state due to UID policy or because it's controlled by a different master op.
4324 *
4325 * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)}
4326 * if the effective mode is needed.
4327 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004328 * @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 -07004329 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004330 */
Svet Ganov8455ba22019-01-02 13:05:56 -08004331 @SystemApi
4332 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
4333 public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops) {
4334 final int opCount = ops.length;
4335 final int[] opCodes = new int[opCount];
4336 for (int i = 0; i < opCount; i++) {
4337 opCodes[i] = sOpStrToOp.get(ops[i]);
4338 }
4339 final List<AppOpsManager.PackageOps> result = getPackagesForOps(opCodes);
4340 return (result != null) ? result : Collections.emptyList();
4341 }
4342
4343 /**
4344 * Retrieve current operation state for all applications.
4345 *
Winson6a864b52019-05-10 10:34:14 -07004346 * The mode of the ops returned are set for the package but may not reflect their effective
4347 * state due to UID policy or because it's controlled by a different master op.
4348 *
4349 * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)}
4350 * if the effective mode is needed.
4351 *
Svet Ganov8455ba22019-01-02 13:05:56 -08004352 * @param ops The set of operations you are interested in, or null if you want all of them.
4353 * @hide
4354 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07004355 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004356 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08004357 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
4358 try {
4359 return mService.getPackagesForOps(ops);
4360 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004361 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08004362 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08004363 }
4364
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004365 /**
4366 * Retrieve current operation state for one application.
4367 *
Winson6a864b52019-05-10 10:34:14 -07004368 * The mode of the ops returned are set for the package but may not reflect their effective
4369 * state due to UID policy or because it's controlled by a different master op.
4370 *
4371 * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)}
4372 * if the effective mode is needed.
4373 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004374 * @param uid The uid of the application of interest.
4375 * @param packageName The name of the application of interest.
4376 * @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 -08004377 *
4378 * @deprecated The int op codes are not stable and you should use the string based op
4379 * names which are stable and namespaced. Use
4380 * {@link #getOpsForPackage(int, String, String...)})}.
4381 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004382 * @hide
Suprabh Shukla169bed72019-05-13 13:54:58 -07004383 * @removed
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004384 */
Svet Ganov8455ba22019-01-02 13:05:56 -08004385 @Deprecated
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07004386 @SystemApi
Dianne Hackbornc216a262018-04-26 13:46:22 -07004387 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Dianne Hackborn62878492019-03-11 15:57:07 -07004388 public @NonNull List<PackageOps> getOpsForPackage(int uid, @NonNull String packageName,
4389 @Nullable int[] ops) {
Dianne Hackborn72e39832013-01-18 18:36:09 -08004390 try {
4391 return mService.getOpsForPackage(uid, packageName, ops);
4392 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004393 throw e.rethrowFromSystemServer();
Dianne Hackborn72e39832013-01-18 18:36:09 -08004394 }
Dianne Hackborn72e39832013-01-18 18:36:09 -08004395 }
4396
Svet Ganovae0e03a2016-02-25 18:22:10 -08004397 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004398 * Retrieve current operation state for one application. The UID and the
4399 * package must match.
4400 *
Winson6a864b52019-05-10 10:34:14 -07004401 * The mode of the ops returned are set for the package but may not reflect their effective
4402 * state due to UID policy or because it's controlled by a different master op.
4403 *
4404 * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)}
4405 * if the effective mode is needed.
4406 *
Svet Ganov8455ba22019-01-02 13:05:56 -08004407 * @param uid The uid of the application of interest.
4408 * @param packageName The name of the application of interest.
4409 * @param ops The set of operations you are interested in, or null if you want all of them.
4410 *
4411 * @hide
4412 */
4413 @SystemApi
4414 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
4415 public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid,
4416 @NonNull String packageName, @Nullable String... ops) {
4417 int[] opCodes = null;
4418 if (ops != null) {
4419 opCodes = new int[ops.length];
4420 for (int i = 0; i < ops.length; i++) {
4421 opCodes[i] = strOpToOp(ops[i]);
4422 }
4423 }
4424 try {
4425 final List<PackageOps> result = mService.getOpsForPackage(uid, packageName, opCodes);
4426 if (result == null) {
4427 return Collections.emptyList();
4428 }
4429 return result;
4430 } catch (RemoteException e) {
4431 throw e.rethrowFromSystemServer();
4432 }
4433 }
4434
4435 /**
4436 * Retrieve historical app op stats for a period.
4437 *
Svet Ganov23c88db2019-01-22 20:38:11 -08004438 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08004439 * @param executor Executor on which to run the callback. If <code>null</code>
4440 * the callback is executed on the default executor running on the main thread.
4441 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004442 *
4443 * @throws IllegalArgumentException If any of the argument contracts is violated.
4444 *
4445 * @hide
4446 */
4447 @TestApi
4448 @SystemApi
4449 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov23c88db2019-01-22 20:38:11 -08004450 public void getHistoricalOps(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08004451 @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) {
4452 Preconditions.checkNotNull(executor, "executor cannot be null");
4453 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07004454 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08004455 mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08004456 request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags,
Svet Ganov8455ba22019-01-02 13:05:56 -08004457 new RemoteCallback((result) -> {
4458 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
4459 final long identity = Binder.clearCallingIdentity();
4460 try {
4461 executor.execute(() -> callback.accept(ops));
4462 } finally {
4463 Binder.restoreCallingIdentity(identity);
4464 }
4465 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07004466 } catch (RemoteException e) {
4467 throw e.rethrowFromSystemServer();
4468 }
4469 }
4470
4471 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004472 * Retrieve historical app op stats for a period.
Svet Ganov8455ba22019-01-02 13:05:56 -08004473 * <p>
4474 * This method queries only the on disk state and the returned ops are raw,
4475 * which is their times are relative to the history start as opposed to the
4476 * epoch start.
4477 *
Svet Ganov23c88db2019-01-22 20:38:11 -08004478 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08004479 * @param executor Executor on which to run the callback. If <code>null</code>
4480 * the callback is executed on the default executor running on the main thread.
4481 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004482 *
4483 * @throws IllegalArgumentException If any of the argument contracts is violated.
4484 *
4485 * @hide
4486 */
4487 @TestApi
Svet Ganov8e5bf962019-03-19 23:59:03 -07004488 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
Svet Ganov23c88db2019-01-22 20:38:11 -08004489 public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08004490 @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) {
4491 Preconditions.checkNotNull(executor, "executor cannot be null");
4492 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07004493 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08004494 mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName,
4495 request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis,
Svet Ganovaf189e32019-02-15 18:45:29 -08004496 request.mFlags, new RemoteCallback((result) -> {
Svet Ganov23c88db2019-01-22 20:38:11 -08004497 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
Svet Ganov8455ba22019-01-02 13:05:56 -08004498 final long identity = Binder.clearCallingIdentity();
4499 try {
4500 executor.execute(() -> callback.accept(ops));
4501 } finally {
4502 Binder.restoreCallingIdentity(identity);
4503 }
4504 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07004505 } catch (RemoteException e) {
4506 throw e.rethrowFromSystemServer();
4507 }
4508 }
4509
4510 /**
Svet Ganov8e5bf962019-03-19 23:59:03 -07004511 * Reloads the non historical state to allow testing the read/write path.
4512 *
4513 * @hide
4514 */
4515 @TestApi
4516 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
4517 public void reloadNonHistoricalState() {
4518 try {
4519 mService.reloadNonHistoricalState();
4520 } catch (RemoteException e) {
4521 throw e.rethrowFromSystemServer();
4522 }
4523 }
4524
4525 /**
Svet Ganovae0e03a2016-02-25 18:22:10 -08004526 * Sets given app op in the specified mode for app ops in the UID.
4527 * This applies to all apps currently in the UID or installed in
4528 * this UID in the future.
4529 *
4530 * @param code The app op.
4531 * @param uid The UID for which to set the app.
4532 * @param mode The app op mode to set.
4533 * @hide
4534 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004535 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004536 public void setUidMode(int code, int uid, @Mode int mode) {
Svet Ganov2af57082015-07-30 08:44:20 -07004537 try {
4538 mService.setUidMode(code, uid, mode);
4539 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004540 throw e.rethrowFromSystemServer();
Svet Ganov2af57082015-07-30 08:44:20 -07004541 }
4542 }
4543
Svet Ganovae0e03a2016-02-25 18:22:10 -08004544 /**
4545 * Sets given app op in the specified mode for app ops in the UID.
4546 * This applies to all apps currently in the UID or installed in
4547 * this UID in the future.
4548 *
4549 * @param appOp The app op.
4550 * @param uid The UID for which to set the app.
4551 * @param mode The app op mode to set.
4552 * @hide
4553 */
4554 @SystemApi
Eugene Susla93519852018-06-13 16:44:31 -07004555 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004556 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004557 public void setUidMode(String appOp, int uid, @Mode int mode) {
Svet Ganovae0e03a2016-02-25 18:22:10 -08004558 try {
4559 mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
4560 } catch (RemoteException e) {
4561 throw e.rethrowFromSystemServer();
4562 }
4563 }
4564
Svet Ganov2af57082015-07-30 08:44:20 -07004565 /** @hide */
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004566 public void setUserRestriction(int code, boolean restricted, IBinder token) {
Ruben Brunk29931bc2016-03-11 00:24:26 -08004567 setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
4568 }
4569
4570 /** @hide */
4571 public void setUserRestriction(int code, boolean restricted, IBinder token,
4572 String[] exceptionPackages) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07004573 setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
4574 }
4575
4576 /** @hide */
4577 public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
4578 String[] exceptionPackages, int userId) {
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004579 try {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07004580 mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004581 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004582 throw e.rethrowFromSystemServer();
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004583 }
4584 }
4585
4586 /** @hide */
Artur Satayev5a525852019-10-31 15:15:50 +00004587 @UnsupportedAppUsage
Peter Visontayb97fbc82017-12-21 16:23:55 +00004588 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004589 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004590 public void setMode(int code, int uid, String packageName, @Mode int mode) {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08004591 try {
4592 mService.setMode(code, uid, packageName, mode);
4593 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004594 throw e.rethrowFromSystemServer();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08004595 }
4596 }
4597
John Spurlock1af30c72014-03-10 08:33:35 -04004598 /**
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004599 * Change the operating mode for the given op in the given app package. You must pass
4600 * in both the uid and name of the application whose mode is being modified; if these
4601 * do not match, the modification will not be applied.
4602 *
4603 * @param op The operation to modify. One of the OPSTR_* constants.
4604 * @param uid The user id of the application whose mode will be changed.
4605 * @param packageName The name of the application package name whose mode will
4606 * be changed.
4607 * @hide
4608 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07004609 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004610 @SystemApi
4611 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004612 public void setMode(String op, int uid, String packageName, @Mode int mode) {
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004613 try {
4614 mService.setMode(strOpToOp(op), uid, packageName, mode);
4615 } catch (RemoteException e) {
4616 throw e.rethrowFromSystemServer();
4617 }
4618 }
4619
4620 /**
John Spurlock1af30c72014-03-10 08:33:35 -04004621 * Set a non-persisted restriction on an audio operation at a stream-level.
4622 * Restrictions are temporary additional constraints imposed on top of the persisted rules
4623 * defined by {@link #setMode}.
4624 *
4625 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04004626 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04004627 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
4628 * @param exceptionPackages Optional list of packages to exclude from the restriction.
4629 * @hide
4630 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004631 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004632 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -08004633 public void setRestriction(int code, @AttributeUsage int usage, @Mode int mode,
John Spurlock7b414672014-07-18 13:02:39 -04004634 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04004635 try {
4636 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04004637 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04004638 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004639 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04004640 }
4641 }
4642
Dianne Hackborn607b4142013-08-02 18:10:10 -07004643 /** @hide */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004644 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004645 @UnsupportedAppUsage
Dianne Hackborn607b4142013-08-02 18:10:10 -07004646 public void resetAllModes() {
4647 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -07004648 mService.resetAllModes(mContext.getUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07004649 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004650 throw e.rethrowFromSystemServer();
Dianne Hackborn607b4142013-08-02 18:10:10 -07004651 }
4652 }
4653
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004654 /**
Svet Ganovfbf01f72015-04-28 18:39:06 -07004655 * Gets the app op name associated with a given permission.
4656 * The app op name is one of the public constants defined
4657 * in this class such as {@link #OPSTR_COARSE_LOCATION}.
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07004658 * This API is intended to be used for mapping runtime
4659 * permissions to the corresponding app op.
Svet Ganovfbf01f72015-04-28 18:39:06 -07004660 *
4661 * @param permission The permission.
4662 * @return The app op associated with the permission or null.
Svet Ganovfbf01f72015-04-28 18:39:06 -07004663 */
Svet Ganovfbf01f72015-04-28 18:39:06 -07004664 public static String permissionToOp(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08004665 final Integer opCode = sPermToOp.get(permission);
Svet Ganovb9d71a62015-04-30 10:38:13 -07004666 if (opCode == null) {
4667 return null;
4668 }
4669 return sOpToString[opCode];
Svet Ganovfbf01f72015-04-28 18:39:06 -07004670 }
4671
4672 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004673 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004674 * You can watch op changes only for your UID.
4675 *
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07004676 * @param op The operation to monitor, one of OPSTR_*.
4677 * @param packageName The name of the application to monitor.
4678 * @param callback Where to report changes.
4679 */
Dianne Hackborn62878492019-03-11 15:57:07 -07004680 public void startWatchingMode(@NonNull String op, @Nullable String packageName,
4681 @NonNull final OnOpChangedListener callback) {
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07004682 startWatchingMode(strOpToOp(op), packageName, callback);
4683 }
4684
4685 /**
4686 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004687 * You can watch op changes only for your UID.
4688 *
4689 * @param op The operation to monitor, one of OPSTR_*.
4690 * @param packageName The name of the application to monitor.
4691 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
4692 * @param callback Where to report changes.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004693 */
Dianne Hackborn62878492019-03-11 15:57:07 -07004694 public void startWatchingMode(@NonNull String op, @Nullable String packageName, int flags,
4695 @NonNull final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004696 startWatchingMode(strOpToOp(op), packageName, flags, callback);
4697 }
4698
4699 /**
4700 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004701 *
4702 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08004703 * you can watch changes only for your UID.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004704 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004705 * @param op The operation to monitor, one of OP_*.
4706 * @param packageName The name of the application to monitor.
4707 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07004708 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004709 */
Jeff Sharkeybf6b2132018-02-27 11:16:37 -07004710 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004711 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004712 startWatchingMode(op, packageName, 0, callback);
4713 }
4714
4715 /**
4716 * Monitor for changes to the operating mode for the given op in the given app package.
4717 *
4718 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4719 * you can watch changes only for your UID.
4720 *
4721 * @param op The operation to monitor, one of OP_*.
4722 * @param packageName The name of the application to monitor.
4723 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
4724 * @param callback Where to report changes.
4725 * @hide
4726 */
4727 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
4728 public void startWatchingMode(int op, String packageName, int flags,
4729 final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08004730 synchronized (mModeWatchers) {
4731 IAppOpsCallback cb = mModeWatchers.get(callback);
4732 if (cb == null) {
4733 cb = new IAppOpsCallback.Stub() {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07004734 public void opChanged(int op, int uid, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004735 if (callback instanceof OnOpChangedInternalListener) {
4736 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
4737 }
4738 if (sOpToString[op] != null) {
4739 callback.onOpChanged(sOpToString[op], packageName);
4740 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08004741 }
4742 };
4743 mModeWatchers.put(callback, cb);
4744 }
4745 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004746 mService.startWatchingModeWithFlags(op, packageName, flags, cb);
Dianne Hackbornc2293022013-02-06 23:14:49 -08004747 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004748 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08004749 }
4750 }
4751 }
4752
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004753 /**
4754 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
4755 * monitoring associated with this callback will be removed.
4756 */
Dianne Hackborn62878492019-03-11 15:57:07 -07004757 public void stopWatchingMode(@NonNull OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08004758 synchronized (mModeWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004759 IAppOpsCallback cb = mModeWatchers.remove(callback);
Dianne Hackbornc2293022013-02-06 23:14:49 -08004760 if (cb != null) {
4761 try {
4762 mService.stopWatchingMode(cb);
4763 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004764 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08004765 }
4766 }
4767 }
4768 }
4769
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004770 /**
4771 * Start watching for changes to the active state of app ops. An app op may be
4772 * long running and it has a clear start and stop delimiters. If an op is being
4773 * started or stopped by any package you will get a callback. To change the
4774 * watched ops for a registered callback you need to unregister and register it
4775 * again.
4776 *
Svet Ganovf7b47252018-02-26 11:11:27 -08004777 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4778 * you can watch changes only for your UID.
4779 *
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004780 * @param ops The ops to watch.
4781 * @param callback Where to report changes.
4782 *
4783 * @see #isOperationActive(int, int, String)
4784 * @see #stopWatchingActive(OnOpActiveChangedListener)
4785 * @see #startOp(int, int, String)
4786 * @see #finishOp(int, int, String)
4787 *
4788 * @hide
4789 */
Svet Ganovf7b47252018-02-26 11:11:27 -08004790 @TestApi
4791 // TODO: Uncomment below annotation once b/73559440 is fixed
4792 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004793 public void startWatchingActive(@NonNull int[] ops,
4794 @NonNull OnOpActiveChangedListener callback) {
4795 Preconditions.checkNotNull(ops, "ops cannot be null");
4796 Preconditions.checkNotNull(callback, "callback cannot be null");
4797 IAppOpsActiveCallback cb;
4798 synchronized (mActiveWatchers) {
4799 cb = mActiveWatchers.get(callback);
4800 if (cb != null) {
4801 return;
4802 }
4803 cb = new IAppOpsActiveCallback.Stub() {
4804 @Override
4805 public void opActiveChanged(int op, int uid, String packageName, boolean active) {
4806 callback.onOpActiveChanged(op, uid, packageName, active);
4807 }
4808 };
4809 mActiveWatchers.put(callback, cb);
4810 }
4811 try {
4812 mService.startWatchingActive(ops, cb);
4813 } catch (RemoteException e) {
4814 throw e.rethrowFromSystemServer();
4815 }
4816 }
4817
4818 /**
4819 * Stop watching for changes to the active state of an app op. An app op may be
4820 * long running and it has a clear start and stop delimiters. Unregistering a
4821 * non-registered callback has no effect.
4822 *
4823 * @see #isOperationActive#(int, int, String)
4824 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
4825 * @see #startOp(int, int, String)
4826 * @see #finishOp(int, int, String)
4827 *
4828 * @hide
4829 */
Svet Ganovf7b47252018-02-26 11:11:27 -08004830 @TestApi
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004831 public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
4832 synchronized (mActiveWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004833 final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004834 if (cb != null) {
4835 try {
4836 mService.stopWatchingActive(cb);
4837 } catch (RemoteException e) {
4838 throw e.rethrowFromSystemServer();
4839 }
4840 }
4841 }
4842 }
4843
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004844 /**
4845 * Start watching for noted app ops. An app op may be immediate or long running.
4846 * Immediate ops are noted while long running ones are started and stopped. This
4847 * method allows registering a listener to be notified when an app op is noted. If
4848 * an op is being noted by any package you will get a callback. To change the
4849 * watched ops for a registered callback you need to unregister and register it again.
4850 *
4851 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4852 * you can watch changes only for your UID.
4853 *
4854 * @param ops The ops to watch.
4855 * @param callback Where to report changes.
4856 *
4857 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
4858 * @see #stopWatchingNoted(OnOpNotedListener)
4859 * @see #noteOp(String, int, String)
4860 *
4861 * @hide
4862 */
4863 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004864 public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004865 IAppOpsNotedCallback cb;
4866 synchronized (mNotedWatchers) {
4867 cb = mNotedWatchers.get(callback);
4868 if (cb != null) {
4869 return;
4870 }
4871 cb = new IAppOpsNotedCallback.Stub() {
4872 @Override
4873 public void opNoted(int op, int uid, String packageName, int mode) {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004874 callback.onOpNoted(op, uid, packageName, mode);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004875 }
4876 };
4877 mNotedWatchers.put(callback, cb);
4878 }
4879 try {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004880 mService.startWatchingNoted(ops, cb);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004881 } catch (RemoteException e) {
4882 throw e.rethrowFromSystemServer();
4883 }
4884 }
4885
4886 /**
4887 * Stop watching for noted app ops. An app op may be immediate or long running.
4888 * Unregistering a non-registered callback has no effect.
4889 *
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004890 * @see #startWatchingNoted(int[], OnOpNotedListener)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004891 * @see #noteOp(String, int, String)
4892 *
4893 * @hide
4894 */
4895 public void stopWatchingNoted(@NonNull OnOpNotedListener callback) {
4896 synchronized (mNotedWatchers) {
4897 final IAppOpsNotedCallback cb = mNotedWatchers.get(callback);
4898 if (cb != null) {
4899 try {
4900 mService.stopWatchingNoted(cb);
4901 } catch (RemoteException e) {
4902 throw e.rethrowFromSystemServer();
4903 }
4904 }
4905 }
4906 }
4907
Dianne Hackborn95d78532013-09-11 09:51:14 -07004908 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
4909 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
4910 }
4911
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07004912 /**
4913 * {@hide}
4914 */
Artur Satayev5a525852019-10-31 15:15:50 +00004915 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07004916 @TestApi
Dianne Hackborn62878492019-03-11 15:57:07 -07004917 public static int strOpToOp(@NonNull String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004918 Integer val = sOpStrToOp.get(op);
4919 if (val == null) {
4920 throw new IllegalArgumentException("Unknown operation string: " + op);
4921 }
4922 return val;
4923 }
4924
4925 /**
4926 * Do a quick check for whether an application might be able to perform an operation.
4927 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
4928 * or {@link #startOp(String, int, String)} for your actual security checks, which also
4929 * ensure that the given uid and package name are consistent. This function can just be
4930 * used for a quick check to see if an operation has been disabled for the application,
4931 * as an early reject of some work. This does not modify the time stamp or other data
4932 * about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07004933 *
4934 * <p>Important things this will not do (which you need to ultimate use
4935 * {@link #noteOp(String, int, String)} or {@link #startOp(String, int, String)} to cover):</p>
4936 * <ul>
4937 * <li>Verifying the uid and package are consistent, so callers can't spoof
4938 * their identity.</li>
4939 * <li>Taking into account the current foreground/background state of the
4940 * app; apps whose mode varies by this state will always be reported
4941 * as {@link #MODE_ALLOWED}.</li>
4942 * </ul>
4943 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004944 * @param op The operation to check. One of the OPSTR_* constants.
4945 * @param uid The user id of the application attempting to perform the operation.
4946 * @param packageName The name of the application attempting to perform the operation.
4947 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4948 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4949 * causing the app to crash).
4950 * @throws SecurityException If the app has been configured to crash on this op.
4951 */
Dianne Hackborn62878492019-03-11 15:57:07 -07004952 public int unsafeCheckOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07004953 return checkOp(strOpToOp(op), uid, packageName);
4954 }
4955
4956 /**
4957 * @deprecated Renamed to {@link #unsafeCheckOp(String, int, String)}.
4958 */
4959 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07004960 public int checkOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004961 return checkOp(strOpToOp(op), uid, packageName);
4962 }
4963
4964 /**
John Spurlock925b85e2014-03-10 16:52:11 -04004965 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004966 * returns {@link #MODE_ERRORED}.
4967 */
Dianne Hackborn62878492019-03-11 15:57:07 -07004968 public int unsafeCheckOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07004969 return checkOpNoThrow(strOpToOp(op), uid, packageName);
4970 }
4971
4972 /**
4973 * @deprecated Renamed to {@link #unsafeCheckOpNoThrow(String, int, String)}.
4974 */
4975 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07004976 public int checkOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004977 return checkOpNoThrow(strOpToOp(op), uid, packageName);
4978 }
4979
4980 /**
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004981 * Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op.
4982 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004983 */
Dianne Hackborn62878492019-03-11 15:57:07 -07004984 public int unsafeCheckOpRaw(@NonNull String op, int uid, @NonNull String packageName) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004985 try {
4986 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
4987 } catch (RemoteException e) {
4988 throw e.rethrowFromSystemServer();
4989 }
4990 }
4991
4992 /**
4993 * Like {@link #unsafeCheckOpNoThrow(String, int, String)} but returns the <em>raw</em>
4994 * mode associated with the op. Does not throw a security exception, does not translate
4995 * {@link #MODE_FOREGROUND}.
4996 */
4997 public int unsafeCheckOpRawNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004998 try {
Svet Ganov9d528a12018-12-19 17:23:11 -08004999 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005000 } catch (RemoteException e) {
5001 throw e.rethrowFromSystemServer();
5002 }
5003 }
5004
5005 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005006 * Make note of an application performing an operation. Note that you must pass
5007 * in both the uid and name of the application to be checked; this function will verify
5008 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5009 * succeeds, the last execution time of the operation for this app will be updated to
5010 * the current time.
5011 * @param op The operation to note. One of the OPSTR_* constants.
5012 * @param uid The user id of the application attempting to perform the operation.
5013 * @param packageName The name of the application attempting to perform the operation.
5014 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5015 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5016 * causing the app to crash).
5017 * @throws SecurityException If the app has been configured to crash on this op.
5018 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005019 public int noteOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005020 return noteOp(strOpToOp(op), uid, packageName);
5021 }
5022
5023 /**
5024 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
5025 * returns {@link #MODE_ERRORED}.
5026 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005027 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005028 return noteOpNoThrow(strOpToOp(op), uid, packageName);
5029 }
5030
5031 /**
Svet Ganov99b60432015-06-27 13:15:22 -07005032 * Make note of an application performing an operation on behalf of another
5033 * application when handling an IPC. Note that you must pass the package name
5034 * of the application that is being proxied while its UID will be inferred from
5035 * the IPC state; this function will verify that the calling uid and proxied
5036 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
5037 * succeeds, the last execution time of the operation for the proxied app and
5038 * your app will be updated to the current time.
5039 * @param op The operation to note. One of the OPSTR_* constants.
5040 * @param proxiedPackageName The name of the application calling into the proxy application.
5041 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5042 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5043 * causing the app to crash).
5044 * @throws SecurityException If the app has been configured to crash on this op.
5045 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005046 public int noteProxyOp(@NonNull String op, @NonNull String proxiedPackageName) {
Svet Ganov99b60432015-06-27 13:15:22 -07005047 return noteProxyOp(strOpToOp(op), proxiedPackageName);
5048 }
5049
5050 /**
5051 * Like {@link #noteProxyOp(String, String)} but instead
5052 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005053 *
5054 * <p>This API requires the package with the {@code proxiedPackageName} to belongs to
5055 * {@link Binder#getCallingUid()}.
Svet Ganov99b60432015-06-27 13:15:22 -07005056 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005057 public int noteProxyOpNoThrow(@NonNull String op, @NonNull String proxiedPackageName) {
Svet Ganov99b60432015-06-27 13:15:22 -07005058 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
5059 }
5060
5061 /**
Philip P. Moltmann78219312019-03-01 17:04:19 -08005062 * Like {@link #noteProxyOpNoThrow(String, String)} but allows to specify the proxied uid.
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005063 *
5064 * <p>This API requires package with the {@code proxiedPackageName} to belong to
5065 * {@code proxiedUid}.
5066 *
5067 * @param op The op to note
5068 * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
5069 * noted for the "android" package
5070 * @param proxiedUid The uid the package belongs to
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005071 */
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005072 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
5073 int proxiedUid) {
5074 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid);
5075 }
5076
5077 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005078 * Report that an application has started executing a long-running operation. Note that you
5079 * must pass in both the uid and name of the application to be checked; this function will
5080 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5081 * succeeds, the last execution time of the operation for this app will be updated to
5082 * the current time and the operation will be marked as "running". In this case you must
5083 * later call {@link #finishOp(String, int, String)} to report when the application is no
5084 * longer performing the operation.
5085 * @param op The operation to start. One of the OPSTR_* constants.
5086 * @param uid The user id of the application attempting to perform the operation.
5087 * @param packageName The name of the application attempting to perform the operation.
5088 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5089 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5090 * causing the app to crash).
5091 * @throws SecurityException If the app has been configured to crash on this op.
5092 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005093 public int startOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005094 return startOp(strOpToOp(op), uid, packageName);
5095 }
5096
5097 /**
5098 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
5099 * returns {@link #MODE_ERRORED}.
5100 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005101 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005102 return startOpNoThrow(strOpToOp(op), uid, packageName);
5103 }
5104
5105 /**
5106 * Report that an application is no longer performing an operation that had previously
5107 * been started with {@link #startOp(String, int, String)}. There is no validation of input
5108 * or result; the parameters supplied here must be the exact same ones previously passed
5109 * in when starting the operation.
5110 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005111 public void finishOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005112 finishOp(strOpToOp(op), uid, packageName);
5113 }
5114
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005115 /**
5116 * Do a quick check for whether an application might be able to perform an operation.
5117 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
5118 * or {@link #startOp(int, int, String)} for your actual security checks, which also
5119 * ensure that the given uid and package name are consistent. This function can just be
5120 * used for a quick check to see if an operation has been disabled for the application,
5121 * as an early reject of some work. This does not modify the time stamp or other data
5122 * about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07005123 *
5124 * <p>Important things this will not do (which you need to ultimate use
5125 * {@link #noteOp(int, int, String)} or {@link #startOp(int, int, String)} to cover):</p>
5126 * <ul>
5127 * <li>Verifying the uid and package are consistent, so callers can't spoof
5128 * their identity.</li>
5129 * <li>Taking into account the current foreground/background state of the
5130 * app; apps whose mode varies by this state will always be reported
5131 * as {@link #MODE_ALLOWED}.</li>
5132 * </ul>
5133 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005134 * @param op The operation to check. One of the OP_* constants.
5135 * @param uid The user id of the application attempting to perform the operation.
5136 * @param packageName The name of the application attempting to perform the operation.
5137 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5138 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5139 * causing the app to crash).
5140 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005141 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005142 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005143 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08005144 public int checkOp(int op, int uid, String packageName) {
5145 try {
5146 int mode = mService.checkOperation(op, uid, packageName);
5147 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07005148 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08005149 }
5150 return mode;
5151 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005152 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08005153 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08005154 }
5155
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005156 /**
5157 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
5158 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005159 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005160 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005161 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08005162 public int checkOpNoThrow(int op, int uid, String packageName) {
5163 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005164 int mode = mService.checkOperation(op, uid, packageName);
5165 return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08005166 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005167 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08005168 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08005169 }
5170
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005171 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07005172 * Do a quick check to validate if a package name belongs to a UID.
5173 *
5174 * @throws SecurityException if the package name doesn't belong to the given
5175 * UID, or if ownership cannot be verified.
5176 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005177 public void checkPackage(int uid, @NonNull String packageName) {
Jeff Sharkey911d7f42013-09-05 18:11:45 -07005178 try {
5179 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
5180 throw new SecurityException(
5181 "Package " + packageName + " does not belong to " + uid);
5182 }
5183 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005184 throw e.rethrowFromSystemServer();
Jeff Sharkey911d7f42013-09-05 18:11:45 -07005185 }
5186 }
5187
5188 /**
John Spurlock1af30c72014-03-10 08:33:35 -04005189 * Like {@link #checkOp} but at a stream-level for audio operations.
5190 * @hide
5191 */
5192 public int checkAudioOp(int op, int stream, int uid, String packageName) {
5193 try {
5194 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
5195 if (mode == MODE_ERRORED) {
5196 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
5197 }
5198 return mode;
5199 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005200 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04005201 }
John Spurlock1af30c72014-03-10 08:33:35 -04005202 }
5203
5204 /**
5205 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
5206 * returns {@link #MODE_ERRORED}.
5207 * @hide
5208 */
5209 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
5210 try {
5211 return mService.checkAudioOperation(op, stream, uid, packageName);
5212 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005213 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04005214 }
John Spurlock1af30c72014-03-10 08:33:35 -04005215 }
5216
5217 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005218 * Make note of an application performing an operation. Note that you must pass
5219 * in both the uid and name of the application to be checked; this function will verify
5220 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5221 * succeeds, the last execution time of the operation for this app will be updated to
5222 * the current time.
5223 * @param op The operation to note. One of the OP_* constants.
5224 * @param uid The user id of the application attempting to perform the operation.
5225 * @param packageName The name of the application attempting to perform the operation.
5226 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5227 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5228 * causing the app to crash).
5229 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005230 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005231 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005232 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005233 public int noteOp(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08005234 final int mode = noteOpNoThrow(op, uid, packageName);
5235 if (mode == MODE_ERRORED) {
5236 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005237 }
Svet Ganovf7b47252018-02-26 11:11:27 -08005238 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005239 }
5240
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005241 /**
Svet Ganov99b60432015-06-27 13:15:22 -07005242 * Make note of an application performing an operation on behalf of another
5243 * application when handling an IPC. Note that you must pass the package name
5244 * of the application that is being proxied while its UID will be inferred from
5245 * the IPC state; this function will verify that the calling uid and proxied
5246 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
5247 * succeeds, the last execution time of the operation for the proxied app and
5248 * your app will be updated to the current time.
5249 * @param op The operation to note. One of the OPSTR_* constants.
5250 * @param proxiedPackageName The name of the application calling into the proxy application.
5251 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5252 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5253 * causing the app to crash).
5254 * @throws SecurityException If the proxy or proxied app has been configured to
5255 * crash on this op.
5256 *
5257 * @hide
5258 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005259 @UnsupportedAppUsage
Svet Ganov99b60432015-06-27 13:15:22 -07005260 public int noteProxyOp(int op, String proxiedPackageName) {
5261 int mode = noteProxyOpNoThrow(op, proxiedPackageName);
5262 if (mode == MODE_ERRORED) {
5263 throw new SecurityException("Proxy package " + mContext.getOpPackageName()
5264 + " from uid " + Process.myUid() + " or calling package "
5265 + proxiedPackageName + " from uid " + Binder.getCallingUid()
5266 + " not allowed to perform " + sOpNames[op]);
5267 }
5268 return mode;
5269 }
5270
5271 /**
5272 * Like {@link #noteProxyOp(int, String)} but instead
5273 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
5274 * @hide
5275 */
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005276 public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) {
Svet Ganov99b60432015-06-27 13:15:22 -07005277 try {
Svet Ganovd873ae62018-06-25 16:39:23 -07005278 return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005279 proxiedUid, proxiedPackageName);
Svet Ganov99b60432015-06-27 13:15:22 -07005280 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005281 throw e.rethrowFromSystemServer();
Svet Ganov99b60432015-06-27 13:15:22 -07005282 }
Svet Ganov99b60432015-06-27 13:15:22 -07005283 }
5284
5285 /**
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005286 * Like {@link #noteProxyOp(int, String)} but instead
5287 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
5288 *
5289 * <p>This API requires the package with {@code proxiedPackageName} to belongs to
5290 * {@link Binder#getCallingUid()}.
5291 *
5292 * @hide
5293 */
5294 public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
5295 return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid());
5296 }
5297
5298 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005299 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
5300 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005301 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005302 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005303 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005304 public int noteOpNoThrow(int op, int uid, String packageName) {
5305 try {
5306 return mService.noteOperation(op, uid, packageName);
5307 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005308 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005309 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005310 }
5311
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005312 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005313 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005314 public int noteOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07005315 return noteOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005316 }
5317
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005318 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005319 @UnsupportedAppUsage
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005320 public static IBinder getToken(IAppOpsService service) {
5321 synchronized (AppOpsManager.class) {
5322 if (sToken != null) {
5323 return sToken;
5324 }
5325 try {
5326 sToken = service.getToken(new Binder());
5327 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005328 throw e.rethrowFromSystemServer();
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005329 }
5330 return sToken;
5331 }
5332 }
5333
Svet Ganovf7b47252018-02-26 11:11:27 -08005334 /** @hide */
5335 public int startOp(int op) {
5336 return startOp(op, Process.myUid(), mContext.getOpPackageName());
5337 }
5338
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005339 /**
5340 * Report that an application has started executing a long-running operation. Note that you
5341 * must pass in both the uid and name of the application to be checked; this function will
5342 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5343 * succeeds, the last execution time of the operation for this app will be updated to
5344 * the current time and the operation will be marked as "running". In this case you must
5345 * later call {@link #finishOp(int, int, String)} to report when the application is no
5346 * longer performing the operation.
Svet Ganovf7b47252018-02-26 11:11:27 -08005347 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005348 * @param op The operation to start. One of the OP_* constants.
5349 * @param uid The user id of the application attempting to perform the operation.
5350 * @param packageName The name of the application attempting to perform the operation.
5351 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5352 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5353 * causing the app to crash).
5354 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005355 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005356 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005357 public int startOp(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08005358 return startOp(op, uid, packageName, false);
5359 }
5360
5361 /**
5362 * Report that an application has started executing a long-running operation. Similar
5363 * to {@link #startOp(String, int, String) except that if the mode is {@link #MODE_DEFAULT}
5364 * the operation should succeed since the caller has performed its standard permission
5365 * checks which passed and would perform the protected operation for this mode.
5366 *
5367 * @param op The operation to start. One of the OP_* constants.
5368 * @param uid The user id of the application attempting to perform the operation.
5369 * @param packageName The name of the application attempting to perform the operation.
5370 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5371 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5372 * causing the app to crash).
5373 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
5374 *
5375 * @throws SecurityException If the app has been configured to crash on this op or
5376 * the package is not in the passed in UID.
5377 *
5378 * @hide
5379 */
5380 public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
5381 final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault);
5382 if (mode == MODE_ERRORED) {
5383 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005384 }
Svet Ganovf7b47252018-02-26 11:11:27 -08005385 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005386 }
5387
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005388 /**
5389 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
5390 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005391 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005392 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005393 public int startOpNoThrow(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08005394 return startOpNoThrow(op, uid, packageName, false);
5395 }
5396
5397 /**
5398 * Like {@link #startOp(int, int, String, boolean)} but instead of throwing a
5399 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
5400 *
5401 * @param op The operation to start. One of the OP_* constants.
5402 * @param uid The user id of the application attempting to perform the operation.
5403 * @param packageName The name of the application attempting to perform the operation.
5404 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5405 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5406 * causing the app to crash).
5407 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
5408 *
5409 * @hide
5410 */
5411 public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005412 try {
Svet Ganovf7b47252018-02-26 11:11:27 -08005413 return mService.startOperation(getToken(mService), op, uid, packageName,
5414 startIfModeDefault);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005415 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005416 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005417 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005418 }
5419
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005420 /**
5421 * Report that an application is no longer performing an operation that had previously
5422 * been started with {@link #startOp(int, int, String)}. There is no validation of input
5423 * or result; the parameters supplied here must be the exact same ones previously passed
5424 * in when starting the operation.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005425 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005426 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005427 public void finishOp(int op, int uid, String packageName) {
5428 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005429 mService.finishOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005430 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005431 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005432 }
5433 }
5434
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005435 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005436 public void finishOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07005437 finishOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005438 }
Jeff Sharkey35e46d22017-06-09 10:01:20 -06005439
Svet Ganovf7b47252018-02-26 11:11:27 -08005440 /**
5441 * Checks whether the given op for a UID and package is active.
5442 *
5443 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
5444 * you can query only for your UID.
5445 *
5446 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
5447 * @see #stopWatchingMode(OnOpChangedListener)
5448 * @see #finishOp(int)
5449 * @see #startOp(int)
5450 *
5451 * @hide */
5452 @TestApi
5453 // TODO: Uncomment below annotation once b/73559440 is fixed
5454 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey35e46d22017-06-09 10:01:20 -06005455 public boolean isOperationActive(int code, int uid, String packageName) {
5456 try {
5457 return mService.isOperationActive(code, uid, packageName);
5458 } catch (RemoteException e) {
5459 throw e.rethrowFromSystemServer();
5460 }
5461 }
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00005462
5463 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005464 * Configures the app ops persistence for testing.
5465 *
5466 * @param mode The mode in which the historical registry operates.
5467 * @param baseSnapshotInterval The base interval on which we would be persisting a snapshot of
5468 * the historical data. The history is recursive where every subsequent step encompasses
5469 * {@code compressionStep} longer interval with {@code compressionStep} distance between
5470 * snapshots.
5471 * @param compressionStep The compression step in every iteration.
5472 *
5473 * @see #HISTORICAL_MODE_DISABLED
5474 * @see #HISTORICAL_MODE_ENABLED_ACTIVE
5475 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
5476 *
5477 * @hide
5478 */
5479 @TestApi
5480 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5481 public void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval,
5482 int compressionStep) {
5483 try {
5484 mService.setHistoryParameters(mode, baseSnapshotInterval, compressionStep);
5485 } catch (RemoteException e) {
5486 throw e.rethrowFromSystemServer();
5487 }
5488 }
5489
5490 /**
5491 * Offsets the history by the given duration.
5492 *
5493 * @param offsetMillis The offset duration.
5494 *
5495 * @hide
5496 */
5497 @TestApi
5498 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5499 public void offsetHistory(long offsetMillis) {
5500 try {
5501 mService.offsetHistory(offsetMillis);
5502 } catch (RemoteException e) {
5503 throw e.rethrowFromSystemServer();
5504 }
5505 }
5506
5507 /**
5508 * Adds ops to the history directly. This could be useful for testing especially
5509 * when the historical registry operates in {@link #HISTORICAL_MODE_ENABLED_PASSIVE}
5510 * mode.
5511 *
5512 * @param ops The ops to add to the history.
5513 *
5514 * @see #setHistoryParameters(int, long, int)
5515 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
5516 *
5517 * @hide
5518 */
5519 @TestApi
5520 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5521 public void addHistoricalOps(@NonNull HistoricalOps ops) {
5522 try {
5523 mService.addHistoricalOps(ops);
5524 } catch (RemoteException e) {
5525 throw e.rethrowFromSystemServer();
5526 }
5527 }
5528
5529 /**
5530 * Resets the app ops persistence for testing.
5531 *
5532 * @see #setHistoryParameters(int, long, int)
5533 *
5534 * @hide
5535 */
5536 @TestApi
5537 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5538 public void resetHistoryParameters() {
5539 try {
5540 mService.resetHistoryParameters();
5541 } catch (RemoteException e) {
5542 throw e.rethrowFromSystemServer();
5543 }
5544 }
5545
5546 /**
5547 * Clears all app ops history.
5548 *
5549 * @hide
5550 */
5551 @TestApi
5552 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5553 public void clearHistory() {
5554 try {
5555 mService.clearHistory();
5556 } catch (RemoteException e) {
5557 throw e.rethrowFromSystemServer();
5558 }
5559 }
5560
5561 /**
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00005562 * Returns all supported operation names.
5563 * @hide
5564 */
5565 @SystemApi
5566 @TestApi
5567 public static String[] getOpStrs() {
5568 return Arrays.copyOf(sOpToString, sOpToString.length);
5569 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07005570
Philip P. Moltmann24576812018-05-07 10:42:05 -07005571
5572 /**
5573 * @return number of App ops
5574 * @hide
5575 */
5576 @TestApi
5577 public static int getNumOps() {
5578 return _NUM_OP;
5579 }
5580
Dianne Hackbornc216a262018-04-26 13:46:22 -07005581 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08005582 * Computes the max for the given flags in between the begin and
5583 * end UID states.
5584 *
5585 * @param counts The data array.
5586 * @param flags The UID flags.
5587 * @param beginUidState The beginning UID state (exclusive).
5588 * @param endUidState The end UID state.
5589 * @return The sum.
Dianne Hackbornc216a262018-04-26 13:46:22 -07005590 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005591 private static long maxForFlagsInStates(@Nullable LongSparseLongArray counts,
5592 @UidState int beginUidState, @UidState int endUidState,
5593 @OpFlags int flags) {
5594 if (counts == null) {
5595 return 0;
5596 }
5597 long max = 0;
5598 while (flags != 0) {
5599 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
5600 flags &= ~flag;
5601 for (int uidState : UID_STATES) {
5602 if (uidState < beginUidState || uidState > endUidState) {
5603 continue;
5604 }
5605 final long key = makeKey(uidState, flag);
5606 max = Math.max(max, counts.get(key));
Dianne Hackbornc216a262018-04-26 13:46:22 -07005607 }
5608 }
Svet Ganovaf189e32019-02-15 18:45:29 -08005609 return max;
5610 }
5611
5612
5613 private static void writeLongSparseLongArrayToParcel(
5614 @Nullable LongSparseLongArray array, @NonNull Parcel parcel) {
5615 if (array != null) {
5616 final int size = array.size();
5617 parcel.writeInt(size);
5618 for (int i = 0; i < size; i++) {
5619 parcel.writeLong(array.keyAt(i));
5620 parcel.writeLong(array.valueAt(i));
5621 }
5622 } else {
5623 parcel.writeInt(-1);
5624 }
5625 }
5626
5627 private static @Nullable LongSparseLongArray readLongSparseLongArrayFromParcel(
5628 @NonNull Parcel parcel) {
5629 final int size = parcel.readInt();
5630 if (size < 0) {
5631 return null;
5632 }
5633 final LongSparseLongArray array = new LongSparseLongArray(size);
5634 for (int i = 0; i < size; i++) {
5635 array.append(parcel.readLong(), parcel.readLong());
5636 }
5637 return array;
5638 }
5639
5640 private static void writeLongSparseStringArrayToParcel(
5641 @Nullable LongSparseArray<String> array, @NonNull Parcel parcel) {
5642 if (array != null) {
5643 final int size = array.size();
5644 parcel.writeInt(size);
5645 for (int i = 0; i < size; i++) {
5646 parcel.writeLong(array.keyAt(i));
5647 parcel.writeString(array.valueAt(i));
5648 }
5649 } else {
5650 parcel.writeInt(-1);
5651 }
5652 }
5653
5654 private static @Nullable LongSparseArray<String> readLongSparseStringArrayFromParcel(
5655 @NonNull Parcel parcel) {
5656 final int size = parcel.readInt();
5657 if (size < 0) {
5658 return null;
5659 }
5660 final LongSparseArray<String> array = new LongSparseArray<>(size);
5661 for (int i = 0; i < size; i++) {
5662 array.append(parcel.readLong(), parcel.readString());
5663 }
5664 return array;
5665 }
5666
5667 /**
5668 * Collects the keys from an array to the result creating the result if needed.
5669 *
5670 * @param array The array whose keys to collect.
5671 * @param result The optional result store collected keys.
5672 * @return The result collected keys array.
5673 */
5674 private static LongSparseArray<Object> collectKeys(@Nullable LongSparseLongArray array,
5675 @Nullable LongSparseArray<Object> result) {
5676 if (array != null) {
5677 if (result == null) {
5678 result = new LongSparseArray<>();
5679 }
5680 final int accessSize = array.size();
5681 for (int i = 0; i < accessSize; i++) {
5682 result.put(array.keyAt(i), null);
5683 }
5684 }
5685 return result;
Dianne Hackbornc216a262018-04-26 13:46:22 -07005686 }
Svet Ganov8455ba22019-01-02 13:05:56 -08005687
5688 /** @hide */
5689 public static String uidStateToString(@UidState int uidState) {
5690 switch (uidState) {
5691 case UID_STATE_PERSISTENT: {
5692 return "UID_STATE_PERSISTENT";
5693 }
5694 case UID_STATE_TOP: {
5695 return "UID_STATE_TOP";
5696 }
Amith Yamasania0a30a12019-01-22 11:38:06 -08005697 case UID_STATE_FOREGROUND_SERVICE_LOCATION: {
5698 return "UID_STATE_FOREGROUND_SERVICE_LOCATION";
5699 }
Svet Ganov8455ba22019-01-02 13:05:56 -08005700 case UID_STATE_FOREGROUND_SERVICE: {
5701 return "UID_STATE_FOREGROUND_SERVICE";
5702 }
5703 case UID_STATE_FOREGROUND: {
5704 return "UID_STATE_FOREGROUND";
5705 }
5706 case UID_STATE_BACKGROUND: {
5707 return "UID_STATE_BACKGROUND";
5708 }
5709 case UID_STATE_CACHED: {
5710 return "UID_STATE_CACHED";
5711 }
5712 default: {
5713 return "UNKNOWN";
5714 }
5715 }
5716 }
5717
5718 /** @hide */
5719 public static int parseHistoricalMode(@NonNull String mode) {
5720 switch (mode) {
5721 case "HISTORICAL_MODE_ENABLED_ACTIVE": {
5722 return HISTORICAL_MODE_ENABLED_ACTIVE;
5723 }
5724 case "HISTORICAL_MODE_ENABLED_PASSIVE": {
5725 return HISTORICAL_MODE_ENABLED_PASSIVE;
5726 }
5727 default: {
5728 return HISTORICAL_MODE_DISABLED;
5729 }
5730 }
5731 }
5732
5733 /** @hide */
5734 public static String historicalModeToString(@HistoricalMode int mode) {
5735 switch (mode) {
5736 case HISTORICAL_MODE_DISABLED: {
5737 return "HISTORICAL_MODE_DISABLED";
5738 }
5739 case HISTORICAL_MODE_ENABLED_ACTIVE: {
5740 return "HISTORICAL_MODE_ENABLED_ACTIVE";
5741 }
5742 case HISTORICAL_MODE_ENABLED_PASSIVE: {
5743 return "HISTORICAL_MODE_ENABLED_PASSIVE";
5744 }
5745 default: {
5746 return "UNKNOWN";
5747 }
5748 }
5749 }
Ng Zhi An65a99b62018-10-01 11:57:53 -07005750
5751 private static int getSystemAlertWindowDefault() {
5752 final Context context = ActivityThread.currentApplication();
5753 if (context == null) {
5754 return AppOpsManager.MODE_DEFAULT;
5755 }
5756
5757 // system alert window is disable on low ram phones starting from Q
5758 final PackageManager pm = context.getPackageManager();
5759 // TVs are constantly plugged in and has less concern for memory/power
5760 if (ActivityManager.isLowRamDeviceStatic()
5761 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) {
5762 return AppOpsManager.MODE_IGNORED;
5763 }
5764
5765 return AppOpsManager.MODE_DEFAULT;
5766 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005767}