blob: 33d83f9b123b7187c531eb3e746a50b0bc64a2fc [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 Ganov05fcd222019-07-08 16:30:45 -0700243 * Uid state: The UID is a foreground persistent app. The lower the UID
244 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700245 * @hide
246 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800247 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700248 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800249 public static final int UID_STATE_PERSISTENT = 100;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700250
251 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700252 * Uid state: The UID is top foreground app. The lower the UID
253 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700254 * @hide
255 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800256 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700257 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800258 public static final int UID_STATE_TOP = 200;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700259
260 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800261 * Uid state: The UID is running a foreground service of location type.
Svet Ganov05fcd222019-07-08 16:30:45 -0700262 * The lower the UID state the more important the UID is for the user.
Amith Yamasania0a30a12019-01-22 11:38:06 -0800263 * @hide
264 */
265 @TestApi
266 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800267 public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800268
269 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700270 * Uid state: The UID is running a foreground service. The lower the UID
271 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700272 * @hide
273 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800274 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700275 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800276 public static final int UID_STATE_FOREGROUND_SERVICE = 400;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700277
278 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800279 * The max, which is min priority, UID state for which any app op
280 * would be considered as performed in the foreground.
Dianne Hackborne93ab412018-05-14 17:52:30 -0700281 * @hide
282 */
Svet Ganovaf189e32019-02-15 18:45:29 -0800283 public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE;
Dianne Hackborne93ab412018-05-14 17:52:30 -0700284
285 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700286 * Uid state: The UID is a foreground app. The lower the UID
287 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700288 * @hide
289 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800290 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700291 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800292 public static final int UID_STATE_FOREGROUND = 500;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700293
294 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700295 * Uid state: The UID is a background app. The lower the UID
296 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700297 * @hide
298 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800299 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700300 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800301 public static final int UID_STATE_BACKGROUND = 600;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700302
303 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700304 * Uid state: The UID is a cached app. The lower the UID
305 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700306 * @hide
307 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800308 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700309 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800310 public static final int UID_STATE_CACHED = 700;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700311
312 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800313 * Uid state: The UID state with the highest priority.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700314 * @hide
315 */
Svet Ganovaf189e32019-02-15 18:45:29 -0800316 public static final int MAX_PRIORITY_UID_STATE = UID_STATE_PERSISTENT;
317
318 /**
319 * Uid state: The UID state with the lowest priority.
320 * @hide
321 */
322 public static final int MIN_PRIORITY_UID_STATE = UID_STATE_CACHED;
323
324 /**
325 * Resolves the first unrestricted state given an app op. Location is
326 * special as we want to allow its access only if a dedicated location
327 * foreground service is running. For other ops we consider any foreground
328 * service as a foreground state.
329 *
330 * @param op The op to resolve.
331 * @return The last restricted UID state.
332 *
333 * @hide
334 */
335 public static int resolveFirstUnrestrictedUidState(int op) {
336 switch (op) {
337 case OP_FINE_LOCATION:
Wei Wange1f864e2019-03-28 18:12:18 -0700338 case OP_COARSE_LOCATION:
339 case OP_MONITOR_LOCATION:
340 case OP_MONITOR_HIGH_POWER_LOCATION: {
Svet Ganovaf189e32019-02-15 18:45:29 -0800341 return UID_STATE_FOREGROUND_SERVICE_LOCATION;
342 }
343 }
344 return UID_STATE_FOREGROUND_SERVICE;
345 }
346
347 /**
348 * Resolves the last restricted state given an app op. Location is
349 * special as we want to allow its access only if a dedicated location
350 * foreground service is running. For other ops we consider any foreground
351 * service as a foreground state.
352 *
353 * @param op The op to resolve.
354 * @return The last restricted UID state.
355 *
356 * @hide
357 */
358 public static int resolveLastRestrictedUidState(int op) {
359 switch (op) {
360 case OP_FINE_LOCATION:
361 case OP_COARSE_LOCATION: {
362 return UID_STATE_FOREGROUND_SERVICE;
363 }
364 }
365 return UID_STATE_FOREGROUND;
366 }
367
368 /** @hide Note: Keep these sorted */
369 public static final int[] UID_STATES = {
370 UID_STATE_PERSISTENT,
371 UID_STATE_TOP,
372 UID_STATE_FOREGROUND_SERVICE_LOCATION,
373 UID_STATE_FOREGROUND_SERVICE,
374 UID_STATE_FOREGROUND,
375 UID_STATE_BACKGROUND,
376 UID_STATE_CACHED
377 };
378
379 /** @hide */
380 public static String getUidStateName(@UidState int uidState) {
381 switch (uidState) {
382 case UID_STATE_PERSISTENT:
383 return "pers";
384 case UID_STATE_TOP:
385 return "top";
386 case UID_STATE_FOREGROUND_SERVICE_LOCATION:
387 return "fgsvcl";
388 case UID_STATE_FOREGROUND_SERVICE:
389 return "fgsvc";
390 case UID_STATE_FOREGROUND:
391 return "fg";
392 case UID_STATE_BACKGROUND:
393 return "bg";
394 case UID_STATE_CACHED:
395 return "cch";
396 default:
397 return "unknown";
398 }
399 }
400
401 /**
402 * Flag: non proxy operations. These are operations
403 * performed on behalf of the app itself and not on behalf of
404 * another one.
405 *
406 * @hide
407 */
408 @TestApi
409 @SystemApi
410 public static final int OP_FLAG_SELF = 0x1;
411
412 /**
413 * Flag: trusted proxy operations. These are operations
414 * performed on behalf of another app by a trusted app.
415 * Which is work a trusted app blames on another app.
416 *
417 * @hide
418 */
419 @TestApi
420 @SystemApi
421 public static final int OP_FLAG_TRUSTED_PROXY = 0x2;
422
423 /**
424 * Flag: untrusted proxy operations. These are operations
425 * performed on behalf of another app by an untrusted app.
426 * Which is work an untrusted app blames on another app.
427 *
428 * @hide
429 */
430 @TestApi
431 @SystemApi
432 public static final int OP_FLAG_UNTRUSTED_PROXY = 0x4;
433
434 /**
435 * Flag: trusted proxied operations. These are operations
436 * performed by a trusted other app on behalf of an app.
437 * Which is work an app was blamed for by a trusted app.
438 *
439 * @hide
440 */
441 @TestApi
442 @SystemApi
443 public static final int OP_FLAG_TRUSTED_PROXIED = 0x8;
444
445 /**
446 * Flag: untrusted proxied operations. These are operations
447 * performed by an untrusted other app on behalf of an app.
448 * Which is work an app was blamed for by an untrusted app.
449 *
450 * @hide
451 */
452 @TestApi
453 @SystemApi
454 public static final int OP_FLAG_UNTRUSTED_PROXIED = 0x10;
455
456 /**
457 * Flags: all operations. These include operations matched
458 * by {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXIED},
459 * {@link #OP_FLAG_UNTRUSTED_PROXIED}, {@link #OP_FLAG_TRUSTED_PROXIED},
460 * {@link #OP_FLAG_UNTRUSTED_PROXIED}.
461 *
462 * @hide
463 */
464 @TestApi
465 @SystemApi
466 public static final int OP_FLAGS_ALL =
467 OP_FLAG_SELF
468 | OP_FLAG_TRUSTED_PROXY
469 | OP_FLAG_UNTRUSTED_PROXY
470 | OP_FLAG_TRUSTED_PROXIED
471 | OP_FLAG_UNTRUSTED_PROXIED;
472
473 /**
474 * Flags: all trusted operations which is ones either the app did {@link #OP_FLAG_SELF},
475 * or it was blamed for by a trusted app {@link #OP_FLAG_TRUSTED_PROXIED}, or ones the
476 * app if untrusted blamed on other apps {@link #OP_FLAG_UNTRUSTED_PROXY}.
477 *
478 * @hide
479 */
480 @SystemApi
481 public static final int OP_FLAGS_ALL_TRUSTED = AppOpsManager.OP_FLAG_SELF
482 | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY
483 | AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
484
485 /** @hide */
486 @Retention(RetentionPolicy.SOURCE)
487 @IntDef(flag = true, prefix = { "FLAG_" }, value = {
488 OP_FLAG_SELF,
489 OP_FLAG_TRUSTED_PROXY,
490 OP_FLAG_UNTRUSTED_PROXY,
491 OP_FLAG_TRUSTED_PROXIED,
492 OP_FLAG_UNTRUSTED_PROXIED
493 })
494 public @interface OpFlags {}
495
496
497 /** @hide */
498 public static final String getFlagName(@OpFlags int flag) {
499 switch (flag) {
500 case OP_FLAG_SELF:
501 return "s";
502 case OP_FLAG_TRUSTED_PROXY:
503 return "tp";
504 case OP_FLAG_UNTRUSTED_PROXY:
505 return "up";
506 case OP_FLAG_TRUSTED_PROXIED:
507 return "tpd";
508 case OP_FLAG_UNTRUSTED_PROXIED:
509 return "upd";
510 default:
511 return "unknown";
512 }
513 }
514
515 private static final int UID_STATE_OFFSET = 31;
516 private static final int FLAGS_MASK = 0xFFFFFFFF;
517
518 /**
519 * Key for a data bucket storing app op state. The bucket
520 * is composed of the uid state and state flags. This way
521 * we can query data for given uid state and a set of flags where
522 * the flags control which type of data to get. For example,
523 * one can get the ops an app did on behalf of other apps
524 * while in the background.
525 *
526 * @hide
527 */
528 @Retention(RetentionPolicy.SOURCE)
529 @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
530 public @interface DataBucketKey {
531 }
532
533 /** @hide */
534 public static String keyToString(@DataBucketKey long key) {
535 final int uidState = extractUidStateFromKey(key);
536 final int flags = extractFlagsFromKey(key);
537 return "[" + getUidStateName(uidState) + "-" + flagsToString(flags) + "]";
538 }
539
540 /** @hide */
541 public static @DataBucketKey long makeKey(@UidState int uidState, @OpFlags int flags) {
542 return ((long) uidState << UID_STATE_OFFSET) | flags;
543 }
544
545 /** @hide */
546 public static int extractUidStateFromKey(@DataBucketKey long key) {
547 return (int) (key >> UID_STATE_OFFSET);
548 }
549
550 /** @hide */
551 public static int extractFlagsFromKey(@DataBucketKey long key) {
552 return (int) (key & FLAGS_MASK);
553 }
554
555 /** @hide */
556 public static String flagsToString(@OpFlags int flags) {
557 final StringBuilder flagsBuilder = new StringBuilder();
558 while (flags != 0) {
559 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
560 flags &= ~flag;
561 if (flagsBuilder.length() > 0) {
562 flagsBuilder.append('|');
563 }
564 flagsBuilder.append(getFlagName(flag));
565 }
566 return flagsBuilder.toString();
567 }
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700568
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500569 // when adding one of these:
570 // - increment _NUM_OP
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000571 // - define an OPSTR_* constant (marked as @SystemApi)
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700572 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500573 // - add descriptive strings to Settings/res/values/arrays.xml
David Christie0b837452013-07-29 16:02:13 -0700574 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700575
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700576 /** @hide No operation specified. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100577 @UnsupportedAppUsage
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800578 public static final int OP_NONE = -1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700579 /** @hide Access to coarse location information. */
Artur Satayev5a525852019-10-31 15:15:50 +0000580 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -0800581 @TestApi
Dianne Hackborn35654b62013-01-14 17:38:02 -0800582 public static final int OP_COARSE_LOCATION = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700583 /** @hide Access to fine location information. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100584 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800585 public static final int OP_FINE_LOCATION = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700586 /** @hide Causing GPS to run. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100587 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800588 public static final int OP_GPS = 2;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800589 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100590 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700591 public static final int OP_VIBRATE = 3;
592 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100593 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700594 public static final int OP_READ_CONTACTS = 4;
595 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100596 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700597 public static final int OP_WRITE_CONTACTS = 5;
598 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100599 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700600 public static final int OP_READ_CALL_LOG = 6;
601 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100602 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700603 public static final int OP_WRITE_CALL_LOG = 7;
604 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100605 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700606 public static final int OP_READ_CALENDAR = 8;
607 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100608 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700609 public static final int OP_WRITE_CALENDAR = 9;
610 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100611 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700612 public static final int OP_WIFI_SCAN = 10;
613 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100614 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700615 public static final int OP_POST_NOTIFICATION = 11;
616 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100617 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700618 public static final int OP_NEIGHBORING_CELLS = 12;
619 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100620 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700621 public static final int OP_CALL_PHONE = 13;
622 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100623 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700624 public static final int OP_READ_SMS = 14;
625 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100626 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700627 public static final int OP_WRITE_SMS = 15;
628 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100629 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700630 public static final int OP_RECEIVE_SMS = 16;
631 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100632 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700633 public static final int OP_RECEIVE_EMERGECY_SMS = 17;
634 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100635 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700636 public static final int OP_RECEIVE_MMS = 18;
637 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100638 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700639 public static final int OP_RECEIVE_WAP_PUSH = 19;
640 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100641 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700642 public static final int OP_SEND_SMS = 20;
643 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100644 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700645 public static final int OP_READ_ICC_SMS = 21;
646 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100647 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700648 public static final int OP_WRITE_ICC_SMS = 22;
649 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100650 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700651 public static final int OP_WRITE_SETTINGS = 23;
Peter Visontay96449f62017-12-11 18:50:03 +0000652 /** @hide Required to draw on top of other apps. */
Artur Satayev5a525852019-10-31 15:15:50 +0000653 @UnsupportedAppUsage
Svet Ganovf7b47252018-02-26 11:11:27 -0800654 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700655 public static final int OP_SYSTEM_ALERT_WINDOW = 24;
656 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100657 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700658 public static final int OP_ACCESS_NOTIFICATIONS = 25;
659 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100660 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700661 public static final int OP_CAMERA = 26;
662 /** @hide */
Artur Satayev5a525852019-10-31 15:15:50 +0000663 @UnsupportedAppUsage
Svet Ganova7a0db62018-02-27 20:08:01 -0800664 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700665 public static final int OP_RECORD_AUDIO = 27;
666 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100667 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700668 public static final int OP_PLAY_AUDIO = 28;
669 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100670 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700671 public static final int OP_READ_CLIPBOARD = 29;
672 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100673 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700674 public static final int OP_WRITE_CLIPBOARD = 30;
675 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100676 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700677 public static final int OP_TAKE_MEDIA_BUTTONS = 31;
678 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100679 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700680 public static final int OP_TAKE_AUDIO_FOCUS = 32;
681 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100682 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700683 public static final int OP_AUDIO_MASTER_VOLUME = 33;
684 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100685 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700686 public static final int OP_AUDIO_VOICE_VOLUME = 34;
687 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100688 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700689 public static final int OP_AUDIO_RING_VOLUME = 35;
690 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100691 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700692 public static final int OP_AUDIO_MEDIA_VOLUME = 36;
693 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100694 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700695 public static final int OP_AUDIO_ALARM_VOLUME = 37;
696 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100697 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700698 public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
699 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100700 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700701 public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
702 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100703 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700704 public static final int OP_WAKE_LOCK = 40;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700705 /** @hide Continually monitoring location data. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100706 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700707 public static final int OP_MONITOR_LOCATION = 41;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700708 /** @hide Continually monitoring location data with a relatively high power request. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100709 @UnsupportedAppUsage
David Christie0b837452013-07-29 16:02:13 -0700710 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700711 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100712 @UnsupportedAppUsage
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700713 public static final int OP_GET_USAGE_STATS = 43;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700714 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100715 @UnsupportedAppUsage
Emily Bernier22c921a2014-05-28 11:01:32 -0400716 public static final int OP_MUTE_MICROPHONE = 44;
717 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100718 @UnsupportedAppUsage
Jason Monk1c7c3192014-06-26 12:52:18 -0400719 public static final int OP_TOAST_WINDOW = 45;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700720 /** @hide Capture the device's display contents and/or audio */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100721 @UnsupportedAppUsage
Michael Wrightc39d47a2014-07-08 18:07:36 -0700722 public static final int OP_PROJECT_MEDIA = 46;
Jeff Davidson05542602014-08-11 14:07:27 -0700723 /** @hide Activate a VPN connection without user intervention. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100724 @UnsupportedAppUsage
Jeff Davidson05542602014-08-11 14:07:27 -0700725 public static final int OP_ACTIVATE_VPN = 47;
Benjamin Franzf3ece362015-02-11 10:51:10 +0000726 /** @hide Access the WallpaperManagerAPI to write wallpapers. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100727 @UnsupportedAppUsage
Benjamin Franzf3ece362015-02-11 10:51:10 +0000728 public static final int OP_WRITE_WALLPAPER = 48;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700729 /** @hide Received the assist structure from an app. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100730 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700731 public static final int OP_ASSIST_STRUCTURE = 49;
732 /** @hide Received a screenshot from assist. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100733 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700734 public static final int OP_ASSIST_SCREENSHOT = 50;
Svet Ganov16a16892015-04-16 10:32:04 -0700735 /** @hide Read the phone state. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100736 @UnsupportedAppUsage
Svet Ganov16a16892015-04-16 10:32:04 -0700737 public static final int OP_READ_PHONE_STATE = 51;
Svet Ganovc3300092015-04-17 09:07:22 -0700738 /** @hide Add voicemail messages to the voicemail content provider. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100739 @UnsupportedAppUsage
Svet Ganovc3300092015-04-17 09:07:22 -0700740 public static final int OP_ADD_VOICEMAIL = 52;
Svetoslav5335b672015-04-29 12:00:51 -0700741 /** @hide Access APIs for SIP calling over VOIP or WiFi. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100742 @UnsupportedAppUsage
Svetoslav5335b672015-04-29 12:00:51 -0700743 public static final int OP_USE_SIP = 53;
Svetoslavc656e6f2015-04-29 14:08:16 -0700744 /** @hide Intercept outgoing calls. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100745 @UnsupportedAppUsage
Svetoslavc656e6f2015-04-29 14:08:16 -0700746 public static final int OP_PROCESS_OUTGOING_CALLS = 54;
Svetoslav4af76a52015-04-29 15:29:46 -0700747 /** @hide User the fingerprint API. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100748 @UnsupportedAppUsage
Svetoslav4af76a52015-04-29 15:29:46 -0700749 public static final int OP_USE_FINGERPRINT = 55;
Svet Ganovb9d71a62015-04-30 10:38:13 -0700750 /** @hide Access to body sensors such as heart rate, etc. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100751 @UnsupportedAppUsage
Svet Ganovb9d71a62015-04-30 10:38:13 -0700752 public static final int OP_BODY_SENSORS = 56;
Svet Ganovede43162015-05-02 17:42:44 -0700753 /** @hide Read previously received cell broadcast messages. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100754 @UnsupportedAppUsage
Svet Ganovede43162015-05-02 17:42:44 -0700755 public static final int OP_READ_CELL_BROADCASTS = 57;
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700756 /** @hide Inject mock location into the system. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100757 @UnsupportedAppUsage
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700758 public static final int OP_MOCK_LOCATION = 58;
Svet Ganov921c7df2015-06-29 21:51:41 -0700759 /** @hide Read external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100760 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700761 public static final int OP_READ_EXTERNAL_STORAGE = 59;
762 /** @hide Write external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100763 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700764 public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700765 /** @hide Turned on the screen. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100766 @UnsupportedAppUsage
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700767 public static final int OP_TURN_SCREEN_ON = 61;
Svetoslavf3f02ac2015-09-08 14:36:35 -0700768 /** @hide Get device accounts. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100769 @UnsupportedAppUsage
Svetoslavf3f02ac2015-09-08 14:36:35 -0700770 public static final int OP_GET_ACCOUNTS = 62;
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700771 /** @hide Control whether an application is allowed to run in the background. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100772 @UnsupportedAppUsage
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700773 public static final int OP_RUN_IN_BACKGROUND = 63;
Jason Monk1c7c3192014-06-26 12:52:18 -0400774 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100775 @UnsupportedAppUsage
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800776 public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800777 /** @hide Read the phone number. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100778 @UnsupportedAppUsage
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700779 public static final int OP_READ_PHONE_NUMBERS = 65;
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800780 /** @hide Request package installs through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100781 @UnsupportedAppUsage
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800782 public static final int OP_REQUEST_INSTALL_PACKAGES = 66;
Winson Chungf4ac0632017-03-17 12:34:12 -0700783 /** @hide Enter picture-in-picture. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100784 @UnsupportedAppUsage
Winson Chungf4ac0632017-03-17 12:34:12 -0700785 public static final int OP_PICTURE_IN_PICTURE = 67;
Chad Brubaker97b383f2017-02-02 15:04:35 -0800786 /** @hide Instant app start foreground service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100787 @UnsupportedAppUsage
Chad Brubaker97b383f2017-02-02 15:04:35 -0800788 public static final int OP_INSTANT_APP_START_FOREGROUND = 68;
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800789 /** @hide Answer incoming phone calls */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100790 @UnsupportedAppUsage
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800791 public static final int OP_ANSWER_PHONE_CALLS = 69;
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700792 /** @hide Run jobs when in background */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100793 @UnsupportedAppUsage
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700794 public static final int OP_RUN_ANY_IN_BACKGROUND = 70;
Peter Visontay1246d9e2017-10-17 17:02:45 +0100795 /** @hide Change Wi-Fi connectivity state */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100796 @UnsupportedAppUsage
Peter Visontay1246d9e2017-10-17 17:02:45 +0100797 public static final int OP_CHANGE_WIFI_STATE = 71;
Peter Visontayf2e38362017-11-27 15:27:16 +0000798 /** @hide Request package deletion through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100799 @UnsupportedAppUsage
Peter Visontayf2e38362017-11-27 15:27:16 +0000800 public static final int OP_REQUEST_DELETE_PACKAGES = 72;
Peter Visontay11950832017-11-14 19:34:59 +0000801 /** @hide Bind an accessibility service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100802 @UnsupportedAppUsage
Peter Visontay11950832017-11-14 19:34:59 +0000803 public static final int OP_BIND_ACCESSIBILITY_SERVICE = 73;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800804 /** @hide Continue handover of a call from another app */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100805 @UnsupportedAppUsage
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800806 public static final int OP_ACCEPT_HANDOVER = 74;
Nathan Harold1bb420672018-03-14 17:08:53 -0700807 /** @hide Create and Manage IPsec Tunnels */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100808 @UnsupportedAppUsage
Nathan Harold1bb420672018-03-14 17:08:53 -0700809 public static final int OP_MANAGE_IPSEC_TUNNELS = 75;
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700810 /** @hide Any app start foreground service. */
Artur Satayev5a525852019-10-31 15:15:50 +0000811 @UnsupportedAppUsage
Svet Ganovaf189e32019-02-15 18:45:29 -0800812 @TestApi
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700813 public static final int OP_START_FOREGROUND = 76;
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800814 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100815 @UnsupportedAppUsage
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700816 public static final int OP_BLUETOOTH_SCAN = 77;
Kevin Chynb3c05aa2018-09-21 16:50:32 -0700817 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
818 public static final int OP_USE_BIOMETRIC = 78;
Zimuzo6cbf9cc2018-10-05 12:05:58 +0100819 /** @hide Physical activity recognition. */
820 public static final int OP_ACTIVITY_RECOGNITION = 79;
Hongming Jin228cd012018-11-09 14:47:50 -0800821 /** @hide Financial app sms read. */
822 public static final int OP_SMS_FINANCIAL_TRANSACTIONS = 80;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -0700823 /** @hide Read media of audio type. */
824 public static final int OP_READ_MEDIA_AUDIO = 81;
825 /** @hide Write media of audio type. */
826 public static final int OP_WRITE_MEDIA_AUDIO = 82;
827 /** @hide Read media of video type. */
828 public static final int OP_READ_MEDIA_VIDEO = 83;
829 /** @hide Write media of video type. */
830 public static final int OP_WRITE_MEDIA_VIDEO = 84;
831 /** @hide Read media of image type. */
832 public static final int OP_READ_MEDIA_IMAGES = 85;
833 /** @hide Write media of image type. */
834 public static final int OP_WRITE_MEDIA_IMAGES = 86;
Jeff Sharkeye82cbb12018-12-06 15:53:11 -0700835 /** @hide Has a legacy (non-isolated) view of storage. */
836 public static final int OP_LEGACY_STORAGE = 87;
Jackal Guo8dc791e2019-01-14 10:26:42 +0800837 /** @hide Accessing accessibility features */
838 public static final int OP_ACCESS_ACCESSIBILITY = 88;
Michael Groover656ef912019-04-09 17:09:57 -0700839 /** @hide Read the device identifiers (IMEI / MEID, IMSI, SIM / Build serial) */
840 public static final int OP_READ_DEVICE_IDENTIFIERS = 89;
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -0700841 /** @hide Read location metadata from media */
842 public static final int OP_ACCESS_MEDIA_LOCATION = 90;
843
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700844 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100845 @UnsupportedAppUsage
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -0700846 public static final int _NUM_OP = 91;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800847
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700848 /** Access to coarse location information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700849 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700850 /** Access to fine location information. */
851 public static final String OPSTR_FINE_LOCATION =
852 "android:fine_location";
853 /** Continually monitoring location data. */
854 public static final String OPSTR_MONITOR_LOCATION
855 = "android:monitor_location";
856 /** Continually monitoring location data with a relatively high power request. */
857 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
858 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700859 /** Access to {@link android.app.usage.UsageStatsManager}. */
860 public static final String OPSTR_GET_USAGE_STATS
861 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700862 /** Activate a VPN connection without user intervention. @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000863 @SystemApi @TestApi
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700864 public static final String OPSTR_ACTIVATE_VPN
865 = "android:activate_vpn";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700866 /** Allows an application to read the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700867 public static final String OPSTR_READ_CONTACTS
868 = "android:read_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700869 /** Allows an application to write to the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700870 public static final String OPSTR_WRITE_CONTACTS
871 = "android:write_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700872 /** Allows an application to read the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700873 public static final String OPSTR_READ_CALL_LOG
874 = "android:read_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700875 /** Allows an application to write to the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700876 public static final String OPSTR_WRITE_CALL_LOG
877 = "android:write_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700878 /** Allows an application to read the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700879 public static final String OPSTR_READ_CALENDAR
880 = "android:read_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700881 /** Allows an application to write to the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700882 public static final String OPSTR_WRITE_CALENDAR
883 = "android:write_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700884 /** Allows an application to initiate a phone call. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700885 public static final String OPSTR_CALL_PHONE
886 = "android:call_phone";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700887 /** Allows an application to read SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700888 public static final String OPSTR_READ_SMS
889 = "android:read_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700890 /** Allows an application to receive SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700891 public static final String OPSTR_RECEIVE_SMS
892 = "android:receive_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700893 /** Allows an application to receive MMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700894 public static final String OPSTR_RECEIVE_MMS
895 = "android:receive_mms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700896 /** Allows an application to receive WAP push messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700897 public static final String OPSTR_RECEIVE_WAP_PUSH
898 = "android:receive_wap_push";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700899 /** Allows an application to send SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700900 public static final String OPSTR_SEND_SMS
901 = "android:send_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700902 /** Required to be able to access the camera device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700903 public static final String OPSTR_CAMERA
904 = "android:camera";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700905 /** Required to be able to access the microphone device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700906 public static final String OPSTR_RECORD_AUDIO
907 = "android:record_audio";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700908 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700909 public static final String OPSTR_READ_PHONE_STATE
910 = "android:read_phone_state";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700911 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700912 public static final String OPSTR_ADD_VOICEMAIL
913 = "android:add_voicemail";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700914 /** Access APIs for SIP calling over VOIP or WiFi */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700915 public static final String OPSTR_USE_SIP
916 = "android:use_sip";
Svet Ganove8e89422016-09-22 19:56:50 -0700917 /** Access APIs for diverting outgoing calls */
Svet Ganov824ad6e2016-09-22 19:36:53 -0700918 public static final String OPSTR_PROCESS_OUTGOING_CALLS
919 = "android:process_outgoing_calls";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700920 /** Use the fingerprint API. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700921 public static final String OPSTR_USE_FINGERPRINT
922 = "android:use_fingerprint";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700923 /** Access to body sensors such as heart rate, etc. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700924 public static final String OPSTR_BODY_SENSORS
925 = "android:body_sensors";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700926 /** Read previously received cell broadcast messages. */
Svet Ganovede43162015-05-02 17:42:44 -0700927 public static final String OPSTR_READ_CELL_BROADCASTS
928 = "android:read_cell_broadcasts";
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700929 /** Inject mock location into the system. */
930 public static final String OPSTR_MOCK_LOCATION
931 = "android:mock_location";
Svet Ganov921c7df2015-06-29 21:51:41 -0700932 /** Read external storage. */
933 public static final String OPSTR_READ_EXTERNAL_STORAGE
934 = "android:read_external_storage";
935 /** Write external storage. */
936 public static final String OPSTR_WRITE_EXTERNAL_STORAGE
937 = "android:write_external_storage";
Billy Lau24b9c832015-07-20 17:34:09 +0100938 /** Required to draw on top of other apps. */
939 public static final String OPSTR_SYSTEM_ALERT_WINDOW
940 = "android:system_alert_window";
941 /** Required to write/modify/update system settingss. */
942 public static final String OPSTR_WRITE_SETTINGS
943 = "android:write_settings";
Svetoslavf3f02ac2015-09-08 14:36:35 -0700944 /** @hide Get device accounts. */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000945 @SystemApi @TestApi
Svetoslavf3f02ac2015-09-08 14:36:35 -0700946 public static final String OPSTR_GET_ACCOUNTS
947 = "android:get_accounts";
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700948 public static final String OPSTR_READ_PHONE_NUMBERS
949 = "android:read_phone_numbers";
Winson Chungf4ac0632017-03-17 12:34:12 -0700950 /** Access to picture-in-picture. */
951 public static final String OPSTR_PICTURE_IN_PICTURE
952 = "android:picture_in_picture";
Chad Brubaker97b383f2017-02-02 15:04:35 -0800953 /** @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000954 @SystemApi @TestApi
Chad Brubaker97b383f2017-02-02 15:04:35 -0800955 public static final String OPSTR_INSTANT_APP_START_FOREGROUND
956 = "android:instant_app_start_foreground";
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800957 /** Answer incoming phone calls */
958 public static final String OPSTR_ANSWER_PHONE_CALLS
959 = "android:answer_phone_calls";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800960 /**
961 * Accept call handover
962 * @hide
963 */
964 @SystemApi @TestApi
965 public static final String OPSTR_ACCEPT_HANDOVER
966 = "android:accept_handover";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000967 /** @hide */
968 @SystemApi @TestApi
969 public static final String OPSTR_GPS = "android:gps";
970 /** @hide */
971 @SystemApi @TestApi
972 public static final String OPSTR_VIBRATE = "android:vibrate";
973 /** @hide */
974 @SystemApi @TestApi
975 public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
976 /** @hide */
977 @SystemApi @TestApi
978 public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
979 /** @hide */
980 @SystemApi @TestApi
981 public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
982 /** @hide */
983 @SystemApi @TestApi
984 public static final String OPSTR_WRITE_SMS = "android:write_sms";
985 /** @hide */
986 @SystemApi @TestApi
987 public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST =
988 "android:receive_emergency_broadcast";
989 /** @hide */
990 @SystemApi @TestApi
991 public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
992 /** @hide */
993 @SystemApi @TestApi
994 public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
995 /** @hide */
996 @SystemApi @TestApi
997 public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
998 /** @hide */
999 @SystemApi @TestApi
1000 public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
1001 /** @hide */
1002 @SystemApi @TestApi
1003 public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
1004 /** @hide */
1005 @SystemApi @TestApi
1006 public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
1007 /** @hide */
1008 @SystemApi @TestApi
1009 public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
1010 /** @hide */
1011 @SystemApi @TestApi
1012 public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
1013 /** @hide */
1014 @SystemApi @TestApi
1015 public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
1016 /** @hide */
1017 @SystemApi @TestApi
1018 public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
1019 /** @hide */
1020 @SystemApi @TestApi
1021 public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
1022 /** @hide */
1023 @SystemApi @TestApi
1024 public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
1025 /** @hide */
1026 @SystemApi @TestApi
1027 public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
1028 /** @hide */
1029 @SystemApi @TestApi
1030 public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME =
1031 "android:audio_notification_volume";
1032 /** @hide */
1033 @SystemApi @TestApi
1034 public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
1035 /** @hide */
1036 @SystemApi @TestApi
1037 public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
1038 /** @hide */
1039 @SystemApi @TestApi
1040 public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
1041 /** @hide */
1042 @SystemApi @TestApi
1043 public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
1044 /** @hide */
1045 @SystemApi @TestApi
1046 public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
1047 /** @hide */
1048 @SystemApi @TestApi
1049 public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
1050 /** @hide */
1051 @SystemApi @TestApi
1052 public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
1053 /** @hide */
1054 @SystemApi @TestApi
1055 public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
1056 /** @hide */
1057 @SystemApi @TestApi
1058 public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
1059 /** @hide */
1060 @SystemApi @TestApi
1061 public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
1062 /** @hide */
1063 @SystemApi @TestApi
1064 public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME =
1065 "android:audio_accessibility_volume";
1066 /** @hide */
1067 @SystemApi @TestApi
1068 public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
1069 /** @hide */
1070 @SystemApi @TestApi
1071 public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
1072 /** @hide */
1073 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001074 public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001075 /** @hide */
1076 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001077 public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001078 /** @hide */
1079 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001080 public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE =
1081 "android:bind_accessibility_service";
Nathan Harold1bb420672018-03-14 17:08:53 -07001082 /** @hide */
1083 @SystemApi @TestApi
1084 public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001085 /** @hide */
1086 @SystemApi @TestApi
1087 public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001088 /** @hide */
1089 public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001090
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001091 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
1092 public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001093
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001094 /** @hide Recognize physical activity. */
1095 public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition";
1096
Hongming Jin228cd012018-11-09 14:47:50 -08001097 /** @hide Financial app read sms. */
1098 public static final String OPSTR_SMS_FINANCIAL_TRANSACTIONS =
1099 "android:sms_financial_transactions";
1100
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001101 /** @hide Read media of audio type. */
1102 public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
1103 /** @hide Write media of audio type. */
1104 public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
1105 /** @hide Read media of video type. */
1106 public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
1107 /** @hide Write media of video type. */
1108 public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
1109 /** @hide Read media of image type. */
1110 public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
1111 /** @hide Write media of image type. */
1112 public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001113 /** @hide Has a legacy (non-isolated) view of storage. */
Philip P. Moltmannc94ba822019-03-04 16:48:22 -08001114 @TestApi
1115 @SystemApi
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001116 public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -07001117 /** @hide Read location metadata from media */
1118 public static final String OPSTR_ACCESS_MEDIA_LOCATION = "android:access_media_location";
1119
Jackal Guo8dc791e2019-01-14 10:26:42 +08001120 /** @hide Interact with accessibility. */
Joel Galensonff4fe202019-02-06 14:43:58 -08001121 @SystemApi
Jackal Guo8dc791e2019-01-14 10:26:42 +08001122 public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
Michael Groover656ef912019-04-09 17:09:57 -07001123 /** @hide Read device identifiers */
1124 public static final String OPSTR_READ_DEVICE_IDENTIFIERS = "android:read_device_identifiers";
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001125
Philip P. Moltmanne56c08e2017-03-15 12:46:04 -07001126 // Warning: If an permission is added here it also has to be added to
1127 // com.android.packageinstaller.permission.utils.EventLogger
Svet Ganovda0acdf2017-02-15 10:28:51 -08001128 private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
1129 // RUNTIME PERMISSIONS
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001130 // Contacts
1131 OP_READ_CONTACTS,
1132 OP_WRITE_CONTACTS,
1133 OP_GET_ACCOUNTS,
1134 // Calendar
1135 OP_READ_CALENDAR,
1136 OP_WRITE_CALENDAR,
1137 // SMS
1138 OP_SEND_SMS,
1139 OP_RECEIVE_SMS,
1140 OP_READ_SMS,
1141 OP_RECEIVE_WAP_PUSH,
1142 OP_RECEIVE_MMS,
1143 OP_READ_CELL_BROADCASTS,
1144 // Storage
1145 OP_READ_EXTERNAL_STORAGE,
1146 OP_WRITE_EXTERNAL_STORAGE,
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -07001147 OP_ACCESS_MEDIA_LOCATION,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001148 // Location
1149 OP_COARSE_LOCATION,
1150 OP_FINE_LOCATION,
1151 // Phone
1152 OP_READ_PHONE_STATE,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001153 OP_READ_PHONE_NUMBERS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001154 OP_CALL_PHONE,
1155 OP_READ_CALL_LOG,
1156 OP_WRITE_CALL_LOG,
1157 OP_ADD_VOICEMAIL,
1158 OP_USE_SIP,
1159 OP_PROCESS_OUTGOING_CALLS,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001160 OP_ANSWER_PHONE_CALLS,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001161 OP_ACCEPT_HANDOVER,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001162 // Microphone
1163 OP_RECORD_AUDIO,
1164 // Camera
1165 OP_CAMERA,
1166 // Body sensors
Svet Ganovda0acdf2017-02-15 10:28:51 -08001167 OP_BODY_SENSORS,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001168 // Activity recognition
1169 OP_ACTIVITY_RECOGNITION,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001170 // Aural
1171 OP_READ_MEDIA_AUDIO,
1172 OP_WRITE_MEDIA_AUDIO,
1173 // Visual
1174 OP_READ_MEDIA_VIDEO,
1175 OP_WRITE_MEDIA_VIDEO,
1176 OP_READ_MEDIA_IMAGES,
1177 OP_WRITE_MEDIA_IMAGES,
Svet Ganovda0acdf2017-02-15 10:28:51 -08001178
1179 // APPOP PERMISSIONS
1180 OP_ACCESS_NOTIFICATIONS,
1181 OP_SYSTEM_ALERT_WINDOW,
1182 OP_WRITE_SETTINGS,
1183 OP_REQUEST_INSTALL_PACKAGES,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001184 OP_START_FOREGROUND,
Hongming Jin228cd012018-11-09 14:47:50 -08001185 OP_SMS_FINANCIAL_TRANSACTIONS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001186 };
1187
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001188 /**
1189 * This maps each operation to the operation that serves as the
1190 * switch to determine whether it is allowed. Generally this is
1191 * a 1:1 mapping, but for some things (like location) that have
1192 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -07001193 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001194 * make them all controlled by the same single operation.
1195 */
1196 private static int[] sOpToSwitch = new int[] {
Dianne Hackbornc216a262018-04-26 13:46:22 -07001197 OP_COARSE_LOCATION, // COARSE_LOCATION
1198 OP_COARSE_LOCATION, // FINE_LOCATION
1199 OP_COARSE_LOCATION, // GPS
1200 OP_VIBRATE, // VIBRATE
1201 OP_READ_CONTACTS, // READ_CONTACTS
1202 OP_WRITE_CONTACTS, // WRITE_CONTACTS
1203 OP_READ_CALL_LOG, // READ_CALL_LOG
1204 OP_WRITE_CALL_LOG, // WRITE_CALL_LOG
1205 OP_READ_CALENDAR, // READ_CALENDAR
1206 OP_WRITE_CALENDAR, // WRITE_CALENDAR
1207 OP_COARSE_LOCATION, // WIFI_SCAN
1208 OP_POST_NOTIFICATION, // POST_NOTIFICATION
1209 OP_COARSE_LOCATION, // NEIGHBORING_CELLS
1210 OP_CALL_PHONE, // CALL_PHONE
1211 OP_READ_SMS, // READ_SMS
1212 OP_WRITE_SMS, // WRITE_SMS
1213 OP_RECEIVE_SMS, // RECEIVE_SMS
1214 OP_RECEIVE_SMS, // RECEIVE_EMERGECY_SMS
1215 OP_RECEIVE_MMS, // RECEIVE_MMS
1216 OP_RECEIVE_WAP_PUSH, // RECEIVE_WAP_PUSH
1217 OP_SEND_SMS, // SEND_SMS
1218 OP_READ_SMS, // READ_ICC_SMS
1219 OP_WRITE_SMS, // WRITE_ICC_SMS
1220 OP_WRITE_SETTINGS, // WRITE_SETTINGS
1221 OP_SYSTEM_ALERT_WINDOW, // SYSTEM_ALERT_WINDOW
1222 OP_ACCESS_NOTIFICATIONS, // ACCESS_NOTIFICATIONS
1223 OP_CAMERA, // CAMERA
1224 OP_RECORD_AUDIO, // RECORD_AUDIO
1225 OP_PLAY_AUDIO, // PLAY_AUDIO
1226 OP_READ_CLIPBOARD, // READ_CLIPBOARD
1227 OP_WRITE_CLIPBOARD, // WRITE_CLIPBOARD
1228 OP_TAKE_MEDIA_BUTTONS, // TAKE_MEDIA_BUTTONS
1229 OP_TAKE_AUDIO_FOCUS, // TAKE_AUDIO_FOCUS
1230 OP_AUDIO_MASTER_VOLUME, // AUDIO_MASTER_VOLUME
1231 OP_AUDIO_VOICE_VOLUME, // AUDIO_VOICE_VOLUME
1232 OP_AUDIO_RING_VOLUME, // AUDIO_RING_VOLUME
1233 OP_AUDIO_MEDIA_VOLUME, // AUDIO_MEDIA_VOLUME
1234 OP_AUDIO_ALARM_VOLUME, // AUDIO_ALARM_VOLUME
1235 OP_AUDIO_NOTIFICATION_VOLUME, // AUDIO_NOTIFICATION_VOLUME
1236 OP_AUDIO_BLUETOOTH_VOLUME, // AUDIO_BLUETOOTH_VOLUME
1237 OP_WAKE_LOCK, // WAKE_LOCK
1238 OP_COARSE_LOCATION, // MONITOR_LOCATION
1239 OP_COARSE_LOCATION, // MONITOR_HIGH_POWER_LOCATION
1240 OP_GET_USAGE_STATS, // GET_USAGE_STATS
1241 OP_MUTE_MICROPHONE, // MUTE_MICROPHONE
1242 OP_TOAST_WINDOW, // TOAST_WINDOW
1243 OP_PROJECT_MEDIA, // PROJECT_MEDIA
1244 OP_ACTIVATE_VPN, // ACTIVATE_VPN
1245 OP_WRITE_WALLPAPER, // WRITE_WALLPAPER
1246 OP_ASSIST_STRUCTURE, // ASSIST_STRUCTURE
1247 OP_ASSIST_SCREENSHOT, // ASSIST_SCREENSHOT
1248 OP_READ_PHONE_STATE, // READ_PHONE_STATE
1249 OP_ADD_VOICEMAIL, // ADD_VOICEMAIL
1250 OP_USE_SIP, // USE_SIP
1251 OP_PROCESS_OUTGOING_CALLS, // PROCESS_OUTGOING_CALLS
1252 OP_USE_FINGERPRINT, // USE_FINGERPRINT
1253 OP_BODY_SENSORS, // BODY_SENSORS
1254 OP_READ_CELL_BROADCASTS, // READ_CELL_BROADCASTS
1255 OP_MOCK_LOCATION, // MOCK_LOCATION
1256 OP_READ_EXTERNAL_STORAGE, // READ_EXTERNAL_STORAGE
1257 OP_WRITE_EXTERNAL_STORAGE, // WRITE_EXTERNAL_STORAGE
1258 OP_TURN_SCREEN_ON, // TURN_SCREEN_ON
1259 OP_GET_ACCOUNTS, // GET_ACCOUNTS
1260 OP_RUN_IN_BACKGROUND, // RUN_IN_BACKGROUND
1261 OP_AUDIO_ACCESSIBILITY_VOLUME, // AUDIO_ACCESSIBILITY_VOLUME
1262 OP_READ_PHONE_NUMBERS, // READ_PHONE_NUMBERS
1263 OP_REQUEST_INSTALL_PACKAGES, // REQUEST_INSTALL_PACKAGES
1264 OP_PICTURE_IN_PICTURE, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
1265 OP_INSTANT_APP_START_FOREGROUND, // INSTANT_APP_START_FOREGROUND
1266 OP_ANSWER_PHONE_CALLS, // ANSWER_PHONE_CALLS
1267 OP_RUN_ANY_IN_BACKGROUND, // OP_RUN_ANY_IN_BACKGROUND
1268 OP_CHANGE_WIFI_STATE, // OP_CHANGE_WIFI_STATE
1269 OP_REQUEST_DELETE_PACKAGES, // OP_REQUEST_DELETE_PACKAGES
1270 OP_BIND_ACCESSIBILITY_SERVICE, // OP_BIND_ACCESSIBILITY_SERVICE
1271 OP_ACCEPT_HANDOVER, // ACCEPT_HANDOVER
1272 OP_MANAGE_IPSEC_TUNNELS, // MANAGE_IPSEC_HANDOVERS
1273 OP_START_FOREGROUND, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001274 OP_COARSE_LOCATION, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001275 OP_USE_BIOMETRIC, // BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001276 OP_ACTIVITY_RECOGNITION, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001277 OP_SMS_FINANCIAL_TRANSACTIONS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001278 OP_READ_MEDIA_AUDIO, // READ_MEDIA_AUDIO
1279 OP_WRITE_MEDIA_AUDIO, // WRITE_MEDIA_AUDIO
1280 OP_READ_MEDIA_VIDEO, // READ_MEDIA_VIDEO
1281 OP_WRITE_MEDIA_VIDEO, // WRITE_MEDIA_VIDEO
1282 OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES
1283 OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001284 OP_LEGACY_STORAGE, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001285 OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001286 OP_READ_DEVICE_IDENTIFIERS, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -07001287 OP_ACCESS_MEDIA_LOCATION, // ACCESS_MEDIA_LOCATION
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001288 };
1289
1290 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001291 * This maps each operation to the public string constant for it.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001292 */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001293 private static String[] sOpToString = new String[]{
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001294 OPSTR_COARSE_LOCATION,
1295 OPSTR_FINE_LOCATION,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001296 OPSTR_GPS,
1297 OPSTR_VIBRATE,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001298 OPSTR_READ_CONTACTS,
1299 OPSTR_WRITE_CONTACTS,
1300 OPSTR_READ_CALL_LOG,
1301 OPSTR_WRITE_CALL_LOG,
1302 OPSTR_READ_CALENDAR,
1303 OPSTR_WRITE_CALENDAR,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001304 OPSTR_WIFI_SCAN,
1305 OPSTR_POST_NOTIFICATION,
1306 OPSTR_NEIGHBORING_CELLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001307 OPSTR_CALL_PHONE,
1308 OPSTR_READ_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001309 OPSTR_WRITE_SMS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001310 OPSTR_RECEIVE_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001311 OPSTR_RECEIVE_EMERGENCY_BROADCAST,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001312 OPSTR_RECEIVE_MMS,
1313 OPSTR_RECEIVE_WAP_PUSH,
1314 OPSTR_SEND_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001315 OPSTR_READ_ICC_SMS,
1316 OPSTR_WRITE_ICC_SMS,
Billy Lau24b9c832015-07-20 17:34:09 +01001317 OPSTR_WRITE_SETTINGS,
1318 OPSTR_SYSTEM_ALERT_WINDOW,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001319 OPSTR_ACCESS_NOTIFICATIONS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001320 OPSTR_CAMERA,
1321 OPSTR_RECORD_AUDIO,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001322 OPSTR_PLAY_AUDIO,
1323 OPSTR_READ_CLIPBOARD,
1324 OPSTR_WRITE_CLIPBOARD,
1325 OPSTR_TAKE_MEDIA_BUTTONS,
1326 OPSTR_TAKE_AUDIO_FOCUS,
1327 OPSTR_AUDIO_MASTER_VOLUME,
1328 OPSTR_AUDIO_VOICE_VOLUME,
1329 OPSTR_AUDIO_RING_VOLUME,
1330 OPSTR_AUDIO_MEDIA_VOLUME,
1331 OPSTR_AUDIO_ALARM_VOLUME,
1332 OPSTR_AUDIO_NOTIFICATION_VOLUME,
1333 OPSTR_AUDIO_BLUETOOTH_VOLUME,
1334 OPSTR_WAKE_LOCK,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001335 OPSTR_MONITOR_LOCATION,
1336 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -07001337 OPSTR_GET_USAGE_STATS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001338 OPSTR_MUTE_MICROPHONE,
1339 OPSTR_TOAST_WINDOW,
1340 OPSTR_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -07001341 OPSTR_ACTIVATE_VPN,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001342 OPSTR_WRITE_WALLPAPER,
1343 OPSTR_ASSIST_STRUCTURE,
1344 OPSTR_ASSIST_SCREENSHOT,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001345 OPSTR_READ_PHONE_STATE,
1346 OPSTR_ADD_VOICEMAIL,
1347 OPSTR_USE_SIP,
Svet Ganov824ad6e2016-09-22 19:36:53 -07001348 OPSTR_PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001349 OPSTR_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001350 OPSTR_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001351 OPSTR_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001352 OPSTR_MOCK_LOCATION,
1353 OPSTR_READ_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001354 OPSTR_WRITE_EXTERNAL_STORAGE,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001355 OPSTR_TURN_SCREEN_ON,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001356 OPSTR_GET_ACCOUNTS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001357 OPSTR_RUN_IN_BACKGROUND,
1358 OPSTR_AUDIO_ACCESSIBILITY_VOLUME,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001359 OPSTR_READ_PHONE_NUMBERS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001360 OPSTR_REQUEST_INSTALL_PACKAGES,
Winson Chungf4ac0632017-03-17 12:34:12 -07001361 OPSTR_PICTURE_IN_PICTURE,
Chad Brubaker97b383f2017-02-02 15:04:35 -08001362 OPSTR_INSTANT_APP_START_FOREGROUND,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001363 OPSTR_ANSWER_PHONE_CALLS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001364 OPSTR_RUN_ANY_IN_BACKGROUND,
1365 OPSTR_CHANGE_WIFI_STATE,
1366 OPSTR_REQUEST_DELETE_PACKAGES,
1367 OPSTR_BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001368 OPSTR_ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001369 OPSTR_MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001370 OPSTR_START_FOREGROUND,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001371 OPSTR_BLUETOOTH_SCAN,
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001372 OPSTR_USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001373 OPSTR_ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001374 OPSTR_SMS_FINANCIAL_TRANSACTIONS,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001375 OPSTR_READ_MEDIA_AUDIO,
1376 OPSTR_WRITE_MEDIA_AUDIO,
1377 OPSTR_READ_MEDIA_VIDEO,
1378 OPSTR_WRITE_MEDIA_VIDEO,
1379 OPSTR_READ_MEDIA_IMAGES,
1380 OPSTR_WRITE_MEDIA_IMAGES,
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001381 OPSTR_LEGACY_STORAGE,
Jackal Guo8dc791e2019-01-14 10:26:42 +08001382 OPSTR_ACCESS_ACCESSIBILITY,
Michael Groover656ef912019-04-09 17:09:57 -07001383 OPSTR_READ_DEVICE_IDENTIFIERS,
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -07001384 OPSTR_ACCESS_MEDIA_LOCATION,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001385 };
1386
1387 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001388 * This provides a simple name for each operation to be used
1389 * in debug output.
1390 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001391 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001392 "COARSE_LOCATION",
1393 "FINE_LOCATION",
1394 "GPS",
1395 "VIBRATE",
1396 "READ_CONTACTS",
1397 "WRITE_CONTACTS",
1398 "READ_CALL_LOG",
1399 "WRITE_CALL_LOG",
1400 "READ_CALENDAR",
1401 "WRITE_CALENDAR",
1402 "WIFI_SCAN",
1403 "POST_NOTIFICATION",
1404 "NEIGHBORING_CELLS",
1405 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001406 "READ_SMS",
1407 "WRITE_SMS",
1408 "RECEIVE_SMS",
1409 "RECEIVE_EMERGECY_SMS",
1410 "RECEIVE_MMS",
1411 "RECEIVE_WAP_PUSH",
1412 "SEND_SMS",
1413 "READ_ICC_SMS",
1414 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -08001415 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -08001416 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001417 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001418 "CAMERA",
1419 "RECORD_AUDIO",
1420 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001421 "READ_CLIPBOARD",
1422 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001423 "TAKE_MEDIA_BUTTONS",
1424 "TAKE_AUDIO_FOCUS",
1425 "AUDIO_MASTER_VOLUME",
1426 "AUDIO_VOICE_VOLUME",
1427 "AUDIO_RING_VOLUME",
1428 "AUDIO_MEDIA_VOLUME",
1429 "AUDIO_ALARM_VOLUME",
1430 "AUDIO_NOTIFICATION_VOLUME",
1431 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -07001432 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001433 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -07001434 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -04001435 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001436 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -04001437 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001438 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -07001439 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +00001440 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001441 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -07001442 "ASSIST_SCREENSHOT",
Eugene Suslae4ee2c22018-11-05 12:23:30 -08001443 "READ_PHONE_STATE",
Svetoslav5335b672015-04-29 12:00:51 -07001444 "ADD_VOICEMAIL",
Svetoslavc656e6f2015-04-29 14:08:16 -07001445 "USE_SIP",
Svetoslav4af76a52015-04-29 15:29:46 -07001446 "PROCESS_OUTGOING_CALLS",
Svet Ganovb9d71a62015-04-30 10:38:13 -07001447 "USE_FINGERPRINT",
Svet Ganovede43162015-05-02 17:42:44 -07001448 "BODY_SENSORS",
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001449 "READ_CELL_BROADCASTS",
Svet Ganov921c7df2015-06-29 21:51:41 -07001450 "MOCK_LOCATION",
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001451 "READ_EXTERNAL_STORAGE",
1452 "WRITE_EXTERNAL_STORAGE",
1453 "TURN_ON_SCREEN",
Svetoslavf3f02ac2015-09-08 14:36:35 -07001454 "GET_ACCOUNTS",
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001455 "RUN_IN_BACKGROUND",
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001456 "AUDIO_ACCESSIBILITY_VOLUME",
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001457 "READ_PHONE_NUMBERS",
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001458 "REQUEST_INSTALL_PACKAGES",
Winson Chungf4ac0632017-03-17 12:34:12 -07001459 "PICTURE_IN_PICTURE",
Chad Brubaker97b383f2017-02-02 15:04:35 -08001460 "INSTANT_APP_START_FOREGROUND",
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001461 "ANSWER_PHONE_CALLS",
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001462 "RUN_ANY_IN_BACKGROUND",
Peter Visontay1246d9e2017-10-17 17:02:45 +01001463 "CHANGE_WIFI_STATE",
Peter Visontayf2e38362017-11-27 15:27:16 +00001464 "REQUEST_DELETE_PACKAGES",
Peter Visontay11950832017-11-14 19:34:59 +00001465 "BIND_ACCESSIBILITY_SERVICE",
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001466 "ACCEPT_HANDOVER",
Nathan Harold1bb420672018-03-14 17:08:53 -07001467 "MANAGE_IPSEC_TUNNELS",
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001468 "START_FOREGROUND",
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001469 "BLUETOOTH_SCAN",
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001470 "USE_BIOMETRIC",
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001471 "ACTIVITY_RECOGNITION",
Hongming Jin228cd012018-11-09 14:47:50 -08001472 "SMS_FINANCIAL_TRANSACTIONS",
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001473 "READ_MEDIA_AUDIO",
1474 "WRITE_MEDIA_AUDIO",
1475 "READ_MEDIA_VIDEO",
1476 "WRITE_MEDIA_VIDEO",
1477 "READ_MEDIA_IMAGES",
1478 "WRITE_MEDIA_IMAGES",
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001479 "LEGACY_STORAGE",
Jackal Guo8dc791e2019-01-14 10:26:42 +08001480 "ACCESS_ACCESSIBILITY",
Michael Groover656ef912019-04-09 17:09:57 -07001481 "READ_DEVICE_IDENTIFIERS",
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -07001482 "ACCESS_MEDIA_LOCATION",
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001483 };
1484
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001485 /**
1486 * This optionally maps a permission to an operation. If there
1487 * is no permission associated with an operation, it is null.
1488 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001489 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001490 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001491 android.Manifest.permission.ACCESS_COARSE_LOCATION,
1492 android.Manifest.permission.ACCESS_FINE_LOCATION,
1493 null,
1494 android.Manifest.permission.VIBRATE,
1495 android.Manifest.permission.READ_CONTACTS,
1496 android.Manifest.permission.WRITE_CONTACTS,
1497 android.Manifest.permission.READ_CALL_LOG,
1498 android.Manifest.permission.WRITE_CALL_LOG,
1499 android.Manifest.permission.READ_CALENDAR,
1500 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001501 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -04001502 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001503 null, // neighboring cells shares the coarse location perm
1504 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001505 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001506 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001507 android.Manifest.permission.RECEIVE_SMS,
1508 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
1509 android.Manifest.permission.RECEIVE_MMS,
1510 android.Manifest.permission.RECEIVE_WAP_PUSH,
1511 android.Manifest.permission.SEND_SMS,
1512 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001513 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -08001514 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -08001515 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001516 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001517 android.Manifest.permission.CAMERA,
1518 android.Manifest.permission.RECORD_AUDIO,
1519 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001520 null, // no permission for reading clipboard
1521 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001522 null, // no permission for taking media buttons
1523 null, // no permission for taking audio focus
1524 null, // no permission for changing master volume
1525 null, // no permission for changing voice volume
1526 null, // no permission for changing ring volume
1527 null, // no permission for changing media volume
1528 null, // no permission for changing alarm volume
1529 null, // no permission for changing notification volume
1530 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -07001531 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001532 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -07001533 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -07001534 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -04001535 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -04001536 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -07001537 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -07001538 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +00001539 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001540 null, // no permission for receiving assist structure
1541 null, // no permission for receiving assist screenshot
Svet Ganovc3300092015-04-17 09:07:22 -07001542 Manifest.permission.READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -07001543 Manifest.permission.ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -07001544 Manifest.permission.USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -07001545 Manifest.permission.PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001546 Manifest.permission.USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001547 Manifest.permission.BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001548 Manifest.permission.READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001549 null,
1550 Manifest.permission.READ_EXTERNAL_STORAGE,
1551 Manifest.permission.WRITE_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001552 null, // no permission for turning the screen on
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001553 Manifest.permission.GET_ACCOUNTS,
1554 null, // no permission for running in background
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001555 null, // no permission for changing accessibility volume
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001556 Manifest.permission.READ_PHONE_NUMBERS,
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001557 Manifest.permission.REQUEST_INSTALL_PACKAGES,
Winson Chung59fda9e2017-01-20 16:14:51 -08001558 null, // no permission for entering picture-in-picture on hide
Chad Brubaker97b383f2017-02-02 15:04:35 -08001559 Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001560 Manifest.permission.ANSWER_PHONE_CALLS,
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001561 null, // no permission for OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001562 Manifest.permission.CHANGE_WIFI_STATE,
Peter Visontayf2e38362017-11-27 15:27:16 +00001563 Manifest.permission.REQUEST_DELETE_PACKAGES,
Peter Visontay11950832017-11-14 19:34:59 +00001564 Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001565 Manifest.permission.ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001566 null, // no permission for OP_MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001567 Manifest.permission.FOREGROUND_SERVICE,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001568 null, // no permission for OP_BLUETOOTH_SCAN
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001569 Manifest.permission.USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001570 Manifest.permission.ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001571 Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001572 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001573 null, // no permission for OP_WRITE_MEDIA_AUDIO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001574 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001575 null, // no permission for OP_WRITE_MEDIA_VIDEO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001576 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001577 null, // no permission for OP_WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001578 null, // no permission for OP_LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001579 null, // no permission for OP_ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001580 null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -07001581 Manifest.permission.ACCESS_MEDIA_LOCATION,
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001582 };
1583
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001584 /**
Jason Monk62062992014-05-06 09:55:28 -04001585 * Specifies whether an Op should be restricted by a user restriction.
1586 * Each Op should be filled with a restriction string from UserManager or
1587 * null to specify it is not affected by any user restriction.
1588 */
1589 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -04001590 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
1591 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
1592 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -04001593 null, //VIBRATE
1594 null, //READ_CONTACTS
1595 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -07001596 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
1597 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -04001598 null, //READ_CALENDAR
1599 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001600 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -04001601 null, //POST_NOTIFICATION
1602 null, //NEIGHBORING_CELLS
1603 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001604 UserManager.DISALLOW_SMS, //READ_SMS
1605 UserManager.DISALLOW_SMS, //WRITE_SMS
1606 UserManager.DISALLOW_SMS, //RECEIVE_SMS
1607 null, //RECEIVE_EMERGENCY_SMS
1608 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -04001609 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001610 UserManager.DISALLOW_SMS, //SEND_SMS
1611 UserManager.DISALLOW_SMS, //READ_ICC_SMS
1612 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -04001613 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -04001614 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -04001615 null, //ACCESS_NOTIFICATIONS
Makoto Onuki759a7632015-10-28 16:43:10 -07001616 UserManager.DISALLOW_CAMERA, //CAMERA
Fyodor Kupolovb5013302015-04-17 17:59:14 -07001617 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
Jason Monk62062992014-05-06 09:55:28 -04001618 null, //PLAY_AUDIO
1619 null, //READ_CLIPBOARD
1620 null, //WRITE_CLIPBOARD
1621 null, //TAKE_MEDIA_BUTTONS
1622 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -04001623 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
1624 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
1625 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
1626 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
1627 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
1628 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
1629 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -04001630 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -04001631 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
1632 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -04001633 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -04001634 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -04001635 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -07001636 null, //PROJECT_MEDIA
Tony Mak33d03a92016-06-02 15:01:16 +01001637 null, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001638 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001639 null, // ASSIST_STRUCTURE
1640 null, // ASSIST_SCREENSHOT
Svet Ganovc3300092015-04-17 09:07:22 -07001641 null, // READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001642 null, // ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001643 null, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001644 null, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001645 null, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001646 null, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001647 null, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001648 null, // MOCK_LOCATION
1649 null, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001650 null, // WRITE_EXTERNAL_STORAGE
1651 null, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001652 null, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001653 null, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001654 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001655 null, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001656 null, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001657 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001658 null, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001659 null, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001660 null, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001661 null, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001662 null, // REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001663 null, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001664 null, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001665 null, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001666 null, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001667 null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001668 null, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001669 null, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001670 UserManager.DISALLOW_SMS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001671 null, // READ_MEDIA_AUDIO
1672 null, // WRITE_MEDIA_AUDIO
1673 null, // READ_MEDIA_VIDEO
1674 null, // WRITE_MEDIA_VIDEO
1675 null, // READ_MEDIA_IMAGES
1676 null, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001677 null, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001678 null, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001679 null, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -07001680 null, // ACCESS_MEDIA_LOCATION
Jason Monk1c7c3192014-06-26 12:52:18 -04001681 };
1682
1683 /**
1684 * This specifies whether each option should allow the system
1685 * (and system ui) to bypass the user restriction when active.
1686 */
1687 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
Fyodor Kupolov639e73d2016-02-25 11:58:21 -08001688 true, //COARSE_LOCATION
1689 true, //FINE_LOCATION
Jason Monk1c7c3192014-06-26 12:52:18 -04001690 false, //GPS
1691 false, //VIBRATE
1692 false, //READ_CONTACTS
1693 false, //WRITE_CONTACTS
1694 false, //READ_CALL_LOG
1695 false, //WRITE_CALL_LOG
1696 false, //READ_CALENDAR
1697 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001698 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -04001699 false, //POST_NOTIFICATION
1700 false, //NEIGHBORING_CELLS
1701 false, //CALL_PHONE
1702 false, //READ_SMS
1703 false, //WRITE_SMS
1704 false, //RECEIVE_SMS
1705 false, //RECEIVE_EMERGECY_SMS
1706 false, //RECEIVE_MMS
1707 false, //RECEIVE_WAP_PUSH
1708 false, //SEND_SMS
1709 false, //READ_ICC_SMS
1710 false, //WRITE_ICC_SMS
1711 false, //WRITE_SETTINGS
1712 true, //SYSTEM_ALERT_WINDOW
1713 false, //ACCESS_NOTIFICATIONS
1714 false, //CAMERA
1715 false, //RECORD_AUDIO
1716 false, //PLAY_AUDIO
1717 false, //READ_CLIPBOARD
1718 false, //WRITE_CLIPBOARD
1719 false, //TAKE_MEDIA_BUTTONS
1720 false, //TAKE_AUDIO_FOCUS
1721 false, //AUDIO_MASTER_VOLUME
1722 false, //AUDIO_VOICE_VOLUME
1723 false, //AUDIO_RING_VOLUME
1724 false, //AUDIO_MEDIA_VOLUME
1725 false, //AUDIO_ALARM_VOLUME
1726 false, //AUDIO_NOTIFICATION_VOLUME
1727 false, //AUDIO_BLUETOOTH_VOLUME
1728 false, //WAKE_LOCK
1729 false, //MONITOR_LOCATION
1730 false, //MONITOR_HIGH_POWER_LOCATION
1731 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -07001732 false, //MUTE_MICROPHONE
1733 true, //TOAST_WINDOW
1734 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -07001735 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001736 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001737 false, //ASSIST_STRUCTURE
1738 false, //ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -07001739 false, //READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001740 false, //ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001741 false, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001742 false, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001743 false, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001744 false, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001745 false, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001746 false, // MOCK_LOCATION
1747 false, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001748 false, // WRITE_EXTERNAL_STORAGE
1749 false, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001750 false, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001751 false, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001752 false, // AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001753 false, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001754 false, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001755 false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001756 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001757 false, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001758 false, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001759 false, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001760 false, // OP_REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001761 false, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001762 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001763 false, // MANAGE_IPSEC_HANDOVERS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001764 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001765 true, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001766 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001767 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001768 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001769 false, // READ_MEDIA_AUDIO
1770 false, // WRITE_MEDIA_AUDIO
1771 false, // READ_MEDIA_VIDEO
1772 false, // WRITE_MEDIA_VIDEO
1773 false, // READ_MEDIA_IMAGES
1774 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001775 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001776 false, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001777 false, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -07001778 false, // ACCESS_MEDIA_LOCATION
Jason Monk62062992014-05-06 09:55:28 -04001779 };
1780
1781 /**
David Braunf5d83192013-09-16 13:43:51 -07001782 * This specifies the default mode for each operation.
1783 */
1784 private static int[] sOpDefaultMode = new int[] {
Eugene Susla93519852018-06-13 16:44:31 -07001785 AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION
1786 AppOpsManager.MODE_ALLOWED, // FINE_LOCATION
1787 AppOpsManager.MODE_ALLOWED, // GPS
1788 AppOpsManager.MODE_ALLOWED, // VIBRATE
1789 AppOpsManager.MODE_ALLOWED, // READ_CONTACTS
1790 AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS
Svet Ganovd563e932019-04-14 13:07:41 -07001791 AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG
1792 AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG
Eugene Susla93519852018-06-13 16:44:31 -07001793 AppOpsManager.MODE_ALLOWED, // READ_CALENDAR
1794 AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR
1795 AppOpsManager.MODE_ALLOWED, // WIFI_SCAN
1796 AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION
1797 AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS
1798 AppOpsManager.MODE_ALLOWED, // CALL_PHONE
Svet Ganovd563e932019-04-14 13:07:41 -07001799 AppOpsManager.MODE_ALLOWED, // READ_SMS
Eugene Suslaaaff0072018-10-30 13:35:03 -07001800 AppOpsManager.MODE_IGNORED, // WRITE_SMS
Svet Ganovd563e932019-04-14 13:07:41 -07001801 AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001802 AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST
Svet Ganovd563e932019-04-14 13:07:41 -07001803 AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS
1804 AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH
1805 AppOpsManager.MODE_ALLOWED, // SEND_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001806 AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS
1807 AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS
1808 AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS
Ng Zhi An65a99b62018-10-01 11:57:53 -07001809 getSystemAlertWindowDefault(), // SYSTEM_ALERT_WINDOW
Eugene Susla93519852018-06-13 16:44:31 -07001810 AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS
1811 AppOpsManager.MODE_ALLOWED, // CAMERA
1812 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO
1813 AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO
1814 AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD
1815 AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD
1816 AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS
1817 AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS
1818 AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME
1819 AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME
1820 AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME
1821 AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME
1822 AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME
1823 AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME
1824 AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME
1825 AppOpsManager.MODE_ALLOWED, // WAKE_LOCK
1826 AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION
1827 AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION
1828 AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS
1829 AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE
1830 AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW
1831 AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA
1832 AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN
1833 AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER
1834 AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE
1835 AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT
1836 AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE
1837 AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL
1838 AppOpsManager.MODE_ALLOWED, // USE_SIP
Svet Ganovd563e932019-04-14 13:07:41 -07001839 AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07001840 AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT
1841 AppOpsManager.MODE_ALLOWED, // BODY_SENSORS
Svet Ganovd563e932019-04-14 13:07:41 -07001842 AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS
Eugene Susla93519852018-06-13 16:44:31 -07001843 AppOpsManager.MODE_ERRORED, // MOCK_LOCATION
1844 AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE
1845 AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE
1846 AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON
1847 AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS
1848 AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND
1849 AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME
1850 AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS
1851 AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES
1852 AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE
1853 AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND
1854 AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
1855 AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND
1856 AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE
1857 AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES
1858 AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE
1859 AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER
1860 AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS
1861 AppOpsManager.MODE_ALLOWED, // START_FOREGROUND
1862 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN
1863 AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001864 AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001865 AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001866 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001867 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001868 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001869 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001870 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001871 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001872 AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001873 AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001874 AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -07001875 AppOpsManager.MODE_ALLOWED, // ALLOW_MEDIA_LOCATION
David Braunf5d83192013-09-16 13:43:51 -07001876 };
1877
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001878 /**
1879 * This specifies whether each option is allowed to be reset
1880 * when resetting all app preferences. Disable reset for
1881 * app ops that are under strong control of some part of the
1882 * system (such as OP_WRITE_SMS, which should be allowed only
1883 * for whichever app is selected as the current SMS app).
1884 */
1885 private static boolean[] sOpDisableReset = new boolean[] {
Eugene Susla93519852018-06-13 16:44:31 -07001886 false, // COARSE_LOCATION
1887 false, // FINE_LOCATION
1888 false, // GPS
1889 false, // VIBRATE
1890 false, // READ_CONTACTS
1891 false, // WRITE_CONTACTS
1892 false, // READ_CALL_LOG
1893 false, // WRITE_CALL_LOG
1894 false, // READ_CALENDAR
1895 false, // WRITE_CALENDAR
1896 false, // WIFI_SCAN
1897 false, // POST_NOTIFICATION
1898 false, // NEIGHBORING_CELLS
1899 false, // CALL_PHONE
1900 true, // READ_SMS
1901 true, // WRITE_SMS
1902 true, // RECEIVE_SMS
1903 false, // RECEIVE_EMERGENCY_BROADCAST
1904 false, // RECEIVE_MMS
1905 true, // RECEIVE_WAP_PUSH
1906 true, // SEND_SMS
1907 false, // READ_ICC_SMS
1908 false, // WRITE_ICC_SMS
1909 false, // WRITE_SETTINGS
1910 false, // SYSTEM_ALERT_WINDOW
1911 false, // ACCESS_NOTIFICATIONS
1912 false, // CAMERA
1913 false, // RECORD_AUDIO
1914 false, // PLAY_AUDIO
1915 false, // READ_CLIPBOARD
1916 false, // WRITE_CLIPBOARD
1917 false, // TAKE_MEDIA_BUTTONS
1918 false, // TAKE_AUDIO_FOCUS
1919 false, // AUDIO_MASTER_VOLUME
1920 false, // AUDIO_VOICE_VOLUME
1921 false, // AUDIO_RING_VOLUME
1922 false, // AUDIO_MEDIA_VOLUME
1923 false, // AUDIO_ALARM_VOLUME
1924 false, // AUDIO_NOTIFICATION_VOLUME
1925 false, // AUDIO_BLUETOOTH_VOLUME
1926 false, // WAKE_LOCK
1927 false, // MONITOR_LOCATION
1928 false, // MONITOR_HIGH_POWER_LOCATION
1929 false, // GET_USAGE_STATS
1930 false, // MUTE_MICROPHONE
1931 false, // TOAST_WINDOW
1932 false, // PROJECT_MEDIA
1933 false, // ACTIVATE_VPN
1934 false, // WRITE_WALLPAPER
1935 false, // ASSIST_STRUCTURE
1936 false, // ASSIST_SCREENSHOT
1937 false, // READ_PHONE_STATE
1938 false, // ADD_VOICEMAIL
1939 false, // USE_SIP
1940 false, // PROCESS_OUTGOING_CALLS
1941 false, // USE_FINGERPRINT
1942 false, // BODY_SENSORS
1943 true, // READ_CELL_BROADCASTS
1944 false, // MOCK_LOCATION
1945 false, // READ_EXTERNAL_STORAGE
1946 false, // WRITE_EXTERNAL_STORAGE
1947 false, // TURN_SCREEN_ON
1948 false, // GET_ACCOUNTS
1949 false, // RUN_IN_BACKGROUND
1950 false, // AUDIO_ACCESSIBILITY_VOLUME
1951 false, // READ_PHONE_NUMBERS
1952 false, // REQUEST_INSTALL_PACKAGES
1953 false, // PICTURE_IN_PICTURE
1954 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001955 false, // ANSWER_PHONE_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07001956 false, // RUN_ANY_IN_BACKGROUND
1957 false, // CHANGE_WIFI_STATE
1958 false, // REQUEST_DELETE_PACKAGES
1959 false, // BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001960 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001961 false, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001962 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001963 false, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001964 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001965 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001966 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001967 false, // READ_MEDIA_AUDIO
1968 false, // WRITE_MEDIA_AUDIO
1969 false, // READ_MEDIA_VIDEO
1970 false, // WRITE_MEDIA_VIDEO
1971 false, // READ_MEDIA_IMAGES
1972 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001973 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001974 false, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001975 false, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmannac7b10c2019-09-13 15:12:34 -07001976 false, // ACCESS_MEDIA_LOCATION
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001977 };
1978
Svet Ganovfbf01f72015-04-28 18:39:06 -07001979 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07001980 * Mapping from an app op name to the app op code.
Svet Ganovfbf01f72015-04-28 18:39:06 -07001981 */
Svet Ganovb9d71a62015-04-30 10:38:13 -07001982 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
Svet Ganovfbf01f72015-04-28 18:39:06 -07001983
Svet Ganovb9d71a62015-04-30 10:38:13 -07001984 /**
1985 * Mapping from a permission to the corresponding app op.
1986 */
Svet Ganovda0acdf2017-02-15 10:28:51 -08001987 private static HashMap<String, Integer> sPermToOp = new HashMap<>();
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001988
1989 static {
1990 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001991 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001992 + " should be " + _NUM_OP);
1993 }
1994 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001995 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001996 + " should be " + _NUM_OP);
1997 }
1998 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001999 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002000 + " should be " + _NUM_OP);
2001 }
2002 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002003 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002004 + " should be " + _NUM_OP);
2005 }
2006 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002007 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
2008 + " should be " + _NUM_OP);
2009 }
2010 if (sOpDisableReset.length != _NUM_OP) {
2011 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002012 + " should be " + _NUM_OP);
2013 }
Jason Monk62062992014-05-06 09:55:28 -04002014 if (sOpRestrictions.length != _NUM_OP) {
2015 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
2016 + " should be " + _NUM_OP);
2017 }
Jason Monk1c7c3192014-06-26 12:52:18 -04002018 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
2019 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
2020 + sOpRestrictions.length + " should be " + _NUM_OP);
2021 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002022 for (int i=0; i<_NUM_OP; i++) {
2023 if (sOpToString[i] != null) {
2024 sOpStrToOp.put(sOpToString[i], i);
2025 }
2026 }
Svet Ganovda0acdf2017-02-15 10:28:51 -08002027 for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07002028 if (sOpPerms[op] != null) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002029 sPermToOp.put(sOpPerms[op], op);
Svet Ganovb9d71a62015-04-30 10:38:13 -07002030 }
2031 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002032 }
2033
Svet Ganov8455ba22019-01-02 13:05:56 -08002034 /** @hide */
2035 public static final String KEY_HISTORICAL_OPS = "historical_ops";
2036
Chad Brubaker7c6dba62019-01-23 15:51:43 -08002037 /** System properties for debug logging of noteOp call sites */
2038 private static final String DEBUG_LOGGING_ENABLE_PROP = "appops.logging_enabled";
2039 private static final String DEBUG_LOGGING_PACKAGES_PROP = "appops.logging_packages";
2040 private static final String DEBUG_LOGGING_OPS_PROP = "appops.logging_ops";
2041 private static final String DEBUG_LOGGING_TAG = "AppOpsManager";
2042
David Braunf5d83192013-09-16 13:43:51 -07002043 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002044 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002045 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002046 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002047 @UnsupportedAppUsage
Dianne Hackbornf265ea92013-01-31 15:00:51 -08002048 public static int opToSwitch(int op) {
2049 return sOpToSwitch[op];
2050 }
2051
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002052 /**
2053 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002054 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002055 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002056 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002057 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08002058 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002059 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
2060 }
2061
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002062 /**
Svet Ganov65f1b9e2019-01-17 19:19:40 -08002063 * Retrieve a non-localized public name for the operation.
2064 *
2065 * @hide
2066 */
2067 public static @NonNull String opToPublicName(int op) {
2068 return sOpToString[op];
2069 }
2070
2071 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08002072 * @hide
2073 */
2074 public static int strDebugOpToOp(String op) {
2075 for (int i=0; i<sOpNames.length; i++) {
2076 if (sOpNames[i].equals(op)) {
2077 return i;
2078 }
2079 }
2080 throw new IllegalArgumentException("Unknown operation string: " + op);
2081 }
2082
2083 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002084 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002085 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002086 */
Artur Satayev5a525852019-10-31 15:15:50 +00002087 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07002088 @TestApi
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002089 public static String opToPermission(int op) {
2090 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002091 }
2092
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002093 /**
Hai Zhangb7776682018-09-25 15:10:57 -07002094 * Retrieve the permission associated with an operation, or null if there is not one.
2095 *
2096 * @param op The operation name.
2097 *
2098 * @hide
2099 */
2100 @Nullable
2101 @SystemApi
2102 public static String opToPermission(@NonNull String op) {
2103 return opToPermission(strOpToOp(op));
2104 }
2105
2106 /**
Jason Monk62062992014-05-06 09:55:28 -04002107 * Retrieve the user restriction associated with an operation, or null if there is not one.
2108 * @hide
2109 */
2110 public static String opToRestriction(int op) {
2111 return sOpRestrictions[op];
2112 }
2113
2114 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07002115 * Retrieve the app op code for a permission, or null if there is not one.
Svet Ganovda0acdf2017-02-15 10:28:51 -08002116 * This API is intended to be used for mapping runtime or appop permissions
2117 * to the corresponding app op.
Svet Ganovb9d71a62015-04-30 10:38:13 -07002118 * @hide
2119 */
Artur Satayev5a525852019-10-31 15:15:50 +00002120 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07002121 @TestApi
Svet Ganovb9d71a62015-04-30 10:38:13 -07002122 public static int permissionToOpCode(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002123 Integer boxedOpCode = sPermToOp.get(permission);
Svet Ganov019d2302015-05-04 11:07:38 -07002124 return boxedOpCode != null ? boxedOpCode : OP_NONE;
Svet Ganovb9d71a62015-04-30 10:38:13 -07002125 }
2126
2127 /**
Jason Monk1c7c3192014-06-26 12:52:18 -04002128 * Retrieve whether the op allows the system (and system ui) to
2129 * bypass the user restriction.
2130 * @hide
2131 */
2132 public static boolean opAllowSystemBypassRestriction(int op) {
2133 return sOpAllowSystemRestrictionBypass[op];
2134 }
2135
2136 /**
David Braunf5d83192013-09-16 13:43:51 -07002137 * Retrieve the default mode for the operation.
2138 * @hide
2139 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002140 public static @Mode int opToDefaultMode(int op) {
David Braunf5d83192013-09-16 13:43:51 -07002141 return sOpDefaultMode[op];
2142 }
2143
2144 /**
Hai Zhangc595f112018-11-06 14:20:38 -08002145 * Retrieve the default mode for the app op.
2146 *
2147 * @param appOp The app op name
2148 *
2149 * @return the default mode for the app op
2150 *
2151 * @hide
2152 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07002153 @TestApi
Hai Zhangc595f112018-11-06 14:20:38 -08002154 @SystemApi
2155 public static int opToDefaultMode(@NonNull String appOp) {
2156 return opToDefaultMode(strOpToOp(appOp));
2157 }
2158
2159 /**
Svet Ganov82f09bc2018-01-12 22:08:40 -08002160 * Retrieve the human readable mode.
2161 * @hide
2162 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002163 public static String modeToName(@Mode int mode) {
Dianne Hackbornc216a262018-04-26 13:46:22 -07002164 if (mode >= 0 && mode < MODE_NAMES.length) {
2165 return MODE_NAMES[mode];
Svet Ganov82f09bc2018-01-12 22:08:40 -08002166 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07002167 return "mode=" + mode;
Svet Ganov82f09bc2018-01-12 22:08:40 -08002168 }
2169
2170 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002171 * Retrieve whether the op allows itself to be reset.
2172 * @hide
2173 */
2174 public static boolean opAllowsReset(int op) {
2175 return !sOpDisableReset[op];
2176 }
2177
2178 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002179 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002180 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002181 */
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002182 @SystemApi
2183 public static final class PackageOps implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002184 private final String mPackageName;
2185 private final int mUid;
2186 private final List<OpEntry> mEntries;
2187
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002188 /**
2189 * @hide
2190 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002191 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002192 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
2193 mPackageName = packageName;
2194 mUid = uid;
2195 mEntries = entries;
2196 }
2197
Svet Ganovaf189e32019-02-15 18:45:29 -08002198 /**
2199 * @return The name of the package.
2200 */
2201 public @NonNull String getPackageName() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002202 return mPackageName;
2203 }
2204
Svet Ganovaf189e32019-02-15 18:45:29 -08002205 /**
2206 * @return The uid of the package.
2207 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002208 public int getUid() {
2209 return mUid;
2210 }
2211
Svet Ganovaf189e32019-02-15 18:45:29 -08002212 /**
2213 * @return The ops of the package.
2214 */
Dianne Hackborn62878492019-03-11 15:57:07 -07002215 public @NonNull List<OpEntry> getOps() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002216 return mEntries;
2217 }
2218
2219 @Override
2220 public int describeContents() {
2221 return 0;
2222 }
2223
2224 @Override
2225 public void writeToParcel(Parcel dest, int flags) {
2226 dest.writeString(mPackageName);
2227 dest.writeInt(mUid);
2228 dest.writeInt(mEntries.size());
2229 for (int i=0; i<mEntries.size(); i++) {
2230 mEntries.get(i).writeToParcel(dest, flags);
2231 }
2232 }
2233
2234 PackageOps(Parcel source) {
2235 mPackageName = source.readString();
2236 mUid = source.readInt();
2237 mEntries = new ArrayList<OpEntry>();
2238 final int N = source.readInt();
2239 for (int i=0; i<N; i++) {
2240 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
2241 }
2242 }
2243
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07002244 public static final @android.annotation.NonNull Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002245 @Override public PackageOps createFromParcel(Parcel source) {
2246 return new PackageOps(source);
2247 }
2248
2249 @Override public PackageOps[] newArray(int size) {
2250 return new PackageOps[size];
2251 }
2252 };
2253 }
2254
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002255 /**
2256 * Class holding the information about one unique operation of an application.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002257 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002258 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002259 @TestApi
2260 @Immutable
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002261 @SystemApi
2262 public static final class OpEntry implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002263 private final int mOp;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002264 private final boolean mRunning;
Svet Ganovaf189e32019-02-15 18:45:29 -08002265 private final @Mode int mMode;
2266 private final @Nullable LongSparseLongArray mAccessTimes;
2267 private final @Nullable LongSparseLongArray mRejectTimes;
2268 private final @Nullable LongSparseLongArray mDurations;
2269 private final @Nullable LongSparseLongArray mProxyUids;
2270 private final @Nullable LongSparseArray<String> mProxyPackageNames;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002271
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002272 /**
2273 * @hide
2274 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002275 public OpEntry(int op, boolean running, @Mode int mode,
2276 @Nullable LongSparseLongArray accessTimes, @Nullable LongSparseLongArray rejectTimes,
2277 @Nullable LongSparseLongArray durations, @Nullable LongSparseLongArray proxyUids,
2278 @Nullable LongSparseArray<String> proxyPackageNames) {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002279 mOp = op;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002280 mRunning = running;
Svet Ganovaf189e32019-02-15 18:45:29 -08002281 mMode = mode;
2282 mAccessTimes = accessTimes;
2283 mRejectTimes = rejectTimes;
2284 mDurations = durations;
2285 mProxyUids = proxyUids;
2286 mProxyPackageNames = proxyPackageNames;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002287 }
2288
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002289 /**
2290 * @hide
2291 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002292 public OpEntry(int op, @Mode int mode) {
2293 mOp = op;
2294 mMode = mode;
2295 mRunning = false;
2296 mAccessTimes = null;
2297 mRejectTimes = null;
2298 mDurations = null;
2299 mProxyUids = null;
2300 mProxyPackageNames = null;
2301 }
2302
2303 /**
2304 * Returns all keys for which we have mapped state in any of the data buckets -
2305 * access time, reject time, duration.
2306 * @hide */
2307 public @Nullable LongSparseArray<Object> collectKeys() {
2308 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessTimes, null);
2309 result = AppOpsManager.collectKeys(mRejectTimes, result);
2310 result = AppOpsManager.collectKeys(mDurations, result);
2311 return result;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002312 }
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 int getOp() {
2319 return mOp;
2320 }
2321
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002322 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002323 * @return This entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}.
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002324 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002325 public @NonNull String getOpStr() {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002326 return sOpToString[mOp];
2327 }
2328
2329 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002330 * @return this entry's current mode, such as {@link #MODE_ALLOWED}.
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002331 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002332 public @Mode int getMode() {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002333 return mMode;
2334 }
2335
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002336 /**
2337 * @hide
2338 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002339 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002340 public long getTime() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002341 return getLastAccessTime(OP_FLAGS_ALL);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002342 }
2343
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002344 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002345 * Return the last wall clock time in milliseconds this op was accessed.
2346 *
2347 * @param flags The flags which are any combination of
2348 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2349 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2350 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2351 * for any flag.
2352 * @return the last access time in milliseconds since
2353 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2354 *
2355 * @see #getLastAccessForegroundTime(int)
2356 * @see #getLastAccessBackgroundTime(int)
2357 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002358 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002359 public long getLastAccessTime(@OpFlags int flags) {
2360 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
2361 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002362 }
2363
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002364 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002365 * Return the last wall clock time in milliseconds this op was accessed
2366 * by the app while in the foreground.
2367 *
2368 * @param flags The flags which are any combination of
2369 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2370 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2371 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2372 * for any flag.
2373 * @return the last foreground access time in milliseconds since
2374 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2375 *
2376 * @see #getLastAccessBackgroundTime(int)
2377 * @see #getLastAccessTime(int)
2378 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002379 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002380 public long getLastAccessForegroundTime(@OpFlags int flags) {
2381 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
2382 resolveFirstUnrestrictedUidState(mOp), flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002383 }
2384
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002385 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002386 * Return the last wall clock time in milliseconds this op was accessed
2387 * by the app while in the background.
2388 *
2389 * @param flags The flags which are any combination of
2390 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2391 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2392 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2393 * for any flag.
2394 * @return the last foreground access time in milliseconds since
2395 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2396 *
2397 * @see #getLastAccessForegroundTime(int)
2398 * @see #getLastAccessTime(int)
2399 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002400 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002401 public long getLastAccessBackgroundTime(@OpFlags int flags) {
2402 return maxForFlagsInStates(mAccessTimes, resolveLastRestrictedUidState(mOp),
2403 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002404 }
2405
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002406 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002407 * Return the last wall clock time in milliseconds this op was accessed
2408 * by the app for a given range of UID states.
2409 *
2410 * @param fromUidState The UID state for which to query. Could be one of
2411 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2412 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2413 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2414 * @param toUidState The UID state for which to query.
2415 * @param flags The flags which are any combination of
2416 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2417 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2418 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2419 * for any flag.
2420 *
2421 * @return the last foreground access time in milliseconds since
2422 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2423 *
2424 * @see #getLastAccessForegroundTime(int)
2425 * @see #getLastAccessBackgroundTime(int)
2426 * @see #getLastAccessTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002427 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002428 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
2429 @OpFlags int flags) {
2430 return maxForFlagsInStates(mAccessTimes, fromUidState, toUidState, flags);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002431 }
2432
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002433 /**
2434 * @hide
2435 */
Andrei Onea2bbb6542019-05-21 18:13:26 +01002436 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002437 public long getRejectTime() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002438 return getLastRejectTime(OP_FLAGS_ALL);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002439 }
2440
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002441 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002442 * Return the last wall clock time in milliseconds the app made an attempt
2443 * to access this op but was rejected.
2444 *
2445 * @param flags The flags which are any combination of
2446 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2447 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2448 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2449 * for any flag.
2450 * @return the last reject time in milliseconds since
2451 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2452 *
2453 * @see #getLastRejectBackgroundTime(int)
2454 * @see #getLastRejectForegroundTime(int)
2455 * @see #getLastRejectTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002456 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002457 public long getLastRejectTime(@OpFlags int flags) {
2458 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
2459 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002460 }
2461
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002462 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002463 * Return the last wall clock time in milliseconds the app made an attempt
2464 * to access this op while in the foreground but was rejected.
2465 *
2466 * @param flags The flags which are any combination of
2467 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2468 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2469 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2470 * for any flag.
2471 * @return the last foreground reject time in milliseconds since
2472 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2473 *
2474 * @see #getLastRejectBackgroundTime(int)
2475 * @see #getLastRejectTime(int, int, int)
2476 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002477 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002478 public long getLastRejectForegroundTime(@OpFlags int flags) {
2479 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
2480 resolveFirstUnrestrictedUidState(mOp), flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002481 }
2482
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002483 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002484 * Return the last wall clock time in milliseconds the app made an attempt
2485 * to access this op while in the background but was rejected.
2486 *
2487 * @param flags The flags which are any combination of
2488 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2489 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2490 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2491 * for any flag.
2492 * @return the last background reject time in milliseconds since
2493 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2494 *
2495 * @see #getLastRejectForegroundTime(int)
2496 * @see #getLastRejectTime(int, int, int)
2497 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002498 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002499 public long getLastRejectBackgroundTime(@OpFlags int flags) {
2500 return maxForFlagsInStates(mRejectTimes, resolveLastRestrictedUidState(mOp),
2501 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002502 }
2503
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002504 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002505 * Return the last wall clock time state in milliseconds the app made an
2506 * attempt to access this op for a given range of UID states.
2507 *
2508 * @param fromUidState The UID state from which to query. Could be one of
2509 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2510 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2511 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2512 * @param toUidState The UID state to which to query.
2513 * @param flags The flags which are any combination of
2514 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2515 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2516 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2517 * for any flag.
2518 * @return the last foreground access time in milliseconds since
2519 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2520 *
2521 * @see #getLastRejectForegroundTime(int)
2522 * @see #getLastRejectBackgroundTime(int)
2523 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002524 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002525 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
2526 @OpFlags int flags) {
2527 return maxForFlagsInStates(mRejectTimes, fromUidState, toUidState, flags);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002528 }
2529
Svet Ganovaf189e32019-02-15 18:45:29 -08002530 /**
2531 * @return Whether the operation is running.
2532 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002533 public boolean isRunning() {
Amith Yamasania1ce9632018-05-28 20:50:48 -07002534 return mRunning;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002535 }
2536
Svet Ganovaf189e32019-02-15 18:45:29 -08002537 /**
Svet Ganov6f672a32019-07-08 16:40:42 -07002538 * @return The duration of the operation in milliseconds. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002539 */
2540 public long getDuration() {
2541 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002542 }
2543
Svet Ganovaf189e32019-02-15 18:45:29 -08002544 /**
2545 * Return the duration in milliseconds the app accessed this op while
Svet Ganov6f672a32019-07-08 16:40:42 -07002546 * in the foreground. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002547 *
2548 * @param flags The flags which are any combination of
2549 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2550 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2551 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2552 * for any flag.
2553 * @return the foreground access duration in milliseconds.
2554 *
2555 * @see #getLastBackgroundDuration(int)
2556 * @see #getLastDuration(int, int, int)
2557 */
2558 public long getLastForegroundDuration(@OpFlags int flags) {
2559 return sumForFlagsInStates(mDurations, MAX_PRIORITY_UID_STATE,
2560 resolveFirstUnrestrictedUidState(mOp), flags);
2561 }
2562
2563 /**
2564 * Return the duration in milliseconds the app accessed this op while
Svet Ganov6f672a32019-07-08 16:40:42 -07002565 * in the background. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002566 *
2567 * @param flags The flags which are any combination of
2568 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2569 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2570 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2571 * for any flag.
2572 * @return the background access duration in milliseconds.
2573 *
2574 * @see #getLastForegroundDuration(int)
2575 * @see #getLastDuration(int, int, int)
2576 */
2577 public long getLastBackgroundDuration(@OpFlags int flags) {
2578 return sumForFlagsInStates(mDurations, resolveLastRestrictedUidState(mOp),
2579 MIN_PRIORITY_UID_STATE, flags);
2580 }
2581
2582 /**
2583 * Return the duration in milliseconds the app accessed this op for
Svet Ganov6f672a32019-07-08 16:40:42 -07002584 * a given range of UID states. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002585 *
2586 * @param fromUidState The UID state for which to query. Could be one of
2587 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2588 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2589 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2590 * @param toUidState The UID state for which to query.
2591 * @param flags The flags which are any combination of
2592 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2593 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2594 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2595 * for any flag.
2596 * @return the access duration in milliseconds.
2597 */
2598 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
2599 @OpFlags int flags) {
2600 return sumForFlagsInStates(mDurations, fromUidState, toUidState, flags);
2601 }
2602
2603 /**
2604 * Gets the UID of the app that performed the op on behalf of this app and
2605 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2606 * there is no proxy.
2607 *
2608 * @return The proxy UID.
2609 */
Svet Ganov99b60432015-06-27 13:15:22 -07002610 public int getProxyUid() {
Philip P. Moltmann4052d362019-09-19 14:52:38 -07002611 return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
Svet Ganovaf189e32019-02-15 18:45:29 -08002612 MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
Svet Ganov99b60432015-06-27 13:15:22 -07002613 }
2614
Svet Ganovaf189e32019-02-15 18:45:29 -08002615 /**
2616 * Gets the UID of the app that performed the op on behalf of this app and
2617 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2618 * there is no proxy.
2619 *
2620 * @param uidState The UID state for which to query. Could be one of
2621 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2622 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2623 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2624 * @param flags The flags which are any combination of
2625 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2626 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2627 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2628 * for any flag.
2629 *
2630 * @return The proxy UID.
2631 */
2632 public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
Philip P. Moltmann4052d362019-09-19 14:52:38 -07002633 return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
Svet Ganovaf189e32019-02-15 18:45:29 -08002634 uidState, uidState, flags);
2635 }
2636
2637 /**
2638 * Gets the package name of the app that performed the op on behalf of this
2639 * app and as a result blamed the op on this app or {@code null}
2640 * if there is no proxy.
2641 *
2642 * @return The proxy package name.
2643 */
2644 public @Nullable String getProxyPackageName() {
2645 return findFirstNonNullForFlagsInStates(mProxyPackageNames, MAX_PRIORITY_UID_STATE,
2646 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
2647 }
2648
2649 /**
2650 * Gets the package name of the app that performed the op on behalf of this
2651 * app and as a result blamed the op on this app for a UID state or
2652 * {@code null} if there is no proxy.
2653 *
2654 * @param uidState The UID state for which to query. Could be one of
2655 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2656 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2657 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2658 * @param flags The flags which are any combination of
2659 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2660 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2661 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2662 * for any flag.
2663 * @return The proxy package name.
2664 */
2665 public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
2666 return findFirstNonNullForFlagsInStates(mProxyPackageNames, uidState, uidState, flags);
Svet Ganov99b60432015-06-27 13:15:22 -07002667 }
2668
Dianne Hackborn35654b62013-01-14 17:38:02 -08002669 @Override
2670 public int describeContents() {
2671 return 0;
2672 }
2673
2674 @Override
2675 public void writeToParcel(Parcel dest, int flags) {
2676 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002677 dest.writeInt(mMode);
Amith Yamasania1ce9632018-05-28 20:50:48 -07002678 dest.writeBoolean(mRunning);
Svet Ganovaf189e32019-02-15 18:45:29 -08002679 writeLongSparseLongArrayToParcel(mAccessTimes, dest);
2680 writeLongSparseLongArrayToParcel(mRejectTimes, dest);
2681 writeLongSparseLongArrayToParcel(mDurations, dest);
2682 writeLongSparseLongArrayToParcel(mProxyUids, dest);
2683 writeLongSparseStringArrayToParcel(mProxyPackageNames, dest);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002684 }
2685
2686 OpEntry(Parcel source) {
2687 mOp = source.readInt();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002688 mMode = source.readInt();
Amith Yamasania1ce9632018-05-28 20:50:48 -07002689 mRunning = source.readBoolean();
Svet Ganovaf189e32019-02-15 18:45:29 -08002690 mAccessTimes = readLongSparseLongArrayFromParcel(source);
2691 mRejectTimes = readLongSparseLongArrayFromParcel(source);
2692 mDurations = readLongSparseLongArrayFromParcel(source);
2693 mProxyUids = readLongSparseLongArrayFromParcel(source);
2694 mProxyPackageNames = readLongSparseStringArrayFromParcel(source);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002695 }
2696
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07002697 public static final @android.annotation.NonNull Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002698 @Override public OpEntry createFromParcel(Parcel source) {
2699 return new OpEntry(source);
2700 }
2701
2702 @Override public OpEntry[] newArray(int size) {
2703 return new OpEntry[size];
2704 }
2705 };
2706 }
2707
Svet Ganov8455ba22019-01-02 13:05:56 -08002708 /** @hide */
2709 public interface HistoricalOpsVisitor {
2710 void visitHistoricalOps(@NonNull HistoricalOps ops);
2711 void visitHistoricalUidOps(@NonNull HistoricalUidOps ops);
2712 void visitHistoricalPackageOps(@NonNull HistoricalPackageOps ops);
2713 void visitHistoricalOp(@NonNull HistoricalOp ops);
2714 }
2715
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002716 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08002717 * Request for getting historical app op usage. The request acts
2718 * as a filtering criteria when querying historical op usage.
2719 *
2720 * @hide
2721 */
2722 @Immutable
2723 @TestApi
2724 @SystemApi
2725 public static final class HistoricalOpsRequest {
2726 private final int mUid;
2727 private final @Nullable String mPackageName;
2728 private final @Nullable List<String> mOpNames;
2729 private final long mBeginTimeMillis;
2730 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08002731 private final @OpFlags int mFlags;
Svet Ganov23c88db2019-01-22 20:38:11 -08002732
2733 private HistoricalOpsRequest(int uid, @Nullable String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08002734 @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
2735 @OpFlags int flags) {
Svet Ganov23c88db2019-01-22 20:38:11 -08002736 mUid = uid;
2737 mPackageName = packageName;
2738 mOpNames = opNames;
2739 mBeginTimeMillis = beginTimeMillis;
2740 mEndTimeMillis = endTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08002741 mFlags = flags;
Svet Ganov23c88db2019-01-22 20:38:11 -08002742 }
2743
2744 /**
2745 * Builder for creating a {@link HistoricalOpsRequest}.
2746 *
2747 * @hide
2748 */
2749 @TestApi
2750 @SystemApi
2751 public static final class Builder {
2752 private int mUid = Process.INVALID_UID;
2753 private @Nullable String mPackageName;
2754 private @Nullable List<String> mOpNames;
2755 private final long mBeginTimeMillis;
2756 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08002757 private @OpFlags int mFlags = OP_FLAGS_ALL;
Svet Ganov23c88db2019-01-22 20:38:11 -08002758
2759 /**
2760 * Creates a new builder.
2761 *
2762 * @param beginTimeMillis The beginning of the interval in milliseconds since
2763 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non
2764 * negative.
2765 * @param endTimeMillis The end of the interval in milliseconds since
2766 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after
2767 * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent
2768 * history including ops that happen while this call is in flight.
2769 */
2770 public Builder(long beginTimeMillis, long endTimeMillis) {
2771 Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
2772 "beginTimeMillis must be non negative and lesser than endTimeMillis");
2773 mBeginTimeMillis = beginTimeMillis;
2774 mEndTimeMillis = endTimeMillis;
2775 }
2776
2777 /**
2778 * Sets the UID to query for.
2779 *
2780 * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid.
2781 * @return This builder.
2782 */
2783 public @NonNull Builder setUid(int uid) {
2784 Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
2785 "uid must be " + Process.INVALID_UID + " or non negative");
2786 mUid = uid;
2787 return this;
2788 }
2789
2790 /**
2791 * Sets the package to query for.
2792 *
2793 * @param packageName The package name. <code>Null</code> for any package.
2794 * @return This builder.
2795 */
2796 public @NonNull Builder setPackageName(@Nullable String packageName) {
2797 mPackageName = packageName;
2798 return this;
2799 }
2800
2801 /**
2802 * Sets the op names to query for.
2803 *
2804 * @param opNames The op names. <code>Null</code> for any op.
2805 * @return This builder.
2806 */
2807 public @NonNull Builder setOpNames(@Nullable List<String> opNames) {
2808 if (opNames != null) {
2809 final int opCount = opNames.size();
2810 for (int i = 0; i < opCount; i++) {
2811 Preconditions.checkArgument(AppOpsManager.strOpToOp(
2812 opNames.get(i)) != AppOpsManager.OP_NONE);
2813 }
2814 }
2815 mOpNames = opNames;
2816 return this;
2817 }
2818
2819 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002820 * Sets the op flags to query for. The flags specify the type of
2821 * op data being queried.
2822 *
2823 * @param flags The flags which are any combination of
2824 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2825 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2826 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2827 * for any flag.
2828 * @return This builder.
2829 */
2830 public @NonNull Builder setFlags(@OpFlags int flags) {
2831 Preconditions.checkFlagsArgument(flags, OP_FLAGS_ALL);
2832 mFlags = flags;
2833 return this;
2834 }
2835
2836 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08002837 * @return a new {@link HistoricalOpsRequest}.
2838 */
2839 public @NonNull HistoricalOpsRequest build() {
2840 return new HistoricalOpsRequest(mUid, mPackageName, mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08002841 mBeginTimeMillis, mEndTimeMillis, mFlags);
Svet Ganov23c88db2019-01-22 20:38:11 -08002842 }
2843 }
2844 }
2845
2846 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08002847 * This class represents historical app op state of all UIDs for a given time interval.
2848 *
2849 * @hide
2850 */
2851 @TestApi
2852 @SystemApi
2853 public static final class HistoricalOps implements Parcelable {
2854 private long mBeginTimeMillis;
2855 private long mEndTimeMillis;
2856 private @Nullable SparseArray<HistoricalUidOps> mHistoricalUidOps;
2857
2858 /** @hide */
2859 @TestApi
2860 public HistoricalOps(long beginTimeMillis, long endTimeMillis) {
2861 Preconditions.checkState(beginTimeMillis <= endTimeMillis);
2862 mBeginTimeMillis = beginTimeMillis;
2863 mEndTimeMillis = endTimeMillis;
2864 }
2865
2866 /** @hide */
2867 public HistoricalOps(@NonNull HistoricalOps other) {
2868 mBeginTimeMillis = other.mBeginTimeMillis;
2869 mEndTimeMillis = other.mEndTimeMillis;
2870 Preconditions.checkState(mBeginTimeMillis <= mEndTimeMillis);
2871 if (other.mHistoricalUidOps != null) {
2872 final int opCount = other.getUidCount();
2873 for (int i = 0; i < opCount; i++) {
2874 final HistoricalUidOps origOps = other.getUidOpsAt(i);
2875 final HistoricalUidOps clonedOps = new HistoricalUidOps(origOps);
2876 if (mHistoricalUidOps == null) {
2877 mHistoricalUidOps = new SparseArray<>(opCount);
2878 }
2879 mHistoricalUidOps.put(clonedOps.getUid(), clonedOps);
2880 }
2881 }
2882 }
2883
2884 private HistoricalOps(Parcel parcel) {
2885 mBeginTimeMillis = parcel.readLong();
2886 mEndTimeMillis = parcel.readLong();
2887 final int[] uids = parcel.createIntArray();
2888 if (!ArrayUtils.isEmpty(uids)) {
2889 final ParceledListSlice<HistoricalUidOps> listSlice = parcel.readParcelable(
2890 HistoricalOps.class.getClassLoader());
2891 final List<HistoricalUidOps> uidOps = (listSlice != null)
2892 ? listSlice.getList() : null;
2893 if (uidOps == null) {
2894 return;
2895 }
2896 for (int i = 0; i < uids.length; i++) {
2897 if (mHistoricalUidOps == null) {
2898 mHistoricalUidOps = new SparseArray<>();
2899 }
2900 mHistoricalUidOps.put(uids[i], uidOps.get(i));
2901 }
2902 }
2903 }
2904
2905 /**
2906 * Splice a piece from the beginning of these ops.
2907 *
2908 * @param splicePoint The fraction of the data to be spliced off.
2909 *
2910 * @hide
2911 */
2912 public @NonNull HistoricalOps spliceFromBeginning(double splicePoint) {
2913 return splice(splicePoint, true);
2914 }
2915
2916 /**
2917 * Splice a piece from the end of these ops.
2918 *
2919 * @param fractionToRemove The fraction of the data to be spliced off.
2920 *
2921 * @hide
2922 */
2923 public @NonNull HistoricalOps spliceFromEnd(double fractionToRemove) {
2924 return splice(fractionToRemove, false);
2925 }
2926
2927 /**
2928 * Splice a piece from the beginning or end of these ops.
2929 *
2930 * @param fractionToRemove The fraction of the data to be spliced off.
2931 * @param beginning Whether to splice off the beginning or the end.
2932 *
2933 * @return The spliced off part.
2934 *
2935 * @hide
2936 */
2937 private @Nullable HistoricalOps splice(double fractionToRemove, boolean beginning) {
2938 final long spliceBeginTimeMills;
2939 final long spliceEndTimeMills;
2940 if (beginning) {
2941 spliceBeginTimeMills = mBeginTimeMillis;
2942 spliceEndTimeMills = (long) (mBeginTimeMillis
2943 + getDurationMillis() * fractionToRemove);
2944 mBeginTimeMillis = spliceEndTimeMills;
2945 } else {
2946 spliceBeginTimeMills = (long) (mEndTimeMillis
2947 - getDurationMillis() * fractionToRemove);
2948 spliceEndTimeMills = mEndTimeMillis;
2949 mEndTimeMillis = spliceBeginTimeMills;
2950 }
2951
2952 HistoricalOps splice = null;
2953 final int uidCount = getUidCount();
2954 for (int i = 0; i < uidCount; i++) {
2955 final HistoricalUidOps origOps = getUidOpsAt(i);
2956 final HistoricalUidOps spliceOps = origOps.splice(fractionToRemove);
2957 if (spliceOps != null) {
2958 if (splice == null) {
2959 splice = new HistoricalOps(spliceBeginTimeMills, spliceEndTimeMills);
2960 }
2961 if (splice.mHistoricalUidOps == null) {
2962 splice.mHistoricalUidOps = new SparseArray<>();
2963 }
2964 splice.mHistoricalUidOps.put(spliceOps.getUid(), spliceOps);
2965 }
2966 }
2967 return splice;
2968 }
2969
2970 /**
2971 * Merge the passed ops into the current ones. The time interval is a
2972 * union of the current and passed in one and the passed in data is
2973 * folded into the data of this instance.
2974 *
2975 * @hide
2976 */
2977 public void merge(@NonNull HistoricalOps other) {
2978 mBeginTimeMillis = Math.min(mBeginTimeMillis, other.mBeginTimeMillis);
2979 mEndTimeMillis = Math.max(mEndTimeMillis, other.mEndTimeMillis);
2980 final int uidCount = other.getUidCount();
2981 for (int i = 0; i < uidCount; i++) {
2982 final HistoricalUidOps otherUidOps = other.getUidOpsAt(i);
2983 final HistoricalUidOps thisUidOps = getUidOps(otherUidOps.getUid());
2984 if (thisUidOps != null) {
2985 thisUidOps.merge(otherUidOps);
2986 } else {
2987 if (mHistoricalUidOps == null) {
2988 mHistoricalUidOps = new SparseArray<>();
2989 }
2990 mHistoricalUidOps.put(otherUidOps.getUid(), otherUidOps);
2991 }
2992 }
2993 }
2994
2995 /**
2996 * AppPermissionUsage the ops to leave only the data we filter for.
2997 *
2998 * @param uid Uid to filter for or {@link android.os.Process#INCIDENTD_UID} for all.
2999 * @param packageName Package to filter for or null for all.
3000 * @param opNames Ops to filter for or null for all.
3001 * @param beginTimeMillis The begin time to filter for or {@link Long#MIN_VALUE} for all.
3002 * @param endTimeMillis The end time to filter for or {@link Long#MAX_VALUE} for all.
3003 *
3004 * @hide
3005 */
3006 public void filter(int uid, @Nullable String packageName, @Nullable String[] opNames,
3007 long beginTimeMillis, long endTimeMillis) {
3008 final long durationMillis = getDurationMillis();
3009 mBeginTimeMillis = Math.max(mBeginTimeMillis, beginTimeMillis);
3010 mEndTimeMillis = Math.min(mEndTimeMillis, endTimeMillis);
3011 final double scaleFactor = Math.min((double) (endTimeMillis - beginTimeMillis)
3012 / (double) durationMillis, 1);
3013 final int uidCount = getUidCount();
3014 for (int i = uidCount - 1; i >= 0; i--) {
3015 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
3016 if (uid != Process.INVALID_UID && uid != uidOp.getUid()) {
3017 mHistoricalUidOps.removeAt(i);
3018 } else {
3019 uidOp.filter(packageName, opNames, scaleFactor);
3020 }
3021 }
3022 }
3023
3024 /** @hide */
3025 public boolean isEmpty() {
3026 if (getBeginTimeMillis() >= getEndTimeMillis()) {
3027 return true;
3028 }
3029 final int uidCount = getUidCount();
3030 for (int i = uidCount - 1; i >= 0; i--) {
3031 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
3032 if (!uidOp.isEmpty()) {
3033 return false;
3034 }
3035 }
3036 return true;
3037 }
3038
3039 /** @hide */
3040 public long getDurationMillis() {
3041 return mEndTimeMillis - mBeginTimeMillis;
3042 }
3043
3044 /** @hide */
3045 @TestApi
3046 public void increaseAccessCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003047 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003048 getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003049 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003050 }
3051
3052 /** @hide */
3053 @TestApi
3054 public void increaseRejectCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003055 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003056 getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003057 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003058 }
3059
3060 /** @hide */
3061 @TestApi
3062 public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003063 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003064 getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003065 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003066 }
3067
3068 /** @hide */
3069 @TestApi
3070 public void offsetBeginAndEndTime(long offsetMillis) {
3071 mBeginTimeMillis += offsetMillis;
3072 mEndTimeMillis += offsetMillis;
3073 }
3074
3075 /** @hide */
3076 public void setBeginAndEndTime(long beginTimeMillis, long endTimeMillis) {
3077 mBeginTimeMillis = beginTimeMillis;
3078 mEndTimeMillis = endTimeMillis;
3079 }
3080
3081 /** @hide */
3082 public void setBeginTime(long beginTimeMillis) {
3083 mBeginTimeMillis = beginTimeMillis;
3084 }
3085
3086 /** @hide */
3087 public void setEndTime(long endTimeMillis) {
3088 mEndTimeMillis = endTimeMillis;
3089 }
3090
3091 /**
3092 * @return The beginning of the interval in milliseconds since
3093 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3094 */
3095 public long getBeginTimeMillis() {
3096 return mBeginTimeMillis;
3097 }
3098
3099 /**
3100 * @return The end of the interval in milliseconds since
3101 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3102 */
3103 public long getEndTimeMillis() {
3104 return mEndTimeMillis;
3105 }
3106
3107 /**
3108 * Gets number of UIDs with historical ops.
3109 *
3110 * @return The number of UIDs with historical ops.
3111 *
3112 * @see #getUidOpsAt(int)
3113 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003114 public @IntRange(from = 0) int getUidCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003115 if (mHistoricalUidOps == null) {
3116 return 0;
3117 }
3118 return mHistoricalUidOps.size();
3119 }
3120
3121 /**
3122 * Gets the historical UID ops at a given index.
3123 *
3124 * @param index The index.
3125 *
3126 * @return The historical UID ops at the given index.
3127 *
3128 * @see #getUidCount()
3129 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003130 public @NonNull HistoricalUidOps getUidOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003131 if (mHistoricalUidOps == null) {
3132 throw new IndexOutOfBoundsException();
3133 }
3134 return mHistoricalUidOps.valueAt(index);
3135 }
3136
3137 /**
3138 * Gets the historical UID ops for a given UID.
3139 *
3140 * @param uid The UID.
3141 *
3142 * @return The historical ops for the UID.
3143 */
3144 public @Nullable HistoricalUidOps getUidOps(int uid) {
3145 if (mHistoricalUidOps == null) {
3146 return null;
3147 }
3148 return mHistoricalUidOps.get(uid);
3149 }
3150
Winson4e3b4352019-05-07 16:29:59 -07003151 /** @hide */
3152 public void clearHistory(int uid, @NonNull String packageName) {
3153 HistoricalUidOps historicalUidOps = getOrCreateHistoricalUidOps(uid);
3154 historicalUidOps.clearHistory(packageName);
3155 if (historicalUidOps.isEmpty()) {
3156 mHistoricalUidOps.remove(uid);
3157 }
3158 }
3159
Svet Ganov8455ba22019-01-02 13:05:56 -08003160 @Override
3161 public int describeContents() {
3162 return 0;
3163 }
3164
3165 @Override
3166 public void writeToParcel(Parcel parcel, int flags) {
3167 parcel.writeLong(mBeginTimeMillis);
3168 parcel.writeLong(mEndTimeMillis);
3169 if (mHistoricalUidOps != null) {
3170 final int uidCount = mHistoricalUidOps.size();
3171 parcel.writeInt(uidCount);
3172 for (int i = 0; i < uidCount; i++) {
3173 parcel.writeInt(mHistoricalUidOps.keyAt(i));
3174 }
3175 final List<HistoricalUidOps> opsList = new ArrayList<>(uidCount);
3176 for (int i = 0; i < uidCount; i++) {
3177 opsList.add(mHistoricalUidOps.valueAt(i));
3178 }
3179 parcel.writeParcelable(new ParceledListSlice<>(opsList), flags);
3180 } else {
3181 parcel.writeInt(-1);
3182 }
3183 }
3184
3185 /**
3186 * Accepts a visitor to traverse the ops tree.
3187 *
3188 * @param visitor The visitor.
3189 *
3190 * @hide
3191 */
3192 public void accept(@NonNull HistoricalOpsVisitor visitor) {
3193 visitor.visitHistoricalOps(this);
3194 final int uidCount = getUidCount();
3195 for (int i = 0; i < uidCount; i++) {
3196 getUidOpsAt(i).accept(visitor);
3197 }
3198 }
3199
3200 private @NonNull HistoricalUidOps getOrCreateHistoricalUidOps(int uid) {
3201 if (mHistoricalUidOps == null) {
3202 mHistoricalUidOps = new SparseArray<>();
3203 }
3204 HistoricalUidOps historicalUidOp = mHistoricalUidOps.get(uid);
3205 if (historicalUidOp == null) {
3206 historicalUidOp = new HistoricalUidOps(uid);
3207 mHistoricalUidOps.put(uid, historicalUidOp);
3208 }
3209 return historicalUidOp;
3210 }
3211
3212 /**
3213 * @return Rounded value up at the 0.5 boundary.
3214 *
3215 * @hide
3216 */
3217 public static double round(double value) {
3218 final BigDecimal decimalScale = new BigDecimal(value);
3219 return decimalScale.setScale(0, RoundingMode.HALF_UP).doubleValue();
3220 }
3221
3222 @Override
Aurimas Liutikas00be9512019-08-28 13:01:05 -07003223 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003224 if (this == obj) {
3225 return true;
3226 }
3227 if (obj == null || getClass() != obj.getClass()) {
3228 return false;
3229 }
3230 final HistoricalOps other = (HistoricalOps) obj;
3231 if (mBeginTimeMillis != other.mBeginTimeMillis) {
3232 return false;
3233 }
3234 if (mEndTimeMillis != other.mEndTimeMillis) {
3235 return false;
3236 }
3237 if (mHistoricalUidOps == null) {
3238 if (other.mHistoricalUidOps != null) {
3239 return false;
3240 }
3241 } else if (!mHistoricalUidOps.equals(other.mHistoricalUidOps)) {
3242 return false;
3243 }
3244 return true;
3245 }
3246
3247 @Override
3248 public int hashCode() {
3249 int result = (int) (mBeginTimeMillis ^ (mBeginTimeMillis >>> 32));
3250 result = 31 * result + mHistoricalUidOps.hashCode();
3251 return result;
3252 }
3253
Aurimas Liutikas00be9512019-08-28 13:01:05 -07003254 @NonNull
Svet Ganov8455ba22019-01-02 13:05:56 -08003255 @Override
3256 public String toString() {
3257 return getClass().getSimpleName() + "[from:"
3258 + mBeginTimeMillis + " to:" + mEndTimeMillis + "]";
3259 }
3260
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07003261 public static final @android.annotation.NonNull Creator<HistoricalOps> CREATOR = new Creator<HistoricalOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003262 @Override
3263 public @NonNull HistoricalOps createFromParcel(@NonNull Parcel parcel) {
3264 return new HistoricalOps(parcel);
3265 }
3266
3267 @Override
3268 public @NonNull HistoricalOps[] newArray(int size) {
3269 return new HistoricalOps[size];
3270 }
3271 };
3272 }
3273
3274 /**
3275 * This class represents historical app op state for a UID.
3276 *
3277 * @hide
3278 */
3279 @TestApi
3280 @SystemApi
3281 public static final class HistoricalUidOps implements Parcelable {
3282 private final int mUid;
3283 private @Nullable ArrayMap<String, HistoricalPackageOps> mHistoricalPackageOps;
3284
3285 /** @hide */
3286 public HistoricalUidOps(int uid) {
3287 mUid = uid;
3288 }
3289
3290 private HistoricalUidOps(@NonNull HistoricalUidOps other) {
3291 mUid = other.mUid;
3292 final int opCount = other.getPackageCount();
3293 for (int i = 0; i < opCount; i++) {
3294 final HistoricalPackageOps origOps = other.getPackageOpsAt(i);
3295 final HistoricalPackageOps cloneOps = new HistoricalPackageOps(origOps);
3296 if (mHistoricalPackageOps == null) {
3297 mHistoricalPackageOps = new ArrayMap<>(opCount);
3298 }
3299 mHistoricalPackageOps.put(cloneOps.getPackageName(), cloneOps);
3300 }
3301 }
3302
3303 private HistoricalUidOps(@NonNull Parcel parcel) {
3304 // No arg check since we always read from a trusted source.
3305 mUid = parcel.readInt();
3306 mHistoricalPackageOps = parcel.createTypedArrayMap(HistoricalPackageOps.CREATOR);
3307 }
3308
3309 private @Nullable HistoricalUidOps splice(double fractionToRemove) {
3310 HistoricalUidOps splice = null;
3311 final int packageCount = getPackageCount();
3312 for (int i = 0; i < packageCount; i++) {
3313 final HistoricalPackageOps origOps = getPackageOpsAt(i);
3314 final HistoricalPackageOps spliceOps = origOps.splice(fractionToRemove);
3315 if (spliceOps != null) {
3316 if (splice == null) {
3317 splice = new HistoricalUidOps(mUid);
3318 }
3319 if (splice.mHistoricalPackageOps == null) {
3320 splice.mHistoricalPackageOps = new ArrayMap<>();
3321 }
3322 splice.mHistoricalPackageOps.put(spliceOps.getPackageName(), spliceOps);
3323 }
3324 }
3325 return splice;
3326 }
3327
3328 private void merge(@NonNull HistoricalUidOps other) {
3329 final int packageCount = other.getPackageCount();
3330 for (int i = 0; i < packageCount; i++) {
3331 final HistoricalPackageOps otherPackageOps = other.getPackageOpsAt(i);
3332 final HistoricalPackageOps thisPackageOps = getPackageOps(
3333 otherPackageOps.getPackageName());
3334 if (thisPackageOps != null) {
3335 thisPackageOps.merge(otherPackageOps);
3336 } else {
3337 if (mHistoricalPackageOps == null) {
3338 mHistoricalPackageOps = new ArrayMap<>();
3339 }
3340 mHistoricalPackageOps.put(otherPackageOps.getPackageName(), otherPackageOps);
3341 }
3342 }
3343 }
3344
3345 private void filter(@Nullable String packageName, @Nullable String[] opNames,
3346 double fractionToRemove) {
3347 final int packageCount = getPackageCount();
3348 for (int i = packageCount - 1; i >= 0; i--) {
3349 final HistoricalPackageOps packageOps = getPackageOpsAt(i);
3350 if (packageName != null && !packageName.equals(packageOps.getPackageName())) {
3351 mHistoricalPackageOps.removeAt(i);
3352 } else {
3353 packageOps.filter(opNames, fractionToRemove);
3354 }
3355 }
3356 }
3357
3358 private boolean isEmpty() {
3359 final int packageCount = getPackageCount();
3360 for (int i = packageCount - 1; i >= 0; i--) {
3361 final HistoricalPackageOps packageOps = mHistoricalPackageOps.valueAt(i);
3362 if (!packageOps.isEmpty()) {
3363 return false;
3364 }
3365 }
3366 return true;
3367 }
3368
3369 private void increaseAccessCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003370 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003371 getOrCreateHistoricalPackageOps(packageName).increaseAccessCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08003372 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003373 }
3374
3375 private void increaseRejectCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003376 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003377 getOrCreateHistoricalPackageOps(packageName).increaseRejectCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08003378 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003379 }
3380
3381 private void increaseAccessDuration(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003382 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003383 getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration(
Svet Ganovaf189e32019-02-15 18:45:29 -08003384 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003385 }
3386
3387 /**
3388 * @return The UID for which the data is related.
3389 */
3390 public int getUid() {
3391 return mUid;
3392 }
3393
3394 /**
3395 * Gets number of packages with historical ops.
3396 *
3397 * @return The number of packages with historical ops.
3398 *
3399 * @see #getPackageOpsAt(int)
3400 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003401 public @IntRange(from = 0) int getPackageCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003402 if (mHistoricalPackageOps == null) {
3403 return 0;
3404 }
3405 return mHistoricalPackageOps.size();
3406 }
3407
3408 /**
3409 * Gets the historical package ops at a given index.
3410 *
3411 * @param index The index.
3412 *
3413 * @return The historical package ops at the given index.
3414 *
3415 * @see #getPackageCount()
3416 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003417 public @NonNull HistoricalPackageOps getPackageOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003418 if (mHistoricalPackageOps == null) {
3419 throw new IndexOutOfBoundsException();
3420 }
3421 return mHistoricalPackageOps.valueAt(index);
3422 }
3423
3424 /**
3425 * Gets the historical package ops for a given package.
3426 *
3427 * @param packageName The package.
3428 *
3429 * @return The historical ops for the package.
3430 */
3431 public @Nullable HistoricalPackageOps getPackageOps(@NonNull String packageName) {
3432 if (mHistoricalPackageOps == null) {
3433 return null;
3434 }
3435 return mHistoricalPackageOps.get(packageName);
3436 }
3437
Winson4e3b4352019-05-07 16:29:59 -07003438 private void clearHistory(@NonNull String packageName) {
3439 if (mHistoricalPackageOps != null) {
3440 mHistoricalPackageOps.remove(packageName);
3441 }
3442 }
3443
Svet Ganov8455ba22019-01-02 13:05:56 -08003444 @Override
3445 public int describeContents() {
3446 return 0;
3447 }
3448
3449 @Override
3450 public void writeToParcel(Parcel parcel, int flags) {
3451 parcel.writeInt(mUid);
3452 parcel.writeTypedArrayMap(mHistoricalPackageOps, flags);
3453 }
3454
3455 private void accept(@NonNull HistoricalOpsVisitor visitor) {
3456 visitor.visitHistoricalUidOps(this);
3457 final int packageCount = getPackageCount();
3458 for (int i = 0; i < packageCount; i++) {
3459 getPackageOpsAt(i).accept(visitor);
3460 }
3461 }
3462
3463 private @NonNull HistoricalPackageOps getOrCreateHistoricalPackageOps(
3464 @NonNull String packageName) {
3465 if (mHistoricalPackageOps == null) {
3466 mHistoricalPackageOps = new ArrayMap<>();
3467 }
3468 HistoricalPackageOps historicalPackageOp = mHistoricalPackageOps.get(packageName);
3469 if (historicalPackageOp == null) {
3470 historicalPackageOp = new HistoricalPackageOps(packageName);
3471 mHistoricalPackageOps.put(packageName, historicalPackageOp);
3472 }
3473 return historicalPackageOp;
3474 }
3475
3476
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07003477 public static final @android.annotation.NonNull Creator<HistoricalUidOps> CREATOR = new Creator<HistoricalUidOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003478 @Override
3479 public @NonNull HistoricalUidOps createFromParcel(@NonNull Parcel parcel) {
3480 return new HistoricalUidOps(parcel);
3481 }
3482
3483 @Override
3484 public @NonNull HistoricalUidOps[] newArray(int size) {
3485 return new HistoricalUidOps[size];
3486 }
3487 };
3488
3489 @Override
Aurimas Liutikas00be9512019-08-28 13:01:05 -07003490 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003491 if (this == obj) {
3492 return true;
3493 }
3494 if (obj == null || getClass() != obj.getClass()) {
3495 return false;
3496 }
3497 final HistoricalUidOps other = (HistoricalUidOps) obj;
3498 if (mUid != other.mUid) {
3499 return false;
3500 }
3501 if (mHistoricalPackageOps == null) {
3502 if (other.mHistoricalPackageOps != null) {
3503 return false;
3504 }
3505 } else if (!mHistoricalPackageOps.equals(other.mHistoricalPackageOps)) {
3506 return false;
3507 }
3508 return true;
3509 }
3510
3511 @Override
3512 public int hashCode() {
3513 int result = mUid;
3514 result = 31 * result + (mHistoricalPackageOps != null
3515 ? mHistoricalPackageOps.hashCode() : 0);
3516 return result;
3517 }
3518 }
3519
3520 /**
3521 * This class represents historical app op information about a package.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003522 *
3523 * @hide
3524 */
3525 @TestApi
3526 @SystemApi
3527 public static final class HistoricalPackageOps implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003528 private final @NonNull String mPackageName;
Svet Ganov8455ba22019-01-02 13:05:56 -08003529 private @Nullable ArrayMap<String, HistoricalOp> mHistoricalOps;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003530
Svet Ganov8455ba22019-01-02 13:05:56 -08003531 /** @hide */
3532 public HistoricalPackageOps(@NonNull String packageName) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003533 mPackageName = packageName;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003534 }
3535
Svet Ganov8455ba22019-01-02 13:05:56 -08003536 private HistoricalPackageOps(@NonNull HistoricalPackageOps other) {
3537 mPackageName = other.mPackageName;
3538 final int opCount = other.getOpCount();
3539 for (int i = 0; i < opCount; i++) {
3540 final HistoricalOp origOp = other.getOpAt(i);
3541 final HistoricalOp cloneOp = new HistoricalOp(origOp);
3542 if (mHistoricalOps == null) {
3543 mHistoricalOps = new ArrayMap<>(opCount);
3544 }
3545 mHistoricalOps.put(cloneOp.getOpName(), cloneOp);
3546 }
3547 }
3548
3549 private HistoricalPackageOps(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003550 mPackageName = parcel.readString();
Svet Ganov8455ba22019-01-02 13:05:56 -08003551 mHistoricalOps = parcel.createTypedArrayMap(HistoricalOp.CREATOR);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003552 }
3553
Svet Ganov8455ba22019-01-02 13:05:56 -08003554 private @Nullable HistoricalPackageOps splice(double fractionToRemove) {
3555 HistoricalPackageOps splice = null;
3556 final int opCount = getOpCount();
3557 for (int i = 0; i < opCount; i++) {
3558 final HistoricalOp origOps = getOpAt(i);
3559 final HistoricalOp spliceOps = origOps.splice(fractionToRemove);
3560 if (spliceOps != null) {
3561 if (splice == null) {
3562 splice = new HistoricalPackageOps(mPackageName);
3563 }
3564 if (splice.mHistoricalOps == null) {
3565 splice.mHistoricalOps = new ArrayMap<>();
3566 }
3567 splice.mHistoricalOps.put(spliceOps.getOpName(), spliceOps);
3568 }
3569 }
3570 return splice;
3571 }
3572
3573 private void merge(@NonNull HistoricalPackageOps other) {
3574 final int opCount = other.getOpCount();
3575 for (int i = 0; i < opCount; i++) {
3576 final HistoricalOp otherOp = other.getOpAt(i);
3577 final HistoricalOp thisOp = getOp(otherOp.getOpName());
3578 if (thisOp != null) {
3579 thisOp.merge(otherOp);
3580 } else {
3581 if (mHistoricalOps == null) {
3582 mHistoricalOps = new ArrayMap<>();
3583 }
3584 mHistoricalOps.put(otherOp.getOpName(), otherOp);
3585 }
3586 }
3587 }
3588
3589 private void filter(@Nullable String[] opNames, double scaleFactor) {
3590 final int opCount = getOpCount();
3591 for (int i = opCount - 1; i >= 0; i--) {
3592 final HistoricalOp op = mHistoricalOps.valueAt(i);
3593 if (opNames != null && !ArrayUtils.contains(opNames, op.getOpName())) {
3594 mHistoricalOps.removeAt(i);
3595 } else {
3596 op.filter(scaleFactor);
3597 }
3598 }
3599 }
3600
3601 private boolean isEmpty() {
3602 final int opCount = getOpCount();
3603 for (int i = opCount - 1; i >= 0; i--) {
3604 final HistoricalOp op = mHistoricalOps.valueAt(i);
3605 if (!op.isEmpty()) {
3606 return false;
3607 }
3608 }
3609 return true;
3610 }
3611
Svet Ganovaf189e32019-02-15 18:45:29 -08003612 private void increaseAccessCount(int opCode, @UidState int uidState,
3613 @OpFlags int flags, long increment) {
3614 getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003615 }
3616
Svet Ganovaf189e32019-02-15 18:45:29 -08003617 private void increaseRejectCount(int opCode, @UidState int uidState,
3618 @OpFlags int flags, long increment) {
3619 getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003620 }
3621
Svet Ganovaf189e32019-02-15 18:45:29 -08003622 private void increaseAccessDuration(int opCode, @UidState int uidState,
3623 @OpFlags int flags, long increment) {
3624 getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, flags, increment);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003625 }
3626
3627 /**
3628 * Gets the package name which the data represents.
3629 *
3630 * @return The package name which the data represents.
3631 */
3632 public @NonNull String getPackageName() {
3633 return mPackageName;
3634 }
3635
3636 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003637 * Gets number historical app ops.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003638 *
Svet Ganov8455ba22019-01-02 13:05:56 -08003639 * @return The number historical app ops.
Svet Ganov8455ba22019-01-02 13:05:56 -08003640 * @see #getOpAt(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003641 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003642 public @IntRange(from = 0) int getOpCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003643 if (mHistoricalOps == null) {
3644 return 0;
3645 }
3646 return mHistoricalOps.size();
Svet Ganovad0a49b2018-10-29 10:07:08 -07003647 }
3648
3649 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003650 * Gets the historical op at a given index.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003651 *
3652 * @param index The index to lookup.
Svet Ganov8455ba22019-01-02 13:05:56 -08003653 * @return The op at the given index.
Svet Ganov8455ba22019-01-02 13:05:56 -08003654 * @see #getOpCount()
Svet Ganovad0a49b2018-10-29 10:07:08 -07003655 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003656 public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003657 if (mHistoricalOps == null) {
3658 throw new IndexOutOfBoundsException();
3659 }
3660 return mHistoricalOps.valueAt(index);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003661 }
3662
3663 /**
3664 * Gets the historical entry for a given op name.
3665 *
3666 * @param opName The op name.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003667 * @return The historical entry for that op name.
3668 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003669 public @Nullable HistoricalOp getOp(@NonNull String opName) {
3670 if (mHistoricalOps == null) {
3671 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003672 }
Svet Ganov8455ba22019-01-02 13:05:56 -08003673 return mHistoricalOps.get(opName);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003674 }
3675
3676 @Override
3677 public int describeContents() {
3678 return 0;
3679 }
3680
3681 @Override
3682 public void writeToParcel(@NonNull Parcel parcel, int flags) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003683 parcel.writeString(mPackageName);
Svet Ganov8455ba22019-01-02 13:05:56 -08003684 parcel.writeTypedArrayMap(mHistoricalOps, flags);
3685 }
3686
3687 private void accept(@NonNull HistoricalOpsVisitor visitor) {
3688 visitor.visitHistoricalPackageOps(this);
3689 final int opCount = getOpCount();
3690 for (int i = 0; i < opCount; i++) {
3691 getOpAt(i).accept(visitor);
3692 }
3693 }
3694
3695 private @NonNull HistoricalOp getOrCreateHistoricalOp(int opCode) {
3696 if (mHistoricalOps == null) {
3697 mHistoricalOps = new ArrayMap<>();
3698 }
3699 final String opStr = sOpToString[opCode];
3700 HistoricalOp op = mHistoricalOps.get(opStr);
3701 if (op == null) {
3702 op = new HistoricalOp(opCode);
3703 mHistoricalOps.put(opStr, op);
3704 }
3705 return op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003706 }
3707
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07003708 public static final @android.annotation.NonNull Creator<HistoricalPackageOps> CREATOR =
Svet Ganovad0a49b2018-10-29 10:07:08 -07003709 new Creator<HistoricalPackageOps>() {
3710 @Override
3711 public @NonNull HistoricalPackageOps createFromParcel(@NonNull Parcel parcel) {
3712 return new HistoricalPackageOps(parcel);
3713 }
3714
3715 @Override
3716 public @NonNull HistoricalPackageOps[] newArray(int size) {
3717 return new HistoricalPackageOps[size];
3718 }
3719 };
Svet Ganov8455ba22019-01-02 13:05:56 -08003720
3721 @Override
Aurimas Liutikas00be9512019-08-28 13:01:05 -07003722 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003723 if (this == obj) {
3724 return true;
3725 }
3726 if (obj == null || getClass() != obj.getClass()) {
3727 return false;
3728 }
3729 final HistoricalPackageOps other = (HistoricalPackageOps) obj;
3730 if (!mPackageName.equals(other.mPackageName)) {
3731 return false;
3732 }
3733 if (mHistoricalOps == null) {
3734 if (other.mHistoricalOps != null) {
3735 return false;
3736 }
3737 } else if (!mHistoricalOps.equals(other.mHistoricalOps)) {
3738 return false;
3739 }
3740 return true;
3741 }
3742
3743 @Override
3744 public int hashCode() {
3745 int result = mPackageName != null ? mPackageName.hashCode() : 0;
3746 result = 31 * result + (mHistoricalOps != null ? mHistoricalOps.hashCode() : 0);
3747 return result;
3748 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003749 }
3750
3751 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003752 * This class represents historical information about an app op.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003753 *
3754 * @hide
3755 */
3756 @TestApi
3757 @SystemApi
Svet Ganov8455ba22019-01-02 13:05:56 -08003758 public static final class HistoricalOp implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003759 private final int mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08003760 private @Nullable LongSparseLongArray mAccessCount;
3761 private @Nullable LongSparseLongArray mRejectCount;
3762 private @Nullable LongSparseLongArray mAccessDuration;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003763
Svet Ganov8455ba22019-01-02 13:05:56 -08003764 /** @hide */
3765 public HistoricalOp(int op) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003766 mOp = op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07003767 }
3768
Svet Ganov8455ba22019-01-02 13:05:56 -08003769 private HistoricalOp(@NonNull HistoricalOp other) {
3770 mOp = other.mOp;
3771 if (other.mAccessCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003772 mAccessCount = other.mAccessCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08003773 }
3774 if (other.mRejectCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003775 mRejectCount = other.mRejectCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08003776 }
3777 if (other.mAccessDuration != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003778 mAccessDuration = other.mAccessDuration.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08003779 }
3780 }
3781
3782 private HistoricalOp(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003783 mOp = parcel.readInt();
Svet Ganovaf189e32019-02-15 18:45:29 -08003784 mAccessCount = readLongSparseLongArrayFromParcel(parcel);
3785 mRejectCount = readLongSparseLongArrayFromParcel(parcel);
3786 mAccessDuration = readLongSparseLongArrayFromParcel(parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003787 }
3788
Svet Ganov8455ba22019-01-02 13:05:56 -08003789 private void filter(double scaleFactor) {
3790 scale(mAccessCount, scaleFactor);
3791 scale(mRejectCount, scaleFactor);
3792 scale(mAccessDuration, scaleFactor);
3793 }
3794
3795 private boolean isEmpty() {
3796 return !hasData(mAccessCount)
3797 && !hasData(mRejectCount)
3798 && !hasData(mAccessDuration);
3799 }
3800
Svet Ganovaf189e32019-02-15 18:45:29 -08003801 private boolean hasData(@NonNull LongSparseLongArray array) {
3802 return (array != null && array.size() > 0);
Svet Ganov8455ba22019-01-02 13:05:56 -08003803 }
3804
3805 private @Nullable HistoricalOp splice(double fractionToRemove) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003806 final HistoricalOp splice = new HistoricalOp(mOp);
3807 splice(mAccessCount, splice::getOrCreateAccessCount, fractionToRemove);
3808 splice(mRejectCount, splice::getOrCreateRejectCount, fractionToRemove);
3809 splice(mAccessDuration, splice::getOrCreateAccessDuration, fractionToRemove);
Svet Ganov8455ba22019-01-02 13:05:56 -08003810 return splice;
3811 }
3812
Svet Ganovaf189e32019-02-15 18:45:29 -08003813 private static void splice(@Nullable LongSparseLongArray sourceContainer,
3814 @NonNull Supplier<LongSparseLongArray> destContainerProvider,
3815 double fractionToRemove) {
3816 if (sourceContainer != null) {
3817 final int size = sourceContainer.size();
3818 for (int i = 0; i < size; i++) {
3819 final long key = sourceContainer.keyAt(i);
3820 final long value = sourceContainer.valueAt(i);
3821 final long removedFraction = Math.round(value * fractionToRemove);
3822 if (removedFraction > 0) {
3823 destContainerProvider.get().put(key, removedFraction);
3824 sourceContainer.put(key, value - removedFraction);
3825 }
3826 }
3827 }
3828 }
3829
Svet Ganov8455ba22019-01-02 13:05:56 -08003830 private void merge(@NonNull HistoricalOp other) {
Svet Ganovaf189e32019-02-15 18:45:29 -08003831 merge(this::getOrCreateAccessCount, other.mAccessCount);
3832 merge(this::getOrCreateRejectCount, other.mRejectCount);
3833 merge(this::getOrCreateAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08003834 }
3835
Svet Ganovaf189e32019-02-15 18:45:29 -08003836 private void increaseAccessCount(@UidState int uidState, @OpFlags int flags,
3837 long increment) {
3838 increaseCount(getOrCreateAccessCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003839 }
3840
Svet Ganovaf189e32019-02-15 18:45:29 -08003841 private void increaseRejectCount(@UidState int uidState, @OpFlags int flags,
3842 long increment) {
3843 increaseCount(getOrCreateRejectCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003844 }
3845
Svet Ganovaf189e32019-02-15 18:45:29 -08003846 private void increaseAccessDuration(@UidState int uidState, @OpFlags int flags,
3847 long increment) {
3848 increaseCount(getOrCreateAccessDuration(), uidState, flags, increment);
3849 }
3850
3851 private void increaseCount(@NonNull LongSparseLongArray counts,
3852 @UidState int uidState, @OpFlags int flags, long increment) {
3853 while (flags != 0) {
3854 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
3855 flags &= ~flag;
3856 final long key = makeKey(uidState, flag);
3857 counts.put(key, counts.get(key) + increment);
3858 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07003859 }
3860
3861 /**
3862 * Gets the op name.
3863 *
3864 * @return The op name.
3865 */
Svet Ganov8455ba22019-01-02 13:05:56 -08003866 public @NonNull String getOpName() {
Svet Ganovad0a49b2018-10-29 10:07:08 -07003867 return sOpToString[mOp];
3868 }
3869
Svet Ganov8455ba22019-01-02 13:05:56 -08003870 /** @hide */
3871 public int getOpCode() {
3872 return mOp;
3873 }
3874
Svet Ganovad0a49b2018-10-29 10:07:08 -07003875 /**
3876 * Gets the number times the op was accessed (performed) in the foreground.
3877 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003878 * @param flags The flags which are any combination of
3879 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3880 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3881 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3882 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003883 * @return The times the op was accessed in the foreground.
3884 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003885 * @see #getBackgroundAccessCount(int)
3886 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003887 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003888 public long getForegroundAccessCount(@OpFlags int flags) {
3889 return sumForFlagsInStates(mAccessCount, MAX_PRIORITY_UID_STATE,
3890 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003891 }
3892
3893 /**
3894 * Gets the number times the op was accessed (performed) in the background.
3895 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003896 * @param flags The flags which are any combination of
3897 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3898 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3899 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3900 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003901 * @return The times the op was accessed in the background.
3902 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003903 * @see #getForegroundAccessCount(int)
3904 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003905 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003906 public long getBackgroundAccessCount(@OpFlags int flags) {
3907 return sumForFlagsInStates(mAccessCount, resolveLastRestrictedUidState(mOp),
3908 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003909 }
3910
3911 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08003912 * Gets the number times the op was accessed (performed) for a
3913 * range of uid states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003914 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003915 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07003916 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08003917 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07003918 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3919 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08003920 * @param toUidState The UID state to which to query.
3921 * @param flags The flags which are any combination of
3922 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3923 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3924 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3925 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003926 *
3927 * @return The times the op was accessed for the given UID state.
3928 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003929 * @see #getForegroundAccessCount(int)
3930 * @see #getBackgroundAccessCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003931 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003932 public long getAccessCount(@UidState int fromUidState, @UidState int toUidState,
3933 @OpFlags int flags) {
3934 return sumForFlagsInStates(mAccessCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003935 }
3936
3937 /**
3938 * Gets the number times the op was rejected in the foreground.
3939 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003940 * @param flags The flags which are any combination of
3941 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3942 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3943 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3944 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003945 * @return The times the op was rejected in the foreground.
3946 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003947 * @see #getBackgroundRejectCount(int)
3948 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003949 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003950 public long getForegroundRejectCount(@OpFlags int flags) {
3951 return sumForFlagsInStates(mRejectCount, MAX_PRIORITY_UID_STATE,
3952 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003953 }
3954
3955 /**
3956 * Gets the number times the op was rejected in the background.
3957 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003958 * @param flags The flags which are any combination of
3959 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3960 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3961 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3962 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003963 * @return The times the op was rejected in the background.
3964 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003965 * @see #getForegroundRejectCount(int)
3966 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003967 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003968 public long getBackgroundRejectCount(@OpFlags int flags) {
3969 return sumForFlagsInStates(mRejectCount, resolveLastRestrictedUidState(mOp),
3970 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003971 }
3972
3973 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08003974 * Gets the number times the op was rejected for a given range of UID states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003975 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003976 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07003977 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08003978 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07003979 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3980 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08003981 * @param toUidState The UID state to which to query.
3982 * @param flags The flags which are any combination of
3983 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3984 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3985 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3986 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07003987 *
3988 * @return The times the op was rejected for the given UID state.
3989 *
Svet Ganovaf189e32019-02-15 18:45:29 -08003990 * @see #getForegroundRejectCount(int)
3991 * @see #getBackgroundRejectCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07003992 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003993 public long getRejectCount(@UidState int fromUidState, @UidState int toUidState,
3994 @OpFlags int flags) {
3995 return sumForFlagsInStates(mRejectCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07003996 }
3997
3998 /**
3999 * Gets the total duration the app op was accessed (performed) in the foreground.
Svet Ganov6f672a32019-07-08 16:40:42 -07004000 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004001 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004002 * @param flags The flags which are any combination of
4003 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4004 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4005 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4006 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004007 * @return The total duration the app op was accessed in the foreground.
4008 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004009 * @see #getBackgroundAccessDuration(int)
4010 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004011 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004012 public long getForegroundAccessDuration(@OpFlags int flags) {
4013 return sumForFlagsInStates(mAccessDuration, MAX_PRIORITY_UID_STATE,
4014 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004015 }
4016
4017 /**
4018 * Gets the total duration the app op was accessed (performed) in the background.
Svet Ganov6f672a32019-07-08 16:40:42 -07004019 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004020 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004021 * @param flags The flags which are any combination of
4022 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4023 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4024 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4025 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004026 * @return The total duration the app op was accessed in the background.
4027 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004028 * @see #getForegroundAccessDuration(int)
4029 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004030 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004031 public long getBackgroundAccessDuration(@OpFlags int flags) {
4032 return sumForFlagsInStates(mAccessDuration, resolveLastRestrictedUidState(mOp),
4033 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004034 }
4035
4036 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08004037 * Gets the total duration the app op was accessed (performed) for a given
Svet Ganov6f672a32019-07-08 16:40:42 -07004038 * range of UID states. The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004039 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004040 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07004041 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
Amith Yamasania0a30a12019-01-22 11:38:06 -08004042 * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
Svet Ganovad0a49b2018-10-29 10:07:08 -07004043 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
4044 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08004045 * @param toUidState The UID state from which to query.
4046 * @param flags The flags which are any combination of
4047 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4048 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4049 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4050 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004051 *
4052 * @return The total duration the app op was accessed for the given UID state.
4053 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004054 * @see #getForegroundAccessDuration(int)
4055 * @see #getBackgroundAccessDuration(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004056 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004057 public long getAccessDuration(@UidState int fromUidState, @UidState int toUidState,
4058 @OpFlags int flags) {
4059 return sumForFlagsInStates(mAccessDuration, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004060 }
4061
4062 @Override
4063 public int describeContents() {
4064 return 0;
4065 }
4066
4067 @Override
4068 public void writeToParcel(Parcel parcel, int flags) {
4069 parcel.writeInt(mOp);
Svet Ganovaf189e32019-02-15 18:45:29 -08004070 writeLongSparseLongArrayToParcel(mAccessCount, parcel);
4071 writeLongSparseLongArrayToParcel(mRejectCount, parcel);
4072 writeLongSparseLongArrayToParcel(mAccessDuration, parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004073 }
4074
Svet Ganov8455ba22019-01-02 13:05:56 -08004075 @Override
Aurimas Liutikas00be9512019-08-28 13:01:05 -07004076 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004077 if (this == obj) {
4078 return true;
4079 }
4080 if (obj == null || getClass() != obj.getClass()) {
4081 return false;
4082 }
4083 final HistoricalOp other = (HistoricalOp) obj;
4084 if (mOp != other.mOp) {
4085 return false;
4086 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004087 if (!Objects.equals(mAccessCount, other.mAccessCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004088 return false;
4089 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004090 if (!Objects.equals(mRejectCount, other.mRejectCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004091 return false;
4092 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004093 return Objects.equals(mAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004094 }
4095
4096 @Override
4097 public int hashCode() {
4098 int result = mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08004099 result = 31 * result + Objects.hashCode(mAccessCount);
4100 result = 31 * result + Objects.hashCode(mRejectCount);
4101 result = 31 * result + Objects.hashCode(mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004102 return result;
4103 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004104
4105 private void accept(@NonNull HistoricalOpsVisitor visitor) {
4106 visitor.visitHistoricalOp(this);
4107 }
4108
4109 private @NonNull LongSparseLongArray getOrCreateAccessCount() {
4110 if (mAccessCount == null) {
4111 mAccessCount = new LongSparseLongArray();
4112 }
4113 return mAccessCount;
4114 }
4115
4116 private @NonNull LongSparseLongArray getOrCreateRejectCount() {
4117 if (mRejectCount == null) {
4118 mRejectCount = new LongSparseLongArray();
4119 }
4120 return mRejectCount;
4121 }
4122
4123 private @NonNull LongSparseLongArray getOrCreateAccessDuration() {
4124 if (mAccessDuration == null) {
4125 mAccessDuration = new LongSparseLongArray();
4126 }
4127 return mAccessDuration;
4128 }
4129
4130 /**
4131 * Multiplies the entries in the array with the passed in scale factor and
4132 * rounds the result at up 0.5 boundary.
4133 *
4134 * @param data The data to scale.
4135 * @param scaleFactor The scale factor.
4136 */
4137 private static void scale(@NonNull LongSparseLongArray data, double scaleFactor) {
4138 if (data != null) {
4139 final int size = data.size();
4140 for (int i = 0; i < size; i++) {
4141 data.put(data.keyAt(i), (long) HistoricalOps.round(
4142 (double) data.valueAt(i) * scaleFactor));
4143 }
4144 }
4145 }
4146
4147 /**
4148 * Merges two arrays while lazily acquiring the destination.
4149 *
4150 * @param thisSupplier The destination supplier.
4151 * @param other The array to merge in.
4152 */
4153 private static void merge(@NonNull Supplier<LongSparseLongArray> thisSupplier,
4154 @Nullable LongSparseLongArray other) {
4155 if (other != null) {
4156 final int otherSize = other.size();
4157 for (int i = 0; i < otherSize; i++) {
4158 final LongSparseLongArray that = thisSupplier.get();
4159 final long otherKey = other.keyAt(i);
4160 final long otherValue = other.valueAt(i);
4161 that.put(otherKey, that.get(otherKey) + otherValue);
4162 }
4163 }
4164 }
4165
4166 /** @hide */
4167 public @Nullable LongSparseArray<Object> collectKeys() {
4168 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessCount,
4169 null /*result*/);
4170 result = AppOpsManager.collectKeys(mRejectCount, result);
4171 result = AppOpsManager.collectKeys(mAccessDuration, result);
4172 return result;
4173 }
4174
4175 public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR =
4176 new Creator<HistoricalOp>() {
4177 @Override
4178 public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) {
4179 return new HistoricalOp(source);
4180 }
4181
4182 @Override
4183 public @NonNull HistoricalOp[] newArray(int size) {
4184 return new HistoricalOp[size];
4185 }
4186 };
4187 }
4188
4189 /**
4190 * Computes the sum of the counts for the given flags in between the begin and
4191 * end UID states.
4192 *
4193 * @param counts The data array.
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004194 * @param beginUidState The beginning UID state (inclusive).
4195 * @param endUidState The end UID state (inclusive).
Svet Ganovaf189e32019-02-15 18:45:29 -08004196 * @param flags The UID flags.
4197 * @return The sum.
4198 */
4199 private static long sumForFlagsInStates(@Nullable LongSparseLongArray counts,
4200 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
4201 if (counts == null) {
4202 return 0;
4203 }
4204 long sum = 0;
4205 while (flags != 0) {
4206 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4207 flags &= ~flag;
4208 for (int uidState : UID_STATES) {
4209 if (uidState < beginUidState || uidState > endUidState) {
4210 continue;
4211 }
4212 final long key = makeKey(uidState, flag);
4213 sum += counts.get(key);
4214 }
4215 }
4216 return sum;
4217 }
4218
4219 /**
4220 * Finds the first non-negative value for the given flags in between the begin and
4221 * end UID states.
4222 *
4223 * @param counts The data array.
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004224 * @param beginUidState The beginning UID state (inclusive).
4225 * @param endUidState The end UID state (inclusive).
Svet Ganovaf189e32019-02-15 18:45:29 -08004226 * @param flags The UID flags.
Svet Ganovaf189e32019-02-15 18:45:29 -08004227 * @return The non-negative value or -1.
4228 */
4229 private static long findFirstNonNegativeForFlagsInStates(@Nullable LongSparseLongArray counts,
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004230 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004231 if (counts == null) {
4232 return -1;
4233 }
4234 while (flags != 0) {
4235 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4236 flags &= ~flag;
4237 for (int uidState : UID_STATES) {
4238 if (uidState < beginUidState || uidState > endUidState) {
4239 continue;
4240 }
4241 final long key = makeKey(uidState, flag);
4242 final long value = counts.get(key);
4243 if (value >= 0) {
4244 return value;
4245 }
4246 }
4247 }
4248 return -1;
4249 }
4250
4251 /**
4252 * Finds the first non-null value for the given flags in between the begin and
4253 * end UID states.
4254 *
4255 * @param counts The data array.
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004256 * @param beginUidState The beginning UID state (inclusive).
4257 * @param endUidState The end UID state (inclusive).
Svet Ganovaf189e32019-02-15 18:45:29 -08004258 * @param flags The UID flags.
Svet Ganovaf189e32019-02-15 18:45:29 -08004259 * @return The non-negative value or -1.
4260 */
4261 private static @Nullable String findFirstNonNullForFlagsInStates(
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004262 @Nullable LongSparseArray<String> counts, @UidState int beginUidState,
4263 @UidState int endUidState, @OpFlags int flags) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004264 if (counts == null) {
4265 return null;
4266 }
4267 while (flags != 0) {
4268 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4269 flags &= ~flag;
4270 for (int uidState : UID_STATES) {
4271 if (uidState < beginUidState || uidState > endUidState) {
4272 continue;
4273 }
4274 final long key = makeKey(uidState, flag);
4275 final String value = counts.get(key);
4276 if (value != null) {
4277 return value;
4278 }
4279 }
4280 }
4281 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004282 }
4283
4284 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004285 * Callback for notification of changes to operation state.
4286 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004287 public interface OnOpChangedListener {
4288 public void onOpChanged(String op, String packageName);
4289 }
4290
4291 /**
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004292 * Callback for notification of changes to operation active state.
4293 *
4294 * @hide
4295 */
Svet Ganovf7b47252018-02-26 11:11:27 -08004296 @TestApi
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004297 public interface OnOpActiveChangedListener {
4298 /**
4299 * Called when the active state of an app op changes.
4300 *
4301 * @param code The op code.
4302 * @param uid The UID performing the operation.
4303 * @param packageName The package performing the operation.
4304 * @param active Whether the operation became active or inactive.
4305 */
4306 void onOpActiveChanged(int code, int uid, String packageName, boolean active);
4307 }
4308
4309 /**
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004310 * Callback for notification of an op being noted.
4311 *
4312 * @hide
4313 */
4314 public interface OnOpNotedListener {
4315 /**
4316 * Called when an op was noted.
4317 *
4318 * @param code The op code.
4319 * @param uid The UID performing the operation.
4320 * @param packageName The package performing the operation.
4321 * @param result The result of the note.
4322 */
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004323 void onOpNoted(int code, int uid, String packageName, int result);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004324 }
4325
4326 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004327 * Callback for notification of changes to operation state.
4328 * This allows you to see the raw op codes instead of strings.
4329 * @hide
4330 */
4331 public static class OnOpChangedInternalListener implements OnOpChangedListener {
4332 public void onOpChanged(String op, String packageName) { }
4333 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -08004334 }
4335
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004336 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004337 mContext = context;
4338 mService = service;
4339 }
4340
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004341 /**
4342 * Retrieve current operation state for all applications.
4343 *
Winson6a864b52019-05-10 10:34:14 -07004344 * The mode of the ops returned are set for the package but may not reflect their effective
4345 * state due to UID policy or because it's controlled by a different master op.
4346 *
4347 * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)}
4348 * if the effective mode is needed.
4349 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004350 * @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 -07004351 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004352 */
Svet Ganov8455ba22019-01-02 13:05:56 -08004353 @SystemApi
4354 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
4355 public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops) {
4356 final int opCount = ops.length;
4357 final int[] opCodes = new int[opCount];
4358 for (int i = 0; i < opCount; i++) {
4359 opCodes[i] = sOpStrToOp.get(ops[i]);
4360 }
4361 final List<AppOpsManager.PackageOps> result = getPackagesForOps(opCodes);
4362 return (result != null) ? result : Collections.emptyList();
4363 }
4364
4365 /**
4366 * Retrieve current operation state for all applications.
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 *
Svet Ganov8455ba22019-01-02 13:05:56 -08004374 * @param ops The set of operations you are interested in, or null if you want all of them.
4375 * @hide
4376 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07004377 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004378 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08004379 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
4380 try {
4381 return mService.getPackagesForOps(ops);
4382 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004383 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08004384 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08004385 }
4386
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004387 /**
4388 * Retrieve current operation state for one application.
4389 *
Winson6a864b52019-05-10 10:34:14 -07004390 * The mode of the ops returned are set for the package but may not reflect their effective
4391 * state due to UID policy or because it's controlled by a different master op.
4392 *
4393 * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)}
4394 * if the effective mode is needed.
4395 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004396 * @param uid The uid of the application of interest.
4397 * @param packageName The name of the application of interest.
4398 * @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 -08004399 *
4400 * @deprecated The int op codes are not stable and you should use the string based op
4401 * names which are stable and namespaced. Use
4402 * {@link #getOpsForPackage(int, String, String...)})}.
4403 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004404 * @hide
Suprabh Shukla169bed72019-05-13 13:54:58 -07004405 * @removed
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004406 */
Svet Ganov8455ba22019-01-02 13:05:56 -08004407 @Deprecated
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07004408 @SystemApi
Dianne Hackbornc216a262018-04-26 13:46:22 -07004409 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Dianne Hackborn62878492019-03-11 15:57:07 -07004410 public @NonNull List<PackageOps> getOpsForPackage(int uid, @NonNull String packageName,
4411 @Nullable int[] ops) {
Dianne Hackborn72e39832013-01-18 18:36:09 -08004412 try {
4413 return mService.getOpsForPackage(uid, packageName, ops);
4414 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004415 throw e.rethrowFromSystemServer();
Dianne Hackborn72e39832013-01-18 18:36:09 -08004416 }
Dianne Hackborn72e39832013-01-18 18:36:09 -08004417 }
4418
Svet Ganovae0e03a2016-02-25 18:22:10 -08004419 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004420 * Retrieve current operation state for one application. The UID and the
4421 * package must match.
4422 *
Winson6a864b52019-05-10 10:34:14 -07004423 * The mode of the ops returned are set for the package but may not reflect their effective
4424 * state due to UID policy or because it's controlled by a different master op.
4425 *
4426 * Use {@link #unsafeCheckOp(String, int, String)}} or {@link #noteOp(String, int, String)}
4427 * if the effective mode is needed.
4428 *
Svet Ganov8455ba22019-01-02 13:05:56 -08004429 * @param uid The uid of the application of interest.
4430 * @param packageName The name of the application of interest.
4431 * @param ops The set of operations you are interested in, or null if you want all of them.
4432 *
4433 * @hide
4434 */
4435 @SystemApi
4436 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
4437 public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid,
4438 @NonNull String packageName, @Nullable String... ops) {
4439 int[] opCodes = null;
4440 if (ops != null) {
4441 opCodes = new int[ops.length];
4442 for (int i = 0; i < ops.length; i++) {
4443 opCodes[i] = strOpToOp(ops[i]);
4444 }
4445 }
4446 try {
4447 final List<PackageOps> result = mService.getOpsForPackage(uid, packageName, opCodes);
4448 if (result == null) {
4449 return Collections.emptyList();
4450 }
4451 return result;
4452 } catch (RemoteException e) {
4453 throw e.rethrowFromSystemServer();
4454 }
4455 }
4456
4457 /**
4458 * Retrieve historical app op stats for a period.
4459 *
Svet Ganov23c88db2019-01-22 20:38:11 -08004460 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08004461 * @param executor Executor on which to run the callback. If <code>null</code>
4462 * the callback is executed on the default executor running on the main thread.
4463 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004464 *
4465 * @throws IllegalArgumentException If any of the argument contracts is violated.
4466 *
4467 * @hide
4468 */
4469 @TestApi
4470 @SystemApi
4471 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov23c88db2019-01-22 20:38:11 -08004472 public void getHistoricalOps(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08004473 @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) {
4474 Preconditions.checkNotNull(executor, "executor cannot be null");
4475 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07004476 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08004477 mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08004478 request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags,
Svet Ganov8455ba22019-01-02 13:05:56 -08004479 new RemoteCallback((result) -> {
4480 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
4481 final long identity = Binder.clearCallingIdentity();
4482 try {
4483 executor.execute(() -> callback.accept(ops));
4484 } finally {
4485 Binder.restoreCallingIdentity(identity);
4486 }
4487 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07004488 } catch (RemoteException e) {
4489 throw e.rethrowFromSystemServer();
4490 }
4491 }
4492
4493 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004494 * Retrieve historical app op stats for a period.
Svet Ganov8455ba22019-01-02 13:05:56 -08004495 * <p>
4496 * This method queries only the on disk state and the returned ops are raw,
4497 * which is their times are relative to the history start as opposed to the
4498 * epoch start.
4499 *
Svet Ganov23c88db2019-01-22 20:38:11 -08004500 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08004501 * @param executor Executor on which to run the callback. If <code>null</code>
4502 * the callback is executed on the default executor running on the main thread.
4503 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004504 *
4505 * @throws IllegalArgumentException If any of the argument contracts is violated.
4506 *
4507 * @hide
4508 */
4509 @TestApi
Svet Ganov8e5bf962019-03-19 23:59:03 -07004510 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
Svet Ganov23c88db2019-01-22 20:38:11 -08004511 public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08004512 @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) {
4513 Preconditions.checkNotNull(executor, "executor cannot be null");
4514 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07004515 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08004516 mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName,
4517 request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis,
Svet Ganovaf189e32019-02-15 18:45:29 -08004518 request.mFlags, new RemoteCallback((result) -> {
Svet Ganov23c88db2019-01-22 20:38:11 -08004519 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
Svet Ganov8455ba22019-01-02 13:05:56 -08004520 final long identity = Binder.clearCallingIdentity();
4521 try {
4522 executor.execute(() -> callback.accept(ops));
4523 } finally {
4524 Binder.restoreCallingIdentity(identity);
4525 }
4526 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07004527 } catch (RemoteException e) {
4528 throw e.rethrowFromSystemServer();
4529 }
4530 }
4531
4532 /**
Svet Ganov8e5bf962019-03-19 23:59:03 -07004533 * Reloads the non historical state to allow testing the read/write path.
4534 *
4535 * @hide
4536 */
4537 @TestApi
4538 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
4539 public void reloadNonHistoricalState() {
4540 try {
4541 mService.reloadNonHistoricalState();
4542 } catch (RemoteException e) {
4543 throw e.rethrowFromSystemServer();
4544 }
4545 }
4546
4547 /**
Svet Ganovae0e03a2016-02-25 18:22:10 -08004548 * Sets given app op in the specified mode for app ops in the UID.
4549 * This applies to all apps currently in the UID or installed in
4550 * this UID in the future.
4551 *
4552 * @param code The app op.
4553 * @param uid The UID for which to set the app.
4554 * @param mode The app op mode to set.
4555 * @hide
4556 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004557 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004558 public void setUidMode(int code, int uid, @Mode int mode) {
Svet Ganov2af57082015-07-30 08:44:20 -07004559 try {
4560 mService.setUidMode(code, uid, mode);
4561 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004562 throw e.rethrowFromSystemServer();
Svet Ganov2af57082015-07-30 08:44:20 -07004563 }
4564 }
4565
Svet Ganovae0e03a2016-02-25 18:22:10 -08004566 /**
4567 * Sets given app op in the specified mode for app ops in the UID.
4568 * This applies to all apps currently in the UID or installed in
4569 * this UID in the future.
4570 *
4571 * @param appOp The app op.
4572 * @param uid The UID for which to set the app.
4573 * @param mode The app op mode to set.
4574 * @hide
4575 */
4576 @SystemApi
Eugene Susla93519852018-06-13 16:44:31 -07004577 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004578 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004579 public void setUidMode(String appOp, int uid, @Mode int mode) {
Svet Ganovae0e03a2016-02-25 18:22:10 -08004580 try {
4581 mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
4582 } catch (RemoteException e) {
4583 throw e.rethrowFromSystemServer();
4584 }
4585 }
4586
Svet Ganov2af57082015-07-30 08:44:20 -07004587 /** @hide */
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004588 public void setUserRestriction(int code, boolean restricted, IBinder token) {
Ruben Brunk29931bc2016-03-11 00:24:26 -08004589 setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
4590 }
4591
4592 /** @hide */
4593 public void setUserRestriction(int code, boolean restricted, IBinder token,
4594 String[] exceptionPackages) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07004595 setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
4596 }
4597
4598 /** @hide */
4599 public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
4600 String[] exceptionPackages, int userId) {
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004601 try {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07004602 mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004603 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004604 throw e.rethrowFromSystemServer();
Svet Ganov9cea80cd2016-02-16 11:47:00 -08004605 }
4606 }
4607
4608 /** @hide */
Artur Satayev5a525852019-10-31 15:15:50 +00004609 @UnsupportedAppUsage
Peter Visontayb97fbc82017-12-21 16:23:55 +00004610 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004611 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004612 public void setMode(int code, int uid, String packageName, @Mode int mode) {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08004613 try {
4614 mService.setMode(code, uid, packageName, mode);
4615 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004616 throw e.rethrowFromSystemServer();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08004617 }
4618 }
4619
John Spurlock1af30c72014-03-10 08:33:35 -04004620 /**
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004621 * Change the operating mode for the given op in the given app package. You must pass
4622 * in both the uid and name of the application whose mode is being modified; if these
4623 * do not match, the modification will not be applied.
4624 *
4625 * @param op The operation to modify. One of the OPSTR_* constants.
4626 * @param uid The user id of the application whose mode will be changed.
4627 * @param packageName The name of the application package name whose mode will
4628 * be changed.
4629 * @hide
4630 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07004631 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004632 @SystemApi
4633 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08004634 public void setMode(String op, int uid, String packageName, @Mode int mode) {
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004635 try {
4636 mService.setMode(strOpToOp(op), uid, packageName, mode);
4637 } catch (RemoteException e) {
4638 throw e.rethrowFromSystemServer();
4639 }
4640 }
4641
4642 /**
John Spurlock1af30c72014-03-10 08:33:35 -04004643 * Set a non-persisted restriction on an audio operation at a stream-level.
4644 * Restrictions are temporary additional constraints imposed on top of the persisted rules
4645 * defined by {@link #setMode}.
4646 *
4647 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04004648 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04004649 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
4650 * @param exceptionPackages Optional list of packages to exclude from the restriction.
4651 * @hide
4652 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004653 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004654 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -08004655 public void setRestriction(int code, @AttributeUsage int usage, @Mode int mode,
John Spurlock7b414672014-07-18 13:02:39 -04004656 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04004657 try {
4658 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04004659 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04004660 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004661 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04004662 }
4663 }
4664
Dianne Hackborn607b4142013-08-02 18:10:10 -07004665 /** @hide */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08004666 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01004667 @UnsupportedAppUsage
Dianne Hackborn607b4142013-08-02 18:10:10 -07004668 public void resetAllModes() {
4669 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -07004670 mService.resetAllModes(mContext.getUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07004671 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004672 throw e.rethrowFromSystemServer();
Dianne Hackborn607b4142013-08-02 18:10:10 -07004673 }
4674 }
4675
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004676 /**
Svet Ganovfbf01f72015-04-28 18:39:06 -07004677 * Gets the app op name associated with a given permission.
4678 * The app op name is one of the public constants defined
4679 * in this class such as {@link #OPSTR_COARSE_LOCATION}.
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07004680 * This API is intended to be used for mapping runtime
4681 * permissions to the corresponding app op.
Svet Ganovfbf01f72015-04-28 18:39:06 -07004682 *
4683 * @param permission The permission.
4684 * @return The app op associated with the permission or null.
Svet Ganovfbf01f72015-04-28 18:39:06 -07004685 */
Svet Ganovfbf01f72015-04-28 18:39:06 -07004686 public static String permissionToOp(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08004687 final Integer opCode = sPermToOp.get(permission);
Svet Ganovb9d71a62015-04-30 10:38:13 -07004688 if (opCode == null) {
4689 return null;
4690 }
4691 return sOpToString[opCode];
Svet Ganovfbf01f72015-04-28 18:39:06 -07004692 }
4693
4694 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004695 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004696 * You can watch op changes only for your UID.
4697 *
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07004698 * @param op The operation to monitor, one of OPSTR_*.
4699 * @param packageName The name of the application to monitor.
4700 * @param callback Where to report changes.
4701 */
Dianne Hackborn62878492019-03-11 15:57:07 -07004702 public void startWatchingMode(@NonNull String op, @Nullable String packageName,
4703 @NonNull final OnOpChangedListener callback) {
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07004704 startWatchingMode(strOpToOp(op), packageName, callback);
4705 }
4706
4707 /**
4708 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004709 * You can watch op changes only for your UID.
4710 *
4711 * @param op The operation to monitor, one of OPSTR_*.
4712 * @param packageName The name of the application to monitor.
4713 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
4714 * @param callback Where to report changes.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004715 */
Dianne Hackborn62878492019-03-11 15:57:07 -07004716 public void startWatchingMode(@NonNull String op, @Nullable String packageName, int flags,
4717 @NonNull final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004718 startWatchingMode(strOpToOp(op), packageName, flags, callback);
4719 }
4720
4721 /**
4722 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004723 *
4724 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08004725 * you can watch changes only for your UID.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004726 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004727 * @param op The operation to monitor, one of OP_*.
4728 * @param packageName The name of the application to monitor.
4729 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07004730 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004731 */
Jeff Sharkeybf6b2132018-02-27 11:16:37 -07004732 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004733 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004734 startWatchingMode(op, packageName, 0, callback);
4735 }
4736
4737 /**
4738 * Monitor for changes to the operating mode for the given op in the given app package.
4739 *
4740 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4741 * you can watch changes only for your UID.
4742 *
4743 * @param op The operation to monitor, one of OP_*.
4744 * @param packageName The name of the application to monitor.
4745 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
4746 * @param callback Where to report changes.
4747 * @hide
4748 */
4749 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
4750 public void startWatchingMode(int op, String packageName, int flags,
4751 final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08004752 synchronized (mModeWatchers) {
4753 IAppOpsCallback cb = mModeWatchers.get(callback);
4754 if (cb == null) {
4755 cb = new IAppOpsCallback.Stub() {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07004756 public void opChanged(int op, int uid, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004757 if (callback instanceof OnOpChangedInternalListener) {
4758 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
4759 }
4760 if (sOpToString[op] != null) {
4761 callback.onOpChanged(sOpToString[op], packageName);
4762 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08004763 }
4764 };
4765 mModeWatchers.put(callback, cb);
4766 }
4767 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07004768 mService.startWatchingModeWithFlags(op, packageName, flags, cb);
Dianne Hackbornc2293022013-02-06 23:14:49 -08004769 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004770 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08004771 }
4772 }
4773 }
4774
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07004775 /**
4776 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
4777 * monitoring associated with this callback will be removed.
4778 */
Dianne Hackborn62878492019-03-11 15:57:07 -07004779 public void stopWatchingMode(@NonNull OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08004780 synchronized (mModeWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004781 IAppOpsCallback cb = mModeWatchers.remove(callback);
Dianne Hackbornc2293022013-02-06 23:14:49 -08004782 if (cb != null) {
4783 try {
4784 mService.stopWatchingMode(cb);
4785 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07004786 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08004787 }
4788 }
4789 }
4790 }
4791
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004792 /**
4793 * Start watching for changes to the active state of app ops. An app op may be
4794 * long running and it has a clear start and stop delimiters. If an op is being
4795 * started or stopped by any package you will get a callback. To change the
4796 * watched ops for a registered callback you need to unregister and register it
4797 * again.
4798 *
Svet Ganovf7b47252018-02-26 11:11:27 -08004799 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4800 * you can watch changes only for your UID.
4801 *
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004802 * @param ops The ops to watch.
4803 * @param callback Where to report changes.
4804 *
4805 * @see #isOperationActive(int, int, String)
4806 * @see #stopWatchingActive(OnOpActiveChangedListener)
4807 * @see #startOp(int, int, String)
4808 * @see #finishOp(int, int, String)
4809 *
4810 * @hide
4811 */
Svet Ganovf7b47252018-02-26 11:11:27 -08004812 @TestApi
4813 // TODO: Uncomment below annotation once b/73559440 is fixed
4814 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004815 public void startWatchingActive(@NonNull int[] ops,
4816 @NonNull OnOpActiveChangedListener callback) {
4817 Preconditions.checkNotNull(ops, "ops cannot be null");
4818 Preconditions.checkNotNull(callback, "callback cannot be null");
4819 IAppOpsActiveCallback cb;
4820 synchronized (mActiveWatchers) {
4821 cb = mActiveWatchers.get(callback);
4822 if (cb != null) {
4823 return;
4824 }
4825 cb = new IAppOpsActiveCallback.Stub() {
4826 @Override
4827 public void opActiveChanged(int op, int uid, String packageName, boolean active) {
4828 callback.onOpActiveChanged(op, uid, packageName, active);
4829 }
4830 };
4831 mActiveWatchers.put(callback, cb);
4832 }
4833 try {
4834 mService.startWatchingActive(ops, cb);
4835 } catch (RemoteException e) {
4836 throw e.rethrowFromSystemServer();
4837 }
4838 }
4839
4840 /**
4841 * Stop watching for changes to the active state of an app op. An app op may be
4842 * long running and it has a clear start and stop delimiters. Unregistering a
4843 * non-registered callback has no effect.
4844 *
4845 * @see #isOperationActive#(int, int, String)
4846 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
4847 * @see #startOp(int, int, String)
4848 * @see #finishOp(int, int, String)
4849 *
4850 * @hide
4851 */
Svet Ganovf7b47252018-02-26 11:11:27 -08004852 @TestApi
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004853 public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
4854 synchronized (mActiveWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004855 final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004856 if (cb != null) {
4857 try {
4858 mService.stopWatchingActive(cb);
4859 } catch (RemoteException e) {
4860 throw e.rethrowFromSystemServer();
4861 }
4862 }
4863 }
4864 }
4865
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004866 /**
4867 * Start watching for noted app ops. An app op may be immediate or long running.
4868 * Immediate ops are noted while long running ones are started and stopped. This
4869 * method allows registering a listener to be notified when an app op is noted. If
4870 * an op is being noted by any package you will get a callback. To change the
4871 * watched ops for a registered callback you need to unregister and register it again.
4872 *
4873 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
4874 * you can watch changes only for your UID.
4875 *
4876 * @param ops The ops to watch.
4877 * @param callback Where to report changes.
4878 *
4879 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
4880 * @see #stopWatchingNoted(OnOpNotedListener)
4881 * @see #noteOp(String, int, String)
4882 *
4883 * @hide
4884 */
4885 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004886 public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004887 IAppOpsNotedCallback cb;
4888 synchronized (mNotedWatchers) {
4889 cb = mNotedWatchers.get(callback);
4890 if (cb != null) {
4891 return;
4892 }
4893 cb = new IAppOpsNotedCallback.Stub() {
4894 @Override
4895 public void opNoted(int op, int uid, String packageName, int mode) {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004896 callback.onOpNoted(op, uid, packageName, mode);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004897 }
4898 };
4899 mNotedWatchers.put(callback, cb);
4900 }
4901 try {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004902 mService.startWatchingNoted(ops, cb);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004903 } catch (RemoteException e) {
4904 throw e.rethrowFromSystemServer();
4905 }
4906 }
4907
4908 /**
4909 * Stop watching for noted app ops. An app op may be immediate or long running.
4910 * Unregistering a non-registered callback has no effect.
4911 *
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004912 * @see #startWatchingNoted(int[], OnOpNotedListener)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004913 * @see #noteOp(String, int, String)
4914 *
4915 * @hide
4916 */
4917 public void stopWatchingNoted(@NonNull OnOpNotedListener callback) {
4918 synchronized (mNotedWatchers) {
4919 final IAppOpsNotedCallback cb = mNotedWatchers.get(callback);
4920 if (cb != null) {
4921 try {
4922 mService.stopWatchingNoted(cb);
4923 } catch (RemoteException e) {
4924 throw e.rethrowFromSystemServer();
4925 }
4926 }
4927 }
4928 }
4929
Dianne Hackborn95d78532013-09-11 09:51:14 -07004930 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
4931 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
4932 }
4933
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07004934 /**
4935 * {@hide}
4936 */
Artur Satayev5a525852019-10-31 15:15:50 +00004937 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07004938 @TestApi
Dianne Hackborn62878492019-03-11 15:57:07 -07004939 public static int strOpToOp(@NonNull String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004940 Integer val = sOpStrToOp.get(op);
4941 if (val == null) {
4942 throw new IllegalArgumentException("Unknown operation string: " + op);
4943 }
4944 return val;
4945 }
4946
4947 /**
4948 * Do a quick check for whether an application might be able to perform an operation.
4949 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String)}
4950 * or {@link #startOp(String, int, String)} for your actual security checks, which also
4951 * ensure that the given uid and package name are consistent. This function can just be
4952 * used for a quick check to see if an operation has been disabled for the application,
4953 * as an early reject of some work. This does not modify the time stamp or other data
4954 * about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07004955 *
4956 * <p>Important things this will not do (which you need to ultimate use
4957 * {@link #noteOp(String, int, String)} or {@link #startOp(String, int, String)} to cover):</p>
4958 * <ul>
4959 * <li>Verifying the uid and package are consistent, so callers can't spoof
4960 * their identity.</li>
4961 * <li>Taking into account the current foreground/background state of the
4962 * app; apps whose mode varies by this state will always be reported
4963 * as {@link #MODE_ALLOWED}.</li>
4964 * </ul>
4965 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004966 * @param op The operation to check. One of the OPSTR_* constants.
4967 * @param uid The user id of the application attempting to perform the operation.
4968 * @param packageName The name of the application attempting to perform the operation.
4969 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
4970 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
4971 * causing the app to crash).
4972 * @throws SecurityException If the app has been configured to crash on this op.
4973 */
Dianne Hackborn62878492019-03-11 15:57:07 -07004974 public int unsafeCheckOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07004975 return checkOp(strOpToOp(op), uid, packageName);
4976 }
4977
4978 /**
4979 * @deprecated Renamed to {@link #unsafeCheckOp(String, int, String)}.
4980 */
4981 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07004982 public int checkOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004983 return checkOp(strOpToOp(op), uid, packageName);
4984 }
4985
4986 /**
John Spurlock925b85e2014-03-10 16:52:11 -04004987 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004988 * returns {@link #MODE_ERRORED}.
4989 */
Dianne Hackborn62878492019-03-11 15:57:07 -07004990 public int unsafeCheckOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07004991 return checkOpNoThrow(strOpToOp(op), uid, packageName);
4992 }
4993
4994 /**
4995 * @deprecated Renamed to {@link #unsafeCheckOpNoThrow(String, int, String)}.
4996 */
4997 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07004998 public int checkOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004999 return checkOpNoThrow(strOpToOp(op), uid, packageName);
5000 }
5001
5002 /**
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005003 * Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op.
5004 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005005 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005006 public int unsafeCheckOpRaw(@NonNull String op, int uid, @NonNull String packageName) {
Svet Ganovaf189e32019-02-15 18:45:29 -08005007 try {
5008 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
5009 } catch (RemoteException e) {
5010 throw e.rethrowFromSystemServer();
5011 }
5012 }
5013
5014 /**
5015 * Like {@link #unsafeCheckOpNoThrow(String, int, String)} but returns the <em>raw</em>
5016 * mode associated with the op. Does not throw a security exception, does not translate
5017 * {@link #MODE_FOREGROUND}.
5018 */
5019 public int unsafeCheckOpRawNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005020 try {
Svet Ganov9d528a12018-12-19 17:23:11 -08005021 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005022 } catch (RemoteException e) {
5023 throw e.rethrowFromSystemServer();
5024 }
5025 }
5026
5027 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005028 * Make note of an application performing an operation. Note that you must pass
5029 * in both the uid and name of the application to be checked; this function will verify
5030 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5031 * succeeds, the last execution time of the operation for this app will be updated to
5032 * the current time.
5033 * @param op The operation to note. One of the OPSTR_* constants.
5034 * @param uid The user id of the application attempting to perform the operation.
5035 * @param packageName The name of the application attempting to perform the operation.
5036 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5037 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5038 * causing the app to crash).
5039 * @throws SecurityException If the app has been configured to crash on this op.
5040 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005041 public int noteOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005042 return noteOp(strOpToOp(op), uid, packageName);
5043 }
5044
5045 /**
5046 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
5047 * returns {@link #MODE_ERRORED}.
5048 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005049 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005050 return noteOpNoThrow(strOpToOp(op), uid, packageName);
5051 }
5052
5053 /**
Svet Ganov99b60432015-06-27 13:15:22 -07005054 * Make note of an application performing an operation on behalf of another
5055 * application when handling an IPC. Note that you must pass the package name
5056 * of the application that is being proxied while its UID will be inferred from
5057 * the IPC state; this function will verify that the calling uid and proxied
5058 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
5059 * succeeds, the last execution time of the operation for the proxied app and
5060 * your app will be updated to the current time.
5061 * @param op The operation to note. One of the OPSTR_* constants.
5062 * @param proxiedPackageName The name of the application calling into the proxy application.
5063 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5064 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5065 * causing the app to crash).
5066 * @throws SecurityException If the app has been configured to crash on this op.
5067 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005068 public int noteProxyOp(@NonNull String op, @NonNull String proxiedPackageName) {
Svet Ganov99b60432015-06-27 13:15:22 -07005069 return noteProxyOp(strOpToOp(op), proxiedPackageName);
5070 }
5071
5072 /**
5073 * Like {@link #noteProxyOp(String, String)} but instead
5074 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005075 *
5076 * <p>This API requires the package with the {@code proxiedPackageName} to belongs to
5077 * {@link Binder#getCallingUid()}.
Svet Ganov99b60432015-06-27 13:15:22 -07005078 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005079 public int noteProxyOpNoThrow(@NonNull String op, @NonNull String proxiedPackageName) {
Svet Ganov99b60432015-06-27 13:15:22 -07005080 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
5081 }
5082
5083 /**
Philip P. Moltmann78219312019-03-01 17:04:19 -08005084 * Like {@link #noteProxyOpNoThrow(String, String)} but allows to specify the proxied uid.
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005085 *
5086 * <p>This API requires package with the {@code proxiedPackageName} to belong to
5087 * {@code proxiedUid}.
5088 *
5089 * @param op The op to note
5090 * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
5091 * noted for the "android" package
5092 * @param proxiedUid The uid the package belongs to
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005093 */
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005094 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
5095 int proxiedUid) {
5096 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid);
5097 }
5098
5099 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005100 * Report that an application has started executing a long-running operation. Note that you
5101 * must pass in both the uid and name of the application to be checked; this function will
5102 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5103 * succeeds, the last execution time of the operation for this app will be updated to
5104 * the current time and the operation will be marked as "running". In this case you must
5105 * later call {@link #finishOp(String, int, String)} to report when the application is no
5106 * longer performing the operation.
5107 * @param op The operation to start. One of the OPSTR_* constants.
5108 * @param uid The user id of the application attempting to perform the operation.
5109 * @param packageName The name of the application attempting to perform the operation.
5110 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5111 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5112 * causing the app to crash).
5113 * @throws SecurityException If the app has been configured to crash on this op.
5114 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005115 public int startOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005116 return startOp(strOpToOp(op), uid, packageName);
5117 }
5118
5119 /**
5120 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
5121 * returns {@link #MODE_ERRORED}.
5122 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005123 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005124 return startOpNoThrow(strOpToOp(op), uid, packageName);
5125 }
5126
5127 /**
5128 * Report that an application is no longer performing an operation that had previously
5129 * been started with {@link #startOp(String, int, String)}. There is no validation of input
5130 * or result; the parameters supplied here must be the exact same ones previously passed
5131 * in when starting the operation.
5132 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005133 public void finishOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005134 finishOp(strOpToOp(op), uid, packageName);
5135 }
5136
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005137 /**
5138 * Do a quick check for whether an application might be able to perform an operation.
5139 * This is <em>not</em> a security check; you must use {@link #noteOp(int, int, String)}
5140 * or {@link #startOp(int, int, String)} for your actual security checks, which also
5141 * ensure that the given uid and package name are consistent. This function can just be
5142 * used for a quick check to see if an operation has been disabled for the application,
5143 * as an early reject of some work. This does not modify the time stamp or other data
5144 * about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07005145 *
5146 * <p>Important things this will not do (which you need to ultimate use
5147 * {@link #noteOp(int, int, String)} or {@link #startOp(int, int, String)} to cover):</p>
5148 * <ul>
5149 * <li>Verifying the uid and package are consistent, so callers can't spoof
5150 * their identity.</li>
5151 * <li>Taking into account the current foreground/background state of the
5152 * app; apps whose mode varies by this state will always be reported
5153 * as {@link #MODE_ALLOWED}.</li>
5154 * </ul>
5155 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005156 * @param op The operation to check. One of the OP_* constants.
5157 * @param uid The user id of the application attempting to perform the operation.
5158 * @param packageName The name of the application attempting to perform the operation.
5159 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5160 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5161 * causing the app to crash).
5162 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005163 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005164 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005165 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08005166 public int checkOp(int op, int uid, String packageName) {
5167 try {
5168 int mode = mService.checkOperation(op, uid, packageName);
5169 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07005170 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08005171 }
5172 return mode;
5173 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005174 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08005175 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08005176 }
5177
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005178 /**
5179 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
5180 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005181 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005182 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005183 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08005184 public int checkOpNoThrow(int op, int uid, String packageName) {
5185 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005186 int mode = mService.checkOperation(op, uid, packageName);
5187 return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08005188 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005189 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08005190 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08005191 }
5192
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005193 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07005194 * Do a quick check to validate if a package name belongs to a UID.
5195 *
5196 * @throws SecurityException if the package name doesn't belong to the given
5197 * UID, or if ownership cannot be verified.
5198 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005199 public void checkPackage(int uid, @NonNull String packageName) {
Jeff Sharkey911d7f42013-09-05 18:11:45 -07005200 try {
5201 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
5202 throw new SecurityException(
5203 "Package " + packageName + " does not belong to " + uid);
5204 }
5205 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005206 throw e.rethrowFromSystemServer();
Jeff Sharkey911d7f42013-09-05 18:11:45 -07005207 }
5208 }
5209
5210 /**
John Spurlock1af30c72014-03-10 08:33:35 -04005211 * Like {@link #checkOp} but at a stream-level for audio operations.
5212 * @hide
5213 */
5214 public int checkAudioOp(int op, int stream, int uid, String packageName) {
5215 try {
5216 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
5217 if (mode == MODE_ERRORED) {
5218 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
5219 }
5220 return mode;
5221 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005222 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04005223 }
John Spurlock1af30c72014-03-10 08:33:35 -04005224 }
5225
5226 /**
5227 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
5228 * returns {@link #MODE_ERRORED}.
5229 * @hide
5230 */
5231 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
5232 try {
5233 return mService.checkAudioOperation(op, stream, uid, packageName);
5234 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005235 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04005236 }
John Spurlock1af30c72014-03-10 08:33:35 -04005237 }
5238
5239 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005240 * Make note of an application performing an operation. Note that you must pass
5241 * in both the uid and name of the application to be checked; this function will verify
5242 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5243 * succeeds, the last execution time of the operation for this app will be updated to
5244 * the current time.
5245 * @param op The operation to note. One of the OP_* constants.
5246 * @param uid The user id of the application attempting to perform the operation.
5247 * @param packageName The name of the application attempting to perform the operation.
5248 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5249 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5250 * causing the app to crash).
5251 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005252 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005253 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005254 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005255 public int noteOp(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08005256 final int mode = noteOpNoThrow(op, uid, packageName);
5257 if (mode == MODE_ERRORED) {
5258 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005259 }
Svet Ganovf7b47252018-02-26 11:11:27 -08005260 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005261 }
5262
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005263 /**
Svet Ganov99b60432015-06-27 13:15:22 -07005264 * Make note of an application performing an operation on behalf of another
5265 * application when handling an IPC. Note that you must pass the package name
5266 * of the application that is being proxied while its UID will be inferred from
5267 * the IPC state; this function will verify that the calling uid and proxied
5268 * package name match, and if not, return {@link #MODE_IGNORED}. If this call
5269 * succeeds, the last execution time of the operation for the proxied app and
5270 * your app will be updated to the current time.
5271 * @param op The operation to note. One of the OPSTR_* constants.
5272 * @param proxiedPackageName The name of the application calling into the proxy application.
5273 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5274 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5275 * causing the app to crash).
5276 * @throws SecurityException If the proxy or proxied app has been configured to
5277 * crash on this op.
5278 *
5279 * @hide
5280 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005281 @UnsupportedAppUsage
Svet Ganov99b60432015-06-27 13:15:22 -07005282 public int noteProxyOp(int op, String proxiedPackageName) {
5283 int mode = noteProxyOpNoThrow(op, proxiedPackageName);
5284 if (mode == MODE_ERRORED) {
5285 throw new SecurityException("Proxy package " + mContext.getOpPackageName()
5286 + " from uid " + Process.myUid() + " or calling package "
5287 + proxiedPackageName + " from uid " + Binder.getCallingUid()
5288 + " not allowed to perform " + sOpNames[op]);
5289 }
5290 return mode;
5291 }
5292
5293 /**
5294 * Like {@link #noteProxyOp(int, String)} but instead
5295 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
5296 * @hide
5297 */
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005298 public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) {
Svet Ganov99b60432015-06-27 13:15:22 -07005299 try {
Svet Ganovd873ae62018-06-25 16:39:23 -07005300 return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005301 proxiedUid, proxiedPackageName);
Svet Ganov99b60432015-06-27 13:15:22 -07005302 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005303 throw e.rethrowFromSystemServer();
Svet Ganov99b60432015-06-27 13:15:22 -07005304 }
Svet Ganov99b60432015-06-27 13:15:22 -07005305 }
5306
5307 /**
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005308 * Like {@link #noteProxyOp(int, String)} but instead
5309 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
5310 *
5311 * <p>This API requires the package with {@code proxiedPackageName} to belongs to
5312 * {@link Binder#getCallingUid()}.
5313 *
5314 * @hide
5315 */
5316 public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
5317 return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid());
5318 }
5319
5320 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005321 * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
5322 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005323 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005324 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005325 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005326 public int noteOpNoThrow(int op, int uid, String packageName) {
5327 try {
5328 return mService.noteOperation(op, uid, packageName);
5329 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005330 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005331 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005332 }
5333
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005334 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005335 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005336 public int noteOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07005337 return noteOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005338 }
5339
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005340 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005341 @UnsupportedAppUsage
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005342 public static IBinder getToken(IAppOpsService service) {
5343 synchronized (AppOpsManager.class) {
5344 if (sToken != null) {
5345 return sToken;
5346 }
5347 try {
5348 sToken = service.getToken(new Binder());
5349 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005350 throw e.rethrowFromSystemServer();
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005351 }
5352 return sToken;
5353 }
5354 }
5355
Svet Ganovf7b47252018-02-26 11:11:27 -08005356 /** @hide */
5357 public int startOp(int op) {
5358 return startOp(op, Process.myUid(), mContext.getOpPackageName());
5359 }
5360
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005361 /**
5362 * Report that an application has started executing a long-running operation. Note that you
5363 * must pass in both the uid and name of the application to be checked; this function will
5364 * verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5365 * succeeds, the last execution time of the operation for this app will be updated to
5366 * the current time and the operation will be marked as "running". In this case you must
5367 * later call {@link #finishOp(int, int, String)} to report when the application is no
5368 * longer performing the operation.
Svet Ganovf7b47252018-02-26 11:11:27 -08005369 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005370 * @param op The operation to start. One of the OP_* constants.
5371 * @param uid The user id of the application attempting to perform the operation.
5372 * @param packageName The name of the application attempting to perform the operation.
5373 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5374 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5375 * causing the app to crash).
5376 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005377 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005378 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005379 public int startOp(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08005380 return startOp(op, uid, packageName, false);
5381 }
5382
5383 /**
5384 * Report that an application has started executing a long-running operation. Similar
5385 * to {@link #startOp(String, int, String) except that if the mode is {@link #MODE_DEFAULT}
5386 * the operation should succeed since the caller has performed its standard permission
5387 * checks which passed and would perform the protected operation for this mode.
5388 *
5389 * @param op The operation to start. One of the OP_* constants.
5390 * @param uid The user id of the application attempting to perform the operation.
5391 * @param packageName The name of the application attempting to perform the operation.
5392 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5393 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5394 * causing the app to crash).
5395 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
5396 *
5397 * @throws SecurityException If the app has been configured to crash on this op or
5398 * the package is not in the passed in UID.
5399 *
5400 * @hide
5401 */
5402 public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
5403 final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault);
5404 if (mode == MODE_ERRORED) {
5405 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005406 }
Svet Ganovf7b47252018-02-26 11:11:27 -08005407 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005408 }
5409
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005410 /**
5411 * Like {@link #startOp} but instead of throwing a {@link SecurityException} it
5412 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005413 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005414 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005415 public int startOpNoThrow(int op, int uid, String packageName) {
Svet Ganovf7b47252018-02-26 11:11:27 -08005416 return startOpNoThrow(op, uid, packageName, false);
5417 }
5418
5419 /**
5420 * Like {@link #startOp(int, int, String, boolean)} but instead of throwing a
5421 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
5422 *
5423 * @param op The operation to start. One of the OP_* constants.
5424 * @param uid The user id of the application attempting to perform the operation.
5425 * @param packageName The name of the application attempting to perform the operation.
5426 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5427 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5428 * causing the app to crash).
5429 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
5430 *
5431 * @hide
5432 */
5433 public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005434 try {
Svet Ganovf7b47252018-02-26 11:11:27 -08005435 return mService.startOperation(getToken(mService), op, uid, packageName,
5436 startIfModeDefault);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005437 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005438 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005439 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005440 }
5441
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005442 /**
5443 * Report that an application is no longer performing an operation that had previously
5444 * been started with {@link #startOp(int, int, String)}. There is no validation of input
5445 * or result; the parameters supplied here must be the exact same ones previously passed
5446 * in when starting the operation.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005447 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005448 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005449 public void finishOp(int op, int uid, String packageName) {
5450 try {
Dianne Hackborne98f5db2013-07-17 17:23:25 -07005451 mService.finishOperation(getToken(mService), op, uid, packageName);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005452 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005453 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005454 }
5455 }
5456
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005457 /** @hide */
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005458 public void finishOp(int op) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07005459 finishOp(op, Process.myUid(), mContext.getOpPackageName());
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005460 }
Jeff Sharkey35e46d22017-06-09 10:01:20 -06005461
Svet Ganovf7b47252018-02-26 11:11:27 -08005462 /**
5463 * Checks whether the given op for a UID and package is active.
5464 *
5465 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
5466 * you can query only for your UID.
5467 *
5468 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
5469 * @see #stopWatchingMode(OnOpChangedListener)
5470 * @see #finishOp(int)
5471 * @see #startOp(int)
5472 *
5473 * @hide */
5474 @TestApi
5475 // TODO: Uncomment below annotation once b/73559440 is fixed
5476 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey35e46d22017-06-09 10:01:20 -06005477 public boolean isOperationActive(int code, int uid, String packageName) {
5478 try {
5479 return mService.isOperationActive(code, uid, packageName);
5480 } catch (RemoteException e) {
5481 throw e.rethrowFromSystemServer();
5482 }
5483 }
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00005484
5485 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005486 * Configures the app ops persistence for testing.
5487 *
5488 * @param mode The mode in which the historical registry operates.
5489 * @param baseSnapshotInterval The base interval on which we would be persisting a snapshot of
5490 * the historical data. The history is recursive where every subsequent step encompasses
5491 * {@code compressionStep} longer interval with {@code compressionStep} distance between
5492 * snapshots.
5493 * @param compressionStep The compression step in every iteration.
5494 *
5495 * @see #HISTORICAL_MODE_DISABLED
5496 * @see #HISTORICAL_MODE_ENABLED_ACTIVE
5497 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
5498 *
5499 * @hide
5500 */
5501 @TestApi
5502 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5503 public void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval,
5504 int compressionStep) {
5505 try {
5506 mService.setHistoryParameters(mode, baseSnapshotInterval, compressionStep);
5507 } catch (RemoteException e) {
5508 throw e.rethrowFromSystemServer();
5509 }
5510 }
5511
5512 /**
5513 * Offsets the history by the given duration.
5514 *
5515 * @param offsetMillis The offset duration.
5516 *
5517 * @hide
5518 */
5519 @TestApi
5520 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5521 public void offsetHistory(long offsetMillis) {
5522 try {
5523 mService.offsetHistory(offsetMillis);
5524 } catch (RemoteException e) {
5525 throw e.rethrowFromSystemServer();
5526 }
5527 }
5528
5529 /**
5530 * Adds ops to the history directly. This could be useful for testing especially
5531 * when the historical registry operates in {@link #HISTORICAL_MODE_ENABLED_PASSIVE}
5532 * mode.
5533 *
5534 * @param ops The ops to add to the history.
5535 *
5536 * @see #setHistoryParameters(int, long, int)
5537 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
5538 *
5539 * @hide
5540 */
5541 @TestApi
5542 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5543 public void addHistoricalOps(@NonNull HistoricalOps ops) {
5544 try {
5545 mService.addHistoricalOps(ops);
5546 } catch (RemoteException e) {
5547 throw e.rethrowFromSystemServer();
5548 }
5549 }
5550
5551 /**
5552 * Resets the app ops persistence for testing.
5553 *
5554 * @see #setHistoryParameters(int, long, int)
5555 *
5556 * @hide
5557 */
5558 @TestApi
5559 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5560 public void resetHistoryParameters() {
5561 try {
5562 mService.resetHistoryParameters();
5563 } catch (RemoteException e) {
5564 throw e.rethrowFromSystemServer();
5565 }
5566 }
5567
5568 /**
5569 * Clears all app ops history.
5570 *
5571 * @hide
5572 */
5573 @TestApi
5574 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5575 public void clearHistory() {
5576 try {
5577 mService.clearHistory();
5578 } catch (RemoteException e) {
5579 throw e.rethrowFromSystemServer();
5580 }
5581 }
5582
5583 /**
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00005584 * Returns all supported operation names.
5585 * @hide
5586 */
5587 @SystemApi
5588 @TestApi
5589 public static String[] getOpStrs() {
5590 return Arrays.copyOf(sOpToString, sOpToString.length);
5591 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07005592
Philip P. Moltmann24576812018-05-07 10:42:05 -07005593
5594 /**
5595 * @return number of App ops
5596 * @hide
5597 */
5598 @TestApi
5599 public static int getNumOps() {
5600 return _NUM_OP;
5601 }
5602
Dianne Hackbornc216a262018-04-26 13:46:22 -07005603 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08005604 * Computes the max for the given flags in between the begin and
5605 * end UID states.
5606 *
5607 * @param counts The data array.
5608 * @param flags The UID flags.
5609 * @param beginUidState The beginning UID state (exclusive).
5610 * @param endUidState The end UID state.
5611 * @return The sum.
Dianne Hackbornc216a262018-04-26 13:46:22 -07005612 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005613 private static long maxForFlagsInStates(@Nullable LongSparseLongArray counts,
5614 @UidState int beginUidState, @UidState int endUidState,
5615 @OpFlags int flags) {
5616 if (counts == null) {
5617 return 0;
5618 }
5619 long max = 0;
5620 while (flags != 0) {
5621 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
5622 flags &= ~flag;
5623 for (int uidState : UID_STATES) {
5624 if (uidState < beginUidState || uidState > endUidState) {
5625 continue;
5626 }
5627 final long key = makeKey(uidState, flag);
5628 max = Math.max(max, counts.get(key));
Dianne Hackbornc216a262018-04-26 13:46:22 -07005629 }
5630 }
Svet Ganovaf189e32019-02-15 18:45:29 -08005631 return max;
5632 }
5633
5634
5635 private static void writeLongSparseLongArrayToParcel(
5636 @Nullable LongSparseLongArray array, @NonNull Parcel parcel) {
5637 if (array != null) {
5638 final int size = array.size();
5639 parcel.writeInt(size);
5640 for (int i = 0; i < size; i++) {
5641 parcel.writeLong(array.keyAt(i));
5642 parcel.writeLong(array.valueAt(i));
5643 }
5644 } else {
5645 parcel.writeInt(-1);
5646 }
5647 }
5648
5649 private static @Nullable LongSparseLongArray readLongSparseLongArrayFromParcel(
5650 @NonNull Parcel parcel) {
5651 final int size = parcel.readInt();
5652 if (size < 0) {
5653 return null;
5654 }
5655 final LongSparseLongArray array = new LongSparseLongArray(size);
5656 for (int i = 0; i < size; i++) {
5657 array.append(parcel.readLong(), parcel.readLong());
5658 }
5659 return array;
5660 }
5661
5662 private static void writeLongSparseStringArrayToParcel(
5663 @Nullable LongSparseArray<String> array, @NonNull Parcel parcel) {
5664 if (array != null) {
5665 final int size = array.size();
5666 parcel.writeInt(size);
5667 for (int i = 0; i < size; i++) {
5668 parcel.writeLong(array.keyAt(i));
5669 parcel.writeString(array.valueAt(i));
5670 }
5671 } else {
5672 parcel.writeInt(-1);
5673 }
5674 }
5675
5676 private static @Nullable LongSparseArray<String> readLongSparseStringArrayFromParcel(
5677 @NonNull Parcel parcel) {
5678 final int size = parcel.readInt();
5679 if (size < 0) {
5680 return null;
5681 }
5682 final LongSparseArray<String> array = new LongSparseArray<>(size);
5683 for (int i = 0; i < size; i++) {
5684 array.append(parcel.readLong(), parcel.readString());
5685 }
5686 return array;
5687 }
5688
5689 /**
5690 * Collects the keys from an array to the result creating the result if needed.
5691 *
5692 * @param array The array whose keys to collect.
5693 * @param result The optional result store collected keys.
5694 * @return The result collected keys array.
5695 */
5696 private static LongSparseArray<Object> collectKeys(@Nullable LongSparseLongArray array,
5697 @Nullable LongSparseArray<Object> result) {
5698 if (array != null) {
5699 if (result == null) {
5700 result = new LongSparseArray<>();
5701 }
5702 final int accessSize = array.size();
5703 for (int i = 0; i < accessSize; i++) {
5704 result.put(array.keyAt(i), null);
5705 }
5706 }
5707 return result;
Dianne Hackbornc216a262018-04-26 13:46:22 -07005708 }
Svet Ganov8455ba22019-01-02 13:05:56 -08005709
5710 /** @hide */
5711 public static String uidStateToString(@UidState int uidState) {
5712 switch (uidState) {
5713 case UID_STATE_PERSISTENT: {
5714 return "UID_STATE_PERSISTENT";
5715 }
5716 case UID_STATE_TOP: {
5717 return "UID_STATE_TOP";
5718 }
Amith Yamasania0a30a12019-01-22 11:38:06 -08005719 case UID_STATE_FOREGROUND_SERVICE_LOCATION: {
5720 return "UID_STATE_FOREGROUND_SERVICE_LOCATION";
5721 }
Svet Ganov8455ba22019-01-02 13:05:56 -08005722 case UID_STATE_FOREGROUND_SERVICE: {
5723 return "UID_STATE_FOREGROUND_SERVICE";
5724 }
5725 case UID_STATE_FOREGROUND: {
5726 return "UID_STATE_FOREGROUND";
5727 }
5728 case UID_STATE_BACKGROUND: {
5729 return "UID_STATE_BACKGROUND";
5730 }
5731 case UID_STATE_CACHED: {
5732 return "UID_STATE_CACHED";
5733 }
5734 default: {
5735 return "UNKNOWN";
5736 }
5737 }
5738 }
5739
5740 /** @hide */
5741 public static int parseHistoricalMode(@NonNull String mode) {
5742 switch (mode) {
5743 case "HISTORICAL_MODE_ENABLED_ACTIVE": {
5744 return HISTORICAL_MODE_ENABLED_ACTIVE;
5745 }
5746 case "HISTORICAL_MODE_ENABLED_PASSIVE": {
5747 return HISTORICAL_MODE_ENABLED_PASSIVE;
5748 }
5749 default: {
5750 return HISTORICAL_MODE_DISABLED;
5751 }
5752 }
5753 }
5754
5755 /** @hide */
5756 public static String historicalModeToString(@HistoricalMode int mode) {
5757 switch (mode) {
5758 case HISTORICAL_MODE_DISABLED: {
5759 return "HISTORICAL_MODE_DISABLED";
5760 }
5761 case HISTORICAL_MODE_ENABLED_ACTIVE: {
5762 return "HISTORICAL_MODE_ENABLED_ACTIVE";
5763 }
5764 case HISTORICAL_MODE_ENABLED_PASSIVE: {
5765 return "HISTORICAL_MODE_ENABLED_PASSIVE";
5766 }
5767 default: {
5768 return "UNKNOWN";
5769 }
5770 }
5771 }
Ng Zhi An65a99b62018-10-01 11:57:53 -07005772
5773 private static int getSystemAlertWindowDefault() {
5774 final Context context = ActivityThread.currentApplication();
5775 if (context == null) {
5776 return AppOpsManager.MODE_DEFAULT;
5777 }
5778
5779 // system alert window is disable on low ram phones starting from Q
5780 final PackageManager pm = context.getPackageManager();
5781 // TVs are constantly plugged in and has less concern for memory/power
5782 if (ActivityManager.isLowRamDeviceStatic()
5783 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) {
5784 return AppOpsManager.MODE_IGNORED;
5785 }
5786
5787 return AppOpsManager.MODE_DEFAULT;
5788 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005789}