blob: f2fa4fd6845c4ddcc3d8698c3411ea14deca867c [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;
Jeff Sharkey7095ab92019-08-20 16:50:28 -060020import android.annotation.CallbackExecutor;
Svet Ganovad0a49b2018-10-29 10:07:08 -070021import android.annotation.IntDef;
Svet Ganov00a46ef2019-03-29 21:13:03 -070022import android.annotation.IntRange;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080023import android.annotation.NonNull;
Hai Zhangb7776682018-09-25 15:10:57 -070024import android.annotation.Nullable;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060025import android.annotation.RequiresPermission;
Jeff Davidson05542602014-08-11 14:07:27 -070026import android.annotation.SystemApi;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060027import android.annotation.SystemService;
Peter Visontay5a2a1ef2017-12-18 20:34:03 +000028import android.annotation.TestApi;
Mathew Inwood61e8ae62018-08-14 14:17:44 +010029import android.annotation.UnsupportedAppUsage;
Jeff Davidson05542602014-08-11 14:07:27 -070030import android.app.usage.UsageStatsManager;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070031import android.content.ContentResolver;
Jeff Davidson05542602014-08-11 14:07:27 -070032import android.content.Context;
Ng Zhi An65a99b62018-10-01 11:57:53 -070033import android.content.pm.PackageManager;
Svet Ganovad0a49b2018-10-29 10:07:08 -070034import android.content.pm.ParceledListSlice;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070035import android.database.DatabaseUtils;
John Spurlock7b414672014-07-18 13:02:39 -040036import android.media.AudioAttributes.AttributeUsage;
Dianne Hackborne98f5db2013-07-17 17:23:25 -070037import android.os.Binder;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070038import android.os.Build;
39import android.os.Handler;
40import android.os.HandlerExecutor;
41import android.os.HandlerThread;
Dianne Hackborne98f5db2013-07-17 17:23:25 -070042import android.os.IBinder;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070043import android.os.Looper;
Dianne Hackborn35654b62013-01-14 17:38:02 -080044import android.os.Parcel;
45import android.os.Parcelable;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080046import android.os.Process;
Svet Ganov8455ba22019-01-02 13:05:56 -080047import android.os.RemoteCallback;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080048import android.os.RemoteException;
Jeff Davidson05542602014-08-11 14:07:27 -070049import android.os.UserManager;
50import android.util.ArrayMap;
Svet Ganovaf189e32019-02-15 18:45:29 -080051import android.util.LongSparseArray;
52import android.util.LongSparseLongArray;
Philip P. Moltmann59076d82019-08-19 15:00:40 -070053import android.util.Pair;
Ng Zhi An65a99b62018-10-01 11:57:53 -070054import android.util.SparseArray;
Jeff Davidson05542602014-08-11 14:07:27 -070055
Svet Ganovb3d2ae22018-12-17 22:06:15 -080056import com.android.internal.annotations.GuardedBy;
Svet Ganov23c88db2019-01-22 20:38:11 -080057import com.android.internal.annotations.Immutable;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080058import com.android.internal.app.IAppOpsActiveCallback;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070059import com.android.internal.app.IAppOpsAsyncNotedCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070060import com.android.internal.app.IAppOpsCallback;
Svet Ganovb3d2ae22018-12-17 22:06:15 -080061import com.android.internal.app.IAppOpsNotedCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070062import com.android.internal.app.IAppOpsService;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070063import com.android.internal.os.RuntimeInit;
64import com.android.internal.os.ZygoteInit;
Svet Ganov8455ba22019-01-02 13:05:56 -080065import com.android.internal.util.ArrayUtils;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080066import com.android.internal.util.Preconditions;
Jeff Davidson05542602014-08-11 14:07:27 -070067
Svet Ganovaf189e32019-02-15 18:45:29 -080068import java.lang.annotation.ElementType;
Svet Ganovad0a49b2018-10-29 10:07:08 -070069import java.lang.annotation.Retention;
70import java.lang.annotation.RetentionPolicy;
Svet Ganovaf189e32019-02-15 18:45:29 -080071import java.lang.annotation.Target;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070072import java.lang.reflect.Method;
Svet Ganov8455ba22019-01-02 13:05:56 -080073import java.math.BigDecimal;
74import java.math.RoundingMode;
Jeff Davidson05542602014-08-11 14:07:27 -070075import java.util.ArrayList;
Peter Visontay5a2a1ef2017-12-18 20:34:03 +000076import java.util.Arrays;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070077import java.util.BitSet;
Svet Ganovad0a49b2018-10-29 10:07:08 -070078import java.util.Collections;
Jeff Davidson05542602014-08-11 14:07:27 -070079import java.util.HashMap;
80import java.util.List;
Philip P. Moltmann59076d82019-08-19 15:00:40 -070081import java.util.Map;
Svet Ganovaf189e32019-02-15 18:45:29 -080082import java.util.Objects;
Svet Ganov8455ba22019-01-02 13:05:56 -080083import java.util.concurrent.Executor;
84import java.util.function.Consumer;
Svet Ganovaf189e32019-02-15 18:45:29 -080085import java.util.function.Supplier;
Philip P. Moltmann59076d82019-08-19 15:00:40 -070086import java.util.function.ToLongFunction;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080087
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080088/**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070089 * API for interacting with "application operation" tracking.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080090 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070091 * <p>This API is not generally intended for third party application developers; most
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060092 * features are only available to system applications.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080093 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060094@SystemService(Context.APP_OPS_SERVICE)
Dianne Hackborna06de0f2012-12-11 16:34:47 -080095public class AppOpsManager {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070096 /**
97 * <p>App ops allows callers to:</p>
98 *
99 * <ul>
100 * <li> Note when operations are happening, and find out if they are allowed for the current
101 * caller.</li>
102 * <li> Disallow specific apps from doing specific operations.</li>
103 * <li> Collect all of the current information about operations that have been executed or
104 * are not being allowed.</li>
105 * <li> Monitor for changes in whether an operation is allowed.</li>
106 * </ul>
107 *
108 * <p>Each operation is identified by a single integer; these integers are a fixed set of
109 * operations, enumerated by the OP_* constants.
110 *
111 * <p></p>When checking operations, the result is a "mode" integer indicating the current
112 * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
113 * the operation but fake its behavior enough so that the caller doesn't crash),
114 * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
115 * will do this for you).
116 */
117
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800118 final Context mContext;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800119
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100120 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800121 final IAppOpsService mService;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800122
123 @GuardedBy("mModeWatchers")
124 private final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers =
125 new ArrayMap<>();
126
127 @GuardedBy("mActiveWatchers")
128 private final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers =
129 new ArrayMap<>();
130
131 @GuardedBy("mNotedWatchers")
132 private final ArrayMap<OnOpNotedListener, IAppOpsNotedCallback> mNotedWatchers =
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -0800133 new ArrayMap<>();
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800134
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -0700135 private static final Object sLock = new Object();
136
137 /** Current {@link AppOpsCollector}. Change via {@link #setNotedAppOpsCollector} */
138 @GuardedBy("sLock")
139 private static @Nullable AppOpsCollector sNotedAppOpsCollector;
140
Dianne Hackborne98f5db2013-07-17 17:23:25 -0700141 static IBinder sToken;
142
Svet Ganov8455ba22019-01-02 13:05:56 -0800143 /** @hide */
144 @Retention(RetentionPolicy.SOURCE)
145 @IntDef(flag = true, prefix = { "HISTORICAL_MODE_" }, value = {
146 HISTORICAL_MODE_DISABLED,
147 HISTORICAL_MODE_ENABLED_ACTIVE,
148 HISTORICAL_MODE_ENABLED_PASSIVE
149 })
150 public @interface HistoricalMode {}
151
152 /**
153 * Mode in which app op history is completely disabled.
154 * @hide
155 */
156 @TestApi
157 public static final int HISTORICAL_MODE_DISABLED = 0;
158
159 /**
160 * Mode in which app op history is enabled and app ops performed by apps would
161 * be tracked. This is the mode in which the feature is completely enabled.
162 * @hide
163 */
164 @TestApi
165 public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1;
166
167 /**
168 * Mode in which app op history is enabled but app ops performed by apps would
169 * not be tracked and the only way to add ops to the history is via explicit calls
170 * to dedicated APIs. This mode is useful for testing to allow full control of
171 * the historical content.
172 * @hide
173 */
174 @TestApi
175 public static final int HISTORICAL_MODE_ENABLED_PASSIVE = 2;
176
177 /** @hide */
178 @Retention(RetentionPolicy.SOURCE)
179 @IntDef(flag = true, prefix = { "MODE_" }, value = {
180 MODE_ALLOWED,
181 MODE_IGNORED,
182 MODE_ERRORED,
183 MODE_DEFAULT,
184 MODE_FOREGROUND
185 })
186 public @interface Mode {}
187
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700188 /**
189 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
190 * allowed to perform the given operation.
191 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800192 public static final int MODE_ALLOWED = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700193
194 /**
195 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
196 * not allowed to perform the given operation, and this attempt should
197 * <em>silently fail</em> (it should not cause the app to crash).
198 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800199 public static final int MODE_IGNORED = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700200
201 /**
202 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
203 * given caller is not allowed to perform the given operation, and this attempt should
204 * cause it to have a fatal error, typically a {@link SecurityException}.
205 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800206 public static final int MODE_ERRORED = 2;
207
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -0700208 /**
209 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
210 * use its default security check. This mode is not normally used; it should only be used
211 * with appop permissions, and callers must explicitly check for it and deal with it.
212 */
213 public static final int MODE_DEFAULT = 3;
214
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700215 /**
Dianne Hackbornc216a262018-04-26 13:46:22 -0700216 * Special mode that means "allow only when app is in foreground." This is <b>not</b>
Dianne Hackbornf8709f52019-02-04 16:31:24 -0800217 * returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}. Rather,
218 * {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always
219 * possible for it to be ultimately allowed, depending on the app's background state),
220 * and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app
221 * being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}.
222 *
223 * <p>The only place you will this normally see this value is through
224 * {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op. Note that because
225 * you can't know the current state of the app being checked (and it can change at any
226 * point), you can only treat the result here as an indication that it will vary between
227 * {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background
228 * state of the app. You thus must always use {@link #noteOp} or {@link #startOp} to do
229 * the actual check for access to the op.</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -0700230 */
231 public static final int MODE_FOREGROUND = 4;
232
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700233 /**
234 * Flag for {@link #startWatchingMode(String, String, int, OnOpChangedListener)}:
235 * Also get reports if the foreground state of an op's uid changes. This only works
236 * when watching a particular op, not when watching a package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700237 */
238 public static final int WATCH_FOREGROUND_CHANGES = 1 << 0;
Dianne Hackbornc216a262018-04-26 13:46:22 -0700239
240 /**
241 * @hide
242 */
243 public static final String[] MODE_NAMES = new String[] {
244 "allow", // MODE_ALLOWED
245 "ignore", // MODE_IGNORED
246 "deny", // MODE_ERRORED
247 "default", // MODE_DEFAULT
248 "foreground", // MODE_FOREGROUND
249 };
250
Svet Ganovad0a49b2018-10-29 10:07:08 -0700251 /** @hide */
252 @Retention(RetentionPolicy.SOURCE)
Svet Ganovaf189e32019-02-15 18:45:29 -0800253 @IntDef(prefix = { "UID_STATE_" }, value = {
Svet Ganovad0a49b2018-10-29 10:07:08 -0700254 UID_STATE_PERSISTENT,
255 UID_STATE_TOP,
Amith Yamasania0a30a12019-01-22 11:38:06 -0800256 UID_STATE_FOREGROUND_SERVICE_LOCATION,
Svet Ganovad0a49b2018-10-29 10:07:08 -0700257 UID_STATE_FOREGROUND_SERVICE,
258 UID_STATE_FOREGROUND,
259 UID_STATE_BACKGROUND,
260 UID_STATE_CACHED
261 })
262 public @interface UidState {}
263
Dianne Hackbornc216a262018-04-26 13:46:22 -0700264 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700265 * Uid state: The UID is a foreground persistent app. The lower the UID
266 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700267 * @hide
268 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800269 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700270 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800271 public static final int UID_STATE_PERSISTENT = 100;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700272
273 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700274 * Uid state: The UID is top foreground app. The lower the UID
275 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700276 * @hide
277 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800278 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700279 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800280 public static final int UID_STATE_TOP = 200;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700281
282 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800283 * Uid state: The UID is running a foreground service of location type.
Svet Ganov05fcd222019-07-08 16:30:45 -0700284 * The lower the UID state the more important the UID is for the user.
Hui Yu26969322019-08-21 14:56:35 -0700285 * This uid state is a counterpart to PROCESS_STATE_FOREGROUND_SERVICE_LOCATION which has been
286 * deprecated.
Amith Yamasania0a30a12019-01-22 11:38:06 -0800287 * @hide
Hui Yu26969322019-08-21 14:56:35 -0700288 * @deprecated
Amith Yamasania0a30a12019-01-22 11:38:06 -0800289 */
290 @TestApi
291 @SystemApi
Hui Yu26969322019-08-21 14:56:35 -0700292 @Deprecated
Svet Ganovaf189e32019-02-15 18:45:29 -0800293 public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800294
295 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700296 * Uid state: The UID is running a foreground service. The lower the UID
297 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700298 * @hide
299 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800300 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700301 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800302 public static final int UID_STATE_FOREGROUND_SERVICE = 400;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700303
304 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700305 * Uid state: The UID is a foreground app. The lower the UID
306 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700307 * @hide
308 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800309 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700310 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800311 public static final int UID_STATE_FOREGROUND = 500;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700312
313 /**
Hui Yu26969322019-08-21 14:56:35 -0700314 * The max, which is min priority, UID state for which any app op
315 * would be considered as performed in the foreground.
316 * @hide
317 */
318 public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND;
319
320 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700321 * Uid state: The UID is a background app. The lower the UID
322 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700323 * @hide
324 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800325 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700326 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800327 public static final int UID_STATE_BACKGROUND = 600;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700328
329 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700330 * Uid state: The UID is a cached app. The lower the UID
331 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700332 * @hide
333 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800334 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700335 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800336 public static final int UID_STATE_CACHED = 700;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700337
338 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800339 * Uid state: The UID state with the highest priority.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700340 * @hide
341 */
Svet Ganovaf189e32019-02-15 18:45:29 -0800342 public static final int MAX_PRIORITY_UID_STATE = UID_STATE_PERSISTENT;
343
344 /**
345 * Uid state: The UID state with the lowest priority.
346 * @hide
347 */
348 public static final int MIN_PRIORITY_UID_STATE = UID_STATE_CACHED;
349
350 /**
Hui Yu26969322019-08-21 14:56:35 -0700351 * Resolves the first unrestricted state given an app op.
Svet Ganovaf189e32019-02-15 18:45:29 -0800352 * @param op The op to resolve.
353 * @return The last restricted UID state.
354 *
355 * @hide
356 */
357 public static int resolveFirstUnrestrictedUidState(int op) {
Hui Yu26969322019-08-21 14:56:35 -0700358 return UID_STATE_FOREGROUND;
Svet Ganovaf189e32019-02-15 18:45:29 -0800359 }
360
361 /**
Hui Yu26969322019-08-21 14:56:35 -0700362 * Resolves the last restricted state given an app op.
Svet Ganovaf189e32019-02-15 18:45:29 -0800363 * @param op The op to resolve.
364 * @return The last restricted UID state.
365 *
366 * @hide
367 */
368 public static int resolveLastRestrictedUidState(int op) {
Hui Yu26969322019-08-21 14:56:35 -0700369 return UID_STATE_BACKGROUND;
Svet Ganovaf189e32019-02-15 18:45:29 -0800370 }
371
372 /** @hide Note: Keep these sorted */
373 public static final int[] UID_STATES = {
374 UID_STATE_PERSISTENT,
375 UID_STATE_TOP,
376 UID_STATE_FOREGROUND_SERVICE_LOCATION,
377 UID_STATE_FOREGROUND_SERVICE,
378 UID_STATE_FOREGROUND,
379 UID_STATE_BACKGROUND,
380 UID_STATE_CACHED
381 };
382
383 /** @hide */
384 public static String getUidStateName(@UidState int uidState) {
385 switch (uidState) {
386 case UID_STATE_PERSISTENT:
387 return "pers";
388 case UID_STATE_TOP:
389 return "top";
390 case UID_STATE_FOREGROUND_SERVICE_LOCATION:
391 return "fgsvcl";
392 case UID_STATE_FOREGROUND_SERVICE:
393 return "fgsvc";
394 case UID_STATE_FOREGROUND:
395 return "fg";
396 case UID_STATE_BACKGROUND:
397 return "bg";
398 case UID_STATE_CACHED:
399 return "cch";
400 default:
401 return "unknown";
402 }
403 }
404
405 /**
406 * Flag: non proxy operations. These are operations
407 * performed on behalf of the app itself and not on behalf of
408 * another one.
409 *
410 * @hide
411 */
412 @TestApi
413 @SystemApi
414 public static final int OP_FLAG_SELF = 0x1;
415
416 /**
417 * Flag: trusted proxy operations. These are operations
418 * performed on behalf of another app by a trusted app.
419 * Which is work a trusted app blames on another app.
420 *
421 * @hide
422 */
423 @TestApi
424 @SystemApi
425 public static final int OP_FLAG_TRUSTED_PROXY = 0x2;
426
427 /**
428 * Flag: untrusted proxy operations. These are operations
429 * performed on behalf of another app by an untrusted app.
430 * Which is work an untrusted app blames on another app.
431 *
432 * @hide
433 */
434 @TestApi
435 @SystemApi
436 public static final int OP_FLAG_UNTRUSTED_PROXY = 0x4;
437
438 /**
439 * Flag: trusted proxied operations. These are operations
440 * performed by a trusted other app on behalf of an app.
441 * Which is work an app was blamed for by a trusted app.
442 *
443 * @hide
444 */
445 @TestApi
446 @SystemApi
447 public static final int OP_FLAG_TRUSTED_PROXIED = 0x8;
448
449 /**
450 * Flag: untrusted proxied operations. These are operations
451 * performed by an untrusted other app on behalf of an app.
452 * Which is work an app was blamed for by an untrusted app.
453 *
454 * @hide
455 */
456 @TestApi
457 @SystemApi
458 public static final int OP_FLAG_UNTRUSTED_PROXIED = 0x10;
459
460 /**
461 * Flags: all operations. These include operations matched
462 * by {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXIED},
463 * {@link #OP_FLAG_UNTRUSTED_PROXIED}, {@link #OP_FLAG_TRUSTED_PROXIED},
464 * {@link #OP_FLAG_UNTRUSTED_PROXIED}.
465 *
466 * @hide
467 */
468 @TestApi
469 @SystemApi
470 public static final int OP_FLAGS_ALL =
471 OP_FLAG_SELF
472 | OP_FLAG_TRUSTED_PROXY
473 | OP_FLAG_UNTRUSTED_PROXY
474 | OP_FLAG_TRUSTED_PROXIED
475 | OP_FLAG_UNTRUSTED_PROXIED;
476
477 /**
478 * Flags: all trusted operations which is ones either the app did {@link #OP_FLAG_SELF},
479 * or it was blamed for by a trusted app {@link #OP_FLAG_TRUSTED_PROXIED}, or ones the
480 * app if untrusted blamed on other apps {@link #OP_FLAG_UNTRUSTED_PROXY}.
481 *
482 * @hide
483 */
484 @SystemApi
485 public static final int OP_FLAGS_ALL_TRUSTED = AppOpsManager.OP_FLAG_SELF
486 | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY
487 | AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
488
489 /** @hide */
490 @Retention(RetentionPolicy.SOURCE)
491 @IntDef(flag = true, prefix = { "FLAG_" }, value = {
492 OP_FLAG_SELF,
493 OP_FLAG_TRUSTED_PROXY,
494 OP_FLAG_UNTRUSTED_PROXY,
495 OP_FLAG_TRUSTED_PROXIED,
496 OP_FLAG_UNTRUSTED_PROXIED
497 })
498 public @interface OpFlags {}
499
500
501 /** @hide */
502 public static final String getFlagName(@OpFlags int flag) {
503 switch (flag) {
504 case OP_FLAG_SELF:
505 return "s";
506 case OP_FLAG_TRUSTED_PROXY:
507 return "tp";
508 case OP_FLAG_UNTRUSTED_PROXY:
509 return "up";
510 case OP_FLAG_TRUSTED_PROXIED:
511 return "tpd";
512 case OP_FLAG_UNTRUSTED_PROXIED:
513 return "upd";
514 default:
515 return "unknown";
516 }
517 }
518
519 private static final int UID_STATE_OFFSET = 31;
520 private static final int FLAGS_MASK = 0xFFFFFFFF;
521
522 /**
523 * Key for a data bucket storing app op state. The bucket
524 * is composed of the uid state and state flags. This way
525 * we can query data for given uid state and a set of flags where
526 * the flags control which type of data to get. For example,
527 * one can get the ops an app did on behalf of other apps
528 * while in the background.
529 *
530 * @hide
531 */
532 @Retention(RetentionPolicy.SOURCE)
533 @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
534 public @interface DataBucketKey {
535 }
536
537 /** @hide */
538 public static String keyToString(@DataBucketKey long key) {
539 final int uidState = extractUidStateFromKey(key);
540 final int flags = extractFlagsFromKey(key);
541 return "[" + getUidStateName(uidState) + "-" + flagsToString(flags) + "]";
542 }
543
544 /** @hide */
545 public static @DataBucketKey long makeKey(@UidState int uidState, @OpFlags int flags) {
546 return ((long) uidState << UID_STATE_OFFSET) | flags;
547 }
548
549 /** @hide */
550 public static int extractUidStateFromKey(@DataBucketKey long key) {
551 return (int) (key >> UID_STATE_OFFSET);
552 }
553
554 /** @hide */
555 public static int extractFlagsFromKey(@DataBucketKey long key) {
556 return (int) (key & FLAGS_MASK);
557 }
558
559 /** @hide */
560 public static String flagsToString(@OpFlags int flags) {
561 final StringBuilder flagsBuilder = new StringBuilder();
562 while (flags != 0) {
563 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
564 flags &= ~flag;
565 if (flagsBuilder.length() > 0) {
566 flagsBuilder.append('|');
567 }
568 flagsBuilder.append(getFlagName(flag));
569 }
570 return flagsBuilder.toString();
571 }
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700572
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500573 // when adding one of these:
574 // - increment _NUM_OP
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000575 // - define an OPSTR_* constant (marked as @SystemApi)
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700576 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500577 // - add descriptive strings to Settings/res/values/arrays.xml
David Christie0b837452013-07-29 16:02:13 -0700578 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700579
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700580 /** @hide No operation specified. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100581 @UnsupportedAppUsage
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800582 public static final int OP_NONE = -1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700583 /** @hide Access to coarse location information. */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000584 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -0800585 @TestApi
Dianne Hackborn35654b62013-01-14 17:38:02 -0800586 public static final int OP_COARSE_LOCATION = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700587 /** @hide Access to fine location information. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100588 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800589 public static final int OP_FINE_LOCATION = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700590 /** @hide Causing GPS to run. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100591 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800592 public static final int OP_GPS = 2;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800593 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100594 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700595 public static final int OP_VIBRATE = 3;
596 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100597 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700598 public static final int OP_READ_CONTACTS = 4;
599 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100600 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700601 public static final int OP_WRITE_CONTACTS = 5;
602 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100603 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700604 public static final int OP_READ_CALL_LOG = 6;
605 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100606 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700607 public static final int OP_WRITE_CALL_LOG = 7;
608 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100609 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700610 public static final int OP_READ_CALENDAR = 8;
611 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100612 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700613 public static final int OP_WRITE_CALENDAR = 9;
614 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100615 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700616 public static final int OP_WIFI_SCAN = 10;
617 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100618 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700619 public static final int OP_POST_NOTIFICATION = 11;
620 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100621 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700622 public static final int OP_NEIGHBORING_CELLS = 12;
623 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100624 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700625 public static final int OP_CALL_PHONE = 13;
626 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100627 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700628 public static final int OP_READ_SMS = 14;
629 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100630 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700631 public static final int OP_WRITE_SMS = 15;
632 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100633 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700634 public static final int OP_RECEIVE_SMS = 16;
635 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100636 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700637 public static final int OP_RECEIVE_EMERGECY_SMS = 17;
638 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100639 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700640 public static final int OP_RECEIVE_MMS = 18;
641 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100642 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700643 public static final int OP_RECEIVE_WAP_PUSH = 19;
644 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100645 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700646 public static final int OP_SEND_SMS = 20;
647 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100648 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700649 public static final int OP_READ_ICC_SMS = 21;
650 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100651 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700652 public static final int OP_WRITE_ICC_SMS = 22;
653 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100654 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700655 public static final int OP_WRITE_SETTINGS = 23;
Peter Visontay96449f62017-12-11 18:50:03 +0000656 /** @hide Required to draw on top of other apps. */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000657 @UnsupportedAppUsage
Svet Ganovf7b47252018-02-26 11:11:27 -0800658 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700659 public static final int OP_SYSTEM_ALERT_WINDOW = 24;
660 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100661 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700662 public static final int OP_ACCESS_NOTIFICATIONS = 25;
663 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100664 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700665 public static final int OP_CAMERA = 26;
666 /** @hide */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000667 @UnsupportedAppUsage
Svet Ganova7a0db62018-02-27 20:08:01 -0800668 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700669 public static final int OP_RECORD_AUDIO = 27;
670 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100671 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700672 public static final int OP_PLAY_AUDIO = 28;
673 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100674 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700675 public static final int OP_READ_CLIPBOARD = 29;
676 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100677 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700678 public static final int OP_WRITE_CLIPBOARD = 30;
679 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100680 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700681 public static final int OP_TAKE_MEDIA_BUTTONS = 31;
682 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100683 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700684 public static final int OP_TAKE_AUDIO_FOCUS = 32;
685 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100686 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700687 public static final int OP_AUDIO_MASTER_VOLUME = 33;
688 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100689 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700690 public static final int OP_AUDIO_VOICE_VOLUME = 34;
691 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100692 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700693 public static final int OP_AUDIO_RING_VOLUME = 35;
694 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100695 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700696 public static final int OP_AUDIO_MEDIA_VOLUME = 36;
697 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100698 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700699 public static final int OP_AUDIO_ALARM_VOLUME = 37;
700 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100701 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700702 public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
703 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100704 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700705 public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
706 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100707 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700708 public static final int OP_WAKE_LOCK = 40;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700709 /** @hide Continually monitoring location data. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100710 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700711 public static final int OP_MONITOR_LOCATION = 41;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700712 /** @hide Continually monitoring location data with a relatively high power request. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100713 @UnsupportedAppUsage
David Christie0b837452013-07-29 16:02:13 -0700714 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700715 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100716 @UnsupportedAppUsage
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700717 public static final int OP_GET_USAGE_STATS = 43;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700718 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100719 @UnsupportedAppUsage
Emily Bernier22c921a2014-05-28 11:01:32 -0400720 public static final int OP_MUTE_MICROPHONE = 44;
721 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100722 @UnsupportedAppUsage
Jason Monk1c7c3192014-06-26 12:52:18 -0400723 public static final int OP_TOAST_WINDOW = 45;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700724 /** @hide Capture the device's display contents and/or audio */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100725 @UnsupportedAppUsage
Michael Wrightc39d47a2014-07-08 18:07:36 -0700726 public static final int OP_PROJECT_MEDIA = 46;
Jeff Davidson05542602014-08-11 14:07:27 -0700727 /** @hide Activate a VPN connection without user intervention. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100728 @UnsupportedAppUsage
Jeff Davidson05542602014-08-11 14:07:27 -0700729 public static final int OP_ACTIVATE_VPN = 47;
Benjamin Franzf3ece362015-02-11 10:51:10 +0000730 /** @hide Access the WallpaperManagerAPI to write wallpapers. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100731 @UnsupportedAppUsage
Benjamin Franzf3ece362015-02-11 10:51:10 +0000732 public static final int OP_WRITE_WALLPAPER = 48;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700733 /** @hide Received the assist structure from an app. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100734 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700735 public static final int OP_ASSIST_STRUCTURE = 49;
736 /** @hide Received a screenshot from assist. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100737 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700738 public static final int OP_ASSIST_SCREENSHOT = 50;
Svet Ganov16a16892015-04-16 10:32:04 -0700739 /** @hide Read the phone state. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100740 @UnsupportedAppUsage
Svet Ganov16a16892015-04-16 10:32:04 -0700741 public static final int OP_READ_PHONE_STATE = 51;
Svet Ganovc3300092015-04-17 09:07:22 -0700742 /** @hide Add voicemail messages to the voicemail content provider. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100743 @UnsupportedAppUsage
Svet Ganovc3300092015-04-17 09:07:22 -0700744 public static final int OP_ADD_VOICEMAIL = 52;
Svetoslav5335b672015-04-29 12:00:51 -0700745 /** @hide Access APIs for SIP calling over VOIP or WiFi. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100746 @UnsupportedAppUsage
Svetoslav5335b672015-04-29 12:00:51 -0700747 public static final int OP_USE_SIP = 53;
Svetoslavc656e6f2015-04-29 14:08:16 -0700748 /** @hide Intercept outgoing calls. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100749 @UnsupportedAppUsage
Svetoslavc656e6f2015-04-29 14:08:16 -0700750 public static final int OP_PROCESS_OUTGOING_CALLS = 54;
Svetoslav4af76a52015-04-29 15:29:46 -0700751 /** @hide User the fingerprint API. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100752 @UnsupportedAppUsage
Svetoslav4af76a52015-04-29 15:29:46 -0700753 public static final int OP_USE_FINGERPRINT = 55;
Svet Ganovb9d71a62015-04-30 10:38:13 -0700754 /** @hide Access to body sensors such as heart rate, etc. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100755 @UnsupportedAppUsage
Svet Ganovb9d71a62015-04-30 10:38:13 -0700756 public static final int OP_BODY_SENSORS = 56;
Svet Ganovede43162015-05-02 17:42:44 -0700757 /** @hide Read previously received cell broadcast messages. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100758 @UnsupportedAppUsage
Svet Ganovede43162015-05-02 17:42:44 -0700759 public static final int OP_READ_CELL_BROADCASTS = 57;
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700760 /** @hide Inject mock location into the system. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100761 @UnsupportedAppUsage
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700762 public static final int OP_MOCK_LOCATION = 58;
Svet Ganov921c7df2015-06-29 21:51:41 -0700763 /** @hide Read external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100764 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700765 public static final int OP_READ_EXTERNAL_STORAGE = 59;
766 /** @hide Write external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100767 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700768 public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700769 /** @hide Turned on the screen. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100770 @UnsupportedAppUsage
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700771 public static final int OP_TURN_SCREEN_ON = 61;
Svetoslavf3f02ac2015-09-08 14:36:35 -0700772 /** @hide Get device accounts. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100773 @UnsupportedAppUsage
Svetoslavf3f02ac2015-09-08 14:36:35 -0700774 public static final int OP_GET_ACCOUNTS = 62;
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700775 /** @hide Control whether an application is allowed to run in the background. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100776 @UnsupportedAppUsage
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700777 public static final int OP_RUN_IN_BACKGROUND = 63;
Jason Monk1c7c3192014-06-26 12:52:18 -0400778 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100779 @UnsupportedAppUsage
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800780 public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800781 /** @hide Read the phone number. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100782 @UnsupportedAppUsage
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700783 public static final int OP_READ_PHONE_NUMBERS = 65;
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800784 /** @hide Request package installs through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100785 @UnsupportedAppUsage
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800786 public static final int OP_REQUEST_INSTALL_PACKAGES = 66;
Winson Chungf4ac0632017-03-17 12:34:12 -0700787 /** @hide Enter picture-in-picture. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100788 @UnsupportedAppUsage
Winson Chungf4ac0632017-03-17 12:34:12 -0700789 public static final int OP_PICTURE_IN_PICTURE = 67;
Chad Brubaker97b383f2017-02-02 15:04:35 -0800790 /** @hide Instant app start foreground service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100791 @UnsupportedAppUsage
Chad Brubaker97b383f2017-02-02 15:04:35 -0800792 public static final int OP_INSTANT_APP_START_FOREGROUND = 68;
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800793 /** @hide Answer incoming phone calls */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100794 @UnsupportedAppUsage
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800795 public static final int OP_ANSWER_PHONE_CALLS = 69;
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700796 /** @hide Run jobs when in background */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100797 @UnsupportedAppUsage
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700798 public static final int OP_RUN_ANY_IN_BACKGROUND = 70;
Peter Visontay1246d9e2017-10-17 17:02:45 +0100799 /** @hide Change Wi-Fi connectivity state */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100800 @UnsupportedAppUsage
Peter Visontay1246d9e2017-10-17 17:02:45 +0100801 public static final int OP_CHANGE_WIFI_STATE = 71;
Peter Visontayf2e38362017-11-27 15:27:16 +0000802 /** @hide Request package deletion through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100803 @UnsupportedAppUsage
Peter Visontayf2e38362017-11-27 15:27:16 +0000804 public static final int OP_REQUEST_DELETE_PACKAGES = 72;
Peter Visontay11950832017-11-14 19:34:59 +0000805 /** @hide Bind an accessibility service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100806 @UnsupportedAppUsage
Peter Visontay11950832017-11-14 19:34:59 +0000807 public static final int OP_BIND_ACCESSIBILITY_SERVICE = 73;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800808 /** @hide Continue handover of a call from another app */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100809 @UnsupportedAppUsage
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800810 public static final int OP_ACCEPT_HANDOVER = 74;
Nathan Harold1bb420672018-03-14 17:08:53 -0700811 /** @hide Create and Manage IPsec Tunnels */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100812 @UnsupportedAppUsage
Nathan Harold1bb420672018-03-14 17:08:53 -0700813 public static final int OP_MANAGE_IPSEC_TUNNELS = 75;
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700814 /** @hide Any app start foreground service. */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000815 @UnsupportedAppUsage
Svet Ganovaf189e32019-02-15 18:45:29 -0800816 @TestApi
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700817 public static final int OP_START_FOREGROUND = 76;
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800818 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100819 @UnsupportedAppUsage
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700820 public static final int OP_BLUETOOTH_SCAN = 77;
Kevin Chynb3c05aa2018-09-21 16:50:32 -0700821 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
822 public static final int OP_USE_BIOMETRIC = 78;
Zimuzo6cbf9cc2018-10-05 12:05:58 +0100823 /** @hide Physical activity recognition. */
824 public static final int OP_ACTIVITY_RECOGNITION = 79;
Hongming Jin228cd012018-11-09 14:47:50 -0800825 /** @hide Financial app sms read. */
826 public static final int OP_SMS_FINANCIAL_TRANSACTIONS = 80;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -0700827 /** @hide Read media of audio type. */
828 public static final int OP_READ_MEDIA_AUDIO = 81;
829 /** @hide Write media of audio type. */
830 public static final int OP_WRITE_MEDIA_AUDIO = 82;
831 /** @hide Read media of video type. */
832 public static final int OP_READ_MEDIA_VIDEO = 83;
833 /** @hide Write media of video type. */
834 public static final int OP_WRITE_MEDIA_VIDEO = 84;
835 /** @hide Read media of image type. */
836 public static final int OP_READ_MEDIA_IMAGES = 85;
837 /** @hide Write media of image type. */
838 public static final int OP_WRITE_MEDIA_IMAGES = 86;
Jeff Sharkeye82cbb12018-12-06 15:53:11 -0700839 /** @hide Has a legacy (non-isolated) view of storage. */
840 public static final int OP_LEGACY_STORAGE = 87;
Jackal Guo8dc791e2019-01-14 10:26:42 +0800841 /** @hide Accessing accessibility features */
842 public static final int OP_ACCESS_ACCESSIBILITY = 88;
Michael Groover656ef912019-04-09 17:09:57 -0700843 /** @hide Read the device identifiers (IMEI / MEID, IMSI, SIM / Build serial) */
844 public static final int OP_READ_DEVICE_IDENTIFIERS = 89;
Philip P. Moltmann89b044f2019-09-13 15:12:34 -0700845 /** @hide Read location metadata from media */
846 public static final int OP_ACCESS_MEDIA_LOCATION = 90;
Patrick Baumann6c1c8092019-06-27 14:55:44 -0700847 /** @hide Query all apps on device, regardless of declarations in the calling app manifest */
Philip P. Moltmann89b044f2019-09-13 15:12:34 -0700848 public static final int OP_QUERY_ALL_PACKAGES = 91;
Patrick Baumann6c1c8092019-06-27 14:55:44 -0700849
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700850 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100851 @UnsupportedAppUsage
Philip P. Moltmann89b044f2019-09-13 15:12:34 -0700852 public static final int _NUM_OP = 92;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800853
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700854 /** Access to coarse location information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700855 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700856 /** Access to fine location information. */
857 public static final String OPSTR_FINE_LOCATION =
858 "android:fine_location";
859 /** Continually monitoring location data. */
860 public static final String OPSTR_MONITOR_LOCATION
861 = "android:monitor_location";
862 /** Continually monitoring location data with a relatively high power request. */
863 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
864 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700865 /** Access to {@link android.app.usage.UsageStatsManager}. */
866 public static final String OPSTR_GET_USAGE_STATS
867 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700868 /** Activate a VPN connection without user intervention. @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000869 @SystemApi @TestApi
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700870 public static final String OPSTR_ACTIVATE_VPN
871 = "android:activate_vpn";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700872 /** Allows an application to read the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700873 public static final String OPSTR_READ_CONTACTS
874 = "android:read_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700875 /** Allows an application to write to the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700876 public static final String OPSTR_WRITE_CONTACTS
877 = "android:write_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700878 /** Allows an application to read the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700879 public static final String OPSTR_READ_CALL_LOG
880 = "android:read_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700881 /** Allows an application to write to the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700882 public static final String OPSTR_WRITE_CALL_LOG
883 = "android:write_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700884 /** Allows an application to read the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700885 public static final String OPSTR_READ_CALENDAR
886 = "android:read_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700887 /** Allows an application to write to the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700888 public static final String OPSTR_WRITE_CALENDAR
889 = "android:write_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700890 /** Allows an application to initiate a phone call. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700891 public static final String OPSTR_CALL_PHONE
892 = "android:call_phone";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700893 /** Allows an application to read SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700894 public static final String OPSTR_READ_SMS
895 = "android:read_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700896 /** Allows an application to receive SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700897 public static final String OPSTR_RECEIVE_SMS
898 = "android:receive_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700899 /** Allows an application to receive MMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700900 public static final String OPSTR_RECEIVE_MMS
901 = "android:receive_mms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700902 /** Allows an application to receive WAP push messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700903 public static final String OPSTR_RECEIVE_WAP_PUSH
904 = "android:receive_wap_push";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700905 /** Allows an application to send SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700906 public static final String OPSTR_SEND_SMS
907 = "android:send_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700908 /** Required to be able to access the camera device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700909 public static final String OPSTR_CAMERA
910 = "android:camera";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700911 /** Required to be able to access the microphone device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700912 public static final String OPSTR_RECORD_AUDIO
913 = "android:record_audio";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700914 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700915 public static final String OPSTR_READ_PHONE_STATE
916 = "android:read_phone_state";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700917 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700918 public static final String OPSTR_ADD_VOICEMAIL
919 = "android:add_voicemail";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700920 /** Access APIs for SIP calling over VOIP or WiFi */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700921 public static final String OPSTR_USE_SIP
922 = "android:use_sip";
Svet Ganove8e89422016-09-22 19:56:50 -0700923 /** Access APIs for diverting outgoing calls */
Svet Ganov824ad6e2016-09-22 19:36:53 -0700924 public static final String OPSTR_PROCESS_OUTGOING_CALLS
925 = "android:process_outgoing_calls";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700926 /** Use the fingerprint API. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700927 public static final String OPSTR_USE_FINGERPRINT
928 = "android:use_fingerprint";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700929 /** Access to body sensors such as heart rate, etc. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700930 public static final String OPSTR_BODY_SENSORS
931 = "android:body_sensors";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700932 /** Read previously received cell broadcast messages. */
Svet Ganovede43162015-05-02 17:42:44 -0700933 public static final String OPSTR_READ_CELL_BROADCASTS
934 = "android:read_cell_broadcasts";
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700935 /** Inject mock location into the system. */
936 public static final String OPSTR_MOCK_LOCATION
937 = "android:mock_location";
Svet Ganov921c7df2015-06-29 21:51:41 -0700938 /** Read external storage. */
939 public static final String OPSTR_READ_EXTERNAL_STORAGE
940 = "android:read_external_storage";
941 /** Write external storage. */
942 public static final String OPSTR_WRITE_EXTERNAL_STORAGE
943 = "android:write_external_storage";
Billy Lau24b9c832015-07-20 17:34:09 +0100944 /** Required to draw on top of other apps. */
945 public static final String OPSTR_SYSTEM_ALERT_WINDOW
946 = "android:system_alert_window";
947 /** Required to write/modify/update system settingss. */
948 public static final String OPSTR_WRITE_SETTINGS
949 = "android:write_settings";
Svetoslavf3f02ac2015-09-08 14:36:35 -0700950 /** @hide Get device accounts. */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000951 @SystemApi @TestApi
Svetoslavf3f02ac2015-09-08 14:36:35 -0700952 public static final String OPSTR_GET_ACCOUNTS
953 = "android:get_accounts";
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700954 public static final String OPSTR_READ_PHONE_NUMBERS
955 = "android:read_phone_numbers";
Winson Chungf4ac0632017-03-17 12:34:12 -0700956 /** Access to picture-in-picture. */
957 public static final String OPSTR_PICTURE_IN_PICTURE
958 = "android:picture_in_picture";
Chad Brubaker97b383f2017-02-02 15:04:35 -0800959 /** @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000960 @SystemApi @TestApi
Chad Brubaker97b383f2017-02-02 15:04:35 -0800961 public static final String OPSTR_INSTANT_APP_START_FOREGROUND
962 = "android:instant_app_start_foreground";
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800963 /** Answer incoming phone calls */
964 public static final String OPSTR_ANSWER_PHONE_CALLS
965 = "android:answer_phone_calls";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800966 /**
967 * Accept call handover
968 * @hide
969 */
970 @SystemApi @TestApi
971 public static final String OPSTR_ACCEPT_HANDOVER
972 = "android:accept_handover";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000973 /** @hide */
974 @SystemApi @TestApi
975 public static final String OPSTR_GPS = "android:gps";
976 /** @hide */
977 @SystemApi @TestApi
978 public static final String OPSTR_VIBRATE = "android:vibrate";
979 /** @hide */
980 @SystemApi @TestApi
981 public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
982 /** @hide */
983 @SystemApi @TestApi
984 public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
985 /** @hide */
986 @SystemApi @TestApi
987 public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
988 /** @hide */
989 @SystemApi @TestApi
990 public static final String OPSTR_WRITE_SMS = "android:write_sms";
991 /** @hide */
992 @SystemApi @TestApi
993 public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST =
994 "android:receive_emergency_broadcast";
995 /** @hide */
996 @SystemApi @TestApi
997 public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
998 /** @hide */
999 @SystemApi @TestApi
1000 public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
1001 /** @hide */
1002 @SystemApi @TestApi
1003 public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
1004 /** @hide */
1005 @SystemApi @TestApi
1006 public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
1007 /** @hide */
1008 @SystemApi @TestApi
1009 public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
1010 /** @hide */
1011 @SystemApi @TestApi
1012 public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
1013 /** @hide */
1014 @SystemApi @TestApi
1015 public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
1016 /** @hide */
1017 @SystemApi @TestApi
1018 public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
1019 /** @hide */
1020 @SystemApi @TestApi
1021 public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
1022 /** @hide */
1023 @SystemApi @TestApi
1024 public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
1025 /** @hide */
1026 @SystemApi @TestApi
1027 public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
1028 /** @hide */
1029 @SystemApi @TestApi
1030 public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
1031 /** @hide */
1032 @SystemApi @TestApi
1033 public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
1034 /** @hide */
1035 @SystemApi @TestApi
1036 public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME =
1037 "android:audio_notification_volume";
1038 /** @hide */
1039 @SystemApi @TestApi
1040 public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
1041 /** @hide */
1042 @SystemApi @TestApi
1043 public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
1044 /** @hide */
1045 @SystemApi @TestApi
1046 public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
1047 /** @hide */
1048 @SystemApi @TestApi
1049 public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
1050 /** @hide */
1051 @SystemApi @TestApi
1052 public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
1053 /** @hide */
1054 @SystemApi @TestApi
1055 public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
1056 /** @hide */
1057 @SystemApi @TestApi
1058 public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
1059 /** @hide */
1060 @SystemApi @TestApi
1061 public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
1062 /** @hide */
1063 @SystemApi @TestApi
1064 public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
1065 /** @hide */
1066 @SystemApi @TestApi
1067 public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
1068 /** @hide */
1069 @SystemApi @TestApi
1070 public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME =
1071 "android:audio_accessibility_volume";
1072 /** @hide */
1073 @SystemApi @TestApi
1074 public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
1075 /** @hide */
1076 @SystemApi @TestApi
1077 public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
1078 /** @hide */
1079 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001080 public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001081 /** @hide */
1082 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001083 public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001084 /** @hide */
1085 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001086 public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE =
1087 "android:bind_accessibility_service";
Nathan Harold1bb420672018-03-14 17:08:53 -07001088 /** @hide */
1089 @SystemApi @TestApi
1090 public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001091 /** @hide */
1092 @SystemApi @TestApi
1093 public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001094 /** @hide */
1095 public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001096
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001097 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
1098 public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001099
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001100 /** @hide Recognize physical activity. */
1101 public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition";
1102
Hongming Jin228cd012018-11-09 14:47:50 -08001103 /** @hide Financial app read sms. */
1104 public static final String OPSTR_SMS_FINANCIAL_TRANSACTIONS =
1105 "android:sms_financial_transactions";
1106
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001107 /** @hide Read media of audio type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001108 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001109 public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
1110 /** @hide Write media of audio type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001111 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001112 public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
1113 /** @hide Read media of video type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001114 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001115 public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
1116 /** @hide Write media of video type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001117 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001118 public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
1119 /** @hide Read media of image type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001120 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001121 public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
1122 /** @hide Write media of image type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001123 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001124 public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001125 /** @hide Has a legacy (non-isolated) view of storage. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001126 @SystemApi @TestApi
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001127 public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001128 /** @hide Read location metadata from media */
1129 public static final String OPSTR_ACCESS_MEDIA_LOCATION = "android:access_media_location";
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001130
Jackal Guo8dc791e2019-01-14 10:26:42 +08001131 /** @hide Interact with accessibility. */
Joel Galensonff4fe202019-02-06 14:43:58 -08001132 @SystemApi
Jackal Guo8dc791e2019-01-14 10:26:42 +08001133 public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
Michael Groover656ef912019-04-09 17:09:57 -07001134 /** @hide Read device identifiers */
1135 public static final String OPSTR_READ_DEVICE_IDENTIFIERS = "android:read_device_identifiers";
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001136 /** @hide Query all packages on device */
1137 public static final String OPSTR_QUERY_ALL_PACKAGES = "android:query_all_packages";
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001138
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07001139
1140 /** {@link #sAppOpsToNote} not initialized yet for this op */
1141 private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
1142 /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
1143 private static final byte SHOULD_NOT_COLLECT_NOTE_OP = 1;
1144 /** Should collect noting of this app-op in {@link #sAppOpsToNote} */
1145 private static final byte SHOULD_COLLECT_NOTE_OP = 2;
1146
1147 @Retention(RetentionPolicy.SOURCE)
1148 @IntDef(flag = true, prefix = { "SHOULD_" }, value = {
1149 SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED,
1150 SHOULD_NOT_COLLECT_NOTE_OP,
1151 SHOULD_COLLECT_NOTE_OP
1152 })
1153 private @interface ShouldCollectNoteOp {}
1154
Philip P. Moltmanne56c08e2017-03-15 12:46:04 -07001155 // Warning: If an permission is added here it also has to be added to
1156 // com.android.packageinstaller.permission.utils.EventLogger
Svet Ganovda0acdf2017-02-15 10:28:51 -08001157 private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
1158 // RUNTIME PERMISSIONS
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001159 // Contacts
1160 OP_READ_CONTACTS,
1161 OP_WRITE_CONTACTS,
1162 OP_GET_ACCOUNTS,
1163 // Calendar
1164 OP_READ_CALENDAR,
1165 OP_WRITE_CALENDAR,
1166 // SMS
1167 OP_SEND_SMS,
1168 OP_RECEIVE_SMS,
1169 OP_READ_SMS,
1170 OP_RECEIVE_WAP_PUSH,
1171 OP_RECEIVE_MMS,
1172 OP_READ_CELL_BROADCASTS,
1173 // Storage
1174 OP_READ_EXTERNAL_STORAGE,
1175 OP_WRITE_EXTERNAL_STORAGE,
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001176 OP_ACCESS_MEDIA_LOCATION,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001177 // Location
1178 OP_COARSE_LOCATION,
1179 OP_FINE_LOCATION,
1180 // Phone
1181 OP_READ_PHONE_STATE,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001182 OP_READ_PHONE_NUMBERS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001183 OP_CALL_PHONE,
1184 OP_READ_CALL_LOG,
1185 OP_WRITE_CALL_LOG,
1186 OP_ADD_VOICEMAIL,
1187 OP_USE_SIP,
1188 OP_PROCESS_OUTGOING_CALLS,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001189 OP_ANSWER_PHONE_CALLS,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001190 OP_ACCEPT_HANDOVER,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001191 // Microphone
1192 OP_RECORD_AUDIO,
1193 // Camera
1194 OP_CAMERA,
1195 // Body sensors
Svet Ganovda0acdf2017-02-15 10:28:51 -08001196 OP_BODY_SENSORS,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001197 // Activity recognition
1198 OP_ACTIVITY_RECOGNITION,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001199 // Aural
1200 OP_READ_MEDIA_AUDIO,
1201 OP_WRITE_MEDIA_AUDIO,
1202 // Visual
1203 OP_READ_MEDIA_VIDEO,
1204 OP_WRITE_MEDIA_VIDEO,
1205 OP_READ_MEDIA_IMAGES,
1206 OP_WRITE_MEDIA_IMAGES,
Svet Ganovda0acdf2017-02-15 10:28:51 -08001207
1208 // APPOP PERMISSIONS
1209 OP_ACCESS_NOTIFICATIONS,
1210 OP_SYSTEM_ALERT_WINDOW,
1211 OP_WRITE_SETTINGS,
1212 OP_REQUEST_INSTALL_PACKAGES,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001213 OP_START_FOREGROUND,
Hongming Jin228cd012018-11-09 14:47:50 -08001214 OP_SMS_FINANCIAL_TRANSACTIONS,
Philip P. Moltmann4b38fbe2019-09-13 21:33:07 -07001215 OP_MANAGE_IPSEC_TUNNELS,
Philip P. Moltmann4b38fbe2019-09-13 21:33:07 -07001216 OP_INSTANT_APP_START_FOREGROUND
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001217 };
1218
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001219 /**
1220 * This maps each operation to the operation that serves as the
1221 * switch to determine whether it is allowed. Generally this is
1222 * a 1:1 mapping, but for some things (like location) that have
1223 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -07001224 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001225 * make them all controlled by the same single operation.
1226 */
1227 private static int[] sOpToSwitch = new int[] {
Dianne Hackbornc216a262018-04-26 13:46:22 -07001228 OP_COARSE_LOCATION, // COARSE_LOCATION
1229 OP_COARSE_LOCATION, // FINE_LOCATION
1230 OP_COARSE_LOCATION, // GPS
1231 OP_VIBRATE, // VIBRATE
1232 OP_READ_CONTACTS, // READ_CONTACTS
1233 OP_WRITE_CONTACTS, // WRITE_CONTACTS
1234 OP_READ_CALL_LOG, // READ_CALL_LOG
1235 OP_WRITE_CALL_LOG, // WRITE_CALL_LOG
1236 OP_READ_CALENDAR, // READ_CALENDAR
1237 OP_WRITE_CALENDAR, // WRITE_CALENDAR
1238 OP_COARSE_LOCATION, // WIFI_SCAN
1239 OP_POST_NOTIFICATION, // POST_NOTIFICATION
1240 OP_COARSE_LOCATION, // NEIGHBORING_CELLS
1241 OP_CALL_PHONE, // CALL_PHONE
1242 OP_READ_SMS, // READ_SMS
1243 OP_WRITE_SMS, // WRITE_SMS
1244 OP_RECEIVE_SMS, // RECEIVE_SMS
1245 OP_RECEIVE_SMS, // RECEIVE_EMERGECY_SMS
1246 OP_RECEIVE_MMS, // RECEIVE_MMS
1247 OP_RECEIVE_WAP_PUSH, // RECEIVE_WAP_PUSH
1248 OP_SEND_SMS, // SEND_SMS
1249 OP_READ_SMS, // READ_ICC_SMS
1250 OP_WRITE_SMS, // WRITE_ICC_SMS
1251 OP_WRITE_SETTINGS, // WRITE_SETTINGS
1252 OP_SYSTEM_ALERT_WINDOW, // SYSTEM_ALERT_WINDOW
1253 OP_ACCESS_NOTIFICATIONS, // ACCESS_NOTIFICATIONS
1254 OP_CAMERA, // CAMERA
1255 OP_RECORD_AUDIO, // RECORD_AUDIO
1256 OP_PLAY_AUDIO, // PLAY_AUDIO
1257 OP_READ_CLIPBOARD, // READ_CLIPBOARD
1258 OP_WRITE_CLIPBOARD, // WRITE_CLIPBOARD
1259 OP_TAKE_MEDIA_BUTTONS, // TAKE_MEDIA_BUTTONS
1260 OP_TAKE_AUDIO_FOCUS, // TAKE_AUDIO_FOCUS
1261 OP_AUDIO_MASTER_VOLUME, // AUDIO_MASTER_VOLUME
1262 OP_AUDIO_VOICE_VOLUME, // AUDIO_VOICE_VOLUME
1263 OP_AUDIO_RING_VOLUME, // AUDIO_RING_VOLUME
1264 OP_AUDIO_MEDIA_VOLUME, // AUDIO_MEDIA_VOLUME
1265 OP_AUDIO_ALARM_VOLUME, // AUDIO_ALARM_VOLUME
1266 OP_AUDIO_NOTIFICATION_VOLUME, // AUDIO_NOTIFICATION_VOLUME
1267 OP_AUDIO_BLUETOOTH_VOLUME, // AUDIO_BLUETOOTH_VOLUME
1268 OP_WAKE_LOCK, // WAKE_LOCK
1269 OP_COARSE_LOCATION, // MONITOR_LOCATION
1270 OP_COARSE_LOCATION, // MONITOR_HIGH_POWER_LOCATION
1271 OP_GET_USAGE_STATS, // GET_USAGE_STATS
1272 OP_MUTE_MICROPHONE, // MUTE_MICROPHONE
1273 OP_TOAST_WINDOW, // TOAST_WINDOW
1274 OP_PROJECT_MEDIA, // PROJECT_MEDIA
1275 OP_ACTIVATE_VPN, // ACTIVATE_VPN
1276 OP_WRITE_WALLPAPER, // WRITE_WALLPAPER
1277 OP_ASSIST_STRUCTURE, // ASSIST_STRUCTURE
1278 OP_ASSIST_SCREENSHOT, // ASSIST_SCREENSHOT
1279 OP_READ_PHONE_STATE, // READ_PHONE_STATE
1280 OP_ADD_VOICEMAIL, // ADD_VOICEMAIL
1281 OP_USE_SIP, // USE_SIP
1282 OP_PROCESS_OUTGOING_CALLS, // PROCESS_OUTGOING_CALLS
1283 OP_USE_FINGERPRINT, // USE_FINGERPRINT
1284 OP_BODY_SENSORS, // BODY_SENSORS
1285 OP_READ_CELL_BROADCASTS, // READ_CELL_BROADCASTS
1286 OP_MOCK_LOCATION, // MOCK_LOCATION
1287 OP_READ_EXTERNAL_STORAGE, // READ_EXTERNAL_STORAGE
1288 OP_WRITE_EXTERNAL_STORAGE, // WRITE_EXTERNAL_STORAGE
1289 OP_TURN_SCREEN_ON, // TURN_SCREEN_ON
1290 OP_GET_ACCOUNTS, // GET_ACCOUNTS
1291 OP_RUN_IN_BACKGROUND, // RUN_IN_BACKGROUND
1292 OP_AUDIO_ACCESSIBILITY_VOLUME, // AUDIO_ACCESSIBILITY_VOLUME
1293 OP_READ_PHONE_NUMBERS, // READ_PHONE_NUMBERS
1294 OP_REQUEST_INSTALL_PACKAGES, // REQUEST_INSTALL_PACKAGES
1295 OP_PICTURE_IN_PICTURE, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
1296 OP_INSTANT_APP_START_FOREGROUND, // INSTANT_APP_START_FOREGROUND
1297 OP_ANSWER_PHONE_CALLS, // ANSWER_PHONE_CALLS
1298 OP_RUN_ANY_IN_BACKGROUND, // OP_RUN_ANY_IN_BACKGROUND
1299 OP_CHANGE_WIFI_STATE, // OP_CHANGE_WIFI_STATE
1300 OP_REQUEST_DELETE_PACKAGES, // OP_REQUEST_DELETE_PACKAGES
1301 OP_BIND_ACCESSIBILITY_SERVICE, // OP_BIND_ACCESSIBILITY_SERVICE
1302 OP_ACCEPT_HANDOVER, // ACCEPT_HANDOVER
1303 OP_MANAGE_IPSEC_TUNNELS, // MANAGE_IPSEC_HANDOVERS
1304 OP_START_FOREGROUND, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001305 OP_COARSE_LOCATION, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001306 OP_USE_BIOMETRIC, // BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001307 OP_ACTIVITY_RECOGNITION, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001308 OP_SMS_FINANCIAL_TRANSACTIONS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001309 OP_READ_MEDIA_AUDIO, // READ_MEDIA_AUDIO
1310 OP_WRITE_MEDIA_AUDIO, // WRITE_MEDIA_AUDIO
1311 OP_READ_MEDIA_VIDEO, // READ_MEDIA_VIDEO
1312 OP_WRITE_MEDIA_VIDEO, // WRITE_MEDIA_VIDEO
1313 OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES
1314 OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001315 OP_LEGACY_STORAGE, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001316 OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001317 OP_READ_DEVICE_IDENTIFIERS, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001318 OP_ACCESS_MEDIA_LOCATION, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001319 OP_QUERY_ALL_PACKAGES, // QUERY_ALL_PACKAGES
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001320 };
1321
1322 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001323 * This maps each operation to the public string constant for it.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001324 */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001325 private static String[] sOpToString = new String[]{
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001326 OPSTR_COARSE_LOCATION,
1327 OPSTR_FINE_LOCATION,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001328 OPSTR_GPS,
1329 OPSTR_VIBRATE,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001330 OPSTR_READ_CONTACTS,
1331 OPSTR_WRITE_CONTACTS,
1332 OPSTR_READ_CALL_LOG,
1333 OPSTR_WRITE_CALL_LOG,
1334 OPSTR_READ_CALENDAR,
1335 OPSTR_WRITE_CALENDAR,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001336 OPSTR_WIFI_SCAN,
1337 OPSTR_POST_NOTIFICATION,
1338 OPSTR_NEIGHBORING_CELLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001339 OPSTR_CALL_PHONE,
1340 OPSTR_READ_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001341 OPSTR_WRITE_SMS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001342 OPSTR_RECEIVE_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001343 OPSTR_RECEIVE_EMERGENCY_BROADCAST,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001344 OPSTR_RECEIVE_MMS,
1345 OPSTR_RECEIVE_WAP_PUSH,
1346 OPSTR_SEND_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001347 OPSTR_READ_ICC_SMS,
1348 OPSTR_WRITE_ICC_SMS,
Billy Lau24b9c832015-07-20 17:34:09 +01001349 OPSTR_WRITE_SETTINGS,
1350 OPSTR_SYSTEM_ALERT_WINDOW,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001351 OPSTR_ACCESS_NOTIFICATIONS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001352 OPSTR_CAMERA,
1353 OPSTR_RECORD_AUDIO,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001354 OPSTR_PLAY_AUDIO,
1355 OPSTR_READ_CLIPBOARD,
1356 OPSTR_WRITE_CLIPBOARD,
1357 OPSTR_TAKE_MEDIA_BUTTONS,
1358 OPSTR_TAKE_AUDIO_FOCUS,
1359 OPSTR_AUDIO_MASTER_VOLUME,
1360 OPSTR_AUDIO_VOICE_VOLUME,
1361 OPSTR_AUDIO_RING_VOLUME,
1362 OPSTR_AUDIO_MEDIA_VOLUME,
1363 OPSTR_AUDIO_ALARM_VOLUME,
1364 OPSTR_AUDIO_NOTIFICATION_VOLUME,
1365 OPSTR_AUDIO_BLUETOOTH_VOLUME,
1366 OPSTR_WAKE_LOCK,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001367 OPSTR_MONITOR_LOCATION,
1368 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -07001369 OPSTR_GET_USAGE_STATS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001370 OPSTR_MUTE_MICROPHONE,
1371 OPSTR_TOAST_WINDOW,
1372 OPSTR_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -07001373 OPSTR_ACTIVATE_VPN,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001374 OPSTR_WRITE_WALLPAPER,
1375 OPSTR_ASSIST_STRUCTURE,
1376 OPSTR_ASSIST_SCREENSHOT,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001377 OPSTR_READ_PHONE_STATE,
1378 OPSTR_ADD_VOICEMAIL,
1379 OPSTR_USE_SIP,
Svet Ganov824ad6e2016-09-22 19:36:53 -07001380 OPSTR_PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001381 OPSTR_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001382 OPSTR_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001383 OPSTR_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001384 OPSTR_MOCK_LOCATION,
1385 OPSTR_READ_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001386 OPSTR_WRITE_EXTERNAL_STORAGE,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001387 OPSTR_TURN_SCREEN_ON,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001388 OPSTR_GET_ACCOUNTS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001389 OPSTR_RUN_IN_BACKGROUND,
1390 OPSTR_AUDIO_ACCESSIBILITY_VOLUME,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001391 OPSTR_READ_PHONE_NUMBERS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001392 OPSTR_REQUEST_INSTALL_PACKAGES,
Winson Chungf4ac0632017-03-17 12:34:12 -07001393 OPSTR_PICTURE_IN_PICTURE,
Chad Brubaker97b383f2017-02-02 15:04:35 -08001394 OPSTR_INSTANT_APP_START_FOREGROUND,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001395 OPSTR_ANSWER_PHONE_CALLS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001396 OPSTR_RUN_ANY_IN_BACKGROUND,
1397 OPSTR_CHANGE_WIFI_STATE,
1398 OPSTR_REQUEST_DELETE_PACKAGES,
1399 OPSTR_BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001400 OPSTR_ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001401 OPSTR_MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001402 OPSTR_START_FOREGROUND,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001403 OPSTR_BLUETOOTH_SCAN,
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001404 OPSTR_USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001405 OPSTR_ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001406 OPSTR_SMS_FINANCIAL_TRANSACTIONS,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001407 OPSTR_READ_MEDIA_AUDIO,
1408 OPSTR_WRITE_MEDIA_AUDIO,
1409 OPSTR_READ_MEDIA_VIDEO,
1410 OPSTR_WRITE_MEDIA_VIDEO,
1411 OPSTR_READ_MEDIA_IMAGES,
1412 OPSTR_WRITE_MEDIA_IMAGES,
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001413 OPSTR_LEGACY_STORAGE,
Jackal Guo8dc791e2019-01-14 10:26:42 +08001414 OPSTR_ACCESS_ACCESSIBILITY,
Michael Groover656ef912019-04-09 17:09:57 -07001415 OPSTR_READ_DEVICE_IDENTIFIERS,
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001416 OPSTR_ACCESS_MEDIA_LOCATION,
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001417 OPSTR_QUERY_ALL_PACKAGES,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001418 };
1419
1420 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001421 * This provides a simple name for each operation to be used
1422 * in debug output.
1423 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001424 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001425 "COARSE_LOCATION",
1426 "FINE_LOCATION",
1427 "GPS",
1428 "VIBRATE",
1429 "READ_CONTACTS",
1430 "WRITE_CONTACTS",
1431 "READ_CALL_LOG",
1432 "WRITE_CALL_LOG",
1433 "READ_CALENDAR",
1434 "WRITE_CALENDAR",
1435 "WIFI_SCAN",
1436 "POST_NOTIFICATION",
1437 "NEIGHBORING_CELLS",
1438 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001439 "READ_SMS",
1440 "WRITE_SMS",
1441 "RECEIVE_SMS",
1442 "RECEIVE_EMERGECY_SMS",
1443 "RECEIVE_MMS",
1444 "RECEIVE_WAP_PUSH",
1445 "SEND_SMS",
1446 "READ_ICC_SMS",
1447 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -08001448 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -08001449 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001450 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001451 "CAMERA",
1452 "RECORD_AUDIO",
1453 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001454 "READ_CLIPBOARD",
1455 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001456 "TAKE_MEDIA_BUTTONS",
1457 "TAKE_AUDIO_FOCUS",
1458 "AUDIO_MASTER_VOLUME",
1459 "AUDIO_VOICE_VOLUME",
1460 "AUDIO_RING_VOLUME",
1461 "AUDIO_MEDIA_VOLUME",
1462 "AUDIO_ALARM_VOLUME",
1463 "AUDIO_NOTIFICATION_VOLUME",
1464 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -07001465 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001466 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -07001467 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -04001468 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001469 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -04001470 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001471 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -07001472 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +00001473 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001474 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -07001475 "ASSIST_SCREENSHOT",
Eugene Suslae4ee2c22018-11-05 12:23:30 -08001476 "READ_PHONE_STATE",
Svetoslav5335b672015-04-29 12:00:51 -07001477 "ADD_VOICEMAIL",
Svetoslavc656e6f2015-04-29 14:08:16 -07001478 "USE_SIP",
Svetoslav4af76a52015-04-29 15:29:46 -07001479 "PROCESS_OUTGOING_CALLS",
Svet Ganovb9d71a62015-04-30 10:38:13 -07001480 "USE_FINGERPRINT",
Svet Ganovede43162015-05-02 17:42:44 -07001481 "BODY_SENSORS",
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001482 "READ_CELL_BROADCASTS",
Svet Ganov921c7df2015-06-29 21:51:41 -07001483 "MOCK_LOCATION",
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001484 "READ_EXTERNAL_STORAGE",
1485 "WRITE_EXTERNAL_STORAGE",
1486 "TURN_ON_SCREEN",
Svetoslavf3f02ac2015-09-08 14:36:35 -07001487 "GET_ACCOUNTS",
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001488 "RUN_IN_BACKGROUND",
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001489 "AUDIO_ACCESSIBILITY_VOLUME",
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001490 "READ_PHONE_NUMBERS",
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001491 "REQUEST_INSTALL_PACKAGES",
Winson Chungf4ac0632017-03-17 12:34:12 -07001492 "PICTURE_IN_PICTURE",
Chad Brubaker97b383f2017-02-02 15:04:35 -08001493 "INSTANT_APP_START_FOREGROUND",
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001494 "ANSWER_PHONE_CALLS",
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001495 "RUN_ANY_IN_BACKGROUND",
Peter Visontay1246d9e2017-10-17 17:02:45 +01001496 "CHANGE_WIFI_STATE",
Peter Visontayf2e38362017-11-27 15:27:16 +00001497 "REQUEST_DELETE_PACKAGES",
Peter Visontay11950832017-11-14 19:34:59 +00001498 "BIND_ACCESSIBILITY_SERVICE",
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001499 "ACCEPT_HANDOVER",
Nathan Harold1bb420672018-03-14 17:08:53 -07001500 "MANAGE_IPSEC_TUNNELS",
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001501 "START_FOREGROUND",
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001502 "BLUETOOTH_SCAN",
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001503 "USE_BIOMETRIC",
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001504 "ACTIVITY_RECOGNITION",
Hongming Jin228cd012018-11-09 14:47:50 -08001505 "SMS_FINANCIAL_TRANSACTIONS",
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001506 "READ_MEDIA_AUDIO",
1507 "WRITE_MEDIA_AUDIO",
1508 "READ_MEDIA_VIDEO",
1509 "WRITE_MEDIA_VIDEO",
1510 "READ_MEDIA_IMAGES",
1511 "WRITE_MEDIA_IMAGES",
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001512 "LEGACY_STORAGE",
Jackal Guo8dc791e2019-01-14 10:26:42 +08001513 "ACCESS_ACCESSIBILITY",
Michael Groover656ef912019-04-09 17:09:57 -07001514 "READ_DEVICE_IDENTIFIERS",
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001515 "ACCESS_MEDIA_LOCATION",
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001516 "QUERY_ALL_PACKAGES",
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001517 };
1518
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001519 /**
1520 * This optionally maps a permission to an operation. If there
1521 * is no permission associated with an operation, it is null.
1522 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001523 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001524 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001525 android.Manifest.permission.ACCESS_COARSE_LOCATION,
1526 android.Manifest.permission.ACCESS_FINE_LOCATION,
1527 null,
1528 android.Manifest.permission.VIBRATE,
1529 android.Manifest.permission.READ_CONTACTS,
1530 android.Manifest.permission.WRITE_CONTACTS,
1531 android.Manifest.permission.READ_CALL_LOG,
1532 android.Manifest.permission.WRITE_CALL_LOG,
1533 android.Manifest.permission.READ_CALENDAR,
1534 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001535 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -04001536 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001537 null, // neighboring cells shares the coarse location perm
1538 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001539 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001540 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001541 android.Manifest.permission.RECEIVE_SMS,
1542 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
1543 android.Manifest.permission.RECEIVE_MMS,
1544 android.Manifest.permission.RECEIVE_WAP_PUSH,
1545 android.Manifest.permission.SEND_SMS,
1546 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001547 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -08001548 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -08001549 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001550 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001551 android.Manifest.permission.CAMERA,
1552 android.Manifest.permission.RECORD_AUDIO,
1553 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001554 null, // no permission for reading clipboard
1555 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001556 null, // no permission for taking media buttons
1557 null, // no permission for taking audio focus
1558 null, // no permission for changing master volume
1559 null, // no permission for changing voice volume
1560 null, // no permission for changing ring volume
1561 null, // no permission for changing media volume
1562 null, // no permission for changing alarm volume
1563 null, // no permission for changing notification volume
1564 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -07001565 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001566 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -07001567 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -07001568 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -04001569 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -04001570 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -07001571 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -07001572 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +00001573 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001574 null, // no permission for receiving assist structure
1575 null, // no permission for receiving assist screenshot
Svet Ganovc3300092015-04-17 09:07:22 -07001576 Manifest.permission.READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -07001577 Manifest.permission.ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -07001578 Manifest.permission.USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -07001579 Manifest.permission.PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001580 Manifest.permission.USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001581 Manifest.permission.BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001582 Manifest.permission.READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001583 null,
1584 Manifest.permission.READ_EXTERNAL_STORAGE,
1585 Manifest.permission.WRITE_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001586 null, // no permission for turning the screen on
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001587 Manifest.permission.GET_ACCOUNTS,
1588 null, // no permission for running in background
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001589 null, // no permission for changing accessibility volume
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001590 Manifest.permission.READ_PHONE_NUMBERS,
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001591 Manifest.permission.REQUEST_INSTALL_PACKAGES,
Winson Chung59fda9e2017-01-20 16:14:51 -08001592 null, // no permission for entering picture-in-picture on hide
Chad Brubaker97b383f2017-02-02 15:04:35 -08001593 Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001594 Manifest.permission.ANSWER_PHONE_CALLS,
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001595 null, // no permission for OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001596 Manifest.permission.CHANGE_WIFI_STATE,
Peter Visontayf2e38362017-11-27 15:27:16 +00001597 Manifest.permission.REQUEST_DELETE_PACKAGES,
Peter Visontay11950832017-11-14 19:34:59 +00001598 Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001599 Manifest.permission.ACCEPT_HANDOVER,
Philip P. Moltmann4b38fbe2019-09-13 21:33:07 -07001600 Manifest.permission.MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001601 Manifest.permission.FOREGROUND_SERVICE,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001602 null, // no permission for OP_BLUETOOTH_SCAN
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001603 Manifest.permission.USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001604 Manifest.permission.ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001605 Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001606 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001607 null, // no permission for OP_WRITE_MEDIA_AUDIO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001608 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001609 null, // no permission for OP_WRITE_MEDIA_VIDEO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001610 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001611 null, // no permission for OP_WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001612 null, // no permission for OP_LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001613 null, // no permission for OP_ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001614 null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001615 Manifest.permission.ACCESS_MEDIA_LOCATION,
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001616 null, // no permission for OP_QUERY_ALL_PACKAGES
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001617 };
1618
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001619 /**
Jason Monk62062992014-05-06 09:55:28 -04001620 * Specifies whether an Op should be restricted by a user restriction.
1621 * Each Op should be filled with a restriction string from UserManager or
1622 * null to specify it is not affected by any user restriction.
1623 */
1624 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -04001625 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
1626 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
1627 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -04001628 null, //VIBRATE
1629 null, //READ_CONTACTS
1630 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -07001631 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
1632 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -04001633 null, //READ_CALENDAR
1634 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001635 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -04001636 null, //POST_NOTIFICATION
1637 null, //NEIGHBORING_CELLS
1638 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001639 UserManager.DISALLOW_SMS, //READ_SMS
1640 UserManager.DISALLOW_SMS, //WRITE_SMS
1641 UserManager.DISALLOW_SMS, //RECEIVE_SMS
1642 null, //RECEIVE_EMERGENCY_SMS
1643 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -04001644 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001645 UserManager.DISALLOW_SMS, //SEND_SMS
1646 UserManager.DISALLOW_SMS, //READ_ICC_SMS
1647 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -04001648 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -04001649 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -04001650 null, //ACCESS_NOTIFICATIONS
Makoto Onuki759a7632015-10-28 16:43:10 -07001651 UserManager.DISALLOW_CAMERA, //CAMERA
Fyodor Kupolovb5013302015-04-17 17:59:14 -07001652 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
Jason Monk62062992014-05-06 09:55:28 -04001653 null, //PLAY_AUDIO
1654 null, //READ_CLIPBOARD
1655 null, //WRITE_CLIPBOARD
1656 null, //TAKE_MEDIA_BUTTONS
1657 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -04001658 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
1659 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
1660 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
1661 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
1662 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
1663 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
1664 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -04001665 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -04001666 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
1667 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -04001668 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -04001669 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -04001670 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -07001671 null, //PROJECT_MEDIA
Tony Mak33d03a92016-06-02 15:01:16 +01001672 null, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001673 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001674 null, // ASSIST_STRUCTURE
1675 null, // ASSIST_SCREENSHOT
Svet Ganovc3300092015-04-17 09:07:22 -07001676 null, // READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001677 null, // ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001678 null, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001679 null, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001680 null, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001681 null, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001682 null, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001683 null, // MOCK_LOCATION
1684 null, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001685 null, // WRITE_EXTERNAL_STORAGE
1686 null, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001687 null, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001688 null, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001689 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001690 null, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001691 null, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001692 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001693 null, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001694 null, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001695 null, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001696 null, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001697 null, // REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001698 null, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001699 null, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001700 null, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001701 null, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001702 null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001703 null, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001704 null, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001705 UserManager.DISALLOW_SMS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001706 null, // READ_MEDIA_AUDIO
1707 null, // WRITE_MEDIA_AUDIO
1708 null, // READ_MEDIA_VIDEO
1709 null, // WRITE_MEDIA_VIDEO
1710 null, // READ_MEDIA_IMAGES
1711 null, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001712 null, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001713 null, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001714 null, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001715 null, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001716 null, // QUERY_ALL_PACKAGES
Jason Monk1c7c3192014-06-26 12:52:18 -04001717 };
1718
1719 /**
1720 * This specifies whether each option should allow the system
1721 * (and system ui) to bypass the user restriction when active.
1722 */
1723 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
Fyodor Kupolov639e73d2016-02-25 11:58:21 -08001724 true, //COARSE_LOCATION
1725 true, //FINE_LOCATION
Jason Monk1c7c3192014-06-26 12:52:18 -04001726 false, //GPS
1727 false, //VIBRATE
1728 false, //READ_CONTACTS
1729 false, //WRITE_CONTACTS
1730 false, //READ_CALL_LOG
1731 false, //WRITE_CALL_LOG
1732 false, //READ_CALENDAR
1733 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001734 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -04001735 false, //POST_NOTIFICATION
1736 false, //NEIGHBORING_CELLS
1737 false, //CALL_PHONE
1738 false, //READ_SMS
1739 false, //WRITE_SMS
1740 false, //RECEIVE_SMS
1741 false, //RECEIVE_EMERGECY_SMS
1742 false, //RECEIVE_MMS
1743 false, //RECEIVE_WAP_PUSH
1744 false, //SEND_SMS
1745 false, //READ_ICC_SMS
1746 false, //WRITE_ICC_SMS
1747 false, //WRITE_SETTINGS
1748 true, //SYSTEM_ALERT_WINDOW
1749 false, //ACCESS_NOTIFICATIONS
1750 false, //CAMERA
1751 false, //RECORD_AUDIO
1752 false, //PLAY_AUDIO
1753 false, //READ_CLIPBOARD
1754 false, //WRITE_CLIPBOARD
1755 false, //TAKE_MEDIA_BUTTONS
1756 false, //TAKE_AUDIO_FOCUS
1757 false, //AUDIO_MASTER_VOLUME
1758 false, //AUDIO_VOICE_VOLUME
1759 false, //AUDIO_RING_VOLUME
1760 false, //AUDIO_MEDIA_VOLUME
1761 false, //AUDIO_ALARM_VOLUME
1762 false, //AUDIO_NOTIFICATION_VOLUME
1763 false, //AUDIO_BLUETOOTH_VOLUME
1764 false, //WAKE_LOCK
1765 false, //MONITOR_LOCATION
1766 false, //MONITOR_HIGH_POWER_LOCATION
1767 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -07001768 false, //MUTE_MICROPHONE
1769 true, //TOAST_WINDOW
1770 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -07001771 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001772 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001773 false, //ASSIST_STRUCTURE
1774 false, //ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -07001775 false, //READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001776 false, //ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001777 false, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001778 false, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001779 false, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001780 false, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001781 false, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001782 false, // MOCK_LOCATION
1783 false, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001784 false, // WRITE_EXTERNAL_STORAGE
1785 false, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001786 false, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001787 false, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001788 false, // AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001789 false, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001790 false, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001791 false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001792 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001793 false, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001794 false, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001795 false, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001796 false, // OP_REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001797 false, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001798 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001799 false, // MANAGE_IPSEC_HANDOVERS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001800 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001801 true, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001802 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001803 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001804 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001805 false, // READ_MEDIA_AUDIO
1806 false, // WRITE_MEDIA_AUDIO
1807 false, // READ_MEDIA_VIDEO
1808 false, // WRITE_MEDIA_VIDEO
1809 false, // READ_MEDIA_IMAGES
1810 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001811 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001812 false, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001813 false, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001814 false, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001815 false, // QUERY_ALL_PACKAGES
Jason Monk62062992014-05-06 09:55:28 -04001816 };
1817
1818 /**
David Braunf5d83192013-09-16 13:43:51 -07001819 * This specifies the default mode for each operation.
1820 */
1821 private static int[] sOpDefaultMode = new int[] {
Eugene Susla93519852018-06-13 16:44:31 -07001822 AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION
1823 AppOpsManager.MODE_ALLOWED, // FINE_LOCATION
1824 AppOpsManager.MODE_ALLOWED, // GPS
1825 AppOpsManager.MODE_ALLOWED, // VIBRATE
1826 AppOpsManager.MODE_ALLOWED, // READ_CONTACTS
1827 AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS
Svet Ganovd563e932019-04-14 13:07:41 -07001828 AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG
1829 AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG
Eugene Susla93519852018-06-13 16:44:31 -07001830 AppOpsManager.MODE_ALLOWED, // READ_CALENDAR
1831 AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR
1832 AppOpsManager.MODE_ALLOWED, // WIFI_SCAN
1833 AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION
1834 AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS
1835 AppOpsManager.MODE_ALLOWED, // CALL_PHONE
Svet Ganovd563e932019-04-14 13:07:41 -07001836 AppOpsManager.MODE_ALLOWED, // READ_SMS
Eugene Suslaaaff0072018-10-30 13:35:03 -07001837 AppOpsManager.MODE_IGNORED, // WRITE_SMS
Svet Ganovd563e932019-04-14 13:07:41 -07001838 AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001839 AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST
Svet Ganovd563e932019-04-14 13:07:41 -07001840 AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS
1841 AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH
1842 AppOpsManager.MODE_ALLOWED, // SEND_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001843 AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS
1844 AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS
1845 AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS
Ng Zhi An65a99b62018-10-01 11:57:53 -07001846 getSystemAlertWindowDefault(), // SYSTEM_ALERT_WINDOW
Eugene Susla93519852018-06-13 16:44:31 -07001847 AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS
1848 AppOpsManager.MODE_ALLOWED, // CAMERA
1849 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO
1850 AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO
1851 AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD
1852 AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD
1853 AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS
1854 AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS
1855 AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME
1856 AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME
1857 AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME
1858 AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME
1859 AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME
1860 AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME
1861 AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME
1862 AppOpsManager.MODE_ALLOWED, // WAKE_LOCK
1863 AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION
1864 AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION
1865 AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS
1866 AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE
1867 AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW
1868 AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA
1869 AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN
1870 AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER
1871 AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE
1872 AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT
1873 AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE
1874 AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL
1875 AppOpsManager.MODE_ALLOWED, // USE_SIP
Svet Ganovd563e932019-04-14 13:07:41 -07001876 AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07001877 AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT
1878 AppOpsManager.MODE_ALLOWED, // BODY_SENSORS
Svet Ganovd563e932019-04-14 13:07:41 -07001879 AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS
Eugene Susla93519852018-06-13 16:44:31 -07001880 AppOpsManager.MODE_ERRORED, // MOCK_LOCATION
1881 AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE
1882 AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE
1883 AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON
1884 AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS
1885 AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND
1886 AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME
1887 AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS
1888 AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES
1889 AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE
1890 AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND
1891 AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
1892 AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND
1893 AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE
1894 AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES
1895 AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE
1896 AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER
1897 AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS
1898 AppOpsManager.MODE_ALLOWED, // START_FOREGROUND
1899 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN
1900 AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001901 AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001902 AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001903 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001904 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001905 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001906 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001907 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001908 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001909 AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001910 AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001911 AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001912 AppOpsManager.MODE_ALLOWED, // ALLOW_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001913 AppOpsManager.MODE_DEFAULT, // QUERY_ALL_PACKAGES
David Braunf5d83192013-09-16 13:43:51 -07001914 };
1915
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001916 /**
1917 * This specifies whether each option is allowed to be reset
1918 * when resetting all app preferences. Disable reset for
1919 * app ops that are under strong control of some part of the
1920 * system (such as OP_WRITE_SMS, which should be allowed only
1921 * for whichever app is selected as the current SMS app).
1922 */
1923 private static boolean[] sOpDisableReset = new boolean[] {
Eugene Susla93519852018-06-13 16:44:31 -07001924 false, // COARSE_LOCATION
1925 false, // FINE_LOCATION
1926 false, // GPS
1927 false, // VIBRATE
1928 false, // READ_CONTACTS
1929 false, // WRITE_CONTACTS
1930 false, // READ_CALL_LOG
1931 false, // WRITE_CALL_LOG
1932 false, // READ_CALENDAR
1933 false, // WRITE_CALENDAR
1934 false, // WIFI_SCAN
1935 false, // POST_NOTIFICATION
1936 false, // NEIGHBORING_CELLS
1937 false, // CALL_PHONE
1938 true, // READ_SMS
1939 true, // WRITE_SMS
1940 true, // RECEIVE_SMS
1941 false, // RECEIVE_EMERGENCY_BROADCAST
1942 false, // RECEIVE_MMS
1943 true, // RECEIVE_WAP_PUSH
1944 true, // SEND_SMS
1945 false, // READ_ICC_SMS
1946 false, // WRITE_ICC_SMS
1947 false, // WRITE_SETTINGS
1948 false, // SYSTEM_ALERT_WINDOW
1949 false, // ACCESS_NOTIFICATIONS
1950 false, // CAMERA
1951 false, // RECORD_AUDIO
1952 false, // PLAY_AUDIO
1953 false, // READ_CLIPBOARD
1954 false, // WRITE_CLIPBOARD
1955 false, // TAKE_MEDIA_BUTTONS
1956 false, // TAKE_AUDIO_FOCUS
1957 false, // AUDIO_MASTER_VOLUME
1958 false, // AUDIO_VOICE_VOLUME
1959 false, // AUDIO_RING_VOLUME
1960 false, // AUDIO_MEDIA_VOLUME
1961 false, // AUDIO_ALARM_VOLUME
1962 false, // AUDIO_NOTIFICATION_VOLUME
1963 false, // AUDIO_BLUETOOTH_VOLUME
1964 false, // WAKE_LOCK
1965 false, // MONITOR_LOCATION
1966 false, // MONITOR_HIGH_POWER_LOCATION
1967 false, // GET_USAGE_STATS
1968 false, // MUTE_MICROPHONE
1969 false, // TOAST_WINDOW
1970 false, // PROJECT_MEDIA
1971 false, // ACTIVATE_VPN
1972 false, // WRITE_WALLPAPER
1973 false, // ASSIST_STRUCTURE
1974 false, // ASSIST_SCREENSHOT
1975 false, // READ_PHONE_STATE
1976 false, // ADD_VOICEMAIL
1977 false, // USE_SIP
1978 false, // PROCESS_OUTGOING_CALLS
1979 false, // USE_FINGERPRINT
1980 false, // BODY_SENSORS
1981 true, // READ_CELL_BROADCASTS
1982 false, // MOCK_LOCATION
1983 false, // READ_EXTERNAL_STORAGE
1984 false, // WRITE_EXTERNAL_STORAGE
1985 false, // TURN_SCREEN_ON
1986 false, // GET_ACCOUNTS
1987 false, // RUN_IN_BACKGROUND
1988 false, // AUDIO_ACCESSIBILITY_VOLUME
1989 false, // READ_PHONE_NUMBERS
1990 false, // REQUEST_INSTALL_PACKAGES
1991 false, // PICTURE_IN_PICTURE
1992 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001993 false, // ANSWER_PHONE_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07001994 false, // RUN_ANY_IN_BACKGROUND
1995 false, // CHANGE_WIFI_STATE
1996 false, // REQUEST_DELETE_PACKAGES
1997 false, // BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001998 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001999 false, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07002000 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07002001 false, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07002002 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01002003 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08002004 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07002005 false, // READ_MEDIA_AUDIO
2006 false, // WRITE_MEDIA_AUDIO
2007 false, // READ_MEDIA_VIDEO
2008 false, // WRITE_MEDIA_VIDEO
2009 false, // READ_MEDIA_IMAGES
2010 false, // WRITE_MEDIA_IMAGES
Zimc72c9d12019-11-27 15:49:33 +00002011 true, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08002012 false, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07002013 false, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07002014 false, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07002015 false, // QUERY_ALL_PACKAGES
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002016 };
2017
Svet Ganovfbf01f72015-04-28 18:39:06 -07002018 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07002019 * Mapping from an app op name to the app op code.
Svet Ganovfbf01f72015-04-28 18:39:06 -07002020 */
Svet Ganovb9d71a62015-04-30 10:38:13 -07002021 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
Svet Ganovfbf01f72015-04-28 18:39:06 -07002022
Svet Ganovb9d71a62015-04-30 10:38:13 -07002023 /**
2024 * Mapping from a permission to the corresponding app op.
2025 */
Svet Ganovda0acdf2017-02-15 10:28:51 -08002026 private static HashMap<String, Integer> sPermToOp = new HashMap<>();
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002027
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002028 /**
2029 * Set to the uid of the caller if this thread is currently executing a two-way binder
2030 * transaction. Not set if this thread is currently not executing a two way binder transaction.
2031 *
2032 * @see #startNotedAppOpsCollection
2033 * @see #markAppOpNoted
2034 */
2035 private static final ThreadLocal<Integer> sBinderThreadCallingUid = new ThreadLocal<>();
2036
2037 /**
2038 * If a thread is currently executing a two-way binder transaction, this stores the op-codes of
2039 * the app-ops that were noted during this transaction.
2040 *
2041 * @see #markAppOpNoted
2042 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002043 private static final ThreadLocal<ArrayMap<String, long[]>> sAppOpsNotedInThisBinderTransaction =
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002044 new ThreadLocal<>();
2045
2046 /** Whether noting for an appop should be collected */
2047 private static final @ShouldCollectNoteOp byte[] sAppOpsToNote = new byte[_NUM_OP];
2048
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002049 static {
2050 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002051 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002052 + " should be " + _NUM_OP);
2053 }
2054 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002055 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002056 + " should be " + _NUM_OP);
2057 }
2058 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002059 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002060 + " should be " + _NUM_OP);
2061 }
2062 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002063 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002064 + " should be " + _NUM_OP);
2065 }
2066 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002067 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
2068 + " should be " + _NUM_OP);
2069 }
2070 if (sOpDisableReset.length != _NUM_OP) {
2071 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002072 + " should be " + _NUM_OP);
2073 }
Jason Monk62062992014-05-06 09:55:28 -04002074 if (sOpRestrictions.length != _NUM_OP) {
2075 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
2076 + " should be " + _NUM_OP);
2077 }
Jason Monk1c7c3192014-06-26 12:52:18 -04002078 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
2079 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
2080 + sOpRestrictions.length + " should be " + _NUM_OP);
2081 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002082 for (int i=0; i<_NUM_OP; i++) {
2083 if (sOpToString[i] != null) {
2084 sOpStrToOp.put(sOpToString[i], i);
2085 }
2086 }
Svet Ganovda0acdf2017-02-15 10:28:51 -08002087 for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07002088 if (sOpPerms[op] != null) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002089 sPermToOp.put(sOpPerms[op], op);
Svet Ganovb9d71a62015-04-30 10:38:13 -07002090 }
2091 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002092
2093 if ((_NUM_OP + Long.SIZE - 1) / Long.SIZE != 2) {
2094 // The code currently assumes that the length of sAppOpsNotedInThisBinderTransaction is
2095 // two longs
2096 throw new IllegalStateException("notedAppOps collection code assumes < 128 appops");
2097 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002098 }
2099
Svet Ganov8455ba22019-01-02 13:05:56 -08002100 /** @hide */
2101 public static final String KEY_HISTORICAL_OPS = "historical_ops";
2102
Chad Brubaker7c6dba62019-01-23 15:51:43 -08002103 /** System properties for debug logging of noteOp call sites */
2104 private static final String DEBUG_LOGGING_ENABLE_PROP = "appops.logging_enabled";
2105 private static final String DEBUG_LOGGING_PACKAGES_PROP = "appops.logging_packages";
2106 private static final String DEBUG_LOGGING_OPS_PROP = "appops.logging_ops";
2107 private static final String DEBUG_LOGGING_TAG = "AppOpsManager";
2108
David Braunf5d83192013-09-16 13:43:51 -07002109 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002110 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002111 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002112 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002113 @UnsupportedAppUsage
Dianne Hackbornf265ea92013-01-31 15:00:51 -08002114 public static int opToSwitch(int op) {
2115 return sOpToSwitch[op];
2116 }
2117
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002118 /**
2119 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002120 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002121 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002122 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002123 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08002124 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002125 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
2126 }
2127
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002128 /**
Svet Ganov65f1b9e2019-01-17 19:19:40 -08002129 * Retrieve a non-localized public name for the operation.
2130 *
2131 * @hide
2132 */
2133 public static @NonNull String opToPublicName(int op) {
2134 return sOpToString[op];
2135 }
2136
2137 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08002138 * @hide
2139 */
2140 public static int strDebugOpToOp(String op) {
2141 for (int i=0; i<sOpNames.length; i++) {
2142 if (sOpNames[i].equals(op)) {
2143 return i;
2144 }
2145 }
2146 throw new IllegalArgumentException("Unknown operation string: " + op);
2147 }
2148
2149 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002150 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002151 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002152 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00002153 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07002154 @TestApi
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002155 public static String opToPermission(int op) {
2156 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002157 }
2158
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002159 /**
Hai Zhangb7776682018-09-25 15:10:57 -07002160 * Retrieve the permission associated with an operation, or null if there is not one.
2161 *
2162 * @param op The operation name.
2163 *
2164 * @hide
2165 */
2166 @Nullable
2167 @SystemApi
2168 public static String opToPermission(@NonNull String op) {
2169 return opToPermission(strOpToOp(op));
2170 }
2171
2172 /**
Jason Monk62062992014-05-06 09:55:28 -04002173 * Retrieve the user restriction associated with an operation, or null if there is not one.
2174 * @hide
2175 */
2176 public static String opToRestriction(int op) {
2177 return sOpRestrictions[op];
2178 }
2179
2180 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07002181 * Retrieve the app op code for a permission, or null if there is not one.
Svet Ganovda0acdf2017-02-15 10:28:51 -08002182 * This API is intended to be used for mapping runtime or appop permissions
2183 * to the corresponding app op.
Svet Ganovb9d71a62015-04-30 10:38:13 -07002184 * @hide
2185 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00002186 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07002187 @TestApi
Svet Ganovb9d71a62015-04-30 10:38:13 -07002188 public static int permissionToOpCode(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002189 Integer boxedOpCode = sPermToOp.get(permission);
Svet Ganov019d2302015-05-04 11:07:38 -07002190 return boxedOpCode != null ? boxedOpCode : OP_NONE;
Svet Ganovb9d71a62015-04-30 10:38:13 -07002191 }
2192
2193 /**
Jason Monk1c7c3192014-06-26 12:52:18 -04002194 * Retrieve whether the op allows the system (and system ui) to
2195 * bypass the user restriction.
2196 * @hide
2197 */
2198 public static boolean opAllowSystemBypassRestriction(int op) {
2199 return sOpAllowSystemRestrictionBypass[op];
2200 }
2201
2202 /**
David Braunf5d83192013-09-16 13:43:51 -07002203 * Retrieve the default mode for the operation.
2204 * @hide
2205 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002206 public static @Mode int opToDefaultMode(int op) {
David Braunf5d83192013-09-16 13:43:51 -07002207 return sOpDefaultMode[op];
2208 }
2209
2210 /**
Hai Zhangc595f112018-11-06 14:20:38 -08002211 * Retrieve the default mode for the app op.
2212 *
2213 * @param appOp The app op name
2214 *
2215 * @return the default mode for the app op
2216 *
2217 * @hide
2218 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07002219 @TestApi
Hai Zhangc595f112018-11-06 14:20:38 -08002220 @SystemApi
2221 public static int opToDefaultMode(@NonNull String appOp) {
2222 return opToDefaultMode(strOpToOp(appOp));
2223 }
2224
2225 /**
Svet Ganov82f09bc2018-01-12 22:08:40 -08002226 * Retrieve the human readable mode.
2227 * @hide
2228 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002229 public static String modeToName(@Mode int mode) {
Dianne Hackbornc216a262018-04-26 13:46:22 -07002230 if (mode >= 0 && mode < MODE_NAMES.length) {
2231 return MODE_NAMES[mode];
Svet Ganov82f09bc2018-01-12 22:08:40 -08002232 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07002233 return "mode=" + mode;
Svet Ganov82f09bc2018-01-12 22:08:40 -08002234 }
2235
2236 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002237 * Retrieve whether the op allows itself to be reset.
2238 * @hide
2239 */
2240 public static boolean opAllowsReset(int op) {
2241 return !sOpDisableReset[op];
2242 }
2243
2244 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002245 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002246 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002247 */
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002248 @SystemApi
2249 public static final class PackageOps implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002250 private final String mPackageName;
2251 private final int mUid;
2252 private final List<OpEntry> mEntries;
2253
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002254 /**
2255 * @hide
2256 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002257 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002258 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
2259 mPackageName = packageName;
2260 mUid = uid;
2261 mEntries = entries;
2262 }
2263
Svet Ganovaf189e32019-02-15 18:45:29 -08002264 /**
2265 * @return The name of the package.
2266 */
2267 public @NonNull String getPackageName() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002268 return mPackageName;
2269 }
2270
Svet Ganovaf189e32019-02-15 18:45:29 -08002271 /**
2272 * @return The uid of the package.
2273 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002274 public int getUid() {
2275 return mUid;
2276 }
2277
Svet Ganovaf189e32019-02-15 18:45:29 -08002278 /**
2279 * @return The ops of the package.
2280 */
Dianne Hackborn62878492019-03-11 15:57:07 -07002281 public @NonNull List<OpEntry> getOps() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002282 return mEntries;
2283 }
2284
2285 @Override
2286 public int describeContents() {
2287 return 0;
2288 }
2289
2290 @Override
2291 public void writeToParcel(Parcel dest, int flags) {
2292 dest.writeString(mPackageName);
2293 dest.writeInt(mUid);
2294 dest.writeInt(mEntries.size());
2295 for (int i=0; i<mEntries.size(); i++) {
2296 mEntries.get(i).writeToParcel(dest, flags);
2297 }
2298 }
2299
2300 PackageOps(Parcel source) {
2301 mPackageName = source.readString();
2302 mUid = source.readInt();
2303 mEntries = new ArrayList<OpEntry>();
2304 final int N = source.readInt();
2305 for (int i=0; i<N; i++) {
2306 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
2307 }
2308 }
2309
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07002310 public static final @android.annotation.NonNull Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002311 @Override public PackageOps createFromParcel(Parcel source) {
2312 return new PackageOps(source);
2313 }
2314
2315 @Override public PackageOps[] newArray(int size) {
2316 return new PackageOps[size];
2317 }
2318 };
2319 }
2320
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002321 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002322 * Class holding the information about one unique operation of a
2323 * {@link Context#createFeatureContext(String) feature}.
2324 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002325 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002326 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002327 @TestApi
2328 @Immutable
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002329 @SystemApi
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002330 public static final class OpFeatureEntry {
2331 private final @NonNull OpEntry mParent;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002332 private final boolean mRunning;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002333
Svet Ganovaf189e32019-02-15 18:45:29 -08002334 private final @Nullable LongSparseLongArray mAccessTimes;
2335 private final @Nullable LongSparseLongArray mRejectTimes;
2336 private final @Nullable LongSparseLongArray mDurations;
2337 private final @Nullable LongSparseLongArray mProxyUids;
2338 private final @Nullable LongSparseArray<String> mProxyPackageNames;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002339 private final @Nullable LongSparseArray<String> mProxyFeatureIds;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002340
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002341 /**
2342 * @hide
2343 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002344 public OpFeatureEntry(@NonNull OpEntry parent, boolean running,
2345 @Nullable LongSparseLongArray accessTimes,
2346 @Nullable LongSparseLongArray rejectTimes,
Svet Ganovaf189e32019-02-15 18:45:29 -08002347 @Nullable LongSparseLongArray durations, @Nullable LongSparseLongArray proxyUids,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002348 @Nullable LongSparseArray<String> proxyPackageNames,
2349 @Nullable LongSparseArray<String> proxyFeatureIds) {
2350 mParent = Preconditions.checkNotNull(parent);
Amith Yamasania1ce9632018-05-28 20:50:48 -07002351 mRunning = running;
Svet Ganovaf189e32019-02-15 18:45:29 -08002352 mAccessTimes = accessTimes;
2353 mRejectTimes = rejectTimes;
2354 mDurations = durations;
2355 mProxyUids = proxyUids;
2356 mProxyPackageNames = proxyPackageNames;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002357 mProxyFeatureIds = proxyFeatureIds;
Svet Ganovaf189e32019-02-15 18:45:29 -08002358 }
2359
2360 /**
2361 * Returns all keys for which we have mapped state in any of the data buckets -
2362 * access time, reject time, duration.
2363 * @hide */
2364 public @Nullable LongSparseArray<Object> collectKeys() {
2365 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessTimes, null);
2366 result = AppOpsManager.collectKeys(mRejectTimes, result);
2367 result = AppOpsManager.collectKeys(mDurations, result);
2368 return result;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002369 }
2370
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002371 /**
2372 * @hide
2373 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002374 public long getTime() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002375 return getLastAccessTime(OP_FLAGS_ALL);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002376 }
2377
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002378 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002379 * Return the last wall clock time in milliseconds this op was accessed.
2380 *
2381 * @param flags The flags which are any combination of
2382 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2383 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2384 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2385 * for any flag.
2386 * @return the last access time in milliseconds since
2387 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2388 *
2389 * @see #getLastAccessForegroundTime(int)
2390 * @see #getLastAccessBackgroundTime(int)
2391 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002392 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002393 public long getLastAccessTime(@OpFlags int flags) {
2394 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
2395 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002396 }
2397
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002398 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002399 * Return the last wall clock time in milliseconds this op was accessed
2400 * by the app while in the foreground.
2401 *
2402 * @param flags The flags which are any combination of
2403 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2404 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2405 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2406 * for any flag.
2407 * @return the last foreground access time in milliseconds since
2408 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2409 *
2410 * @see #getLastAccessBackgroundTime(int)
2411 * @see #getLastAccessTime(int)
2412 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002413 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002414 public long getLastAccessForegroundTime(@OpFlags int flags) {
2415 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002416 resolveFirstUnrestrictedUidState(mParent.mOp), flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002417 }
2418
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002419 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002420 * Return the last wall clock time in milliseconds this op was accessed
2421 * by the app while in the background.
2422 *
2423 * @param flags The flags which are any combination of
2424 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2425 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2426 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2427 * for any flag.
2428 * @return the last foreground access time in milliseconds since
2429 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2430 *
2431 * @see #getLastAccessForegroundTime(int)
2432 * @see #getLastAccessTime(int)
2433 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002434 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002435 public long getLastAccessBackgroundTime(@OpFlags int flags) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002436 return maxForFlagsInStates(mAccessTimes, resolveLastRestrictedUidState(mParent.mOp),
Svet Ganovaf189e32019-02-15 18:45:29 -08002437 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002438 }
2439
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002440 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002441 * Return the last wall clock time in milliseconds this op was accessed
2442 * by the app for a given range of UID states.
2443 *
2444 * @param fromUidState The UID state for which to query. Could be one of
2445 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2446 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2447 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2448 * @param toUidState The UID state for which to query.
2449 * @param flags The flags which are any combination of
2450 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2451 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2452 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2453 * for any flag.
2454 *
2455 * @return the last foreground access time in milliseconds since
2456 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2457 *
2458 * @see #getLastAccessForegroundTime(int)
2459 * @see #getLastAccessBackgroundTime(int)
2460 * @see #getLastAccessTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002461 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002462 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
2463 @OpFlags int flags) {
2464 return maxForFlagsInStates(mAccessTimes, fromUidState, toUidState, flags);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002465 }
2466
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002467 /**
2468 * @hide
2469 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002470 public long getRejectTime() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002471 return getLastRejectTime(OP_FLAGS_ALL);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002472 }
2473
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002474 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002475 * Return the last wall clock time in milliseconds the app made an attempt
2476 * to access this op but was rejected.
2477 *
2478 * @param flags The flags which are any combination of
2479 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2480 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2481 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2482 * for any flag.
2483 * @return the last reject time in milliseconds since
2484 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2485 *
2486 * @see #getLastRejectBackgroundTime(int)
2487 * @see #getLastRejectForegroundTime(int)
2488 * @see #getLastRejectTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002489 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002490 public long getLastRejectTime(@OpFlags int flags) {
2491 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
2492 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002493 }
2494
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002495 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002496 * Return the last wall clock time in milliseconds the app made an attempt
2497 * to access this op while in the foreground but was rejected.
2498 *
2499 * @param flags The flags which are any combination of
2500 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2501 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2502 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2503 * for any flag.
2504 * @return the last foreground reject time in milliseconds since
2505 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2506 *
2507 * @see #getLastRejectBackgroundTime(int)
2508 * @see #getLastRejectTime(int, int, int)
2509 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002510 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002511 public long getLastRejectForegroundTime(@OpFlags int flags) {
2512 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002513 resolveFirstUnrestrictedUidState(mParent.mOp), flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002514 }
2515
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002516 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002517 * Return the last wall clock time in milliseconds the app made an attempt
2518 * to access this op while in the background but was rejected.
2519 *
2520 * @param flags The flags which are any combination of
2521 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2522 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2523 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2524 * for any flag.
2525 * @return the last background reject time in milliseconds since
2526 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2527 *
2528 * @see #getLastRejectForegroundTime(int)
2529 * @see #getLastRejectTime(int, int, int)
2530 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002531 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002532 public long getLastRejectBackgroundTime(@OpFlags int flags) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002533 return maxForFlagsInStates(mRejectTimes, resolveLastRestrictedUidState(mParent.mOp),
Svet Ganovaf189e32019-02-15 18:45:29 -08002534 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002535 }
2536
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002537 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002538 * Return the last wall clock time state in milliseconds the app made an
2539 * attempt to access this op for a given range of UID states.
2540 *
2541 * @param fromUidState The UID state from which to query. Could be one of
2542 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2543 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2544 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2545 * @param toUidState The UID state to which to query.
2546 * @param flags The flags which are any combination of
2547 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2548 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2549 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2550 * for any flag.
2551 * @return the last foreground access time in milliseconds since
2552 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2553 *
2554 * @see #getLastRejectForegroundTime(int)
2555 * @see #getLastRejectBackgroundTime(int)
2556 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002557 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002558 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
2559 @OpFlags int flags) {
2560 return maxForFlagsInStates(mRejectTimes, fromUidState, toUidState, flags);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002561 }
2562
Svet Ganovaf189e32019-02-15 18:45:29 -08002563 /**
2564 * @return Whether the operation is running.
2565 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002566 public boolean isRunning() {
Amith Yamasania1ce9632018-05-28 20:50:48 -07002567 return mRunning;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002568 }
2569
Svet Ganovaf189e32019-02-15 18:45:29 -08002570 /**
Svet Ganov6f672a32019-07-08 16:40:42 -07002571 * @return The duration of the operation in milliseconds. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002572 */
2573 public long getDuration() {
2574 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002575 }
2576
Svet Ganovaf189e32019-02-15 18:45:29 -08002577 /**
2578 * Return the duration in milliseconds the app accessed this op while
Svet Ganov6f672a32019-07-08 16:40:42 -07002579 * in the foreground. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002580 *
2581 * @param flags The flags which are any combination of
2582 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2583 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2584 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2585 * for any flag.
2586 * @return the foreground access duration in milliseconds.
2587 *
2588 * @see #getLastBackgroundDuration(int)
2589 * @see #getLastDuration(int, int, int)
2590 */
2591 public long getLastForegroundDuration(@OpFlags int flags) {
2592 return sumForFlagsInStates(mDurations, MAX_PRIORITY_UID_STATE,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002593 resolveFirstUnrestrictedUidState(mParent.mOp), flags);
Svet Ganovaf189e32019-02-15 18:45:29 -08002594 }
2595
2596 /**
2597 * Return the duration in milliseconds the app accessed this op while
Svet Ganov6f672a32019-07-08 16:40:42 -07002598 * in the background. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002599 *
2600 * @param flags The flags which are any combination of
2601 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2602 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2603 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2604 * for any flag.
2605 * @return the background access duration in milliseconds.
2606 *
2607 * @see #getLastForegroundDuration(int)
2608 * @see #getLastDuration(int, int, int)
2609 */
2610 public long getLastBackgroundDuration(@OpFlags int flags) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002611 return sumForFlagsInStates(mDurations, resolveLastRestrictedUidState(mParent.mOp),
Svet Ganovaf189e32019-02-15 18:45:29 -08002612 MIN_PRIORITY_UID_STATE, flags);
2613 }
2614
2615 /**
2616 * Return the duration in milliseconds the app accessed this op for
Svet Ganov6f672a32019-07-08 16:40:42 -07002617 * a given range of UID states. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002618 *
2619 * @param fromUidState The UID state for which to query. Could be one of
2620 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2621 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2622 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2623 * @param toUidState The UID state for which to query.
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 * @return the access duration in milliseconds.
2630 */
2631 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
2632 @OpFlags int flags) {
2633 return sumForFlagsInStates(mDurations, fromUidState, toUidState, flags);
2634 }
2635
2636 /**
2637 * Gets the UID of the app that performed the op on behalf of this app and
2638 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2639 * there is no proxy.
2640 *
2641 * @return The proxy UID.
2642 */
Svet Ganov99b60432015-06-27 13:15:22 -07002643 public int getProxyUid() {
Philip P. Moltmann4052d362019-09-19 14:52:38 -07002644 return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
Svet Ganovaf189e32019-02-15 18:45:29 -08002645 MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
Svet Ganov99b60432015-06-27 13:15:22 -07002646 }
2647
Svet Ganovaf189e32019-02-15 18:45:29 -08002648 /**
2649 * Gets the UID of the app that performed the op on behalf of this app and
2650 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2651 * there is no proxy.
2652 *
2653 * @param uidState The UID state for which to query. Could be one of
2654 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2655 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2656 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2657 * @param flags The flags which are any combination of
2658 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2659 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2660 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2661 * for any flag.
2662 *
2663 * @return The proxy UID.
2664 */
2665 public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
Philip P. Moltmann4052d362019-09-19 14:52:38 -07002666 return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
Svet Ganovaf189e32019-02-15 18:45:29 -08002667 uidState, uidState, flags);
2668 }
2669
2670 /**
2671 * Gets the package name of the app that performed the op on behalf of this
2672 * app and as a result blamed the op on this app or {@code null}
2673 * if there is no proxy.
2674 *
2675 * @return The proxy package name.
2676 */
2677 public @Nullable String getProxyPackageName() {
2678 return findFirstNonNullForFlagsInStates(mProxyPackageNames, MAX_PRIORITY_UID_STATE,
2679 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
2680 }
2681
2682 /**
2683 * Gets the package name of the app that performed the op on behalf of this
2684 * app and as a result blamed the op on this app for a UID state or
2685 * {@code null} if there is no proxy.
2686 *
2687 * @param uidState The UID state for which to query. Could be one of
2688 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2689 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2690 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2691 * @param flags The flags which are any combination of
2692 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2693 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2694 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2695 * for any flag.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002696 * @return The feature id.
Svet Ganovaf189e32019-02-15 18:45:29 -08002697 */
2698 public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
2699 return findFirstNonNullForFlagsInStates(mProxyPackageNames, uidState, uidState, flags);
Svet Ganov99b60432015-06-27 13:15:22 -07002700 }
2701
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002702 /**
2703 * Gets the feature of the app that performed the op on behalf of this
2704 * app and as a result blamed the op on this app or {@code null}
2705 * if there is no proxy.
2706 *
2707 * @return The proxy package name.
2708 */
2709 public @Nullable String getProxyFeatureId() {
2710 return findFirstNonNullForFlagsInStates(mProxyFeatureIds, MAX_PRIORITY_UID_STATE,
2711 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
2712 }
2713
2714 /**
2715 * Gets the feature of the app that performed the op on behalf of this
2716 * app and as a result blamed the op on this app for a UID state or
2717 * {@code null} if there is no proxy.
2718 *
2719 * @param uidState The UID state for which to query. Could be one of
2720 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2721 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2722 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2723 * @param flags The flags which are any combination of
2724 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2725 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2726 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2727 * for any flag.
2728 * @return The feature id.
2729 */
2730 public @Nullable String getProxyFeatureId(@UidState int uidState, @OpFlags int flags) {
2731 return findFirstNonNullForFlagsInStates(mProxyFeatureIds, uidState, uidState, flags);
2732 }
2733
2734 /**
2735 * @hide
2736 */
2737 public static class Builder {
2738 private final boolean mRunning;
2739
2740 private final @Nullable LongSparseLongArray mAccessTimes;
2741 private final @Nullable LongSparseLongArray mRejectTimes;
2742 private final @Nullable LongSparseLongArray mDurations;
2743 private final @Nullable LongSparseLongArray mProxyUids;
2744 private final @Nullable LongSparseArray<String> mProxyPackageNames;
2745 private final @Nullable LongSparseArray<String> mProxyFeatureIds;
2746 private @NonNull OpEntry mParent;
2747
2748 public Builder(boolean running, @Nullable LongSparseLongArray accessTimes,
2749 @Nullable LongSparseLongArray rejectTimes,
2750 @Nullable LongSparseLongArray durations,
2751 @Nullable LongSparseLongArray proxyUids,
2752 @Nullable LongSparseArray<String> proxyPackageNames,
2753 @Nullable LongSparseArray<String> proxyFeatureIds) {
2754 mRunning = running;
2755 mAccessTimes = accessTimes;
2756 mRejectTimes = rejectTimes;
2757 mDurations = durations;
2758 mProxyUids = proxyUids;
2759 mProxyPackageNames = proxyPackageNames;
2760 mProxyFeatureIds = proxyFeatureIds;
2761 }
2762
2763 public Builder setParent(@NonNull OpEntry parent) {
2764 mParent = parent;
2765
2766 return this;
2767 }
2768
2769 /**
2770 * Create OpFeatureEntry from builder
2771 */
2772 public OpFeatureEntry build() {
2773 Preconditions.checkNotNull(mParent);
2774
2775 return new OpFeatureEntry(mParent, mRunning, mAccessTimes, mRejectTimes,
2776 mDurations, mProxyUids, mProxyPackageNames, mProxyFeatureIds);
2777 }
2778 }
2779
2780 /**
2781 * @hide
2782 */
2783 public void writeToParcel(@NonNull Parcel dest, int flags) {
2784 LongSparseLongArray.Parcelling longSparseLongArrayParcelling =
2785 LongSparseLongArray.Parcelling.Cache.getOrCreate(
2786 LongSparseLongArray.Parcelling.class);
2787 LongSparseArray.StringParcelling longSparseStringArrayParcelling =
2788 LongSparseArray.StringParcelling.Cache.getOrCreate(
2789 LongSparseArray.StringParcelling.class);
2790
2791 dest.writeBoolean(mRunning);
2792 longSparseLongArrayParcelling.parcel(mAccessTimes, dest, flags);
2793 longSparseLongArrayParcelling.parcel(mRejectTimes, dest, flags);
2794 longSparseLongArrayParcelling.parcel(mDurations, dest, flags);
2795 longSparseLongArrayParcelling.parcel(mProxyUids, dest, flags);
2796 longSparseStringArrayParcelling.parcel(mProxyPackageNames, dest, flags);
2797 longSparseStringArrayParcelling.parcel(mProxyFeatureIds, dest, flags);
2798 }
2799
2800 /**
2801 * @hide
2802 */
2803 public static OpFeatureEntry.Builder createFromParcel(@NonNull Parcel source) {
2804 LongSparseLongArray.Parcelling longSparseLongArrayParcelling =
2805 LongSparseLongArray.Parcelling.Cache.getOrCreate(
2806 LongSparseLongArray.Parcelling.class);
2807 LongSparseArray.StringParcelling longSparseStringArrayParcelling =
2808 LongSparseArray.StringParcelling.Cache.getOrCreate(
2809 LongSparseArray.StringParcelling.class);
2810
2811 return new OpFeatureEntry.Builder(source.readBoolean(),
Philip P. Moltmannbadc09c2019-10-23 10:28:27 -07002812 longSparseLongArrayParcelling.unparcel(source),
2813 longSparseLongArrayParcelling.unparcel(source),
2814 longSparseLongArrayParcelling.unparcel(source),
2815 longSparseLongArrayParcelling.unparcel(source),
2816 longSparseStringArrayParcelling.unparcel(source),
2817 longSparseStringArrayParcelling.unparcel(source));
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002818 }
2819 }
2820
2821 /**
2822 * Class holding the information about one unique operation of an application.
2823 * @hide
2824 */
2825 @TestApi
2826 @Immutable
2827 @SystemApi
2828 public static final class OpEntry implements Parcelable {
2829 private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp;
2830 private final @Mode int mMode;
2831 private final @NonNull ArrayMap<String, OpFeatureEntry> mFeatures;
2832
2833 /**
2834 * @hide
2835 */
2836 public OpEntry(@IntRange(from = 0, to = _NUM_OP - 1) int op, @Mode int mode,
2837 @NonNull Pair<String, OpFeatureEntry.Builder>[] featureBuilders) {
2838 mOp = Preconditions.checkArgumentInRange(op, 0, _NUM_OP - 1, "op");
2839 mMode = Preconditions.checkArgumentInRange(mode, 0, MODE_FOREGROUND, "mode");
2840
2841 mFeatures = new ArrayMap<>(featureBuilders.length);
2842 for (Pair<String, OpFeatureEntry.Builder> feature : featureBuilders) {
2843 mFeatures.put(feature.first, feature.second.setParent(this).build());
2844 }
2845 }
2846
2847 /**
2848 * @return The mapping from the feature ids to the feature state
2849 */
2850 public @NonNull Map<String, OpFeatureEntry> getFeatures() {
2851 return mFeatures;
2852 }
2853
2854 /**
2855 * @hide
2856 */
2857 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
2858 + "#getOpStr()}")
2859 public int getOp() {
2860 return mOp;
2861 }
2862
2863 /**
2864 * @return This entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}.
2865 */
2866 public @NonNull String getOpStr() {
2867 return sOpToString[mOp];
2868 }
2869
2870 /**
2871 * @return this entry's current mode, such as {@link #MODE_ALLOWED}.
2872 */
2873 public @Mode int getMode() {
2874 return mMode;
2875 }
2876
2877 /**
2878 * @deprecated Use {@link OpEntry#getLastAccessTime(int)} instead
2879 *
2880 * @hide
2881 */
2882 @Deprecated
2883 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
2884 + "#getLastAccessTime(int)}")
2885 public long getTime() {
2886 return getLastAccessTime(OP_FLAGS_ALL);
2887 }
2888
2889 private long getMaxOfFeatures(@NonNull ToLongFunction<OpFeatureEntry> timeGetter) {
2890 long max = 0;
2891
2892 int numFeatures = mFeatures.size();
2893 for (int i = 0; i < numFeatures; i++) {
2894 max = Math.max(max, timeGetter.applyAsLong(mFeatures.valueAt(i)));
2895 }
2896
2897 return max;
2898 }
2899
2900 private long getSumOfFeatures(@NonNull ToLongFunction<OpFeatureEntry> getter) {
2901 long sum = 0;
2902
2903 int numFeatures = mFeatures.size();
2904 for (int i = 0; i < numFeatures; i++) {
2905 sum += getter.applyAsLong(mFeatures.valueAt(i));
2906 }
2907
2908 return sum;
2909 }
2910
2911 /**
2912 * Return the last wall clock time in milliseconds this op was accessed
2913 * by the app for a given range of UID states.
2914 *
2915 * @param fromUidState The UID state for which to query. Could be one of
2916 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2917 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2918 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2919 * @param toUidState The UID state for which to query.
2920 * @param flags The flags which are any combination of
2921 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2922 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2923 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2924 * for any flag.
2925 *
2926 * @return the last foreground access time in milliseconds since
2927 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2928 *
2929 * @see #getLastAccessForegroundTime(int)
2930 * @see #getLastAccessBackgroundTime(int)
2931 * @see #getLastAccessTime(int)
2932 */
2933 public long getLastAccessTime(@OpFlags int flags) {
2934 return getMaxOfFeatures(
2935 (featureEntry -> featureEntry.getLastAccessTime(flags)));
2936 }
2937
2938 /**
2939 * Return the last wall clock time in milliseconds this op was accessed
2940 * by the app while in the foreground.
2941 *
2942 * @param flags The flags which are any combination of
2943 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2944 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2945 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2946 * for any flag.
2947 * @return the last foreground access time in milliseconds since
2948 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2949 *
2950 * @see #getLastAccessBackgroundTime(int)
2951 * @see #getLastAccessTime(int)
2952 * @see #getLastAccessTime(int, int, int)
2953 */
2954 public long getLastAccessForegroundTime(@OpFlags int flags) {
2955 return getMaxOfFeatures(
2956 (featureEntry -> featureEntry.getLastAccessForegroundTime(flags)));
2957 }
2958
2959 /**
2960 * Return the last wall clock time in milliseconds this op was accessed
2961 * by the app while in the background.
2962 *
2963 * @param flags The flags which are any combination of
2964 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2965 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2966 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2967 * for any flag.
2968 * @return the last foreground access time in milliseconds since
2969 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2970 *
2971 * @see #getLastAccessForegroundTime(int)
2972 * @see #getLastAccessTime(int)
2973 * @see #getLastAccessTime(int, int, int)
2974 */
2975 public long getLastAccessBackgroundTime(@OpFlags int flags) {
2976 return getMaxOfFeatures(
2977 (featureEntry -> featureEntry.getLastAccessBackgroundTime(flags)));
2978 }
2979
2980 /**
2981 * Return the last wall clock time in milliseconds this op was accessed
2982 * by the app for a given range of UID states.
2983 *
2984 * @param fromUidState The UID state for which to query. Could be one of
2985 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2986 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2987 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2988 * @param toUidState The UID state for which to query.
2989 * @param flags The flags which are any combination of
2990 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2991 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2992 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2993 * for any flag.
2994 *
2995 * @return the last foreground access time in milliseconds since
2996 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2997 *
2998 * @see #getLastAccessForegroundTime(int)
2999 * @see #getLastAccessBackgroundTime(int)
3000 * @see #getLastAccessTime(int)
3001 */
3002 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
3003 @OpFlags int flags) {
3004 return getMaxOfFeatures(
3005 (featureEntry -> featureEntry.getLastAccessTime(fromUidState,
3006 toUidState, flags)));
3007 }
3008
3009 /**
3010 * @deprecated Use {@link OpEntry#getLastRejectTime(int)} instead
3011 *
3012 * @hide
3013 */
3014 @Deprecated
3015 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
3016 + "#getLastRejectTime(int)}")
3017 public long getRejectTime() {
3018 return getLastRejectTime(OP_FLAGS_ALL);
3019 }
3020
3021 /**
3022 * Return the last wall clock time in milliseconds the app made an attempt
3023 * to access this op but was rejected.
3024 *
3025 * @param flags The flags which are any combination of
3026 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3027 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3028 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3029 * for any flag.
3030 * @return the last reject time in milliseconds since
3031 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3032 *
3033 * @see #getLastRejectBackgroundTime(int)
3034 * @see #getLastRejectForegroundTime(int)
3035 * @see #getLastRejectTime(int, int, int)
3036 */
3037 public long getLastRejectTime(@OpFlags int flags) {
3038 return getMaxOfFeatures(
3039 (featureEntry -> featureEntry.getLastRejectTime(flags)));
3040 }
3041
3042 /**
3043 * Return the last wall clock time in milliseconds the app made an attempt
3044 * to access this op while in the foreground but was rejected.
3045 *
3046 * @param flags The flags which are any combination of
3047 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3048 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3049 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3050 * for any flag.
3051 * @return the last foreground reject time in milliseconds since
3052 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3053 *
3054 * @see #getLastRejectBackgroundTime(int)
3055 * @see #getLastRejectTime(int, int, int)
3056 * @see #getLastRejectTime(int)
3057 */
3058 public long getLastRejectForegroundTime(@OpFlags int flags) {
3059 return getMaxOfFeatures(
3060 (featureEntry -> featureEntry.getLastRejectForegroundTime(flags)));
3061 }
3062
3063 /**
3064 * Return the last wall clock time in milliseconds the app made an attempt
3065 * to access this op while in the background but was rejected.
3066 *
3067 * @param flags The flags which are any combination of
3068 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3069 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3070 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3071 * for any flag.
3072 * @return the last background reject time in milliseconds since
3073 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3074 *
3075 * @see #getLastRejectForegroundTime(int)
3076 * @see #getLastRejectTime(int, int, int)
3077 * @see #getLastRejectTime(int)
3078 */
3079 public long getLastRejectBackgroundTime(@OpFlags int flags) {
3080 return getMaxOfFeatures(
3081 (featureEntry -> featureEntry.getLastRejectBackgroundTime(flags)));
3082 }
3083
3084 /**
3085 * Return the last wall clock time state in milliseconds the app made an
3086 * attempt to access this op for a given range of UID states.
3087 *
3088 * @param fromUidState The UID state from which to query. Could be one of
3089 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
3090 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3091 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3092 * @param toUidState The UID state to which to query.
3093 * @param flags The flags which are any combination of
3094 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3095 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3096 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3097 * for any flag.
3098 * @return the last foreground access time in milliseconds since
3099 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3100 *
3101 * @see #getLastRejectForegroundTime(int)
3102 * @see #getLastRejectBackgroundTime(int)
3103 * @see #getLastRejectTime(int)
3104 */
3105 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
3106 @OpFlags int flags) {
3107 return getMaxOfFeatures(
3108 (featureEntry -> featureEntry.getLastRejectTime(fromUidState,
3109 toUidState, flags)));
3110 }
3111
3112 /**
3113 * @return Whether the operation is running.
3114 */
3115 public boolean isRunning() {
3116 int numFeatures = mFeatures.size();
3117 if (mFeatures.isEmpty()) {
3118 return false;
3119 }
3120
3121 for (int i = 0; i < numFeatures; i++) {
3122 if (mFeatures.valueAt(i).mRunning) {
3123 return true;
3124 }
3125 }
3126
3127 return false;
3128 }
3129
3130 /**
3131 * @return The duration of the operation in milliseconds. The duration is in wall time.
3132 */
3133 public long getDuration() {
3134 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
3135 }
3136
3137 /**
3138 * Return the duration in milliseconds the app accessed this op while
3139 * in the foreground. The duration is in wall time.
3140 *
3141 * @param flags The flags which are any combination of
3142 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3143 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3144 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3145 * for any flag.
3146 * @return the foreground access duration in milliseconds.
3147 *
3148 * @see #getLastBackgroundDuration(int)
3149 * @see #getLastDuration(int, int, int)
3150 */
3151 public long getLastForegroundDuration(@OpFlags int flags) {
3152 return getSumOfFeatures((featureEntry) ->
3153 featureEntry.getLastForegroundDuration(flags));
3154 }
3155
3156 /**
3157 * Return the duration in milliseconds the app accessed this op while
3158 * in the background. The duration is in wall time.
3159 *
3160 * @param flags The flags which are any combination of
3161 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3162 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3163 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3164 * for any flag.
3165 * @return the background access duration in milliseconds.
3166 *
3167 * @see #getLastForegroundDuration(int)
3168 * @see #getLastDuration(int, int, int)
3169 */
3170 public long getLastBackgroundDuration(@OpFlags int flags) {
3171 return getSumOfFeatures((featureEntry) ->
3172 featureEntry.getLastBackgroundDuration(flags));
3173 }
3174
3175 /**
3176 * Return the duration in milliseconds the app accessed this op for
3177 * a given range of UID states. The duration is in wall time.
3178 *
3179 * @param fromUidState The UID state for which to query. Could be one of
3180 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
3181 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3182 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3183 * @param toUidState The UID state for which to query.
3184 * @param flags The flags which are any combination of
3185 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3186 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3187 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3188 * for any flag.
3189 * @return the access duration in milliseconds.
3190 */
3191 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
3192 @OpFlags int flags) {
3193 return getSumOfFeatures((featureEntry) ->
3194 featureEntry.getLastDuration(fromUidState, toUidState, flags));
3195 }
3196
3197 /**
3198 * Like {@link #findFirstNonNegativeForFlagsInStates(LongSparseLongArray, int, int, int)}
3199 * but for all proxy uid in all features.
3200 */
3201 private long findFirstNonNegativeProxyUidInFeatureStates(@UidState int beginUidState,
3202 @UidState int endUidState, @OpFlags int flags) {
3203 int numFeatures = mFeatures.size();
3204
3205 if (numFeatures == 0) {
3206 return -1;
3207 }
3208
3209 while (flags != 0) {
3210 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
3211 flags &= ~flag;
3212 for (int uidState : UID_STATES) {
3213 if (uidState < beginUidState || uidState > endUidState) {
3214 continue;
3215 }
3216
3217 final long key = makeKey(uidState, flag);
3218
3219 for (int i = 0; i < numFeatures; i++) {
3220 OpFeatureEntry featureEntry = mFeatures.valueAt(i);
3221
3222 if (featureEntry.mProxyUids == null) {
3223 continue;
3224 }
3225
3226 final long proxyUid = featureEntry.mProxyUids.get(key);
3227 if (proxyUid >= 0) {
3228 return proxyUid;
3229 }
3230 }
3231 }
3232 }
3233
3234 return -1;
3235 }
3236
3237 /**
3238 * Like {@link #findFirstNonNullForFlagsInStates(LongSparseArray, int, int, int)} but
3239 * for all proxyPackageNames in all features.
3240 */
3241 private @Nullable String findFirstNonNullProxyPackageNameInFeatureStates(
3242 @OpFlags int flags, @UidState int beginUidState, @UidState int endUidState) {
3243 int numFeatures = mFeatures.size();
3244
3245 if (numFeatures == 0) {
3246 return null;
3247 }
3248
3249 while (flags != 0) {
3250 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
3251 flags &= ~flag;
3252 for (int uidState : UID_STATES) {
3253 if (uidState < beginUidState || uidState > endUidState) {
3254 continue;
3255 }
3256 final long key = makeKey(uidState, flag);
3257
3258 for (int i = 0; i < numFeatures; i++) {
3259 OpFeatureEntry featureEntry = mFeatures.valueAt(i);
3260
3261 if (featureEntry.mProxyPackageNames == null) {
3262 continue;
3263 }
3264
3265 final String proxyName = featureEntry.mProxyPackageNames.get(key);
3266 if (proxyName != null) {
3267 return proxyName;
3268 }
3269 }
3270 }
3271 }
3272 return null;
3273 }
3274
3275 /**
3276 * @deprecated Use {@link #getProxyUid(int, int)} instead
3277 */
3278 @Deprecated
3279 public int getProxyUid() {
3280 return (int) findFirstNonNegativeProxyUidInFeatureStates(MAX_PRIORITY_UID_STATE,
3281 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
3282 }
3283
3284 /**
3285 * Gets the UID of the app that performed the op on behalf of this app and
3286 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
3287 * there is no proxy.
3288 *
3289 * @param uidState The UID state for which to query. Could be one of
3290 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
3291 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3292 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3293 * @param flags The flags which are any combination of
3294 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3295 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3296 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3297 * for any flag.
3298 *
3299 * @return The proxy UID.
3300 */
3301 public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
3302 return (int) findFirstNonNegativeProxyUidInFeatureStates(uidState, uidState, flags);
3303 }
3304
3305 /**
3306 * @deprecated Use {@link #getProxyPackageName(int, int)} instead
3307 */
3308 @Deprecated
3309 public @Nullable String getProxyPackageName() {
3310 return findFirstNonNullProxyPackageNameInFeatureStates(MAX_PRIORITY_UID_STATE,
3311 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
3312 }
3313
3314 /**
3315 * Gets the package name of the app that performed the op on behalf of this
3316 * app and as a result blamed the op on this app for a UID state or
3317 * {@code null} if there is no proxy.
3318 *
3319 * @param uidState The UID state for which to query. Could be one of
3320 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
3321 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3322 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3323 * @param flags The flags which are any combination of
3324 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3325 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3326 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3327 * for any flag.
3328 * @return The proxy package name.
3329 */
3330 public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
3331 return findFirstNonNullProxyPackageNameInFeatureStates(uidState, uidState, flags);
3332 }
3333
3334 /**
3335 * Create OpEntry from parcel.
3336 *
3337 * @hide
3338 */
3339 public static OpEntry createFromParcel(@NonNull Parcel source) {
3340 int op = source.readInt();
3341 int mode = source.readInt();
3342
3343 int numFeatures = source.readInt();
3344 Pair<String, OpFeatureEntry.Builder>[] features = new Pair[numFeatures];
3345 for (int i = 0; i < numFeatures; i++) {
3346 features[i] = new Pair<>(source.readString(),
3347 OpFeatureEntry.createFromParcel(source));
3348 }
3349
3350 return new OpEntry(op, mode, features);
3351 }
3352
Dianne Hackborn35654b62013-01-14 17:38:02 -08003353 @Override
3354 public int describeContents() {
3355 return 0;
3356 }
3357
3358 @Override
3359 public void writeToParcel(Parcel dest, int flags) {
3360 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08003361 dest.writeInt(mMode);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003362
3363 int numFeatures = mFeatures.size();
3364 dest.writeInt(numFeatures);
3365 for (int i = 0; i < numFeatures; i++) {
3366 dest.writeString(mFeatures.keyAt(i));
3367 mFeatures.valueAt(i).writeToParcel(dest, flags);
3368 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08003369 }
3370
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003371 public static final @NonNull Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
3372 @Override
3373 public @NonNull OpEntry createFromParcel(@NonNull Parcel parcel) {
3374 return OpEntry.createFromParcel(parcel);
Dianne Hackborn35654b62013-01-14 17:38:02 -08003375 }
3376
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003377 @Override
3378 public @NonNull OpEntry[] newArray(int size) {
Dianne Hackborn35654b62013-01-14 17:38:02 -08003379 return new OpEntry[size];
3380 }
3381 };
3382 }
3383
Svet Ganov8455ba22019-01-02 13:05:56 -08003384 /** @hide */
3385 public interface HistoricalOpsVisitor {
3386 void visitHistoricalOps(@NonNull HistoricalOps ops);
3387 void visitHistoricalUidOps(@NonNull HistoricalUidOps ops);
3388 void visitHistoricalPackageOps(@NonNull HistoricalPackageOps ops);
3389 void visitHistoricalOp(@NonNull HistoricalOp ops);
3390 }
3391
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08003392 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08003393 * Request for getting historical app op usage. The request acts
3394 * as a filtering criteria when querying historical op usage.
3395 *
3396 * @hide
3397 */
3398 @Immutable
3399 @TestApi
3400 @SystemApi
3401 public static final class HistoricalOpsRequest {
3402 private final int mUid;
3403 private final @Nullable String mPackageName;
3404 private final @Nullable List<String> mOpNames;
3405 private final long mBeginTimeMillis;
3406 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08003407 private final @OpFlags int mFlags;
Svet Ganov23c88db2019-01-22 20:38:11 -08003408
3409 private HistoricalOpsRequest(int uid, @Nullable String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003410 @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
3411 @OpFlags int flags) {
Svet Ganov23c88db2019-01-22 20:38:11 -08003412 mUid = uid;
3413 mPackageName = packageName;
3414 mOpNames = opNames;
3415 mBeginTimeMillis = beginTimeMillis;
3416 mEndTimeMillis = endTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08003417 mFlags = flags;
Svet Ganov23c88db2019-01-22 20:38:11 -08003418 }
3419
3420 /**
3421 * Builder for creating a {@link HistoricalOpsRequest}.
3422 *
3423 * @hide
3424 */
3425 @TestApi
3426 @SystemApi
3427 public static final class Builder {
3428 private int mUid = Process.INVALID_UID;
3429 private @Nullable String mPackageName;
3430 private @Nullable List<String> mOpNames;
3431 private final long mBeginTimeMillis;
3432 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08003433 private @OpFlags int mFlags = OP_FLAGS_ALL;
Svet Ganov23c88db2019-01-22 20:38:11 -08003434
3435 /**
3436 * Creates a new builder.
3437 *
3438 * @param beginTimeMillis The beginning of the interval in milliseconds since
3439 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non
3440 * negative.
3441 * @param endTimeMillis The end of the interval in milliseconds since
3442 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after
3443 * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent
3444 * history including ops that happen while this call is in flight.
3445 */
3446 public Builder(long beginTimeMillis, long endTimeMillis) {
3447 Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
3448 "beginTimeMillis must be non negative and lesser than endTimeMillis");
3449 mBeginTimeMillis = beginTimeMillis;
3450 mEndTimeMillis = endTimeMillis;
3451 }
3452
3453 /**
3454 * Sets the UID to query for.
3455 *
3456 * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid.
3457 * @return This builder.
3458 */
3459 public @NonNull Builder setUid(int uid) {
3460 Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
3461 "uid must be " + Process.INVALID_UID + " or non negative");
3462 mUid = uid;
3463 return this;
3464 }
3465
3466 /**
3467 * Sets the package to query for.
3468 *
3469 * @param packageName The package name. <code>Null</code> for any package.
3470 * @return This builder.
3471 */
3472 public @NonNull Builder setPackageName(@Nullable String packageName) {
3473 mPackageName = packageName;
3474 return this;
3475 }
3476
3477 /**
3478 * Sets the op names to query for.
3479 *
3480 * @param opNames The op names. <code>Null</code> for any op.
3481 * @return This builder.
3482 */
3483 public @NonNull Builder setOpNames(@Nullable List<String> opNames) {
3484 if (opNames != null) {
3485 final int opCount = opNames.size();
3486 for (int i = 0; i < opCount; i++) {
3487 Preconditions.checkArgument(AppOpsManager.strOpToOp(
3488 opNames.get(i)) != AppOpsManager.OP_NONE);
3489 }
3490 }
3491 mOpNames = opNames;
3492 return this;
3493 }
3494
3495 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08003496 * Sets the op flags to query for. The flags specify the type of
3497 * op data being queried.
3498 *
3499 * @param flags The flags which are any combination of
3500 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3501 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3502 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3503 * for any flag.
3504 * @return This builder.
3505 */
3506 public @NonNull Builder setFlags(@OpFlags int flags) {
3507 Preconditions.checkFlagsArgument(flags, OP_FLAGS_ALL);
3508 mFlags = flags;
3509 return this;
3510 }
3511
3512 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08003513 * @return a new {@link HistoricalOpsRequest}.
3514 */
3515 public @NonNull HistoricalOpsRequest build() {
3516 return new HistoricalOpsRequest(mUid, mPackageName, mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08003517 mBeginTimeMillis, mEndTimeMillis, mFlags);
Svet Ganov23c88db2019-01-22 20:38:11 -08003518 }
3519 }
3520 }
3521
3522 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003523 * This class represents historical app op state of all UIDs for a given time interval.
3524 *
3525 * @hide
3526 */
3527 @TestApi
3528 @SystemApi
3529 public static final class HistoricalOps implements Parcelable {
3530 private long mBeginTimeMillis;
3531 private long mEndTimeMillis;
3532 private @Nullable SparseArray<HistoricalUidOps> mHistoricalUidOps;
3533
3534 /** @hide */
3535 @TestApi
3536 public HistoricalOps(long beginTimeMillis, long endTimeMillis) {
3537 Preconditions.checkState(beginTimeMillis <= endTimeMillis);
3538 mBeginTimeMillis = beginTimeMillis;
3539 mEndTimeMillis = endTimeMillis;
3540 }
3541
3542 /** @hide */
3543 public HistoricalOps(@NonNull HistoricalOps other) {
3544 mBeginTimeMillis = other.mBeginTimeMillis;
3545 mEndTimeMillis = other.mEndTimeMillis;
3546 Preconditions.checkState(mBeginTimeMillis <= mEndTimeMillis);
3547 if (other.mHistoricalUidOps != null) {
3548 final int opCount = other.getUidCount();
3549 for (int i = 0; i < opCount; i++) {
3550 final HistoricalUidOps origOps = other.getUidOpsAt(i);
3551 final HistoricalUidOps clonedOps = new HistoricalUidOps(origOps);
3552 if (mHistoricalUidOps == null) {
3553 mHistoricalUidOps = new SparseArray<>(opCount);
3554 }
3555 mHistoricalUidOps.put(clonedOps.getUid(), clonedOps);
3556 }
3557 }
3558 }
3559
3560 private HistoricalOps(Parcel parcel) {
3561 mBeginTimeMillis = parcel.readLong();
3562 mEndTimeMillis = parcel.readLong();
3563 final int[] uids = parcel.createIntArray();
3564 if (!ArrayUtils.isEmpty(uids)) {
3565 final ParceledListSlice<HistoricalUidOps> listSlice = parcel.readParcelable(
3566 HistoricalOps.class.getClassLoader());
3567 final List<HistoricalUidOps> uidOps = (listSlice != null)
3568 ? listSlice.getList() : null;
3569 if (uidOps == null) {
3570 return;
3571 }
3572 for (int i = 0; i < uids.length; i++) {
3573 if (mHistoricalUidOps == null) {
3574 mHistoricalUidOps = new SparseArray<>();
3575 }
3576 mHistoricalUidOps.put(uids[i], uidOps.get(i));
3577 }
3578 }
3579 }
3580
3581 /**
3582 * Splice a piece from the beginning of these ops.
3583 *
3584 * @param splicePoint The fraction of the data to be spliced off.
3585 *
3586 * @hide
3587 */
3588 public @NonNull HistoricalOps spliceFromBeginning(double splicePoint) {
3589 return splice(splicePoint, true);
3590 }
3591
3592 /**
3593 * Splice a piece from the end of these ops.
3594 *
3595 * @param fractionToRemove The fraction of the data to be spliced off.
3596 *
3597 * @hide
3598 */
3599 public @NonNull HistoricalOps spliceFromEnd(double fractionToRemove) {
3600 return splice(fractionToRemove, false);
3601 }
3602
3603 /**
3604 * Splice a piece from the beginning or end of these ops.
3605 *
3606 * @param fractionToRemove The fraction of the data to be spliced off.
3607 * @param beginning Whether to splice off the beginning or the end.
3608 *
3609 * @return The spliced off part.
3610 *
3611 * @hide
3612 */
3613 private @Nullable HistoricalOps splice(double fractionToRemove, boolean beginning) {
3614 final long spliceBeginTimeMills;
3615 final long spliceEndTimeMills;
3616 if (beginning) {
3617 spliceBeginTimeMills = mBeginTimeMillis;
3618 spliceEndTimeMills = (long) (mBeginTimeMillis
3619 + getDurationMillis() * fractionToRemove);
3620 mBeginTimeMillis = spliceEndTimeMills;
3621 } else {
3622 spliceBeginTimeMills = (long) (mEndTimeMillis
3623 - getDurationMillis() * fractionToRemove);
3624 spliceEndTimeMills = mEndTimeMillis;
3625 mEndTimeMillis = spliceBeginTimeMills;
3626 }
3627
3628 HistoricalOps splice = null;
3629 final int uidCount = getUidCount();
3630 for (int i = 0; i < uidCount; i++) {
3631 final HistoricalUidOps origOps = getUidOpsAt(i);
3632 final HistoricalUidOps spliceOps = origOps.splice(fractionToRemove);
3633 if (spliceOps != null) {
3634 if (splice == null) {
3635 splice = new HistoricalOps(spliceBeginTimeMills, spliceEndTimeMills);
3636 }
3637 if (splice.mHistoricalUidOps == null) {
3638 splice.mHistoricalUidOps = new SparseArray<>();
3639 }
3640 splice.mHistoricalUidOps.put(spliceOps.getUid(), spliceOps);
3641 }
3642 }
3643 return splice;
3644 }
3645
3646 /**
3647 * Merge the passed ops into the current ones. The time interval is a
3648 * union of the current and passed in one and the passed in data is
3649 * folded into the data of this instance.
3650 *
3651 * @hide
3652 */
3653 public void merge(@NonNull HistoricalOps other) {
3654 mBeginTimeMillis = Math.min(mBeginTimeMillis, other.mBeginTimeMillis);
3655 mEndTimeMillis = Math.max(mEndTimeMillis, other.mEndTimeMillis);
3656 final int uidCount = other.getUidCount();
3657 for (int i = 0; i < uidCount; i++) {
3658 final HistoricalUidOps otherUidOps = other.getUidOpsAt(i);
3659 final HistoricalUidOps thisUidOps = getUidOps(otherUidOps.getUid());
3660 if (thisUidOps != null) {
3661 thisUidOps.merge(otherUidOps);
3662 } else {
3663 if (mHistoricalUidOps == null) {
3664 mHistoricalUidOps = new SparseArray<>();
3665 }
3666 mHistoricalUidOps.put(otherUidOps.getUid(), otherUidOps);
3667 }
3668 }
3669 }
3670
3671 /**
3672 * AppPermissionUsage the ops to leave only the data we filter for.
3673 *
3674 * @param uid Uid to filter for or {@link android.os.Process#INCIDENTD_UID} for all.
3675 * @param packageName Package to filter for or null for all.
3676 * @param opNames Ops to filter for or null for all.
3677 * @param beginTimeMillis The begin time to filter for or {@link Long#MIN_VALUE} for all.
3678 * @param endTimeMillis The end time to filter for or {@link Long#MAX_VALUE} for all.
3679 *
3680 * @hide
3681 */
3682 public void filter(int uid, @Nullable String packageName, @Nullable String[] opNames,
3683 long beginTimeMillis, long endTimeMillis) {
3684 final long durationMillis = getDurationMillis();
3685 mBeginTimeMillis = Math.max(mBeginTimeMillis, beginTimeMillis);
3686 mEndTimeMillis = Math.min(mEndTimeMillis, endTimeMillis);
3687 final double scaleFactor = Math.min((double) (endTimeMillis - beginTimeMillis)
3688 / (double) durationMillis, 1);
3689 final int uidCount = getUidCount();
3690 for (int i = uidCount - 1; i >= 0; i--) {
3691 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
3692 if (uid != Process.INVALID_UID && uid != uidOp.getUid()) {
3693 mHistoricalUidOps.removeAt(i);
3694 } else {
3695 uidOp.filter(packageName, opNames, scaleFactor);
3696 }
3697 }
3698 }
3699
3700 /** @hide */
3701 public boolean isEmpty() {
3702 if (getBeginTimeMillis() >= getEndTimeMillis()) {
3703 return true;
3704 }
3705 final int uidCount = getUidCount();
3706 for (int i = uidCount - 1; i >= 0; i--) {
3707 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
3708 if (!uidOp.isEmpty()) {
3709 return false;
3710 }
3711 }
3712 return true;
3713 }
3714
3715 /** @hide */
3716 public long getDurationMillis() {
3717 return mEndTimeMillis - mBeginTimeMillis;
3718 }
3719
3720 /** @hide */
3721 @TestApi
3722 public void increaseAccessCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003723 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003724 getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003725 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003726 }
3727
3728 /** @hide */
3729 @TestApi
3730 public void increaseRejectCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003731 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003732 getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003733 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003734 }
3735
3736 /** @hide */
3737 @TestApi
3738 public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003739 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003740 getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003741 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003742 }
3743
3744 /** @hide */
3745 @TestApi
3746 public void offsetBeginAndEndTime(long offsetMillis) {
3747 mBeginTimeMillis += offsetMillis;
3748 mEndTimeMillis += offsetMillis;
3749 }
3750
3751 /** @hide */
3752 public void setBeginAndEndTime(long beginTimeMillis, long endTimeMillis) {
3753 mBeginTimeMillis = beginTimeMillis;
3754 mEndTimeMillis = endTimeMillis;
3755 }
3756
3757 /** @hide */
3758 public void setBeginTime(long beginTimeMillis) {
3759 mBeginTimeMillis = beginTimeMillis;
3760 }
3761
3762 /** @hide */
3763 public void setEndTime(long endTimeMillis) {
3764 mEndTimeMillis = endTimeMillis;
3765 }
3766
3767 /**
3768 * @return The beginning of the interval in milliseconds since
3769 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3770 */
3771 public long getBeginTimeMillis() {
3772 return mBeginTimeMillis;
3773 }
3774
3775 /**
3776 * @return The end of the interval in milliseconds since
3777 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3778 */
3779 public long getEndTimeMillis() {
3780 return mEndTimeMillis;
3781 }
3782
3783 /**
3784 * Gets number of UIDs with historical ops.
3785 *
3786 * @return The number of UIDs with historical ops.
3787 *
3788 * @see #getUidOpsAt(int)
3789 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003790 public @IntRange(from = 0) int getUidCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003791 if (mHistoricalUidOps == null) {
3792 return 0;
3793 }
3794 return mHistoricalUidOps.size();
3795 }
3796
3797 /**
3798 * Gets the historical UID ops at a given index.
3799 *
3800 * @param index The index.
3801 *
3802 * @return The historical UID ops at the given index.
3803 *
3804 * @see #getUidCount()
3805 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003806 public @NonNull HistoricalUidOps getUidOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003807 if (mHistoricalUidOps == null) {
3808 throw new IndexOutOfBoundsException();
3809 }
3810 return mHistoricalUidOps.valueAt(index);
3811 }
3812
3813 /**
3814 * Gets the historical UID ops for a given UID.
3815 *
3816 * @param uid The UID.
3817 *
3818 * @return The historical ops for the UID.
3819 */
3820 public @Nullable HistoricalUidOps getUidOps(int uid) {
3821 if (mHistoricalUidOps == null) {
3822 return null;
3823 }
3824 return mHistoricalUidOps.get(uid);
3825 }
3826
Winson4e3b4352019-05-07 16:29:59 -07003827 /** @hide */
3828 public void clearHistory(int uid, @NonNull String packageName) {
3829 HistoricalUidOps historicalUidOps = getOrCreateHistoricalUidOps(uid);
3830 historicalUidOps.clearHistory(packageName);
3831 if (historicalUidOps.isEmpty()) {
3832 mHistoricalUidOps.remove(uid);
3833 }
3834 }
3835
Svet Ganov8455ba22019-01-02 13:05:56 -08003836 @Override
3837 public int describeContents() {
3838 return 0;
3839 }
3840
3841 @Override
3842 public void writeToParcel(Parcel parcel, int flags) {
3843 parcel.writeLong(mBeginTimeMillis);
3844 parcel.writeLong(mEndTimeMillis);
3845 if (mHistoricalUidOps != null) {
3846 final int uidCount = mHistoricalUidOps.size();
3847 parcel.writeInt(uidCount);
3848 for (int i = 0; i < uidCount; i++) {
3849 parcel.writeInt(mHistoricalUidOps.keyAt(i));
3850 }
3851 final List<HistoricalUidOps> opsList = new ArrayList<>(uidCount);
3852 for (int i = 0; i < uidCount; i++) {
3853 opsList.add(mHistoricalUidOps.valueAt(i));
3854 }
3855 parcel.writeParcelable(new ParceledListSlice<>(opsList), flags);
3856 } else {
3857 parcel.writeInt(-1);
3858 }
3859 }
3860
3861 /**
3862 * Accepts a visitor to traverse the ops tree.
3863 *
3864 * @param visitor The visitor.
3865 *
3866 * @hide
3867 */
3868 public void accept(@NonNull HistoricalOpsVisitor visitor) {
3869 visitor.visitHistoricalOps(this);
3870 final int uidCount = getUidCount();
3871 for (int i = 0; i < uidCount; i++) {
3872 getUidOpsAt(i).accept(visitor);
3873 }
3874 }
3875
3876 private @NonNull HistoricalUidOps getOrCreateHistoricalUidOps(int uid) {
3877 if (mHistoricalUidOps == null) {
3878 mHistoricalUidOps = new SparseArray<>();
3879 }
3880 HistoricalUidOps historicalUidOp = mHistoricalUidOps.get(uid);
3881 if (historicalUidOp == null) {
3882 historicalUidOp = new HistoricalUidOps(uid);
3883 mHistoricalUidOps.put(uid, historicalUidOp);
3884 }
3885 return historicalUidOp;
3886 }
3887
3888 /**
3889 * @return Rounded value up at the 0.5 boundary.
3890 *
3891 * @hide
3892 */
3893 public static double round(double value) {
3894 final BigDecimal decimalScale = new BigDecimal(value);
3895 return decimalScale.setScale(0, RoundingMode.HALF_UP).doubleValue();
3896 }
3897
3898 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07003899 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003900 if (this == obj) {
3901 return true;
3902 }
3903 if (obj == null || getClass() != obj.getClass()) {
3904 return false;
3905 }
3906 final HistoricalOps other = (HistoricalOps) obj;
3907 if (mBeginTimeMillis != other.mBeginTimeMillis) {
3908 return false;
3909 }
3910 if (mEndTimeMillis != other.mEndTimeMillis) {
3911 return false;
3912 }
3913 if (mHistoricalUidOps == null) {
3914 if (other.mHistoricalUidOps != null) {
3915 return false;
3916 }
3917 } else if (!mHistoricalUidOps.equals(other.mHistoricalUidOps)) {
3918 return false;
3919 }
3920 return true;
3921 }
3922
3923 @Override
3924 public int hashCode() {
3925 int result = (int) (mBeginTimeMillis ^ (mBeginTimeMillis >>> 32));
3926 result = 31 * result + mHistoricalUidOps.hashCode();
3927 return result;
3928 }
3929
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07003930 @NonNull
Svet Ganov8455ba22019-01-02 13:05:56 -08003931 @Override
3932 public String toString() {
3933 return getClass().getSimpleName() + "[from:"
3934 + mBeginTimeMillis + " to:" + mEndTimeMillis + "]";
3935 }
3936
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07003937 public static final @android.annotation.NonNull Creator<HistoricalOps> CREATOR = new Creator<HistoricalOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003938 @Override
3939 public @NonNull HistoricalOps createFromParcel(@NonNull Parcel parcel) {
3940 return new HistoricalOps(parcel);
3941 }
3942
3943 @Override
3944 public @NonNull HistoricalOps[] newArray(int size) {
3945 return new HistoricalOps[size];
3946 }
3947 };
3948 }
3949
3950 /**
3951 * This class represents historical app op state for a UID.
3952 *
3953 * @hide
3954 */
3955 @TestApi
3956 @SystemApi
3957 public static final class HistoricalUidOps implements Parcelable {
3958 private final int mUid;
3959 private @Nullable ArrayMap<String, HistoricalPackageOps> mHistoricalPackageOps;
3960
3961 /** @hide */
3962 public HistoricalUidOps(int uid) {
3963 mUid = uid;
3964 }
3965
3966 private HistoricalUidOps(@NonNull HistoricalUidOps other) {
3967 mUid = other.mUid;
3968 final int opCount = other.getPackageCount();
3969 for (int i = 0; i < opCount; i++) {
3970 final HistoricalPackageOps origOps = other.getPackageOpsAt(i);
3971 final HistoricalPackageOps cloneOps = new HistoricalPackageOps(origOps);
3972 if (mHistoricalPackageOps == null) {
3973 mHistoricalPackageOps = new ArrayMap<>(opCount);
3974 }
3975 mHistoricalPackageOps.put(cloneOps.getPackageName(), cloneOps);
3976 }
3977 }
3978
3979 private HistoricalUidOps(@NonNull Parcel parcel) {
3980 // No arg check since we always read from a trusted source.
3981 mUid = parcel.readInt();
3982 mHistoricalPackageOps = parcel.createTypedArrayMap(HistoricalPackageOps.CREATOR);
3983 }
3984
3985 private @Nullable HistoricalUidOps splice(double fractionToRemove) {
3986 HistoricalUidOps splice = null;
3987 final int packageCount = getPackageCount();
3988 for (int i = 0; i < packageCount; i++) {
3989 final HistoricalPackageOps origOps = getPackageOpsAt(i);
3990 final HistoricalPackageOps spliceOps = origOps.splice(fractionToRemove);
3991 if (spliceOps != null) {
3992 if (splice == null) {
3993 splice = new HistoricalUidOps(mUid);
3994 }
3995 if (splice.mHistoricalPackageOps == null) {
3996 splice.mHistoricalPackageOps = new ArrayMap<>();
3997 }
3998 splice.mHistoricalPackageOps.put(spliceOps.getPackageName(), spliceOps);
3999 }
4000 }
4001 return splice;
4002 }
4003
4004 private void merge(@NonNull HistoricalUidOps other) {
4005 final int packageCount = other.getPackageCount();
4006 for (int i = 0; i < packageCount; i++) {
4007 final HistoricalPackageOps otherPackageOps = other.getPackageOpsAt(i);
4008 final HistoricalPackageOps thisPackageOps = getPackageOps(
4009 otherPackageOps.getPackageName());
4010 if (thisPackageOps != null) {
4011 thisPackageOps.merge(otherPackageOps);
4012 } else {
4013 if (mHistoricalPackageOps == null) {
4014 mHistoricalPackageOps = new ArrayMap<>();
4015 }
4016 mHistoricalPackageOps.put(otherPackageOps.getPackageName(), otherPackageOps);
4017 }
4018 }
4019 }
4020
4021 private void filter(@Nullable String packageName, @Nullable String[] opNames,
4022 double fractionToRemove) {
4023 final int packageCount = getPackageCount();
4024 for (int i = packageCount - 1; i >= 0; i--) {
4025 final HistoricalPackageOps packageOps = getPackageOpsAt(i);
4026 if (packageName != null && !packageName.equals(packageOps.getPackageName())) {
4027 mHistoricalPackageOps.removeAt(i);
4028 } else {
4029 packageOps.filter(opNames, fractionToRemove);
4030 }
4031 }
4032 }
4033
4034 private boolean isEmpty() {
4035 final int packageCount = getPackageCount();
4036 for (int i = packageCount - 1; i >= 0; i--) {
4037 final HistoricalPackageOps packageOps = mHistoricalPackageOps.valueAt(i);
4038 if (!packageOps.isEmpty()) {
4039 return false;
4040 }
4041 }
4042 return true;
4043 }
4044
4045 private void increaseAccessCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004046 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004047 getOrCreateHistoricalPackageOps(packageName).increaseAccessCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08004048 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004049 }
4050
4051 private void increaseRejectCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004052 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004053 getOrCreateHistoricalPackageOps(packageName).increaseRejectCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08004054 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004055 }
4056
4057 private void increaseAccessDuration(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004058 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004059 getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration(
Svet Ganovaf189e32019-02-15 18:45:29 -08004060 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004061 }
4062
4063 /**
4064 * @return The UID for which the data is related.
4065 */
4066 public int getUid() {
4067 return mUid;
4068 }
4069
4070 /**
4071 * Gets number of packages with historical ops.
4072 *
4073 * @return The number of packages with historical ops.
4074 *
4075 * @see #getPackageOpsAt(int)
4076 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004077 public @IntRange(from = 0) int getPackageCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004078 if (mHistoricalPackageOps == null) {
4079 return 0;
4080 }
4081 return mHistoricalPackageOps.size();
4082 }
4083
4084 /**
4085 * Gets the historical package ops at a given index.
4086 *
4087 * @param index The index.
4088 *
4089 * @return The historical package ops at the given index.
4090 *
4091 * @see #getPackageCount()
4092 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004093 public @NonNull HistoricalPackageOps getPackageOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004094 if (mHistoricalPackageOps == null) {
4095 throw new IndexOutOfBoundsException();
4096 }
4097 return mHistoricalPackageOps.valueAt(index);
4098 }
4099
4100 /**
4101 * Gets the historical package ops for a given package.
4102 *
4103 * @param packageName The package.
4104 *
4105 * @return The historical ops for the package.
4106 */
4107 public @Nullable HistoricalPackageOps getPackageOps(@NonNull String packageName) {
4108 if (mHistoricalPackageOps == null) {
4109 return null;
4110 }
4111 return mHistoricalPackageOps.get(packageName);
4112 }
4113
Winson4e3b4352019-05-07 16:29:59 -07004114 private void clearHistory(@NonNull String packageName) {
4115 if (mHistoricalPackageOps != null) {
4116 mHistoricalPackageOps.remove(packageName);
4117 }
4118 }
4119
Svet Ganov8455ba22019-01-02 13:05:56 -08004120 @Override
4121 public int describeContents() {
4122 return 0;
4123 }
4124
4125 @Override
4126 public void writeToParcel(Parcel parcel, int flags) {
4127 parcel.writeInt(mUid);
4128 parcel.writeTypedArrayMap(mHistoricalPackageOps, flags);
4129 }
4130
4131 private void accept(@NonNull HistoricalOpsVisitor visitor) {
4132 visitor.visitHistoricalUidOps(this);
4133 final int packageCount = getPackageCount();
4134 for (int i = 0; i < packageCount; i++) {
4135 getPackageOpsAt(i).accept(visitor);
4136 }
4137 }
4138
4139 private @NonNull HistoricalPackageOps getOrCreateHistoricalPackageOps(
4140 @NonNull String packageName) {
4141 if (mHistoricalPackageOps == null) {
4142 mHistoricalPackageOps = new ArrayMap<>();
4143 }
4144 HistoricalPackageOps historicalPackageOp = mHistoricalPackageOps.get(packageName);
4145 if (historicalPackageOp == null) {
4146 historicalPackageOp = new HistoricalPackageOps(packageName);
4147 mHistoricalPackageOps.put(packageName, historicalPackageOp);
4148 }
4149 return historicalPackageOp;
4150 }
4151
4152
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07004153 public static final @android.annotation.NonNull Creator<HistoricalUidOps> CREATOR = new Creator<HistoricalUidOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004154 @Override
4155 public @NonNull HistoricalUidOps createFromParcel(@NonNull Parcel parcel) {
4156 return new HistoricalUidOps(parcel);
4157 }
4158
4159 @Override
4160 public @NonNull HistoricalUidOps[] newArray(int size) {
4161 return new HistoricalUidOps[size];
4162 }
4163 };
4164
4165 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004166 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004167 if (this == obj) {
4168 return true;
4169 }
4170 if (obj == null || getClass() != obj.getClass()) {
4171 return false;
4172 }
4173 final HistoricalUidOps other = (HistoricalUidOps) obj;
4174 if (mUid != other.mUid) {
4175 return false;
4176 }
4177 if (mHistoricalPackageOps == null) {
4178 if (other.mHistoricalPackageOps != null) {
4179 return false;
4180 }
4181 } else if (!mHistoricalPackageOps.equals(other.mHistoricalPackageOps)) {
4182 return false;
4183 }
4184 return true;
4185 }
4186
4187 @Override
4188 public int hashCode() {
4189 int result = mUid;
4190 result = 31 * result + (mHistoricalPackageOps != null
4191 ? mHistoricalPackageOps.hashCode() : 0);
4192 return result;
4193 }
4194 }
4195
4196 /**
4197 * This class represents historical app op information about a package.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004198 *
4199 * @hide
4200 */
4201 @TestApi
4202 @SystemApi
4203 public static final class HistoricalPackageOps implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004204 private final @NonNull String mPackageName;
Svet Ganov8455ba22019-01-02 13:05:56 -08004205 private @Nullable ArrayMap<String, HistoricalOp> mHistoricalOps;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004206
Svet Ganov8455ba22019-01-02 13:05:56 -08004207 /** @hide */
4208 public HistoricalPackageOps(@NonNull String packageName) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004209 mPackageName = packageName;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004210 }
4211
Svet Ganov8455ba22019-01-02 13:05:56 -08004212 private HistoricalPackageOps(@NonNull HistoricalPackageOps other) {
4213 mPackageName = other.mPackageName;
4214 final int opCount = other.getOpCount();
4215 for (int i = 0; i < opCount; i++) {
4216 final HistoricalOp origOp = other.getOpAt(i);
4217 final HistoricalOp cloneOp = new HistoricalOp(origOp);
4218 if (mHistoricalOps == null) {
4219 mHistoricalOps = new ArrayMap<>(opCount);
4220 }
4221 mHistoricalOps.put(cloneOp.getOpName(), cloneOp);
4222 }
4223 }
4224
4225 private HistoricalPackageOps(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004226 mPackageName = parcel.readString();
Svet Ganov8455ba22019-01-02 13:05:56 -08004227 mHistoricalOps = parcel.createTypedArrayMap(HistoricalOp.CREATOR);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004228 }
4229
Svet Ganov8455ba22019-01-02 13:05:56 -08004230 private @Nullable HistoricalPackageOps splice(double fractionToRemove) {
4231 HistoricalPackageOps splice = null;
4232 final int opCount = getOpCount();
4233 for (int i = 0; i < opCount; i++) {
4234 final HistoricalOp origOps = getOpAt(i);
4235 final HistoricalOp spliceOps = origOps.splice(fractionToRemove);
4236 if (spliceOps != null) {
4237 if (splice == null) {
4238 splice = new HistoricalPackageOps(mPackageName);
4239 }
4240 if (splice.mHistoricalOps == null) {
4241 splice.mHistoricalOps = new ArrayMap<>();
4242 }
4243 splice.mHistoricalOps.put(spliceOps.getOpName(), spliceOps);
4244 }
4245 }
4246 return splice;
4247 }
4248
4249 private void merge(@NonNull HistoricalPackageOps other) {
4250 final int opCount = other.getOpCount();
4251 for (int i = 0; i < opCount; i++) {
4252 final HistoricalOp otherOp = other.getOpAt(i);
4253 final HistoricalOp thisOp = getOp(otherOp.getOpName());
4254 if (thisOp != null) {
4255 thisOp.merge(otherOp);
4256 } else {
4257 if (mHistoricalOps == null) {
4258 mHistoricalOps = new ArrayMap<>();
4259 }
4260 mHistoricalOps.put(otherOp.getOpName(), otherOp);
4261 }
4262 }
4263 }
4264
4265 private void filter(@Nullable String[] opNames, double scaleFactor) {
4266 final int opCount = getOpCount();
4267 for (int i = opCount - 1; i >= 0; i--) {
4268 final HistoricalOp op = mHistoricalOps.valueAt(i);
4269 if (opNames != null && !ArrayUtils.contains(opNames, op.getOpName())) {
4270 mHistoricalOps.removeAt(i);
4271 } else {
4272 op.filter(scaleFactor);
4273 }
4274 }
4275 }
4276
4277 private boolean isEmpty() {
4278 final int opCount = getOpCount();
4279 for (int i = opCount - 1; i >= 0; i--) {
4280 final HistoricalOp op = mHistoricalOps.valueAt(i);
4281 if (!op.isEmpty()) {
4282 return false;
4283 }
4284 }
4285 return true;
4286 }
4287
Svet Ganovaf189e32019-02-15 18:45:29 -08004288 private void increaseAccessCount(int opCode, @UidState int uidState,
4289 @OpFlags int flags, long increment) {
4290 getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004291 }
4292
Svet Ganovaf189e32019-02-15 18:45:29 -08004293 private void increaseRejectCount(int opCode, @UidState int uidState,
4294 @OpFlags int flags, long increment) {
4295 getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004296 }
4297
Svet Ganovaf189e32019-02-15 18:45:29 -08004298 private void increaseAccessDuration(int opCode, @UidState int uidState,
4299 @OpFlags int flags, long increment) {
4300 getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, flags, increment);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004301 }
4302
4303 /**
4304 * Gets the package name which the data represents.
4305 *
4306 * @return The package name which the data represents.
4307 */
4308 public @NonNull String getPackageName() {
4309 return mPackageName;
4310 }
4311
4312 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004313 * Gets number historical app ops.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004314 *
Svet Ganov8455ba22019-01-02 13:05:56 -08004315 * @return The number historical app ops.
Svet Ganov8455ba22019-01-02 13:05:56 -08004316 * @see #getOpAt(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004317 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004318 public @IntRange(from = 0) int getOpCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004319 if (mHistoricalOps == null) {
4320 return 0;
4321 }
4322 return mHistoricalOps.size();
Svet Ganovad0a49b2018-10-29 10:07:08 -07004323 }
4324
4325 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004326 * Gets the historical op at a given index.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004327 *
4328 * @param index The index to lookup.
Svet Ganov8455ba22019-01-02 13:05:56 -08004329 * @return The op at the given index.
Svet Ganov8455ba22019-01-02 13:05:56 -08004330 * @see #getOpCount()
Svet Ganovad0a49b2018-10-29 10:07:08 -07004331 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004332 public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004333 if (mHistoricalOps == null) {
4334 throw new IndexOutOfBoundsException();
4335 }
4336 return mHistoricalOps.valueAt(index);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004337 }
4338
4339 /**
4340 * Gets the historical entry for a given op name.
4341 *
4342 * @param opName The op name.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004343 * @return The historical entry for that op name.
4344 */
Svet Ganov8455ba22019-01-02 13:05:56 -08004345 public @Nullable HistoricalOp getOp(@NonNull String opName) {
4346 if (mHistoricalOps == null) {
4347 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004348 }
Svet Ganov8455ba22019-01-02 13:05:56 -08004349 return mHistoricalOps.get(opName);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004350 }
4351
4352 @Override
4353 public int describeContents() {
4354 return 0;
4355 }
4356
4357 @Override
4358 public void writeToParcel(@NonNull Parcel parcel, int flags) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004359 parcel.writeString(mPackageName);
Svet Ganov8455ba22019-01-02 13:05:56 -08004360 parcel.writeTypedArrayMap(mHistoricalOps, flags);
4361 }
4362
4363 private void accept(@NonNull HistoricalOpsVisitor visitor) {
4364 visitor.visitHistoricalPackageOps(this);
4365 final int opCount = getOpCount();
4366 for (int i = 0; i < opCount; i++) {
4367 getOpAt(i).accept(visitor);
4368 }
4369 }
4370
4371 private @NonNull HistoricalOp getOrCreateHistoricalOp(int opCode) {
4372 if (mHistoricalOps == null) {
4373 mHistoricalOps = new ArrayMap<>();
4374 }
4375 final String opStr = sOpToString[opCode];
4376 HistoricalOp op = mHistoricalOps.get(opStr);
4377 if (op == null) {
4378 op = new HistoricalOp(opCode);
4379 mHistoricalOps.put(opStr, op);
4380 }
4381 return op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004382 }
4383
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07004384 public static final @android.annotation.NonNull Creator<HistoricalPackageOps> CREATOR =
Svet Ganovad0a49b2018-10-29 10:07:08 -07004385 new Creator<HistoricalPackageOps>() {
4386 @Override
4387 public @NonNull HistoricalPackageOps createFromParcel(@NonNull Parcel parcel) {
4388 return new HistoricalPackageOps(parcel);
4389 }
4390
4391 @Override
4392 public @NonNull HistoricalPackageOps[] newArray(int size) {
4393 return new HistoricalPackageOps[size];
4394 }
4395 };
Svet Ganov8455ba22019-01-02 13:05:56 -08004396
4397 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004398 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004399 if (this == obj) {
4400 return true;
4401 }
4402 if (obj == null || getClass() != obj.getClass()) {
4403 return false;
4404 }
4405 final HistoricalPackageOps other = (HistoricalPackageOps) obj;
4406 if (!mPackageName.equals(other.mPackageName)) {
4407 return false;
4408 }
4409 if (mHistoricalOps == null) {
4410 if (other.mHistoricalOps != null) {
4411 return false;
4412 }
4413 } else if (!mHistoricalOps.equals(other.mHistoricalOps)) {
4414 return false;
4415 }
4416 return true;
4417 }
4418
4419 @Override
4420 public int hashCode() {
4421 int result = mPackageName != null ? mPackageName.hashCode() : 0;
4422 result = 31 * result + (mHistoricalOps != null ? mHistoricalOps.hashCode() : 0);
4423 return result;
4424 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07004425 }
4426
4427 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004428 * This class represents historical information about an app op.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004429 *
4430 * @hide
4431 */
4432 @TestApi
4433 @SystemApi
Svet Ganov8455ba22019-01-02 13:05:56 -08004434 public static final class HistoricalOp implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004435 private final int mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08004436 private @Nullable LongSparseLongArray mAccessCount;
4437 private @Nullable LongSparseLongArray mRejectCount;
4438 private @Nullable LongSparseLongArray mAccessDuration;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004439
Svet Ganov8455ba22019-01-02 13:05:56 -08004440 /** @hide */
4441 public HistoricalOp(int op) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004442 mOp = op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004443 }
4444
Svet Ganov8455ba22019-01-02 13:05:56 -08004445 private HistoricalOp(@NonNull HistoricalOp other) {
4446 mOp = other.mOp;
4447 if (other.mAccessCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004448 mAccessCount = other.mAccessCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08004449 }
4450 if (other.mRejectCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004451 mRejectCount = other.mRejectCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08004452 }
4453 if (other.mAccessDuration != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004454 mAccessDuration = other.mAccessDuration.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08004455 }
4456 }
4457
4458 private HistoricalOp(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004459 mOp = parcel.readInt();
Svet Ganovaf189e32019-02-15 18:45:29 -08004460 mAccessCount = readLongSparseLongArrayFromParcel(parcel);
4461 mRejectCount = readLongSparseLongArrayFromParcel(parcel);
4462 mAccessDuration = readLongSparseLongArrayFromParcel(parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004463 }
4464
Svet Ganov8455ba22019-01-02 13:05:56 -08004465 private void filter(double scaleFactor) {
4466 scale(mAccessCount, scaleFactor);
4467 scale(mRejectCount, scaleFactor);
4468 scale(mAccessDuration, scaleFactor);
4469 }
4470
4471 private boolean isEmpty() {
4472 return !hasData(mAccessCount)
4473 && !hasData(mRejectCount)
4474 && !hasData(mAccessDuration);
4475 }
4476
Svet Ganovaf189e32019-02-15 18:45:29 -08004477 private boolean hasData(@NonNull LongSparseLongArray array) {
4478 return (array != null && array.size() > 0);
Svet Ganov8455ba22019-01-02 13:05:56 -08004479 }
4480
4481 private @Nullable HistoricalOp splice(double fractionToRemove) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004482 final HistoricalOp splice = new HistoricalOp(mOp);
4483 splice(mAccessCount, splice::getOrCreateAccessCount, fractionToRemove);
4484 splice(mRejectCount, splice::getOrCreateRejectCount, fractionToRemove);
4485 splice(mAccessDuration, splice::getOrCreateAccessDuration, fractionToRemove);
Svet Ganov8455ba22019-01-02 13:05:56 -08004486 return splice;
4487 }
4488
Svet Ganovaf189e32019-02-15 18:45:29 -08004489 private static void splice(@Nullable LongSparseLongArray sourceContainer,
4490 @NonNull Supplier<LongSparseLongArray> destContainerProvider,
4491 double fractionToRemove) {
4492 if (sourceContainer != null) {
4493 final int size = sourceContainer.size();
4494 for (int i = 0; i < size; i++) {
4495 final long key = sourceContainer.keyAt(i);
4496 final long value = sourceContainer.valueAt(i);
4497 final long removedFraction = Math.round(value * fractionToRemove);
4498 if (removedFraction > 0) {
4499 destContainerProvider.get().put(key, removedFraction);
4500 sourceContainer.put(key, value - removedFraction);
4501 }
4502 }
4503 }
4504 }
4505
Svet Ganov8455ba22019-01-02 13:05:56 -08004506 private void merge(@NonNull HistoricalOp other) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004507 merge(this::getOrCreateAccessCount, other.mAccessCount);
4508 merge(this::getOrCreateRejectCount, other.mRejectCount);
4509 merge(this::getOrCreateAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004510 }
4511
Svet Ganovaf189e32019-02-15 18:45:29 -08004512 private void increaseAccessCount(@UidState int uidState, @OpFlags int flags,
4513 long increment) {
4514 increaseCount(getOrCreateAccessCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004515 }
4516
Svet Ganovaf189e32019-02-15 18:45:29 -08004517 private void increaseRejectCount(@UidState int uidState, @OpFlags int flags,
4518 long increment) {
4519 increaseCount(getOrCreateRejectCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004520 }
4521
Svet Ganovaf189e32019-02-15 18:45:29 -08004522 private void increaseAccessDuration(@UidState int uidState, @OpFlags int flags,
4523 long increment) {
4524 increaseCount(getOrCreateAccessDuration(), uidState, flags, increment);
4525 }
4526
4527 private void increaseCount(@NonNull LongSparseLongArray counts,
4528 @UidState int uidState, @OpFlags int flags, long increment) {
4529 while (flags != 0) {
4530 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4531 flags &= ~flag;
4532 final long key = makeKey(uidState, flag);
4533 counts.put(key, counts.get(key) + increment);
4534 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07004535 }
4536
4537 /**
4538 * Gets the op name.
4539 *
4540 * @return The op name.
4541 */
Svet Ganov8455ba22019-01-02 13:05:56 -08004542 public @NonNull String getOpName() {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004543 return sOpToString[mOp];
4544 }
4545
Svet Ganov8455ba22019-01-02 13:05:56 -08004546 /** @hide */
4547 public int getOpCode() {
4548 return mOp;
4549 }
4550
Svet Ganovad0a49b2018-10-29 10:07:08 -07004551 /**
4552 * Gets the number times the op was accessed (performed) in the foreground.
4553 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004554 * @param flags The flags which are any combination of
4555 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4556 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4557 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4558 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004559 * @return The times the op was accessed in the foreground.
4560 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004561 * @see #getBackgroundAccessCount(int)
4562 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004563 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004564 public long getForegroundAccessCount(@OpFlags int flags) {
4565 return sumForFlagsInStates(mAccessCount, MAX_PRIORITY_UID_STATE,
4566 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004567 }
4568
4569 /**
4570 * Gets the number times the op was accessed (performed) in the background.
4571 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004572 * @param flags The flags which are any combination of
4573 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4574 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4575 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4576 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004577 * @return The times the op was accessed in the background.
4578 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004579 * @see #getForegroundAccessCount(int)
4580 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004581 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004582 public long getBackgroundAccessCount(@OpFlags int flags) {
4583 return sumForFlagsInStates(mAccessCount, resolveLastRestrictedUidState(mOp),
4584 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004585 }
4586
4587 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08004588 * Gets the number times the op was accessed (performed) for a
4589 * range of uid states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004590 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004591 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07004592 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
4593 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
4594 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08004595 * @param toUidState The UID state to which to query.
4596 * @param flags The flags which are any combination of
4597 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4598 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4599 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4600 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004601 *
4602 * @return The times the op was accessed for the given UID state.
4603 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004604 * @see #getForegroundAccessCount(int)
4605 * @see #getBackgroundAccessCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004606 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004607 public long getAccessCount(@UidState int fromUidState, @UidState int toUidState,
4608 @OpFlags int flags) {
4609 return sumForFlagsInStates(mAccessCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004610 }
4611
4612 /**
4613 * Gets the number times the op was rejected in the foreground.
4614 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004615 * @param flags The flags which are any combination of
4616 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4617 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4618 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4619 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004620 * @return The times the op was rejected in the foreground.
4621 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004622 * @see #getBackgroundRejectCount(int)
4623 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004624 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004625 public long getForegroundRejectCount(@OpFlags int flags) {
4626 return sumForFlagsInStates(mRejectCount, MAX_PRIORITY_UID_STATE,
4627 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004628 }
4629
4630 /**
4631 * Gets the number times the op was rejected in the background.
4632 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004633 * @param flags The flags which are any combination of
4634 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4635 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4636 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4637 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004638 * @return The times the op was rejected in the background.
4639 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004640 * @see #getForegroundRejectCount(int)
4641 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004642 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004643 public long getBackgroundRejectCount(@OpFlags int flags) {
4644 return sumForFlagsInStates(mRejectCount, resolveLastRestrictedUidState(mOp),
4645 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004646 }
4647
4648 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08004649 * Gets the number times the op was rejected for a given range of UID states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004650 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004651 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07004652 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
4653 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
4654 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08004655 * @param toUidState The UID state to which to query.
4656 * @param flags The flags which are any combination of
4657 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4658 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4659 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4660 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004661 *
4662 * @return The times the op was rejected for the given UID state.
4663 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004664 * @see #getForegroundRejectCount(int)
4665 * @see #getBackgroundRejectCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004666 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004667 public long getRejectCount(@UidState int fromUidState, @UidState int toUidState,
4668 @OpFlags int flags) {
4669 return sumForFlagsInStates(mRejectCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004670 }
4671
4672 /**
4673 * Gets the total duration the app op was accessed (performed) in the foreground.
Svet Ganov6f672a32019-07-08 16:40:42 -07004674 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004675 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004676 * @param flags The flags which are any combination of
4677 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4678 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4679 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4680 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004681 * @return The total duration the app op was accessed in the foreground.
4682 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004683 * @see #getBackgroundAccessDuration(int)
4684 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004685 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004686 public long getForegroundAccessDuration(@OpFlags int flags) {
4687 return sumForFlagsInStates(mAccessDuration, MAX_PRIORITY_UID_STATE,
4688 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004689 }
4690
4691 /**
4692 * Gets the total duration the app op was accessed (performed) in the background.
Svet Ganov6f672a32019-07-08 16:40:42 -07004693 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004694 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004695 * @param flags The flags which are any combination of
4696 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4697 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4698 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4699 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004700 * @return The total duration the app op was accessed in the background.
4701 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004702 * @see #getForegroundAccessDuration(int)
4703 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004704 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004705 public long getBackgroundAccessDuration(@OpFlags int flags) {
4706 return sumForFlagsInStates(mAccessDuration, resolveLastRestrictedUidState(mOp),
4707 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004708 }
4709
4710 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08004711 * Gets the total duration the app op was accessed (performed) for a given
Svet Ganov6f672a32019-07-08 16:40:42 -07004712 * range of UID states. The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004713 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004714 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07004715 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
4716 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
4717 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08004718 * @param toUidState The UID state from which to query.
4719 * @param flags The flags which are any combination of
4720 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4721 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4722 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4723 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004724 *
4725 * @return The total duration the app op was accessed for the given UID state.
4726 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004727 * @see #getForegroundAccessDuration(int)
4728 * @see #getBackgroundAccessDuration(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004729 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004730 public long getAccessDuration(@UidState int fromUidState, @UidState int toUidState,
4731 @OpFlags int flags) {
4732 return sumForFlagsInStates(mAccessDuration, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004733 }
4734
4735 @Override
4736 public int describeContents() {
4737 return 0;
4738 }
4739
4740 @Override
4741 public void writeToParcel(Parcel parcel, int flags) {
4742 parcel.writeInt(mOp);
Svet Ganovaf189e32019-02-15 18:45:29 -08004743 writeLongSparseLongArrayToParcel(mAccessCount, parcel);
4744 writeLongSparseLongArrayToParcel(mRejectCount, parcel);
4745 writeLongSparseLongArrayToParcel(mAccessDuration, parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004746 }
4747
Svet Ganov8455ba22019-01-02 13:05:56 -08004748 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004749 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004750 if (this == obj) {
4751 return true;
4752 }
4753 if (obj == null || getClass() != obj.getClass()) {
4754 return false;
4755 }
4756 final HistoricalOp other = (HistoricalOp) obj;
4757 if (mOp != other.mOp) {
4758 return false;
4759 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004760 if (!Objects.equals(mAccessCount, other.mAccessCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004761 return false;
4762 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004763 if (!Objects.equals(mRejectCount, other.mRejectCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004764 return false;
4765 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004766 return Objects.equals(mAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004767 }
4768
4769 @Override
4770 public int hashCode() {
4771 int result = mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08004772 result = 31 * result + Objects.hashCode(mAccessCount);
4773 result = 31 * result + Objects.hashCode(mRejectCount);
4774 result = 31 * result + Objects.hashCode(mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004775 return result;
4776 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004777
4778 private void accept(@NonNull HistoricalOpsVisitor visitor) {
4779 visitor.visitHistoricalOp(this);
4780 }
4781
4782 private @NonNull LongSparseLongArray getOrCreateAccessCount() {
4783 if (mAccessCount == null) {
4784 mAccessCount = new LongSparseLongArray();
4785 }
4786 return mAccessCount;
4787 }
4788
4789 private @NonNull LongSparseLongArray getOrCreateRejectCount() {
4790 if (mRejectCount == null) {
4791 mRejectCount = new LongSparseLongArray();
4792 }
4793 return mRejectCount;
4794 }
4795
4796 private @NonNull LongSparseLongArray getOrCreateAccessDuration() {
4797 if (mAccessDuration == null) {
4798 mAccessDuration = new LongSparseLongArray();
4799 }
4800 return mAccessDuration;
4801 }
4802
4803 /**
4804 * Multiplies the entries in the array with the passed in scale factor and
4805 * rounds the result at up 0.5 boundary.
4806 *
4807 * @param data The data to scale.
4808 * @param scaleFactor The scale factor.
4809 */
4810 private static void scale(@NonNull LongSparseLongArray data, double scaleFactor) {
4811 if (data != null) {
4812 final int size = data.size();
4813 for (int i = 0; i < size; i++) {
4814 data.put(data.keyAt(i), (long) HistoricalOps.round(
4815 (double) data.valueAt(i) * scaleFactor));
4816 }
4817 }
4818 }
4819
4820 /**
4821 * Merges two arrays while lazily acquiring the destination.
4822 *
4823 * @param thisSupplier The destination supplier.
4824 * @param other The array to merge in.
4825 */
4826 private static void merge(@NonNull Supplier<LongSparseLongArray> thisSupplier,
4827 @Nullable LongSparseLongArray other) {
4828 if (other != null) {
4829 final int otherSize = other.size();
4830 for (int i = 0; i < otherSize; i++) {
4831 final LongSparseLongArray that = thisSupplier.get();
4832 final long otherKey = other.keyAt(i);
4833 final long otherValue = other.valueAt(i);
4834 that.put(otherKey, that.get(otherKey) + otherValue);
4835 }
4836 }
4837 }
4838
4839 /** @hide */
4840 public @Nullable LongSparseArray<Object> collectKeys() {
4841 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessCount,
4842 null /*result*/);
4843 result = AppOpsManager.collectKeys(mRejectCount, result);
4844 result = AppOpsManager.collectKeys(mAccessDuration, result);
4845 return result;
4846 }
4847
4848 public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR =
4849 new Creator<HistoricalOp>() {
4850 @Override
4851 public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) {
4852 return new HistoricalOp(source);
4853 }
4854
4855 @Override
4856 public @NonNull HistoricalOp[] newArray(int size) {
4857 return new HistoricalOp[size];
4858 }
4859 };
4860 }
4861
4862 /**
4863 * Computes the sum of the counts for the given flags in between the begin and
4864 * end UID states.
4865 *
4866 * @param counts The data array.
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004867 * @param beginUidState The beginning UID state (inclusive).
4868 * @param endUidState The end UID state (inclusive).
Svet Ganovaf189e32019-02-15 18:45:29 -08004869 * @param flags The UID flags.
4870 * @return The sum.
4871 */
4872 private static long sumForFlagsInStates(@Nullable LongSparseLongArray counts,
4873 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
4874 if (counts == null) {
4875 return 0;
4876 }
4877 long sum = 0;
4878 while (flags != 0) {
4879 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4880 flags &= ~flag;
4881 for (int uidState : UID_STATES) {
4882 if (uidState < beginUidState || uidState > endUidState) {
4883 continue;
4884 }
4885 final long key = makeKey(uidState, flag);
4886 sum += counts.get(key);
4887 }
4888 }
4889 return sum;
4890 }
4891
4892 /**
4893 * Finds the first non-negative value for the given flags in between the begin and
4894 * end UID states.
4895 *
4896 * @param counts The data array.
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004897 * @param beginUidState The beginning UID state (inclusive).
4898 * @param endUidState The end UID state (inclusive).
Svet Ganovaf189e32019-02-15 18:45:29 -08004899 * @param flags The UID flags.
Svet Ganovaf189e32019-02-15 18:45:29 -08004900 * @return The non-negative value or -1.
4901 */
4902 private static long findFirstNonNegativeForFlagsInStates(@Nullable LongSparseLongArray counts,
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004903 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004904 if (counts == null) {
4905 return -1;
4906 }
4907 while (flags != 0) {
4908 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4909 flags &= ~flag;
4910 for (int uidState : UID_STATES) {
4911 if (uidState < beginUidState || uidState > endUidState) {
4912 continue;
4913 }
4914 final long key = makeKey(uidState, flag);
4915 final long value = counts.get(key);
4916 if (value >= 0) {
4917 return value;
4918 }
4919 }
4920 }
4921 return -1;
4922 }
4923
4924 /**
4925 * Finds the first non-null value for the given flags in between the begin and
4926 * end UID states.
4927 *
4928 * @param counts The data array.
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004929 * @param beginUidState The beginning UID state (inclusive).
4930 * @param endUidState The end UID state (inclusive).
Svet Ganovaf189e32019-02-15 18:45:29 -08004931 * @param flags The UID flags.
Svet Ganovaf189e32019-02-15 18:45:29 -08004932 * @return The non-negative value or -1.
4933 */
4934 private static @Nullable String findFirstNonNullForFlagsInStates(
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004935 @Nullable LongSparseArray<String> counts, @UidState int beginUidState,
4936 @UidState int endUidState, @OpFlags int flags) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004937 if (counts == null) {
4938 return null;
4939 }
4940 while (flags != 0) {
4941 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4942 flags &= ~flag;
4943 for (int uidState : UID_STATES) {
4944 if (uidState < beginUidState || uidState > endUidState) {
4945 continue;
4946 }
4947 final long key = makeKey(uidState, flag);
4948 final String value = counts.get(key);
4949 if (value != null) {
4950 return value;
4951 }
4952 }
4953 }
4954 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004955 }
4956
4957 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004958 * Callback for notification of changes to operation state.
4959 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004960 public interface OnOpChangedListener {
4961 public void onOpChanged(String op, String packageName);
4962 }
4963
4964 /**
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004965 * Callback for notification of changes to operation active state.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004966 */
4967 public interface OnOpActiveChangedListener {
4968 /**
4969 * Called when the active state of an app op changes.
4970 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06004971 * @param op The operation that changed.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004972 * @param packageName The package performing the operation.
4973 * @param active Whether the operation became active or inactive.
4974 */
Jeff Sharkey7095ab92019-08-20 16:50:28 -06004975 void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName,
4976 boolean active);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004977 }
4978
4979 /**
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004980 * Callback for notification of an op being noted.
4981 *
4982 * @hide
4983 */
4984 public interface OnOpNotedListener {
4985 /**
4986 * Called when an op was noted.
4987 *
4988 * @param code The op code.
4989 * @param uid The UID performing the operation.
4990 * @param packageName The package performing the operation.
4991 * @param result The result of the note.
4992 */
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004993 void onOpNoted(int code, int uid, String packageName, int result);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004994 }
4995
4996 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004997 * Callback for notification of changes to operation state.
4998 * This allows you to see the raw op codes instead of strings.
4999 * @hide
5000 */
5001 public static class OnOpChangedInternalListener implements OnOpChangedListener {
5002 public void onOpChanged(String op, String packageName) { }
5003 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -08005004 }
5005
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005006 /**
5007 * Callback for notification of changes to operation state.
5008 * This allows you to see the raw op codes instead of strings.
5009 * @hide
5010 */
5011 public interface OnOpActiveChangedInternalListener extends OnOpActiveChangedListener {
5012 default void onOpActiveChanged(String op, int uid, String packageName, boolean active) { }
5013 default void onOpActiveChanged(int op, int uid, String packageName, boolean active) { }
5014 }
5015
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005016 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005017 mContext = context;
5018 mService = service;
5019 }
5020
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005021 /**
5022 * Retrieve current operation state for all applications.
5023 *
Winson6a864b52019-05-10 10:34:14 -07005024 * The mode of the ops returned are set for the package but may not reflect their effective
5025 * state due to UID policy or because it's controlled by a different master op.
5026 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005027 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005028 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005029 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005030 * @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 -07005031 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005032 */
Svet Ganov8455ba22019-01-02 13:05:56 -08005033 @SystemApi
5034 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
5035 public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops) {
5036 final int opCount = ops.length;
5037 final int[] opCodes = new int[opCount];
5038 for (int i = 0; i < opCount; i++) {
5039 opCodes[i] = sOpStrToOp.get(ops[i]);
5040 }
5041 final List<AppOpsManager.PackageOps> result = getPackagesForOps(opCodes);
5042 return (result != null) ? result : Collections.emptyList();
5043 }
5044
5045 /**
5046 * Retrieve current operation state for all applications.
5047 *
Winson6a864b52019-05-10 10:34:14 -07005048 * The mode of the ops returned are set for the package but may not reflect their effective
5049 * state due to UID policy or because it's controlled by a different master op.
5050 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005051 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005052 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005053 *
Svet Ganov8455ba22019-01-02 13:05:56 -08005054 * @param ops The set of operations you are interested in, or null if you want all of them.
5055 * @hide
5056 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07005057 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005058 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08005059 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
5060 try {
5061 return mService.getPackagesForOps(ops);
5062 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005063 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08005064 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08005065 }
5066
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005067 /**
5068 * Retrieve current operation state for one application.
5069 *
Winson6a864b52019-05-10 10:34:14 -07005070 * The mode of the ops returned are set for the package but may not reflect their effective
5071 * state due to UID policy or because it's controlled by a different master op.
5072 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005073 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005074 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005075 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005076 * @param uid The uid of the application of interest.
5077 * @param packageName The name of the application of interest.
5078 * @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 -08005079 *
5080 * @deprecated The int op codes are not stable and you should use the string based op
5081 * names which are stable and namespaced. Use
5082 * {@link #getOpsForPackage(int, String, String...)})}.
5083 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005084 * @hide
Suprabh Shukla169bed72019-05-13 13:54:58 -07005085 * @removed
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005086 */
Svet Ganov8455ba22019-01-02 13:05:56 -08005087 @Deprecated
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07005088 @SystemApi
Dianne Hackbornc216a262018-04-26 13:46:22 -07005089 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Dianne Hackborn62878492019-03-11 15:57:07 -07005090 public @NonNull List<PackageOps> getOpsForPackage(int uid, @NonNull String packageName,
5091 @Nullable int[] ops) {
Dianne Hackborn72e39832013-01-18 18:36:09 -08005092 try {
5093 return mService.getOpsForPackage(uid, packageName, ops);
5094 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005095 throw e.rethrowFromSystemServer();
Dianne Hackborn72e39832013-01-18 18:36:09 -08005096 }
Dianne Hackborn72e39832013-01-18 18:36:09 -08005097 }
5098
Svet Ganovae0e03a2016-02-25 18:22:10 -08005099 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005100 * Retrieve current operation state for one application. The UID and the
5101 * package must match.
5102 *
Winson6a864b52019-05-10 10:34:14 -07005103 * The mode of the ops returned are set for the package but may not reflect their effective
5104 * state due to UID policy or because it's controlled by a different master op.
5105 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005106 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005107 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005108 *
Svet Ganov8455ba22019-01-02 13:05:56 -08005109 * @param uid The uid of the application of interest.
5110 * @param packageName The name of the application of interest.
5111 * @param ops The set of operations you are interested in, or null if you want all of them.
5112 *
5113 * @hide
5114 */
5115 @SystemApi
5116 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
5117 public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid,
5118 @NonNull String packageName, @Nullable String... ops) {
5119 int[] opCodes = null;
5120 if (ops != null) {
5121 opCodes = new int[ops.length];
5122 for (int i = 0; i < ops.length; i++) {
5123 opCodes[i] = strOpToOp(ops[i]);
5124 }
5125 }
5126 try {
5127 final List<PackageOps> result = mService.getOpsForPackage(uid, packageName, opCodes);
5128 if (result == null) {
5129 return Collections.emptyList();
5130 }
5131 return result;
5132 } catch (RemoteException e) {
5133 throw e.rethrowFromSystemServer();
5134 }
5135 }
5136
5137 /**
5138 * Retrieve historical app op stats for a period.
5139 *
Svet Ganov23c88db2019-01-22 20:38:11 -08005140 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08005141 * @param executor Executor on which to run the callback. If <code>null</code>
5142 * the callback is executed on the default executor running on the main thread.
5143 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005144 *
5145 * @throws IllegalArgumentException If any of the argument contracts is violated.
5146 *
5147 * @hide
5148 */
5149 @TestApi
5150 @SystemApi
5151 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov23c88db2019-01-22 20:38:11 -08005152 public void getHistoricalOps(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08005153 @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) {
5154 Preconditions.checkNotNull(executor, "executor cannot be null");
5155 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07005156 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08005157 mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08005158 request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags,
Svet Ganov8455ba22019-01-02 13:05:56 -08005159 new RemoteCallback((result) -> {
5160 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
5161 final long identity = Binder.clearCallingIdentity();
5162 try {
5163 executor.execute(() -> callback.accept(ops));
5164 } finally {
5165 Binder.restoreCallingIdentity(identity);
5166 }
5167 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07005168 } catch (RemoteException e) {
5169 throw e.rethrowFromSystemServer();
5170 }
5171 }
5172
5173 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005174 * Retrieve historical app op stats for a period.
Svet Ganov8455ba22019-01-02 13:05:56 -08005175 * <p>
5176 * This method queries only the on disk state and the returned ops are raw,
5177 * which is their times are relative to the history start as opposed to the
5178 * epoch start.
5179 *
Svet Ganov23c88db2019-01-22 20:38:11 -08005180 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08005181 * @param executor Executor on which to run the callback. If <code>null</code>
5182 * the callback is executed on the default executor running on the main thread.
5183 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005184 *
5185 * @throws IllegalArgumentException If any of the argument contracts is violated.
5186 *
5187 * @hide
5188 */
5189 @TestApi
Svet Ganov8e5bf962019-03-19 23:59:03 -07005190 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
Svet Ganov23c88db2019-01-22 20:38:11 -08005191 public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08005192 @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) {
5193 Preconditions.checkNotNull(executor, "executor cannot be null");
5194 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07005195 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08005196 mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName,
5197 request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis,
Svet Ganovaf189e32019-02-15 18:45:29 -08005198 request.mFlags, new RemoteCallback((result) -> {
Svet Ganov23c88db2019-01-22 20:38:11 -08005199 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
Svet Ganov8455ba22019-01-02 13:05:56 -08005200 final long identity = Binder.clearCallingIdentity();
5201 try {
5202 executor.execute(() -> callback.accept(ops));
5203 } finally {
5204 Binder.restoreCallingIdentity(identity);
5205 }
5206 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07005207 } catch (RemoteException e) {
5208 throw e.rethrowFromSystemServer();
5209 }
5210 }
5211
5212 /**
Svet Ganov8e5bf962019-03-19 23:59:03 -07005213 * Reloads the non historical state to allow testing the read/write path.
5214 *
5215 * @hide
5216 */
5217 @TestApi
5218 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5219 public void reloadNonHistoricalState() {
5220 try {
5221 mService.reloadNonHistoricalState();
5222 } catch (RemoteException e) {
5223 throw e.rethrowFromSystemServer();
5224 }
5225 }
5226
5227 /**
Svet Ganovae0e03a2016-02-25 18:22:10 -08005228 * Sets given app op in the specified mode for app ops in the UID.
5229 * This applies to all apps currently in the UID or installed in
5230 * this UID in the future.
5231 *
5232 * @param code The app op.
5233 * @param uid The UID for which to set the app.
5234 * @param mode The app op mode to set.
5235 * @hide
5236 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005237 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005238 public void setUidMode(int code, int uid, @Mode int mode) {
Svet Ganov2af57082015-07-30 08:44:20 -07005239 try {
5240 mService.setUidMode(code, uid, mode);
5241 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005242 throw e.rethrowFromSystemServer();
Svet Ganov2af57082015-07-30 08:44:20 -07005243 }
5244 }
5245
Svet Ganovae0e03a2016-02-25 18:22:10 -08005246 /**
5247 * Sets given app op in the specified mode for app ops in the UID.
5248 * This applies to all apps currently in the UID or installed in
5249 * this UID in the future.
5250 *
5251 * @param appOp The app op.
5252 * @param uid The UID for which to set the app.
5253 * @param mode The app op mode to set.
5254 * @hide
5255 */
5256 @SystemApi
Eugene Susla93519852018-06-13 16:44:31 -07005257 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005258 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005259 public void setUidMode(String appOp, int uid, @Mode int mode) {
Svet Ganovae0e03a2016-02-25 18:22:10 -08005260 try {
5261 mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
5262 } catch (RemoteException e) {
5263 throw e.rethrowFromSystemServer();
5264 }
5265 }
5266
Svet Ganov2af57082015-07-30 08:44:20 -07005267 /** @hide */
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005268 public void setUserRestriction(int code, boolean restricted, IBinder token) {
Ruben Brunk29931bc2016-03-11 00:24:26 -08005269 setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
5270 }
5271
5272 /** @hide */
5273 public void setUserRestriction(int code, boolean restricted, IBinder token,
5274 String[] exceptionPackages) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07005275 setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
5276 }
5277
5278 /** @hide */
5279 public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
5280 String[] exceptionPackages, int userId) {
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005281 try {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07005282 mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005283 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005284 throw e.rethrowFromSystemServer();
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005285 }
5286 }
5287
5288 /** @hide */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00005289 @UnsupportedAppUsage
Peter Visontayb97fbc82017-12-21 16:23:55 +00005290 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005291 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005292 public void setMode(int code, int uid, String packageName, @Mode int mode) {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08005293 try {
5294 mService.setMode(code, uid, packageName, mode);
5295 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005296 throw e.rethrowFromSystemServer();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08005297 }
5298 }
5299
John Spurlock1af30c72014-03-10 08:33:35 -04005300 /**
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005301 * Change the operating mode for the given op in the given app package. You must pass
5302 * in both the uid and name of the application whose mode is being modified; if these
5303 * do not match, the modification will not be applied.
5304 *
5305 * @param op The operation to modify. One of the OPSTR_* constants.
5306 * @param uid The user id of the application whose mode will be changed.
5307 * @param packageName The name of the application package name whose mode will
5308 * be changed.
5309 * @hide
5310 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07005311 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005312 @SystemApi
5313 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005314 public void setMode(String op, int uid, String packageName, @Mode int mode) {
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005315 try {
5316 mService.setMode(strOpToOp(op), uid, packageName, mode);
5317 } catch (RemoteException e) {
5318 throw e.rethrowFromSystemServer();
5319 }
5320 }
5321
5322 /**
John Spurlock1af30c72014-03-10 08:33:35 -04005323 * Set a non-persisted restriction on an audio operation at a stream-level.
5324 * Restrictions are temporary additional constraints imposed on top of the persisted rules
5325 * defined by {@link #setMode}.
5326 *
5327 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04005328 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04005329 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
5330 * @param exceptionPackages Optional list of packages to exclude from the restriction.
5331 * @hide
5332 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005333 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005334 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -08005335 public void setRestriction(int code, @AttributeUsage int usage, @Mode int mode,
John Spurlock7b414672014-07-18 13:02:39 -04005336 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04005337 try {
5338 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04005339 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04005340 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005341 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04005342 }
5343 }
5344
Dianne Hackborn607b4142013-08-02 18:10:10 -07005345 /** @hide */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005346 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005347 @UnsupportedAppUsage
Dianne Hackborn607b4142013-08-02 18:10:10 -07005348 public void resetAllModes() {
5349 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -07005350 mService.resetAllModes(mContext.getUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07005351 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005352 throw e.rethrowFromSystemServer();
Dianne Hackborn607b4142013-08-02 18:10:10 -07005353 }
5354 }
5355
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005356 /**
Svet Ganovfbf01f72015-04-28 18:39:06 -07005357 * Gets the app op name associated with a given permission.
5358 * The app op name is one of the public constants defined
5359 * in this class such as {@link #OPSTR_COARSE_LOCATION}.
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07005360 * This API is intended to be used for mapping runtime
5361 * permissions to the corresponding app op.
Svet Ganovfbf01f72015-04-28 18:39:06 -07005362 *
5363 * @param permission The permission.
5364 * @return The app op associated with the permission or null.
Svet Ganovfbf01f72015-04-28 18:39:06 -07005365 */
Svet Ganovfbf01f72015-04-28 18:39:06 -07005366 public static String permissionToOp(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08005367 final Integer opCode = sPermToOp.get(permission);
Svet Ganovb9d71a62015-04-30 10:38:13 -07005368 if (opCode == null) {
5369 return null;
5370 }
5371 return sOpToString[opCode];
Svet Ganovfbf01f72015-04-28 18:39:06 -07005372 }
5373
5374 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005375 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005376 * You can watch op changes only for your UID.
5377 *
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07005378 * @param op The operation to monitor, one of OPSTR_*.
5379 * @param packageName The name of the application to monitor.
5380 * @param callback Where to report changes.
5381 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005382 public void startWatchingMode(@NonNull String op, @Nullable String packageName,
5383 @NonNull final OnOpChangedListener callback) {
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07005384 startWatchingMode(strOpToOp(op), packageName, callback);
5385 }
5386
5387 /**
5388 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005389 * You can watch op changes only for your UID.
5390 *
5391 * @param op The operation to monitor, one of OPSTR_*.
5392 * @param packageName The name of the application to monitor.
5393 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
5394 * @param callback Where to report changes.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005395 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005396 public void startWatchingMode(@NonNull String op, @Nullable String packageName, int flags,
5397 @NonNull final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005398 startWatchingMode(strOpToOp(op), packageName, flags, callback);
5399 }
5400
5401 /**
5402 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005403 *
5404 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08005405 * you can watch changes only for your UID.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005406 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005407 * @param op The operation to monitor, one of OP_*.
5408 * @param packageName The name of the application to monitor.
5409 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07005410 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005411 */
Jeff Sharkeybf6b2132018-02-27 11:16:37 -07005412 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005413 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005414 startWatchingMode(op, packageName, 0, callback);
5415 }
5416
5417 /**
5418 * Monitor for changes to the operating mode for the given op in the given app package.
5419 *
5420 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
5421 * you can watch changes only for your UID.
5422 *
5423 * @param op The operation to monitor, one of OP_*.
5424 * @param packageName The name of the application to monitor.
5425 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
5426 * @param callback Where to report changes.
5427 * @hide
5428 */
5429 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
5430 public void startWatchingMode(int op, String packageName, int flags,
5431 final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08005432 synchronized (mModeWatchers) {
5433 IAppOpsCallback cb = mModeWatchers.get(callback);
5434 if (cb == null) {
5435 cb = new IAppOpsCallback.Stub() {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07005436 public void opChanged(int op, int uid, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005437 if (callback instanceof OnOpChangedInternalListener) {
5438 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
5439 }
5440 if (sOpToString[op] != null) {
5441 callback.onOpChanged(sOpToString[op], packageName);
5442 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08005443 }
5444 };
5445 mModeWatchers.put(callback, cb);
5446 }
5447 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005448 mService.startWatchingModeWithFlags(op, packageName, flags, cb);
Dianne Hackbornc2293022013-02-06 23:14:49 -08005449 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005450 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08005451 }
5452 }
5453 }
5454
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005455 /**
5456 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
5457 * monitoring associated with this callback will be removed.
5458 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005459 public void stopWatchingMode(@NonNull OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08005460 synchronized (mModeWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005461 IAppOpsCallback cb = mModeWatchers.remove(callback);
Dianne Hackbornc2293022013-02-06 23:14:49 -08005462 if (cb != null) {
5463 try {
5464 mService.stopWatchingMode(cb);
5465 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005466 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08005467 }
5468 }
5469 }
5470 }
5471
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005472 /** {@hide} */
5473 @Deprecated
5474 public void startWatchingActive(@NonNull int[] ops,
5475 @NonNull OnOpActiveChangedListener callback) {
5476 final String[] strOps = new String[ops.length];
5477 for (int i = 0; i < ops.length; i++) {
5478 strOps[i] = opToPublicName(ops[i]);
5479 }
5480 startWatchingActive(strOps, mContext.getMainExecutor(), callback);
5481 }
5482
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005483 /**
5484 * Start watching for changes to the active state of app ops. An app op may be
5485 * long running and it has a clear start and stop delimiters. If an op is being
5486 * started or stopped by any package you will get a callback. To change the
5487 * watched ops for a registered callback you need to unregister and register it
5488 * again.
5489 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005490 * <p> If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08005491 * you can watch changes only for your UID.
5492 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005493 * @param ops The operations to watch.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005494 * @param callback Where to report changes.
5495 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005496 * @see #isOperationActive
5497 * @see #stopWatchingActive
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005498 * @see #startOp(int, int, String, boolean, String, String)
5499 * @see #finishOp(int, int, String, String)
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005500 */
Svet Ganovf7b47252018-02-26 11:11:27 -08005501 // TODO: Uncomment below annotation once b/73559440 is fixed
5502 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005503 public void startWatchingActive(@NonNull String[] ops,
5504 @CallbackExecutor @NonNull Executor executor,
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005505 @NonNull OnOpActiveChangedListener callback) {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005506 Objects.requireNonNull(ops);
5507 Objects.requireNonNull(executor);
5508 Objects.requireNonNull(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005509 IAppOpsActiveCallback cb;
5510 synchronized (mActiveWatchers) {
5511 cb = mActiveWatchers.get(callback);
5512 if (cb != null) {
5513 return;
5514 }
5515 cb = new IAppOpsActiveCallback.Stub() {
5516 @Override
5517 public void opActiveChanged(int op, int uid, String packageName, boolean active) {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005518 executor.execute(() -> {
5519 if (callback instanceof OnOpActiveChangedInternalListener) {
5520 ((OnOpActiveChangedInternalListener) callback).onOpActiveChanged(op,
5521 uid, packageName, active);
5522 }
5523 if (sOpToString[op] != null) {
5524 callback.onOpActiveChanged(sOpToString[op], uid, packageName, active);
5525 }
5526 });
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005527 }
5528 };
5529 mActiveWatchers.put(callback, cb);
5530 }
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005531 final int[] rawOps = new int[ops.length];
5532 for (int i = 0; i < ops.length; i++) {
5533 rawOps[i] = strOpToOp(ops[i]);
5534 }
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005535 try {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005536 mService.startWatchingActive(rawOps, cb);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005537 } catch (RemoteException e) {
5538 throw e.rethrowFromSystemServer();
5539 }
5540 }
5541
5542 /**
5543 * Stop watching for changes to the active state of an app op. An app op may be
5544 * long running and it has a clear start and stop delimiters. Unregistering a
5545 * non-registered callback has no effect.
5546 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005547 * @see #isOperationActive
5548 * @see #startWatchingActive
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005549 * @see #startOp(int, int, String, boolean, String, String)
5550 * @see #finishOp(int, int, String, String)
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005551 */
5552 public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
5553 synchronized (mActiveWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005554 final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005555 if (cb != null) {
5556 try {
5557 mService.stopWatchingActive(cb);
5558 } catch (RemoteException e) {
5559 throw e.rethrowFromSystemServer();
5560 }
5561 }
5562 }
5563 }
5564
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005565 /**
5566 * Start watching for noted app ops. An app op may be immediate or long running.
5567 * Immediate ops are noted while long running ones are started and stopped. This
5568 * method allows registering a listener to be notified when an app op is noted. If
5569 * an op is being noted by any package you will get a callback. To change the
5570 * watched ops for a registered callback you need to unregister and register it again.
5571 *
5572 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
5573 * you can watch changes only for your UID.
5574 *
5575 * @param ops The ops to watch.
5576 * @param callback Where to report changes.
5577 *
5578 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
5579 * @see #stopWatchingNoted(OnOpNotedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005580 * @see #noteOp(String, int, String, String, String)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005581 *
5582 * @hide
5583 */
5584 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05005585 public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005586 IAppOpsNotedCallback cb;
5587 synchronized (mNotedWatchers) {
5588 cb = mNotedWatchers.get(callback);
5589 if (cb != null) {
5590 return;
5591 }
5592 cb = new IAppOpsNotedCallback.Stub() {
5593 @Override
5594 public void opNoted(int op, int uid, String packageName, int mode) {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05005595 callback.onOpNoted(op, uid, packageName, mode);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005596 }
5597 };
5598 mNotedWatchers.put(callback, cb);
5599 }
5600 try {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05005601 mService.startWatchingNoted(ops, cb);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005602 } catch (RemoteException e) {
5603 throw e.rethrowFromSystemServer();
5604 }
5605 }
5606
5607 /**
5608 * Stop watching for noted app ops. An app op may be immediate or long running.
5609 * Unregistering a non-registered callback has no effect.
5610 *
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05005611 * @see #startWatchingNoted(int[], OnOpNotedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005612 * @see #noteOp(String, int, String, String, String)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005613 *
5614 * @hide
5615 */
5616 public void stopWatchingNoted(@NonNull OnOpNotedListener callback) {
5617 synchronized (mNotedWatchers) {
5618 final IAppOpsNotedCallback cb = mNotedWatchers.get(callback);
5619 if (cb != null) {
5620 try {
5621 mService.stopWatchingNoted(cb);
5622 } catch (RemoteException e) {
5623 throw e.rethrowFromSystemServer();
5624 }
5625 }
5626 }
5627 }
5628
Dianne Hackborn95d78532013-09-11 09:51:14 -07005629 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
5630 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
5631 }
5632
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07005633 /**
5634 * {@hide}
5635 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00005636 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07005637 @TestApi
Dianne Hackborn62878492019-03-11 15:57:07 -07005638 public static int strOpToOp(@NonNull String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005639 Integer val = sOpStrToOp.get(op);
5640 if (val == null) {
5641 throw new IllegalArgumentException("Unknown operation string: " + op);
5642 }
5643 return val;
5644 }
5645
5646 /**
5647 * Do a quick check for whether an application might be able to perform an operation.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005648 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005649 * String, String)} or {@link #startOp(String, int, String, String, String)} for your actual
5650 * security checks, which also ensure that the given uid and package name are consistent. This
5651 * function can just be used for a quick check to see if an operation has been disabled for the
5652 * application, as an early reject of some work. This does not modify the time stamp or other
5653 * data about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07005654 *
5655 * <p>Important things this will not do (which you need to ultimate use
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005656 * {@link #noteOp(String, int, String, String, String)} or
5657 * {@link #startOp(String, int, String, String, String)} to cover):</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -07005658 * <ul>
5659 * <li>Verifying the uid and package are consistent, so callers can't spoof
5660 * their identity.</li>
5661 * <li>Taking into account the current foreground/background state of the
5662 * app; apps whose mode varies by this state will always be reported
5663 * as {@link #MODE_ALLOWED}.</li>
5664 * </ul>
5665 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005666 * @param op The operation to check. One of the OPSTR_* constants.
5667 * @param uid The user id of the application attempting to perform the operation.
5668 * @param packageName The name of the application attempting to perform the operation.
5669 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5670 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5671 * causing the app to crash).
5672 * @throws SecurityException If the app has been configured to crash on this op.
5673 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005674 public int unsafeCheckOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07005675 return checkOp(strOpToOp(op), uid, packageName);
5676 }
5677
5678 /**
5679 * @deprecated Renamed to {@link #unsafeCheckOp(String, int, String)}.
5680 */
5681 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07005682 public int checkOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005683 return checkOp(strOpToOp(op), uid, packageName);
5684 }
5685
5686 /**
John Spurlock925b85e2014-03-10 16:52:11 -04005687 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005688 * returns {@link #MODE_ERRORED}.
5689 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005690 public int unsafeCheckOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07005691 return checkOpNoThrow(strOpToOp(op), uid, packageName);
5692 }
5693
5694 /**
5695 * @deprecated Renamed to {@link #unsafeCheckOpNoThrow(String, int, String)}.
5696 */
5697 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07005698 public int checkOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005699 return checkOpNoThrow(strOpToOp(op), uid, packageName);
5700 }
5701
5702 /**
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005703 * Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op.
5704 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005705 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005706 public int unsafeCheckOpRaw(@NonNull String op, int uid, @NonNull String packageName) {
Svet Ganovaf189e32019-02-15 18:45:29 -08005707 try {
5708 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
5709 } catch (RemoteException e) {
5710 throw e.rethrowFromSystemServer();
5711 }
5712 }
5713
5714 /**
5715 * Like {@link #unsafeCheckOpNoThrow(String, int, String)} but returns the <em>raw</em>
5716 * mode associated with the op. Does not throw a security exception, does not translate
5717 * {@link #MODE_FOREGROUND}.
5718 */
5719 public int unsafeCheckOpRawNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005720 try {
Svet Ganov9d528a12018-12-19 17:23:11 -08005721 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005722 } catch (RemoteException e) {
5723 throw e.rethrowFromSystemServer();
5724 }
5725 }
5726
5727 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005728 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005729 */
5730 @Deprecated
5731 public int noteOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005732 return noteOp(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005733 }
5734
5735 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005736 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005737 *
5738 * @hide
5739 */
5740 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005741 + "#noteOp(java.lang.String, int, java.lang.String, java.lang.String, "
5742 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005743 @Deprecated
5744 public int noteOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005745 return noteOp(op, Process.myUid(), mContext.getOpPackageName(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005746 }
5747
5748 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005749 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005750 *
5751 * @hide
5752 */
5753 @Deprecated
5754 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005755 + "#noteOp(java.lang.String, int, java.lang.String, java.lang.String, "
5756 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005757 public int noteOp(int op, int uid, @Nullable String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005758 return noteOp(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005759 }
5760
5761 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005762 * Make note of an application performing an operation. Note that you must pass
5763 * in both the uid and name of the application to be checked; this function will verify
5764 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5765 * succeeds, the last execution time of the operation for this app will be updated to
5766 * the current time.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005767 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005768 * @param op The operation to note. One of the OPSTR_* constants.
5769 * @param uid The user id of the application attempting to perform the operation.
5770 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005771 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005772 * @param message A message describing the reason the op was noted
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005773 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005774 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5775 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5776 * causing the app to crash).
5777 *
5778 * @throws SecurityException If the app has been configured to crash on this op.
Svet Ganov99b60432015-06-27 13:15:22 -07005779 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005780 public int noteOp(@NonNull String op, int uid, @Nullable String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005781 @Nullable String featureId, @Nullable String message) {
5782 return noteOp(strOpToOp(op), uid, packageName, featureId, message);
Svet Ganov99b60432015-06-27 13:15:22 -07005783 }
5784
5785 /**
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005786 * Make note of an application performing an operation. Note that you must pass
5787 * in both the uid and name of the application to be checked; this function will verify
5788 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5789 * succeeds, the last execution time of the operation for this app will be updated to
5790 * the current time.
5791 *
5792 * @param op The operation to note. One of the OP_* constants.
5793 * @param uid The user id of the application attempting to perform the operation.
5794 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005795 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005796 * @param message A message describing the reason the op was noted
5797 *
5798 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5799 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5800 * causing the app to crash).
5801 *
5802 * @throws SecurityException If the app has been configured to crash on this op.
5803 *
5804 * @hide
5805 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005806 public int noteOp(int op, int uid, @Nullable String packageName, @Nullable String featureId,
5807 @Nullable String message) {
5808 final int mode = noteOpNoThrow(op, uid, packageName, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005809 if (mode == MODE_ERRORED) {
5810 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
5811 }
5812 return mode;
5813 }
5814
5815 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005816 * @deprecated Use {@link #noteOpNoThrow(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005817 */
5818 @Deprecated
5819 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005820 return noteOpNoThrow(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005821 }
5822
5823 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005824 * @deprecated Use {@link #noteOpNoThrow(int, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005825 *
5826 * @hide
5827 */
5828 @Deprecated
5829 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005830 + "#noteOpNoThrow(java.lang.String, int, java.lang.String, java.lang.String, "
5831 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005832 public int noteOpNoThrow(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005833 return noteOpNoThrow(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005834 }
5835
5836 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005837 * Like {@link #noteOp(String, int, String, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005838 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
5839 *
5840 * @param op The operation to note. One of the OPSTR_* constants.
5841 * @param uid The user id of the application attempting to perform the operation.
5842 * @param packageName The name of the application attempting to perform the operation.
5843 * @param message A message describing the reason the op was noted
5844 *
5845 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5846 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5847 * causing the app to crash).
5848 */
5849 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005850 @Nullable String feature, @Nullable String message) {
5851 return noteOpNoThrow(strOpToOp(op), uid, packageName, feature, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005852 }
5853
5854 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005855 * Like {@link #noteOp(String, int, String, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005856 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
5857 *
5858 * @param op The operation to note. One of the OP_* constants.
5859 * @param uid The user id of the application attempting to perform the operation.
5860 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005861 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005862 * @param message A message describing the reason the op was noted
5863 *
5864 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5865 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5866 * causing the app to crash).
5867 *
5868 * @hide
5869 */
5870 public int noteOpNoThrow(int op, int uid, @Nullable String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005871 @Nullable String featureId, @Nullable String message) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005872 try {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005873 int mode = mService.noteOperation(op, uid, packageName, featureId);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005874 if (mode == MODE_ALLOWED) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005875 markAppOpNoted(uid, packageName, op, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005876 }
5877
5878 return mode;
5879 } catch (RemoteException e) {
5880 throw e.rethrowFromSystemServer();
5881 }
5882 }
5883
5884 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005885 * @deprecated Use {@link #noteProxyOp(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005886 */
5887 @Deprecated
5888 public int noteProxyOp(@NonNull String op, @NonNull String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005889 return noteProxyOp(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005890 }
5891
5892 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005893 * @deprecated Use {@link #noteProxyOp(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005894 *
5895 * @hide
5896 */
5897 @Deprecated
5898 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005899 + "#noteProxyOp(java.lang.String, java.lang.String, int, java.lang.String, "
5900 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005901 public int noteProxyOp(int op, @Nullable String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005902 return noteProxyOp(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005903 }
5904
5905 /**
5906 * Make note of an application performing an operation on behalf of another application when
5907 * handling an IPC. This function will verify that the calling uid and proxied package name
5908 * match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution
5909 * time of the operation for the proxied app and your app will be updated to the current time.
5910 *
5911 * @param op The operation to note. One of the OP_* constants.
5912 * @param proxiedPackageName The name of the application calling into the proxy application.
5913 * @param proxiedUid The uid of the proxied application
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005914 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
5915 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005916 * @param message A message describing the reason the op was noted
5917 *
5918 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED}
5919 * if it is not allowed and should be silently ignored (without causing the app to crash).
5920 *
5921 * @throws SecurityException If the proxy or proxied app has been configured to crash on this
5922 * op.
5923 *
5924 * @hide
5925 */
5926 public int noteProxyOp(int op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005927 @Nullable String proxiedFeatureId, @Nullable String message) {
5928 int mode = noteProxyOpNoThrow(op, proxiedPackageName, proxiedUid, proxiedFeatureId,
5929 message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005930 if (mode == MODE_ERRORED) {
5931 throw new SecurityException("Proxy package " + mContext.getOpPackageName()
5932 + " from uid " + Process.myUid() + " or calling package " + proxiedPackageName
5933 + " from uid " + proxiedUid + " not allowed to perform " + sOpNames[op]);
5934 }
5935 return mode;
5936 }
5937
5938 /**
5939 * Make note of an application performing an operation on behalf of another application when
5940 * handling an IPC. This function will verify that the calling uid and proxied package name
5941 * match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution
5942 * time of the operation for the proxied app and your app will be updated to the current time.
5943 *
5944 * @param op The operation to note. One of the OPSTR_* constants.
5945 * @param proxiedPackageName The name of the application calling into the proxy application.
5946 * @param proxiedUid The uid of the proxied application
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005947 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
5948 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005949 * @param message A message describing the reason the op was noted
5950 *
5951 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED}
5952 * if it is not allowed and should be silently ignored (without causing the app to crash).
5953 *
5954 * @throws SecurityException If the proxy or proxied app has been configured to crash on this
5955 * op.
5956 */
5957 public int noteProxyOp(@NonNull String op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005958 @Nullable String proxiedFeatureId, @Nullable String message) {
5959 return noteProxyOp(strOpToOp(op), proxiedPackageName, proxiedUid, proxiedFeatureId,
5960 message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005961 }
5962
5963 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005964 * @deprecated Use {@link #noteProxyOpNoThrow(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005965 */
5966 @Deprecated
5967 public int noteProxyOpNoThrow(@NonNull String op, @NonNull String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005968 return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005969 }
5970
5971 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005972 * @deprecated Use {@link #noteProxyOpNoThrow(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005973 */
5974 @Deprecated
5975 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
5976 int proxiedUid) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005977 return noteProxyOpNoThrow(op, proxiedPackageName, proxiedUid, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005978 }
5979
5980 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005981 * Like {@link #noteProxyOp(String, String, int, String, String)} but instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005982 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005983 *
5984 * <p>This API requires package with the {@code proxiedPackageName} to belong to
5985 * {@code proxiedUid}.
5986 *
5987 * @param op The op to note
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005988 * @param proxiedPackageName The package to note the op for
5989 * @param proxiedUid The uid the package belongs to
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005990 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
5991 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005992 * @param message A message describing the reason the op was noted
5993 */
5994 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005995 int proxiedUid, @Nullable String proxiedFeatureId, @Nullable String message) {
5996 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid,
5997 proxiedFeatureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005998 }
5999
6000 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006001 * Like {@link #noteProxyOp(int, String, int, String, String)} but instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006002 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
6003 *
6004 * @param op The op to note
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08006005 * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
6006 * noted for the "android" package
6007 * @param proxiedUid The uid the package belongs to
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006008 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
6009 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006010 * @param message A message describing the reason the op was noted
6011 *
6012 * @hide
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08006013 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006014 public int noteProxyOpNoThrow(int op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006015 @Nullable String proxiedFeatureId, @Nullable String message) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006016 int myUid = Process.myUid();
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08006017
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006018 try {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006019 int mode = mService.noteProxyOperation(op, proxiedUid, proxiedPackageName,
6020 proxiedFeatureId, myUid, mContext.getOpPackageName(),
6021 mContext.getFeatureId());
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006022 if (mode == MODE_ALLOWED
6023 // Only collect app-ops when the proxy is trusted
6024 && mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1, myUid)
6025 == PackageManager.PERMISSION_GRANTED) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006026 markAppOpNoted(proxiedUid, proxiedPackageName, op, proxiedFeatureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006027 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006028
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006029 return mode;
6030 } catch (RemoteException e) {
6031 throw e.rethrowFromSystemServer();
6032 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006033 }
6034
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006035 /**
6036 * Do a quick check for whether an application might be able to perform an operation.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006037 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006038 * String, String)} or {@link #startOp(int, int, String, boolean, String, String)} for your
6039 * actual security checks, which also ensure that the given uid and package name are consistent.
6040 * This function can just be used for a quick check to see if an operation has been disabled for
6041 * the application, as an early reject of some work. This does not modify the time stamp or
6042 * other data about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07006043 *
6044 * <p>Important things this will not do (which you need to ultimate use
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006045 * {@link #noteOp(String, int, String, String, String)} or
6046 * {@link #startOp(int, int, String, boolean, String, String)} to cover):</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -07006047 * <ul>
6048 * <li>Verifying the uid and package are consistent, so callers can't spoof
6049 * their identity.</li>
6050 * <li>Taking into account the current foreground/background state of the
6051 * app; apps whose mode varies by this state will always be reported
6052 * as {@link #MODE_ALLOWED}.</li>
6053 * </ul>
6054 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006055 * @param op The operation to check. One of the OP_* constants.
6056 * @param uid The user id of the application attempting to perform the operation.
6057 * @param packageName The name of the application attempting to perform the operation.
6058 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6059 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6060 * causing the app to crash).
6061 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006062 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006063 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01006064 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08006065 public int checkOp(int op, int uid, String packageName) {
6066 try {
6067 int mode = mService.checkOperation(op, uid, packageName);
6068 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07006069 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08006070 }
6071 return mode;
6072 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006073 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08006074 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08006075 }
6076
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006077 /**
6078 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
6079 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006080 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006081 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01006082 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08006083 public int checkOpNoThrow(int op, int uid, String packageName) {
6084 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006085 int mode = mService.checkOperation(op, uid, packageName);
6086 return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08006087 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006088 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08006089 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08006090 }
6091
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006092 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07006093 * Do a quick check to validate if a package name belongs to a UID.
6094 *
6095 * @throws SecurityException if the package name doesn't belong to the given
6096 * UID, or if ownership cannot be verified.
6097 */
Dianne Hackborn62878492019-03-11 15:57:07 -07006098 public void checkPackage(int uid, @NonNull String packageName) {
Jeff Sharkey911d7f42013-09-05 18:11:45 -07006099 try {
6100 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
6101 throw new SecurityException(
6102 "Package " + packageName + " does not belong to " + uid);
6103 }
6104 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006105 throw e.rethrowFromSystemServer();
Jeff Sharkey911d7f42013-09-05 18:11:45 -07006106 }
6107 }
6108
6109 /**
John Spurlock1af30c72014-03-10 08:33:35 -04006110 * Like {@link #checkOp} but at a stream-level for audio operations.
6111 * @hide
6112 */
6113 public int checkAudioOp(int op, int stream, int uid, String packageName) {
6114 try {
6115 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
6116 if (mode == MODE_ERRORED) {
6117 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
6118 }
6119 return mode;
6120 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006121 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04006122 }
John Spurlock1af30c72014-03-10 08:33:35 -04006123 }
6124
6125 /**
6126 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
6127 * returns {@link #MODE_ERRORED}.
6128 * @hide
6129 */
6130 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
6131 try {
6132 return mService.checkAudioOperation(op, stream, uid, packageName);
6133 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006134 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04006135 }
John Spurlock1af30c72014-03-10 08:33:35 -04006136 }
6137
Dianne Hackborne98f5db2013-07-17 17:23:25 -07006138 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01006139 @UnsupportedAppUsage
Dianne Hackborne98f5db2013-07-17 17:23:25 -07006140 public static IBinder getToken(IAppOpsService service) {
6141 synchronized (AppOpsManager.class) {
6142 if (sToken != null) {
6143 return sToken;
6144 }
6145 try {
6146 sToken = service.getToken(new Binder());
6147 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006148 throw e.rethrowFromSystemServer();
Dianne Hackborne98f5db2013-07-17 17:23:25 -07006149 }
6150 return sToken;
6151 }
6152 }
6153
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006154
6155 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006156 * @deprecated use {@link #startOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006157 */
6158 @Deprecated
6159 public int startOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006160 return startOp(op, uid, packageName, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08006161 }
6162
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006163 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006164 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Svet Ganovf7b47252018-02-26 11:11:27 -08006165 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006166 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006167 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006168 @Deprecated
6169 public int startOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006170 return startOp(op, Process.myUid(), mContext.getOpPackageName(), false, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08006171 }
6172
6173 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006174 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006175 *
6176 * @hide
6177 */
6178 @Deprecated
6179 public int startOp(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006180 return startOp(op, uid, packageName, false, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006181 }
6182
6183 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006184 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006185 *
6186 * @hide
6187 */
6188 @Deprecated
6189 public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006190 return startOp(op, uid, packageName, startIfModeDefault, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006191 }
6192
6193 /**
6194 * Report that an application has started executing a long-running operation.
6195 *
6196 * @param op The operation to start. One of the OPSTR_* constants.
6197 * @param uid The user id of the application attempting to perform the operation.
6198 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006199 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006200 * @param message Description why op was started
6201 *
6202 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6203 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6204 * causing the app to crash).
6205 *
6206 * @throws SecurityException If the app has been configured to crash on this op or
6207 * the package is not in the passed in UID.
6208 */
6209 public int startOp(@NonNull String op, int uid, @Nullable String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006210 @NonNull String featureId, @Nullable String message) {
6211 return startOp(strOpToOp(op), uid, packageName, false, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006212 }
6213
6214 /**
6215 * Report that an application has started executing a long-running operation.
Svet Ganovf7b47252018-02-26 11:11:27 -08006216 *
6217 * @param op The operation to start. One of the OP_* constants.
6218 * @param uid The user id of the application attempting to perform the operation.
6219 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006220 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006221 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
6222 * @param message Description why op was started
6223 *
Svet Ganovf7b47252018-02-26 11:11:27 -08006224 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6225 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6226 * causing the app to crash).
Svet Ganovf7b47252018-02-26 11:11:27 -08006227 *
6228 * @throws SecurityException If the app has been configured to crash on this op or
6229 * the package is not in the passed in UID.
6230 *
6231 * @hide
6232 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006233 public int startOp(int op, int uid, @Nullable String packageName, boolean startIfModeDefault,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006234 @NonNull String featureId, @Nullable String message) {
6235 final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault, featureId,
6236 message);
Svet Ganovf7b47252018-02-26 11:11:27 -08006237 if (mode == MODE_ERRORED) {
6238 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006239 }
Svet Ganovf7b47252018-02-26 11:11:27 -08006240 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006241 }
6242
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006243 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006244 * @deprecated use {@link #startOpNoThrow(String, int, String, String, String)} instead
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006245 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006246 @Deprecated
6247 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006248 return startOpNoThrow(op, uid, packageName, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08006249 }
6250
6251 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006252 * @deprecated Use {@link #startOpNoThrow(int, int, String, boolean, String, String} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006253 *
6254 * @hide
6255 */
6256 @Deprecated
6257 public int startOpNoThrow(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006258 return startOpNoThrow(op, uid, packageName, false, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006259 }
6260
6261 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006262 * @deprecated Use {@link #startOpNoThrow(int, int, String, boolean, String, String} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006263 *
6264 * @hide
6265 */
6266 @Deprecated
6267 public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006268 return startOpNoThrow(op, uid, packageName, startIfModeDefault, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006269 }
6270
6271 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006272 * Like {@link #startOp(String, int, String, String, String)} but instead of throwing a
Svet Ganovf7b47252018-02-26 11:11:27 -08006273 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
6274 *
6275 * @param op The operation to start. One of the OP_* constants.
6276 * @param uid The user id of the application attempting to perform the operation.
6277 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006278 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006279 * @param message Description why op was started
6280 *
Svet Ganovf7b47252018-02-26 11:11:27 -08006281 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6282 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6283 * causing the app to crash).
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006284 */
6285 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006286 @NonNull String featureId, @Nullable String message) {
6287 return startOpNoThrow(strOpToOp(op), uid, packageName, false, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006288 }
6289
6290 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006291 * Like {@link #startOp(int, int, String, boolean, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006292 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
6293 *
6294 * @param op The operation to start. One of the OP_* constants.
6295 * @param uid The user id of the application attempting to perform the operation.
6296 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006297 * @param featureId The feature in the app or {@code null} for default feature
Svet Ganovf7b47252018-02-26 11:11:27 -08006298 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006299 * @param message Description why op was started
6300 *
6301 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6302 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6303 * causing the app to crash).
Svet Ganovf7b47252018-02-26 11:11:27 -08006304 *
6305 * @hide
6306 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006307 public int startOpNoThrow(int op, int uid, @NonNull String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006308 boolean startIfModeDefault, @Nullable String featureId, @Nullable String message) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006309 try {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006310 int mode = mService.startOperation(getToken(mService), op, uid, packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006311 featureId, startIfModeDefault);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006312 if (mode == MODE_ALLOWED) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006313 markAppOpNoted(uid, packageName, op, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006314 }
6315
6316 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006317 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006318 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006319 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006320 }
6321
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006322 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006323 * @deprecated Use {@link #finishOp(String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006324 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006325 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006326 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006327 @Deprecated
6328 public void finishOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006329 finishOp(op, Process.myUid(), mContext.getOpPackageName(), null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006330 }
6331
6332 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006333 * @deprecated Use {@link #finishOp(String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006334 */
6335 public void finishOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006336 finishOp(strOpToOp(op), uid, packageName, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006337 }
6338
6339 /**
6340 * Report that an application is no longer performing an operation that had previously
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006341 * been started with {@link #startOp(String, int, String, String, String)}. There is no
6342 * validation of input or result; the parameters supplied here must be the exact same ones
6343 * previously passed in when starting the operation.
6344 */
6345 public void finishOp(@NonNull String op, int uid, @NonNull String packageName,
6346 @Nullable String featureId) {
6347 finishOp(strOpToOp(op), uid, packageName, featureId);
6348 }
6349
6350 /**
6351 * @deprecated Use {@link #finishOp(int, int, String, String)} instead
6352 *
6353 * @hide
6354 */
6355 public void finishOp(int op, int uid, @NonNull String packageName) {
6356 finishOp(op, uid, packageName, null);
6357 }
6358
6359 /**
6360 * Report that an application is no longer performing an operation that had previously
6361 * been started with {@link #startOp(int, int, String, boolean, String, String)}. There is no
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006362 * validation of input or result; the parameters supplied here must be the exact same ones
6363 * previously passed in when starting the operation.
6364 *
6365 * @hide
6366 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006367 public void finishOp(int op, int uid, @NonNull String packageName,
6368 @Nullable String featureId) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006369 try {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006370 mService.finishOperation(getToken(mService), op, uid, packageName, featureId);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006371 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006372 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006373 }
6374 }
6375
Svet Ganovf7b47252018-02-26 11:11:27 -08006376 /**
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006377 * Checks whether the given op for a package is active.
6378 * <p>
6379 * If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS}
6380 * permission you can query only for your UID.
6381 *
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006382 * @see #finishOp(String, int, String, String)
6383 * @see #startOp(String, int, String, String, String)
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006384 */
6385 public boolean isOpActive(@NonNull String op, int uid, @NonNull String packageName) {
6386 return isOperationActive(strOpToOp(op), uid, packageName);
6387 }
6388
6389 /**
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006390 * Start collection of noted appops on this thread.
6391 *
6392 * <p>Called at the beginning of a two way binder transaction.
6393 *
6394 * @see #finishNotedAppOpsCollection()
6395 *
6396 * @hide
6397 */
6398 public static void startNotedAppOpsCollection(int callingUid) {
6399 sBinderThreadCallingUid.set(callingUid);
6400 }
6401
6402 /**
6403 * State of a temporarily paused noted app-ops collection.
6404 *
6405 * @see #pauseNotedAppOpsCollection()
6406 *
6407 * @hide
6408 */
6409 public static class PausedNotedAppOpsCollection {
6410 final int mUid;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006411 final @Nullable ArrayMap<String, long[]> mCollectedNotedAppOps;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006412
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006413 PausedNotedAppOpsCollection(int uid, @Nullable ArrayMap<String,
6414 long[]> collectedNotedAppOps) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006415 mUid = uid;
6416 mCollectedNotedAppOps = collectedNotedAppOps;
6417 }
6418 }
6419
6420 /**
6421 * Temporarily suspend collection of noted app-ops when binder-thread calls into the other
6422 * process. During such a call there might be call-backs coming back on the same thread which
6423 * should not be accounted to the current collection.
6424 *
6425 * @return a state needed to resume the collection
6426 *
6427 * @hide
6428 */
6429 public static @Nullable PausedNotedAppOpsCollection pauseNotedAppOpsCollection() {
6430 Integer previousUid = sBinderThreadCallingUid.get();
6431 if (previousUid != null) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006432 ArrayMap<String, long[]> previousCollectedNotedAppOps =
6433 sAppOpsNotedInThisBinderTransaction.get();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006434
6435 sBinderThreadCallingUid.remove();
6436 sAppOpsNotedInThisBinderTransaction.remove();
6437
6438 return new PausedNotedAppOpsCollection(previousUid, previousCollectedNotedAppOps);
6439 }
6440
6441 return null;
6442 }
6443
6444 /**
6445 * Resume a collection paused via {@link #pauseNotedAppOpsCollection}.
6446 *
6447 * @param prevCollection The state of the previous collection
6448 *
6449 * @hide
6450 */
6451 public static void resumeNotedAppOpsCollection(
6452 @Nullable PausedNotedAppOpsCollection prevCollection) {
6453 if (prevCollection != null) {
6454 sBinderThreadCallingUid.set(prevCollection.mUid);
6455
6456 if (prevCollection.mCollectedNotedAppOps != null) {
6457 sAppOpsNotedInThisBinderTransaction.set(prevCollection.mCollectedNotedAppOps);
6458 }
6459 }
6460 }
6461
6462 /**
6463 * Finish collection of noted appops on this thread.
6464 *
6465 * <p>Called at the end of a two way binder transaction.
6466 *
6467 * @see #startNotedAppOpsCollection(int)
6468 *
6469 * @hide
6470 */
6471 public static void finishNotedAppOpsCollection() {
6472 sBinderThreadCallingUid.remove();
6473 sAppOpsNotedInThisBinderTransaction.remove();
6474 }
6475
6476 /**
6477 * Mark an app-op as noted
6478 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006479 private void markAppOpNoted(int uid, @Nullable String packageName, int code,
6480 @Nullable String featureId, @Nullable String message) {
6481 if (packageName == null) {
6482 packageName = "android";
6483 }
6484
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006485 // check it the appops needs to be collected and cache result
6486 if (sAppOpsToNote[code] == SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED) {
6487 boolean shouldCollectNotes;
6488 try {
6489 shouldCollectNotes = mService.shouldCollectNotes(code);
6490 } catch (RemoteException e) {
6491 return;
6492 }
6493
6494 if (shouldCollectNotes) {
6495 sAppOpsToNote[code] = SHOULD_COLLECT_NOTE_OP;
6496 } else {
6497 sAppOpsToNote[code] = SHOULD_NOT_COLLECT_NOTE_OP;
6498 }
6499 }
6500
6501 if (sAppOpsToNote[code] != SHOULD_COLLECT_NOTE_OP) {
6502 return;
6503 }
6504
6505 Integer binderUid = sBinderThreadCallingUid.get();
6506
6507 synchronized (sLock) {
6508 if (sNotedAppOpsCollector != null && uid == Process.myUid() && packageName.equals(
6509 ActivityThread.currentOpPackageName())) {
6510 // This app is noting an app-op for itself. Deliver immediately.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006511 sNotedAppOpsCollector.onSelfNoted(new SyncNotedAppOp(code, featureId));
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006512
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006513 return;
6514 }
6515 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006516
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006517 if (binderUid != null && binderUid == uid) {
6518 // If this is inside of a two-way binder call: Delivered to caller via
6519 // {@link #prefixParcelWithAppOpsIfNeeded}
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006520 // We are inside of a two-way binder call. Delivered to caller via
6521 // {@link #prefixParcelWithAppOpsIfNeeded}
6522 ArrayMap<String, long[]> appOpsNoted = sAppOpsNotedInThisBinderTransaction.get();
6523 if (appOpsNoted == null) {
6524 appOpsNoted = new ArrayMap<>(1);
6525 sAppOpsNotedInThisBinderTransaction.set(appOpsNoted);
6526 }
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006527
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006528 long[] appOpsNotedForFeature = appOpsNoted.get(featureId);
6529 if (appOpsNotedForFeature == null) {
6530 appOpsNotedForFeature = new long[2];
6531 appOpsNoted.put(featureId, appOpsNotedForFeature);
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006532 }
6533
6534 if (code < 64) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006535 appOpsNotedForFeature[0] |= 1L << code;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006536 } else {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006537 appOpsNotedForFeature[1] |= 1L << (code - 64);
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006538 }
6539 } else {
6540 // Cannot deliver the note synchronous: Hence send it to the system server to
6541 // notify the noted process.
6542 if (message == null) {
6543 // Default message is a stack trace
6544 message = getFormattedStackTrace();
6545 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006546
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006547 long token = Binder.clearCallingIdentity();
6548 try {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006549 mService.noteAsyncOp(mContext.getOpPackageName(), uid, packageName, code,
6550 featureId, message);
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006551 } catch (RemoteException e) {
6552 e.rethrowFromSystemServer();
6553 } finally {
6554 Binder.restoreCallingIdentity(token);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006555 }
6556 }
6557 }
6558
6559 /**
6560 * Append app-ops noted in the current two-way binder transaction to parcel.
6561 *
6562 * <p>This is called on the callee side of a two way binder transaction just before the
6563 * transaction returns.
6564 *
6565 * @param p the parcel to append the noted app-ops to
6566 *
6567 * @hide
6568 */
6569 public static void prefixParcelWithAppOpsIfNeeded(@NonNull Parcel p) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006570 ArrayMap<String, long[]> notedAppOps = sAppOpsNotedInThisBinderTransaction.get();
6571 if (notedAppOps == null) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006572 return;
6573 }
6574
6575 p.writeInt(Parcel.EX_HAS_NOTED_APPOPS_REPLY_HEADER);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006576
6577 int numFeatureWithNotesAppOps = notedAppOps.size();
6578 p.writeInt(numFeatureWithNotesAppOps);
6579
6580 for (int i = 0; i < numFeatureWithNotesAppOps; i++) {
6581 p.writeString(notedAppOps.keyAt(i));
6582 p.writeLong(notedAppOps.valueAt(i)[0]);
6583 p.writeLong(notedAppOps.valueAt(i)[1]);
6584 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006585 }
6586
6587 /**
6588 * Read app-ops noted during a two-way binder transaction from parcel.
6589 *
6590 * <p>This is called on the calling side of a two way binder transaction just after the
6591 * transaction returns.
6592 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006593 * @param p The parcel to read from
6594 *
6595 * @hide
6596 */
6597 public static void readAndLogNotedAppops(@NonNull Parcel p) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006598 int numFeaturesWithNotedAppOps = p.readInt();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006599
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006600 for (int i = 0; i < numFeaturesWithNotedAppOps; i++) {
6601 String featureId = p.readString();
6602 long[] rawNotedAppOps = new long[2];
6603 rawNotedAppOps[0] = p.readLong();
6604 rawNotedAppOps[1] = p.readLong();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006605
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006606 if (rawNotedAppOps[0] != 0 || rawNotedAppOps[1] != 0) {
6607 BitSet notedAppOps = BitSet.valueOf(rawNotedAppOps);
6608
6609 synchronized (sLock) {
6610 for (int code = notedAppOps.nextSetBit(0); code != -1;
6611 code = notedAppOps.nextSetBit(code + 1)) {
6612 if (sNotedAppOpsCollector != null) {
6613 sNotedAppOpsCollector.onNoted(new SyncNotedAppOp(code, featureId));
6614 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006615 }
6616 }
6617 }
6618 }
6619 }
6620
6621 /**
6622 * Register a new {@link AppOpsCollector}.
6623 *
6624 * <p>There can only ever be one collector per process. If there currently is a collector
6625 * registered, it will be unregistered.
6626 *
6627 * <p><b>Only appops related to dangerous permissions are collected.</b>
6628 *
6629 * @param collector The collector to set or {@code null} to unregister.
6630 */
6631 public void setNotedAppOpsCollector(@Nullable AppOpsCollector collector) {
6632 synchronized (sLock) {
6633 if (sNotedAppOpsCollector != null) {
6634 try {
6635 mService.stopWatchingAsyncNoted(mContext.getPackageName(),
6636 sNotedAppOpsCollector.mAsyncCb);
6637 } catch (RemoteException e) {
6638 e.rethrowFromSystemServer();
6639 }
6640 }
6641
6642 sNotedAppOpsCollector = collector;
6643
6644 if (sNotedAppOpsCollector != null) {
6645 List<AsyncNotedAppOp> missedAsyncOps = null;
6646 try {
6647 mService.startWatchingAsyncNoted(mContext.getPackageName(),
6648 sNotedAppOpsCollector.mAsyncCb);
6649 missedAsyncOps = mService.extractAsyncOps(mContext.getPackageName());
6650 } catch (RemoteException e) {
6651 e.rethrowFromSystemServer();
6652 }
6653
6654 if (missedAsyncOps != null) {
6655 int numMissedAsyncOps = missedAsyncOps.size();
6656 for (int i = 0; i < numMissedAsyncOps; i++) {
6657 final AsyncNotedAppOp asyncNotedAppOp = missedAsyncOps.get(i);
6658 if (sNotedAppOpsCollector != null) {
6659 sNotedAppOpsCollector.getAsyncNotedExecutor().execute(
6660 () -> sNotedAppOpsCollector.onAsyncNoted(
6661 asyncNotedAppOp));
6662 }
6663 }
6664 }
6665 }
6666 }
6667 }
6668
6669 /**
6670 * @return {@code true} iff the process currently is currently collecting noted appops.
6671 *
6672 * @see #setNotedAppOpsCollector(AppOpsCollector)
6673 *
6674 * @hide
6675 */
6676 public static boolean isCollectingNotedAppOps() {
6677 synchronized (sLock) {
6678 return sNotedAppOpsCollector != null;
6679 }
6680 }
6681
6682 /**
6683 * Callback an app can choose to {@link #setNotedAppOpsCollector register} to monitor it's noted
6684 * appops.
6685 *
6686 * <p><b>Only appops related to dangerous permissions are collected.</b>
6687 */
6688 public abstract static class AppOpsCollector {
6689 /** Callback registered with the system. This will receive the async notes ops */
6690 private final IAppOpsAsyncNotedCallback mAsyncCb = new IAppOpsAsyncNotedCallback.Stub() {
6691 @Override
6692 public void opNoted(AsyncNotedAppOp op) {
6693 Preconditions.checkNotNull(op);
6694
6695 getAsyncNotedExecutor().execute(() -> onAsyncNoted(op));
6696 }
6697 };
6698
6699 /**
6700 * @return The executor for the system to use when calling {@link #onAsyncNoted}.
6701 */
6702 public @NonNull Executor getAsyncNotedExecutor() {
6703 return new HandlerExecutor(Handler.getMain());
6704 }
6705
6706 /**
6707 * Called when an app-op was noted for this package inside of a two-way binder-call.
6708 *
6709 * <p>Called on the calling thread just after executing the binder-call. This allows
6710 * the app to e.g. collect stack traces to figure out where the access came from.
6711 *
6712 * @param op The op noted
6713 */
6714 public abstract void onNoted(@NonNull SyncNotedAppOp op);
6715
6716 /**
6717 * Called when this app noted an app-op for its own package.
6718 *
6719 * <p>Called on the thread the noted the op. This allows the app to e.g. collect stack
6720 * traces to figure out where the access came from.
6721 *
6722 * @param op The op noted
6723 */
6724 public abstract void onSelfNoted(@NonNull SyncNotedAppOp op);
6725
6726 /**
6727 * Called when an app-op was noted for this package which cannot be delivered via the other
6728 * two mechanisms.
6729 *
6730 * <p>Called as soon as possible after the app-op was noted, but the delivery delay is not
6731 * guaranteed. Due to how async calls work in Android this might even be delivered slightly
6732 * before the private data is delivered to the app.
6733 *
6734 * <p>If the app is not running or no {@link AppOpsCollector} is registered a small amount
6735 * of noted app-ops are buffered and then delivered as soon as a collector is registered.
6736 *
6737 * @param asyncOp The op noted
6738 */
6739 public abstract void onAsyncNoted(@NonNull AsyncNotedAppOp asyncOp);
6740 }
6741
6742 /**
6743 * Generate a stack trace used for noted app-ops logging.
6744 *
6745 * <p>This strips away the first few and last few stack trace elements as they are not
6746 * interesting to apps.
6747 */
6748 private static String getFormattedStackTrace() {
6749 StackTraceElement[] trace = new Exception().getStackTrace();
6750
6751 int firstInteresting = 0;
6752 for (int i = 0; i < trace.length; i++) {
6753 if (trace[i].getClassName().startsWith(AppOpsManager.class.getName())
6754 || trace[i].getClassName().startsWith(Parcel.class.getName())
6755 || trace[i].getClassName().contains("$Stub$Proxy")
6756 || trace[i].getClassName().startsWith(DatabaseUtils.class.getName())
6757 || trace[i].getClassName().startsWith("android.content.ContentProviderProxy")
6758 || trace[i].getClassName().startsWith(ContentResolver.class.getName())) {
6759 firstInteresting = i;
6760 } else {
6761 break;
6762 }
6763 }
6764
6765 int lastInteresting = trace.length - 1;
6766 for (int i = trace.length - 1; i >= 0; i--) {
6767 if (trace[i].getClassName().startsWith(HandlerThread.class.getName())
6768 || trace[i].getClassName().startsWith(Handler.class.getName())
6769 || trace[i].getClassName().startsWith(Looper.class.getName())
6770 || trace[i].getClassName().startsWith(Binder.class.getName())
6771 || trace[i].getClassName().startsWith(RuntimeInit.class.getName())
6772 || trace[i].getClassName().startsWith(ZygoteInit.class.getName())
6773 || trace[i].getClassName().startsWith(ActivityThread.class.getName())
6774 || trace[i].getClassName().startsWith(Method.class.getName())
6775 || trace[i].getClassName().startsWith("com.android.server.SystemServer")) {
6776 lastInteresting = i;
6777 } else {
6778 break;
6779 }
6780 }
6781
6782 StringBuilder sb = new StringBuilder();
6783 for (int i = firstInteresting; i <= lastInteresting; i++) {
6784 sb.append(trace[i]);
6785 if (i != lastInteresting) {
6786 sb.append('\n');
6787 }
6788 }
6789
6790 return sb.toString();
6791 }
6792
6793 /**
Svet Ganovf7b47252018-02-26 11:11:27 -08006794 * Checks whether the given op for a UID and package is active.
6795 *
6796 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
6797 * you can query only for your UID.
6798 *
6799 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
6800 * @see #stopWatchingMode(OnOpChangedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006801 * @see #finishOp(int, int, String, String)
6802 * @see #startOp(int, int, String, boolean, String, String)
Svet Ganovf7b47252018-02-26 11:11:27 -08006803 *
6804 * @hide */
6805 @TestApi
6806 // TODO: Uncomment below annotation once b/73559440 is fixed
6807 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey35e46d22017-06-09 10:01:20 -06006808 public boolean isOperationActive(int code, int uid, String packageName) {
6809 try {
6810 return mService.isOperationActive(code, uid, packageName);
6811 } catch (RemoteException e) {
6812 throw e.rethrowFromSystemServer();
6813 }
6814 }
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00006815
6816 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08006817 * Configures the app ops persistence for testing.
6818 *
6819 * @param mode The mode in which the historical registry operates.
6820 * @param baseSnapshotInterval The base interval on which we would be persisting a snapshot of
6821 * the historical data. The history is recursive where every subsequent step encompasses
6822 * {@code compressionStep} longer interval with {@code compressionStep} distance between
6823 * snapshots.
6824 * @param compressionStep The compression step in every iteration.
6825 *
6826 * @see #HISTORICAL_MODE_DISABLED
6827 * @see #HISTORICAL_MODE_ENABLED_ACTIVE
6828 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
6829 *
6830 * @hide
6831 */
6832 @TestApi
6833 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
6834 public void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval,
6835 int compressionStep) {
6836 try {
6837 mService.setHistoryParameters(mode, baseSnapshotInterval, compressionStep);
6838 } catch (RemoteException e) {
6839 throw e.rethrowFromSystemServer();
6840 }
6841 }
6842
6843 /**
6844 * Offsets the history by the given duration.
6845 *
6846 * @param offsetMillis The offset duration.
6847 *
6848 * @hide
6849 */
6850 @TestApi
6851 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
6852 public void offsetHistory(long offsetMillis) {
6853 try {
6854 mService.offsetHistory(offsetMillis);
6855 } catch (RemoteException e) {
6856 throw e.rethrowFromSystemServer();
6857 }
6858 }
6859
6860 /**
6861 * Adds ops to the history directly. This could be useful for testing especially
6862 * when the historical registry operates in {@link #HISTORICAL_MODE_ENABLED_PASSIVE}
6863 * mode.
6864 *
6865 * @param ops The ops to add to the history.
6866 *
6867 * @see #setHistoryParameters(int, long, int)
6868 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
6869 *
6870 * @hide
6871 */
6872 @TestApi
6873 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
6874 public void addHistoricalOps(@NonNull HistoricalOps ops) {
6875 try {
6876 mService.addHistoricalOps(ops);
6877 } catch (RemoteException e) {
6878 throw e.rethrowFromSystemServer();
6879 }
6880 }
6881
6882 /**
6883 * Resets the app ops persistence for testing.
6884 *
6885 * @see #setHistoryParameters(int, long, int)
6886 *
6887 * @hide
6888 */
6889 @TestApi
6890 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
6891 public void resetHistoryParameters() {
6892 try {
6893 mService.resetHistoryParameters();
6894 } catch (RemoteException e) {
6895 throw e.rethrowFromSystemServer();
6896 }
6897 }
6898
6899 /**
6900 * Clears all app ops history.
6901 *
6902 * @hide
6903 */
6904 @TestApi
6905 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
6906 public void clearHistory() {
6907 try {
6908 mService.clearHistory();
6909 } catch (RemoteException e) {
6910 throw e.rethrowFromSystemServer();
6911 }
6912 }
6913
6914 /**
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00006915 * Returns all supported operation names.
6916 * @hide
6917 */
6918 @SystemApi
6919 @TestApi
6920 public static String[] getOpStrs() {
6921 return Arrays.copyOf(sOpToString, sOpToString.length);
6922 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07006923
Philip P. Moltmann24576812018-05-07 10:42:05 -07006924
6925 /**
6926 * @return number of App ops
6927 * @hide
6928 */
6929 @TestApi
6930 public static int getNumOps() {
6931 return _NUM_OP;
6932 }
6933
Dianne Hackbornc216a262018-04-26 13:46:22 -07006934 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08006935 * Computes the max for the given flags in between the begin and
6936 * end UID states.
6937 *
6938 * @param counts The data array.
6939 * @param flags The UID flags.
6940 * @param beginUidState The beginning UID state (exclusive).
6941 * @param endUidState The end UID state.
6942 * @return The sum.
Dianne Hackbornc216a262018-04-26 13:46:22 -07006943 */
Svet Ganovaf189e32019-02-15 18:45:29 -08006944 private static long maxForFlagsInStates(@Nullable LongSparseLongArray counts,
6945 @UidState int beginUidState, @UidState int endUidState,
6946 @OpFlags int flags) {
6947 if (counts == null) {
6948 return 0;
6949 }
6950 long max = 0;
6951 while (flags != 0) {
6952 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
6953 flags &= ~flag;
6954 for (int uidState : UID_STATES) {
6955 if (uidState < beginUidState || uidState > endUidState) {
6956 continue;
6957 }
6958 final long key = makeKey(uidState, flag);
6959 max = Math.max(max, counts.get(key));
Dianne Hackbornc216a262018-04-26 13:46:22 -07006960 }
6961 }
Svet Ganovaf189e32019-02-15 18:45:29 -08006962 return max;
6963 }
6964
6965
6966 private static void writeLongSparseLongArrayToParcel(
6967 @Nullable LongSparseLongArray array, @NonNull Parcel parcel) {
6968 if (array != null) {
6969 final int size = array.size();
6970 parcel.writeInt(size);
6971 for (int i = 0; i < size; i++) {
6972 parcel.writeLong(array.keyAt(i));
6973 parcel.writeLong(array.valueAt(i));
6974 }
6975 } else {
6976 parcel.writeInt(-1);
6977 }
6978 }
6979
6980 private static @Nullable LongSparseLongArray readLongSparseLongArrayFromParcel(
6981 @NonNull Parcel parcel) {
6982 final int size = parcel.readInt();
6983 if (size < 0) {
6984 return null;
6985 }
6986 final LongSparseLongArray array = new LongSparseLongArray(size);
6987 for (int i = 0; i < size; i++) {
6988 array.append(parcel.readLong(), parcel.readLong());
6989 }
6990 return array;
6991 }
6992
6993 private static void writeLongSparseStringArrayToParcel(
6994 @Nullable LongSparseArray<String> array, @NonNull Parcel parcel) {
6995 if (array != null) {
6996 final int size = array.size();
6997 parcel.writeInt(size);
6998 for (int i = 0; i < size; i++) {
6999 parcel.writeLong(array.keyAt(i));
7000 parcel.writeString(array.valueAt(i));
7001 }
7002 } else {
7003 parcel.writeInt(-1);
7004 }
7005 }
7006
7007 private static @Nullable LongSparseArray<String> readLongSparseStringArrayFromParcel(
7008 @NonNull Parcel parcel) {
7009 final int size = parcel.readInt();
7010 if (size < 0) {
7011 return null;
7012 }
7013 final LongSparseArray<String> array = new LongSparseArray<>(size);
7014 for (int i = 0; i < size; i++) {
7015 array.append(parcel.readLong(), parcel.readString());
7016 }
7017 return array;
7018 }
7019
7020 /**
7021 * Collects the keys from an array to the result creating the result if needed.
7022 *
7023 * @param array The array whose keys to collect.
7024 * @param result The optional result store collected keys.
7025 * @return The result collected keys array.
7026 */
7027 private static LongSparseArray<Object> collectKeys(@Nullable LongSparseLongArray array,
7028 @Nullable LongSparseArray<Object> result) {
7029 if (array != null) {
7030 if (result == null) {
7031 result = new LongSparseArray<>();
7032 }
7033 final int accessSize = array.size();
7034 for (int i = 0; i < accessSize; i++) {
7035 result.put(array.keyAt(i), null);
7036 }
7037 }
7038 return result;
Dianne Hackbornc216a262018-04-26 13:46:22 -07007039 }
Svet Ganov8455ba22019-01-02 13:05:56 -08007040
7041 /** @hide */
7042 public static String uidStateToString(@UidState int uidState) {
7043 switch (uidState) {
7044 case UID_STATE_PERSISTENT: {
7045 return "UID_STATE_PERSISTENT";
7046 }
7047 case UID_STATE_TOP: {
7048 return "UID_STATE_TOP";
7049 }
Amith Yamasania0a30a12019-01-22 11:38:06 -08007050 case UID_STATE_FOREGROUND_SERVICE_LOCATION: {
7051 return "UID_STATE_FOREGROUND_SERVICE_LOCATION";
7052 }
Svet Ganov8455ba22019-01-02 13:05:56 -08007053 case UID_STATE_FOREGROUND_SERVICE: {
7054 return "UID_STATE_FOREGROUND_SERVICE";
7055 }
7056 case UID_STATE_FOREGROUND: {
7057 return "UID_STATE_FOREGROUND";
7058 }
7059 case UID_STATE_BACKGROUND: {
7060 return "UID_STATE_BACKGROUND";
7061 }
7062 case UID_STATE_CACHED: {
7063 return "UID_STATE_CACHED";
7064 }
7065 default: {
7066 return "UNKNOWN";
7067 }
7068 }
7069 }
7070
7071 /** @hide */
7072 public static int parseHistoricalMode(@NonNull String mode) {
7073 switch (mode) {
7074 case "HISTORICAL_MODE_ENABLED_ACTIVE": {
7075 return HISTORICAL_MODE_ENABLED_ACTIVE;
7076 }
7077 case "HISTORICAL_MODE_ENABLED_PASSIVE": {
7078 return HISTORICAL_MODE_ENABLED_PASSIVE;
7079 }
7080 default: {
7081 return HISTORICAL_MODE_DISABLED;
7082 }
7083 }
7084 }
7085
7086 /** @hide */
7087 public static String historicalModeToString(@HistoricalMode int mode) {
7088 switch (mode) {
7089 case HISTORICAL_MODE_DISABLED: {
7090 return "HISTORICAL_MODE_DISABLED";
7091 }
7092 case HISTORICAL_MODE_ENABLED_ACTIVE: {
7093 return "HISTORICAL_MODE_ENABLED_ACTIVE";
7094 }
7095 case HISTORICAL_MODE_ENABLED_PASSIVE: {
7096 return "HISTORICAL_MODE_ENABLED_PASSIVE";
7097 }
7098 default: {
7099 return "UNKNOWN";
7100 }
7101 }
7102 }
Ng Zhi An65a99b62018-10-01 11:57:53 -07007103
7104 private static int getSystemAlertWindowDefault() {
7105 final Context context = ActivityThread.currentApplication();
7106 if (context == null) {
7107 return AppOpsManager.MODE_DEFAULT;
7108 }
7109
7110 // system alert window is disable on low ram phones starting from Q
7111 final PackageManager pm = context.getPackageManager();
7112 // TVs are constantly plugged in and has less concern for memory/power
7113 if (ActivityManager.isLowRamDeviceStatic()
7114 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) {
7115 return AppOpsManager.MODE_IGNORED;
7116 }
7117
7118 return AppOpsManager.MODE_DEFAULT;
7119 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007120}