blob: 765c358748a3342b96f7a3b57ead7fb25aaafcea [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. */
Svet Ganov8455ba22019-01-02 13:05:56 -0800584 @TestApi
Dianne Hackborn35654b62013-01-14 17:38:02 -0800585 public static final int OP_COARSE_LOCATION = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700586 /** @hide Access to fine location information. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100587 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800588 public static final int OP_FINE_LOCATION = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700589 /** @hide Causing GPS to run. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100590 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800591 public static final int OP_GPS = 2;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800592 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100593 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700594 public static final int OP_VIBRATE = 3;
595 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100596 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700597 public static final int OP_READ_CONTACTS = 4;
598 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100599 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700600 public static final int OP_WRITE_CONTACTS = 5;
601 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100602 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700603 public static final int OP_READ_CALL_LOG = 6;
604 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100605 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700606 public static final int OP_WRITE_CALL_LOG = 7;
607 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100608 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700609 public static final int OP_READ_CALENDAR = 8;
610 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100611 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700612 public static final int OP_WRITE_CALENDAR = 9;
613 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100614 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700615 public static final int OP_WIFI_SCAN = 10;
616 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100617 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700618 public static final int OP_POST_NOTIFICATION = 11;
619 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100620 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700621 public static final int OP_NEIGHBORING_CELLS = 12;
622 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100623 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700624 public static final int OP_CALL_PHONE = 13;
625 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100626 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700627 public static final int OP_READ_SMS = 14;
628 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100629 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700630 public static final int OP_WRITE_SMS = 15;
631 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100632 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700633 public static final int OP_RECEIVE_SMS = 16;
634 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100635 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700636 public static final int OP_RECEIVE_EMERGECY_SMS = 17;
637 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100638 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700639 public static final int OP_RECEIVE_MMS = 18;
640 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100641 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700642 public static final int OP_RECEIVE_WAP_PUSH = 19;
643 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100644 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700645 public static final int OP_SEND_SMS = 20;
646 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100647 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700648 public static final int OP_READ_ICC_SMS = 21;
649 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100650 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700651 public static final int OP_WRITE_ICC_SMS = 22;
652 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100653 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700654 public static final int OP_WRITE_SETTINGS = 23;
Peter Visontay96449f62017-12-11 18:50:03 +0000655 /** @hide Required to draw on top of other apps. */
Svet Ganovf7b47252018-02-26 11:11:27 -0800656 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700657 public static final int OP_SYSTEM_ALERT_WINDOW = 24;
658 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100659 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700660 public static final int OP_ACCESS_NOTIFICATIONS = 25;
661 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100662 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700663 public static final int OP_CAMERA = 26;
664 /** @hide */
Svet Ganova7a0db62018-02-27 20:08:01 -0800665 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700666 public static final int OP_RECORD_AUDIO = 27;
667 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100668 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700669 public static final int OP_PLAY_AUDIO = 28;
670 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100671 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700672 public static final int OP_READ_CLIPBOARD = 29;
673 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100674 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700675 public static final int OP_WRITE_CLIPBOARD = 30;
676 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100677 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700678 public static final int OP_TAKE_MEDIA_BUTTONS = 31;
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_AUDIO_FOCUS = 32;
682 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100683 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700684 public static final int OP_AUDIO_MASTER_VOLUME = 33;
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_VOICE_VOLUME = 34;
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_RING_VOLUME = 35;
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_MEDIA_VOLUME = 36;
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_ALARM_VOLUME = 37;
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_NOTIFICATION_VOLUME = 38;
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_BLUETOOTH_VOLUME = 39;
703 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100704 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700705 public static final int OP_WAKE_LOCK = 40;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700706 /** @hide Continually monitoring location data. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100707 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700708 public static final int OP_MONITOR_LOCATION = 41;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700709 /** @hide Continually monitoring location data with a relatively high power request. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100710 @UnsupportedAppUsage
David Christie0b837452013-07-29 16:02:13 -0700711 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700712 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100713 @UnsupportedAppUsage
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700714 public static final int OP_GET_USAGE_STATS = 43;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700715 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100716 @UnsupportedAppUsage
Emily Bernier22c921a2014-05-28 11:01:32 -0400717 public static final int OP_MUTE_MICROPHONE = 44;
718 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100719 @UnsupportedAppUsage
Jason Monk1c7c3192014-06-26 12:52:18 -0400720 public static final int OP_TOAST_WINDOW = 45;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700721 /** @hide Capture the device's display contents and/or audio */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100722 @UnsupportedAppUsage
Michael Wrightc39d47a2014-07-08 18:07:36 -0700723 public static final int OP_PROJECT_MEDIA = 46;
Jeff Davidson05542602014-08-11 14:07:27 -0700724 /** @hide Activate a VPN connection without user intervention. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100725 @UnsupportedAppUsage
Jeff Davidson05542602014-08-11 14:07:27 -0700726 public static final int OP_ACTIVATE_VPN = 47;
Benjamin Franzf3ece362015-02-11 10:51:10 +0000727 /** @hide Access the WallpaperManagerAPI to write wallpapers. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100728 @UnsupportedAppUsage
Benjamin Franzf3ece362015-02-11 10:51:10 +0000729 public static final int OP_WRITE_WALLPAPER = 48;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700730 /** @hide Received the assist structure from an app. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100731 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700732 public static final int OP_ASSIST_STRUCTURE = 49;
733 /** @hide Received a screenshot from assist. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100734 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700735 public static final int OP_ASSIST_SCREENSHOT = 50;
Svet Ganov16a16892015-04-16 10:32:04 -0700736 /** @hide Read the phone state. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100737 @UnsupportedAppUsage
Svet Ganov16a16892015-04-16 10:32:04 -0700738 public static final int OP_READ_PHONE_STATE = 51;
Svet Ganovc3300092015-04-17 09:07:22 -0700739 /** @hide Add voicemail messages to the voicemail content provider. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100740 @UnsupportedAppUsage
Svet Ganovc3300092015-04-17 09:07:22 -0700741 public static final int OP_ADD_VOICEMAIL = 52;
Svetoslav5335b672015-04-29 12:00:51 -0700742 /** @hide Access APIs for SIP calling over VOIP or WiFi. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100743 @UnsupportedAppUsage
Svetoslav5335b672015-04-29 12:00:51 -0700744 public static final int OP_USE_SIP = 53;
Svetoslavc656e6f2015-04-29 14:08:16 -0700745 /** @hide Intercept outgoing calls. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100746 @UnsupportedAppUsage
Svetoslavc656e6f2015-04-29 14:08:16 -0700747 public static final int OP_PROCESS_OUTGOING_CALLS = 54;
Svetoslav4af76a52015-04-29 15:29:46 -0700748 /** @hide User the fingerprint API. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100749 @UnsupportedAppUsage
Svetoslav4af76a52015-04-29 15:29:46 -0700750 public static final int OP_USE_FINGERPRINT = 55;
Svet Ganovb9d71a62015-04-30 10:38:13 -0700751 /** @hide Access to body sensors such as heart rate, etc. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100752 @UnsupportedAppUsage
Svet Ganovb9d71a62015-04-30 10:38:13 -0700753 public static final int OP_BODY_SENSORS = 56;
Svet Ganovede43162015-05-02 17:42:44 -0700754 /** @hide Read previously received cell broadcast messages. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100755 @UnsupportedAppUsage
Svet Ganovede43162015-05-02 17:42:44 -0700756 public static final int OP_READ_CELL_BROADCASTS = 57;
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700757 /** @hide Inject mock location into the system. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100758 @UnsupportedAppUsage
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700759 public static final int OP_MOCK_LOCATION = 58;
Svet Ganov921c7df2015-06-29 21:51:41 -0700760 /** @hide Read external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100761 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700762 public static final int OP_READ_EXTERNAL_STORAGE = 59;
763 /** @hide Write external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100764 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700765 public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700766 /** @hide Turned on the screen. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100767 @UnsupportedAppUsage
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700768 public static final int OP_TURN_SCREEN_ON = 61;
Svetoslavf3f02ac2015-09-08 14:36:35 -0700769 /** @hide Get device accounts. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100770 @UnsupportedAppUsage
Svetoslavf3f02ac2015-09-08 14:36:35 -0700771 public static final int OP_GET_ACCOUNTS = 62;
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700772 /** @hide Control whether an application is allowed to run in the background. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100773 @UnsupportedAppUsage
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700774 public static final int OP_RUN_IN_BACKGROUND = 63;
Jason Monk1c7c3192014-06-26 12:52:18 -0400775 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100776 @UnsupportedAppUsage
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800777 public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800778 /** @hide Read the phone number. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100779 @UnsupportedAppUsage
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700780 public static final int OP_READ_PHONE_NUMBERS = 65;
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800781 /** @hide Request package installs through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100782 @UnsupportedAppUsage
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800783 public static final int OP_REQUEST_INSTALL_PACKAGES = 66;
Winson Chungf4ac0632017-03-17 12:34:12 -0700784 /** @hide Enter picture-in-picture. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100785 @UnsupportedAppUsage
Winson Chungf4ac0632017-03-17 12:34:12 -0700786 public static final int OP_PICTURE_IN_PICTURE = 67;
Chad Brubaker97b383f2017-02-02 15:04:35 -0800787 /** @hide Instant app start foreground service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100788 @UnsupportedAppUsage
Chad Brubaker97b383f2017-02-02 15:04:35 -0800789 public static final int OP_INSTANT_APP_START_FOREGROUND = 68;
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800790 /** @hide Answer incoming phone calls */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100791 @UnsupportedAppUsage
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800792 public static final int OP_ANSWER_PHONE_CALLS = 69;
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700793 /** @hide Run jobs when in background */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100794 @UnsupportedAppUsage
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700795 public static final int OP_RUN_ANY_IN_BACKGROUND = 70;
Peter Visontay1246d9e2017-10-17 17:02:45 +0100796 /** @hide Change Wi-Fi connectivity state */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100797 @UnsupportedAppUsage
Peter Visontay1246d9e2017-10-17 17:02:45 +0100798 public static final int OP_CHANGE_WIFI_STATE = 71;
Peter Visontayf2e38362017-11-27 15:27:16 +0000799 /** @hide Request package deletion through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100800 @UnsupportedAppUsage
Peter Visontayf2e38362017-11-27 15:27:16 +0000801 public static final int OP_REQUEST_DELETE_PACKAGES = 72;
Peter Visontay11950832017-11-14 19:34:59 +0000802 /** @hide Bind an accessibility service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100803 @UnsupportedAppUsage
Peter Visontay11950832017-11-14 19:34:59 +0000804 public static final int OP_BIND_ACCESSIBILITY_SERVICE = 73;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800805 /** @hide Continue handover of a call from another app */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100806 @UnsupportedAppUsage
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800807 public static final int OP_ACCEPT_HANDOVER = 74;
Nathan Harold1bb420672018-03-14 17:08:53 -0700808 /** @hide Create and Manage IPsec Tunnels */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100809 @UnsupportedAppUsage
Nathan Harold1bb420672018-03-14 17:08:53 -0700810 public static final int OP_MANAGE_IPSEC_TUNNELS = 75;
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700811 /** @hide Any app start foreground service. */
Svet Ganovaf189e32019-02-15 18:45:29 -0800812 @TestApi
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700813 public static final int OP_START_FOREGROUND = 76;
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800814 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100815 @UnsupportedAppUsage
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700816 public static final int OP_BLUETOOTH_SCAN = 77;
Kevin Chynb3c05aa2018-09-21 16:50:32 -0700817 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
818 public static final int OP_USE_BIOMETRIC = 78;
Zimuzo6cbf9cc2018-10-05 12:05:58 +0100819 /** @hide Physical activity recognition. */
820 public static final int OP_ACTIVITY_RECOGNITION = 79;
Hongming Jin228cd012018-11-09 14:47:50 -0800821 /** @hide Financial app sms read. */
822 public static final int OP_SMS_FINANCIAL_TRANSACTIONS = 80;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -0700823 /** @hide Read media of audio type. */
824 public static final int OP_READ_MEDIA_AUDIO = 81;
825 /** @hide Write media of audio type. */
826 public static final int OP_WRITE_MEDIA_AUDIO = 82;
827 /** @hide Read media of video type. */
828 public static final int OP_READ_MEDIA_VIDEO = 83;
829 /** @hide Write media of video type. */
830 public static final int OP_WRITE_MEDIA_VIDEO = 84;
831 /** @hide Read media of image type. */
832 public static final int OP_READ_MEDIA_IMAGES = 85;
833 /** @hide Write media of image type. */
834 public static final int OP_WRITE_MEDIA_IMAGES = 86;
Jeff Sharkeye82cbb12018-12-06 15:53:11 -0700835 /** @hide Has a legacy (non-isolated) view of storage. */
836 public static final int OP_LEGACY_STORAGE = 87;
Jackal Guo8dc791e2019-01-14 10:26:42 +0800837 /** @hide Accessing accessibility features */
838 public static final int OP_ACCESS_ACCESSIBILITY = 88;
Michael Groover656ef912019-04-09 17:09:57 -0700839 /** @hide Read the device identifiers (IMEI / MEID, IMSI, SIM / Build serial) */
840 public static final int OP_READ_DEVICE_IDENTIFIERS = 89;
Philip P. Moltmann89b044f2019-09-13 15:12:34 -0700841 /** @hide Read location metadata from media */
842 public static final int OP_ACCESS_MEDIA_LOCATION = 90;
Patrick Baumann6c1c8092019-06-27 14:55:44 -0700843 /** @hide Query all apps on device, regardless of declarations in the calling app manifest */
Philip P. Moltmann89b044f2019-09-13 15:12:34 -0700844 public static final int OP_QUERY_ALL_PACKAGES = 91;
Patrick Baumann6c1c8092019-06-27 14:55:44 -0700845
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700846 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100847 @UnsupportedAppUsage
Philip P. Moltmann89b044f2019-09-13 15:12:34 -0700848 public static final int _NUM_OP = 92;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800849
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700850 /** Access to coarse location information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700851 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700852 /** Access to fine location information. */
853 public static final String OPSTR_FINE_LOCATION =
854 "android:fine_location";
855 /** Continually monitoring location data. */
856 public static final String OPSTR_MONITOR_LOCATION
857 = "android:monitor_location";
858 /** Continually monitoring location data with a relatively high power request. */
859 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
860 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700861 /** Access to {@link android.app.usage.UsageStatsManager}. */
862 public static final String OPSTR_GET_USAGE_STATS
863 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700864 /** Activate a VPN connection without user intervention. @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000865 @SystemApi @TestApi
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700866 public static final String OPSTR_ACTIVATE_VPN
867 = "android:activate_vpn";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700868 /** Allows an application to read the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700869 public static final String OPSTR_READ_CONTACTS
870 = "android:read_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700871 /** Allows an application to write to the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700872 public static final String OPSTR_WRITE_CONTACTS
873 = "android:write_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700874 /** Allows an application to read the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700875 public static final String OPSTR_READ_CALL_LOG
876 = "android:read_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700877 /** Allows an application to write to the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700878 public static final String OPSTR_WRITE_CALL_LOG
879 = "android:write_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700880 /** Allows an application to read the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700881 public static final String OPSTR_READ_CALENDAR
882 = "android:read_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700883 /** Allows an application to write to the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700884 public static final String OPSTR_WRITE_CALENDAR
885 = "android:write_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700886 /** Allows an application to initiate a phone call. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700887 public static final String OPSTR_CALL_PHONE
888 = "android:call_phone";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700889 /** Allows an application to read SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700890 public static final String OPSTR_READ_SMS
891 = "android:read_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700892 /** Allows an application to receive SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700893 public static final String OPSTR_RECEIVE_SMS
894 = "android:receive_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700895 /** Allows an application to receive MMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700896 public static final String OPSTR_RECEIVE_MMS
897 = "android:receive_mms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700898 /** Allows an application to receive WAP push messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700899 public static final String OPSTR_RECEIVE_WAP_PUSH
900 = "android:receive_wap_push";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700901 /** Allows an application to send SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700902 public static final String OPSTR_SEND_SMS
903 = "android:send_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700904 /** Required to be able to access the camera device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700905 public static final String OPSTR_CAMERA
906 = "android:camera";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700907 /** Required to be able to access the microphone device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700908 public static final String OPSTR_RECORD_AUDIO
909 = "android:record_audio";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700910 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700911 public static final String OPSTR_READ_PHONE_STATE
912 = "android:read_phone_state";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700913 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700914 public static final String OPSTR_ADD_VOICEMAIL
915 = "android:add_voicemail";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700916 /** Access APIs for SIP calling over VOIP or WiFi */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700917 public static final String OPSTR_USE_SIP
918 = "android:use_sip";
Svet Ganove8e89422016-09-22 19:56:50 -0700919 /** Access APIs for diverting outgoing calls */
Svet Ganov824ad6e2016-09-22 19:36:53 -0700920 public static final String OPSTR_PROCESS_OUTGOING_CALLS
921 = "android:process_outgoing_calls";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700922 /** Use the fingerprint API. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700923 public static final String OPSTR_USE_FINGERPRINT
924 = "android:use_fingerprint";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700925 /** Access to body sensors such as heart rate, etc. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700926 public static final String OPSTR_BODY_SENSORS
927 = "android:body_sensors";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700928 /** Read previously received cell broadcast messages. */
Svet Ganovede43162015-05-02 17:42:44 -0700929 public static final String OPSTR_READ_CELL_BROADCASTS
930 = "android:read_cell_broadcasts";
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700931 /** Inject mock location into the system. */
932 public static final String OPSTR_MOCK_LOCATION
933 = "android:mock_location";
Svet Ganov921c7df2015-06-29 21:51:41 -0700934 /** Read external storage. */
935 public static final String OPSTR_READ_EXTERNAL_STORAGE
936 = "android:read_external_storage";
937 /** Write external storage. */
938 public static final String OPSTR_WRITE_EXTERNAL_STORAGE
939 = "android:write_external_storage";
Billy Lau24b9c832015-07-20 17:34:09 +0100940 /** Required to draw on top of other apps. */
941 public static final String OPSTR_SYSTEM_ALERT_WINDOW
942 = "android:system_alert_window";
943 /** Required to write/modify/update system settingss. */
944 public static final String OPSTR_WRITE_SETTINGS
945 = "android:write_settings";
Svetoslavf3f02ac2015-09-08 14:36:35 -0700946 /** @hide Get device accounts. */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000947 @SystemApi @TestApi
Svetoslavf3f02ac2015-09-08 14:36:35 -0700948 public static final String OPSTR_GET_ACCOUNTS
949 = "android:get_accounts";
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700950 public static final String OPSTR_READ_PHONE_NUMBERS
951 = "android:read_phone_numbers";
Winson Chungf4ac0632017-03-17 12:34:12 -0700952 /** Access to picture-in-picture. */
953 public static final String OPSTR_PICTURE_IN_PICTURE
954 = "android:picture_in_picture";
Chad Brubaker97b383f2017-02-02 15:04:35 -0800955 /** @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000956 @SystemApi @TestApi
Chad Brubaker97b383f2017-02-02 15:04:35 -0800957 public static final String OPSTR_INSTANT_APP_START_FOREGROUND
958 = "android:instant_app_start_foreground";
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800959 /** Answer incoming phone calls */
960 public static final String OPSTR_ANSWER_PHONE_CALLS
961 = "android:answer_phone_calls";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800962 /**
963 * Accept call handover
964 * @hide
965 */
966 @SystemApi @TestApi
967 public static final String OPSTR_ACCEPT_HANDOVER
968 = "android:accept_handover";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000969 /** @hide */
970 @SystemApi @TestApi
971 public static final String OPSTR_GPS = "android:gps";
972 /** @hide */
973 @SystemApi @TestApi
974 public static final String OPSTR_VIBRATE = "android:vibrate";
975 /** @hide */
976 @SystemApi @TestApi
977 public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
978 /** @hide */
979 @SystemApi @TestApi
980 public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
981 /** @hide */
982 @SystemApi @TestApi
983 public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
984 /** @hide */
985 @SystemApi @TestApi
986 public static final String OPSTR_WRITE_SMS = "android:write_sms";
987 /** @hide */
988 @SystemApi @TestApi
989 public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST =
990 "android:receive_emergency_broadcast";
991 /** @hide */
992 @SystemApi @TestApi
993 public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
994 /** @hide */
995 @SystemApi @TestApi
996 public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
997 /** @hide */
998 @SystemApi @TestApi
999 public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
1000 /** @hide */
1001 @SystemApi @TestApi
1002 public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
1003 /** @hide */
1004 @SystemApi @TestApi
1005 public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
1006 /** @hide */
1007 @SystemApi @TestApi
1008 public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
1009 /** @hide */
1010 @SystemApi @TestApi
1011 public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
1012 /** @hide */
1013 @SystemApi @TestApi
1014 public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
1015 /** @hide */
1016 @SystemApi @TestApi
1017 public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
1018 /** @hide */
1019 @SystemApi @TestApi
1020 public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
1021 /** @hide */
1022 @SystemApi @TestApi
1023 public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
1024 /** @hide */
1025 @SystemApi @TestApi
1026 public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
1027 /** @hide */
1028 @SystemApi @TestApi
1029 public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
1030 /** @hide */
1031 @SystemApi @TestApi
1032 public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME =
1033 "android:audio_notification_volume";
1034 /** @hide */
1035 @SystemApi @TestApi
1036 public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
1037 /** @hide */
1038 @SystemApi @TestApi
1039 public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
1040 /** @hide */
1041 @SystemApi @TestApi
1042 public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
1043 /** @hide */
1044 @SystemApi @TestApi
1045 public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
1046 /** @hide */
1047 @SystemApi @TestApi
1048 public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
1049 /** @hide */
1050 @SystemApi @TestApi
1051 public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
1052 /** @hide */
1053 @SystemApi @TestApi
1054 public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
1055 /** @hide */
1056 @SystemApi @TestApi
1057 public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
1058 /** @hide */
1059 @SystemApi @TestApi
1060 public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
1061 /** @hide */
1062 @SystemApi @TestApi
1063 public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
1064 /** @hide */
1065 @SystemApi @TestApi
1066 public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME =
1067 "android:audio_accessibility_volume";
1068 /** @hide */
1069 @SystemApi @TestApi
1070 public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
1071 /** @hide */
1072 @SystemApi @TestApi
1073 public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
1074 /** @hide */
1075 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001076 public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001077 /** @hide */
1078 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001079 public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001080 /** @hide */
1081 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001082 public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE =
1083 "android:bind_accessibility_service";
Nathan Harold1bb420672018-03-14 17:08:53 -07001084 /** @hide */
1085 @SystemApi @TestApi
1086 public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001087 /** @hide */
1088 @SystemApi @TestApi
1089 public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001090 /** @hide */
1091 public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001092
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001093 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
1094 public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001095
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001096 /** @hide Recognize physical activity. */
1097 public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition";
1098
Hongming Jin228cd012018-11-09 14:47:50 -08001099 /** @hide Financial app read sms. */
1100 public static final String OPSTR_SMS_FINANCIAL_TRANSACTIONS =
1101 "android:sms_financial_transactions";
1102
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001103 /** @hide Read media of audio type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001104 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001105 public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
1106 /** @hide Write media of audio type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001107 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001108 public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
1109 /** @hide Read media of video type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001110 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001111 public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
1112 /** @hide Write media of video type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001113 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001114 public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
1115 /** @hide Read media of image type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001116 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001117 public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
1118 /** @hide Write media of image type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001119 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001120 public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001121 /** @hide Has a legacy (non-isolated) view of storage. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001122 @SystemApi @TestApi
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001123 public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001124 /** @hide Read location metadata from media */
1125 public static final String OPSTR_ACCESS_MEDIA_LOCATION = "android:access_media_location";
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001126
Jackal Guo8dc791e2019-01-14 10:26:42 +08001127 /** @hide Interact with accessibility. */
Joel Galensonff4fe202019-02-06 14:43:58 -08001128 @SystemApi
Jackal Guo8dc791e2019-01-14 10:26:42 +08001129 public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
Michael Groover656ef912019-04-09 17:09:57 -07001130 /** @hide Read device identifiers */
1131 public static final String OPSTR_READ_DEVICE_IDENTIFIERS = "android:read_device_identifiers";
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001132 /** @hide Query all packages on device */
1133 public static final String OPSTR_QUERY_ALL_PACKAGES = "android:query_all_packages";
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001134
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07001135
1136 /** {@link #sAppOpsToNote} not initialized yet for this op */
1137 private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
1138 /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
1139 private static final byte SHOULD_NOT_COLLECT_NOTE_OP = 1;
1140 /** Should collect noting of this app-op in {@link #sAppOpsToNote} */
1141 private static final byte SHOULD_COLLECT_NOTE_OP = 2;
1142
1143 @Retention(RetentionPolicy.SOURCE)
1144 @IntDef(flag = true, prefix = { "SHOULD_" }, value = {
1145 SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED,
1146 SHOULD_NOT_COLLECT_NOTE_OP,
1147 SHOULD_COLLECT_NOTE_OP
1148 })
1149 private @interface ShouldCollectNoteOp {}
1150
Philip P. Moltmanne56c08e2017-03-15 12:46:04 -07001151 // Warning: If an permission is added here it also has to be added to
1152 // com.android.packageinstaller.permission.utils.EventLogger
Svet Ganovda0acdf2017-02-15 10:28:51 -08001153 private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
1154 // RUNTIME PERMISSIONS
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001155 // Contacts
1156 OP_READ_CONTACTS,
1157 OP_WRITE_CONTACTS,
1158 OP_GET_ACCOUNTS,
1159 // Calendar
1160 OP_READ_CALENDAR,
1161 OP_WRITE_CALENDAR,
1162 // SMS
1163 OP_SEND_SMS,
1164 OP_RECEIVE_SMS,
1165 OP_READ_SMS,
1166 OP_RECEIVE_WAP_PUSH,
1167 OP_RECEIVE_MMS,
1168 OP_READ_CELL_BROADCASTS,
1169 // Storage
1170 OP_READ_EXTERNAL_STORAGE,
1171 OP_WRITE_EXTERNAL_STORAGE,
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001172 OP_ACCESS_MEDIA_LOCATION,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001173 // Location
1174 OP_COARSE_LOCATION,
1175 OP_FINE_LOCATION,
1176 // Phone
1177 OP_READ_PHONE_STATE,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001178 OP_READ_PHONE_NUMBERS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001179 OP_CALL_PHONE,
1180 OP_READ_CALL_LOG,
1181 OP_WRITE_CALL_LOG,
1182 OP_ADD_VOICEMAIL,
1183 OP_USE_SIP,
1184 OP_PROCESS_OUTGOING_CALLS,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001185 OP_ANSWER_PHONE_CALLS,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001186 OP_ACCEPT_HANDOVER,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001187 // Microphone
1188 OP_RECORD_AUDIO,
1189 // Camera
1190 OP_CAMERA,
1191 // Body sensors
Svet Ganovda0acdf2017-02-15 10:28:51 -08001192 OP_BODY_SENSORS,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001193 // Activity recognition
1194 OP_ACTIVITY_RECOGNITION,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001195 // Aural
1196 OP_READ_MEDIA_AUDIO,
1197 OP_WRITE_MEDIA_AUDIO,
1198 // Visual
1199 OP_READ_MEDIA_VIDEO,
1200 OP_WRITE_MEDIA_VIDEO,
1201 OP_READ_MEDIA_IMAGES,
1202 OP_WRITE_MEDIA_IMAGES,
Svet Ganovda0acdf2017-02-15 10:28:51 -08001203
1204 // APPOP PERMISSIONS
1205 OP_ACCESS_NOTIFICATIONS,
1206 OP_SYSTEM_ALERT_WINDOW,
1207 OP_WRITE_SETTINGS,
1208 OP_REQUEST_INSTALL_PACKAGES,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001209 OP_START_FOREGROUND,
Hongming Jin228cd012018-11-09 14:47:50 -08001210 OP_SMS_FINANCIAL_TRANSACTIONS,
Philip P. Moltmann4b38fbe2019-09-13 21:33:07 -07001211 OP_MANAGE_IPSEC_TUNNELS,
1212 OP_GET_USAGE_STATS,
1213 OP_INSTANT_APP_START_FOREGROUND
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001214 };
1215
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001216 /**
1217 * This maps each operation to the operation that serves as the
1218 * switch to determine whether it is allowed. Generally this is
1219 * a 1:1 mapping, but for some things (like location) that have
1220 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -07001221 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001222 * make them all controlled by the same single operation.
1223 */
1224 private static int[] sOpToSwitch = new int[] {
Dianne Hackbornc216a262018-04-26 13:46:22 -07001225 OP_COARSE_LOCATION, // COARSE_LOCATION
1226 OP_COARSE_LOCATION, // FINE_LOCATION
1227 OP_COARSE_LOCATION, // GPS
1228 OP_VIBRATE, // VIBRATE
1229 OP_READ_CONTACTS, // READ_CONTACTS
1230 OP_WRITE_CONTACTS, // WRITE_CONTACTS
1231 OP_READ_CALL_LOG, // READ_CALL_LOG
1232 OP_WRITE_CALL_LOG, // WRITE_CALL_LOG
1233 OP_READ_CALENDAR, // READ_CALENDAR
1234 OP_WRITE_CALENDAR, // WRITE_CALENDAR
1235 OP_COARSE_LOCATION, // WIFI_SCAN
1236 OP_POST_NOTIFICATION, // POST_NOTIFICATION
1237 OP_COARSE_LOCATION, // NEIGHBORING_CELLS
1238 OP_CALL_PHONE, // CALL_PHONE
1239 OP_READ_SMS, // READ_SMS
1240 OP_WRITE_SMS, // WRITE_SMS
1241 OP_RECEIVE_SMS, // RECEIVE_SMS
1242 OP_RECEIVE_SMS, // RECEIVE_EMERGECY_SMS
1243 OP_RECEIVE_MMS, // RECEIVE_MMS
1244 OP_RECEIVE_WAP_PUSH, // RECEIVE_WAP_PUSH
1245 OP_SEND_SMS, // SEND_SMS
1246 OP_READ_SMS, // READ_ICC_SMS
1247 OP_WRITE_SMS, // WRITE_ICC_SMS
1248 OP_WRITE_SETTINGS, // WRITE_SETTINGS
1249 OP_SYSTEM_ALERT_WINDOW, // SYSTEM_ALERT_WINDOW
1250 OP_ACCESS_NOTIFICATIONS, // ACCESS_NOTIFICATIONS
1251 OP_CAMERA, // CAMERA
1252 OP_RECORD_AUDIO, // RECORD_AUDIO
1253 OP_PLAY_AUDIO, // PLAY_AUDIO
1254 OP_READ_CLIPBOARD, // READ_CLIPBOARD
1255 OP_WRITE_CLIPBOARD, // WRITE_CLIPBOARD
1256 OP_TAKE_MEDIA_BUTTONS, // TAKE_MEDIA_BUTTONS
1257 OP_TAKE_AUDIO_FOCUS, // TAKE_AUDIO_FOCUS
1258 OP_AUDIO_MASTER_VOLUME, // AUDIO_MASTER_VOLUME
1259 OP_AUDIO_VOICE_VOLUME, // AUDIO_VOICE_VOLUME
1260 OP_AUDIO_RING_VOLUME, // AUDIO_RING_VOLUME
1261 OP_AUDIO_MEDIA_VOLUME, // AUDIO_MEDIA_VOLUME
1262 OP_AUDIO_ALARM_VOLUME, // AUDIO_ALARM_VOLUME
1263 OP_AUDIO_NOTIFICATION_VOLUME, // AUDIO_NOTIFICATION_VOLUME
1264 OP_AUDIO_BLUETOOTH_VOLUME, // AUDIO_BLUETOOTH_VOLUME
1265 OP_WAKE_LOCK, // WAKE_LOCK
1266 OP_COARSE_LOCATION, // MONITOR_LOCATION
1267 OP_COARSE_LOCATION, // MONITOR_HIGH_POWER_LOCATION
1268 OP_GET_USAGE_STATS, // GET_USAGE_STATS
1269 OP_MUTE_MICROPHONE, // MUTE_MICROPHONE
1270 OP_TOAST_WINDOW, // TOAST_WINDOW
1271 OP_PROJECT_MEDIA, // PROJECT_MEDIA
1272 OP_ACTIVATE_VPN, // ACTIVATE_VPN
1273 OP_WRITE_WALLPAPER, // WRITE_WALLPAPER
1274 OP_ASSIST_STRUCTURE, // ASSIST_STRUCTURE
1275 OP_ASSIST_SCREENSHOT, // ASSIST_SCREENSHOT
1276 OP_READ_PHONE_STATE, // READ_PHONE_STATE
1277 OP_ADD_VOICEMAIL, // ADD_VOICEMAIL
1278 OP_USE_SIP, // USE_SIP
1279 OP_PROCESS_OUTGOING_CALLS, // PROCESS_OUTGOING_CALLS
1280 OP_USE_FINGERPRINT, // USE_FINGERPRINT
1281 OP_BODY_SENSORS, // BODY_SENSORS
1282 OP_READ_CELL_BROADCASTS, // READ_CELL_BROADCASTS
1283 OP_MOCK_LOCATION, // MOCK_LOCATION
1284 OP_READ_EXTERNAL_STORAGE, // READ_EXTERNAL_STORAGE
1285 OP_WRITE_EXTERNAL_STORAGE, // WRITE_EXTERNAL_STORAGE
1286 OP_TURN_SCREEN_ON, // TURN_SCREEN_ON
1287 OP_GET_ACCOUNTS, // GET_ACCOUNTS
1288 OP_RUN_IN_BACKGROUND, // RUN_IN_BACKGROUND
1289 OP_AUDIO_ACCESSIBILITY_VOLUME, // AUDIO_ACCESSIBILITY_VOLUME
1290 OP_READ_PHONE_NUMBERS, // READ_PHONE_NUMBERS
1291 OP_REQUEST_INSTALL_PACKAGES, // REQUEST_INSTALL_PACKAGES
1292 OP_PICTURE_IN_PICTURE, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
1293 OP_INSTANT_APP_START_FOREGROUND, // INSTANT_APP_START_FOREGROUND
1294 OP_ANSWER_PHONE_CALLS, // ANSWER_PHONE_CALLS
1295 OP_RUN_ANY_IN_BACKGROUND, // OP_RUN_ANY_IN_BACKGROUND
1296 OP_CHANGE_WIFI_STATE, // OP_CHANGE_WIFI_STATE
1297 OP_REQUEST_DELETE_PACKAGES, // OP_REQUEST_DELETE_PACKAGES
1298 OP_BIND_ACCESSIBILITY_SERVICE, // OP_BIND_ACCESSIBILITY_SERVICE
1299 OP_ACCEPT_HANDOVER, // ACCEPT_HANDOVER
1300 OP_MANAGE_IPSEC_TUNNELS, // MANAGE_IPSEC_HANDOVERS
1301 OP_START_FOREGROUND, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001302 OP_COARSE_LOCATION, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001303 OP_USE_BIOMETRIC, // BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001304 OP_ACTIVITY_RECOGNITION, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001305 OP_SMS_FINANCIAL_TRANSACTIONS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001306 OP_READ_MEDIA_AUDIO, // READ_MEDIA_AUDIO
1307 OP_WRITE_MEDIA_AUDIO, // WRITE_MEDIA_AUDIO
1308 OP_READ_MEDIA_VIDEO, // READ_MEDIA_VIDEO
1309 OP_WRITE_MEDIA_VIDEO, // WRITE_MEDIA_VIDEO
1310 OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES
1311 OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001312 OP_LEGACY_STORAGE, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001313 OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001314 OP_READ_DEVICE_IDENTIFIERS, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001315 OP_ACCESS_MEDIA_LOCATION, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001316 OP_QUERY_ALL_PACKAGES, // QUERY_ALL_PACKAGES
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001317 };
1318
1319 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001320 * This maps each operation to the public string constant for it.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001321 */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001322 private static String[] sOpToString = new String[]{
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001323 OPSTR_COARSE_LOCATION,
1324 OPSTR_FINE_LOCATION,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001325 OPSTR_GPS,
1326 OPSTR_VIBRATE,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001327 OPSTR_READ_CONTACTS,
1328 OPSTR_WRITE_CONTACTS,
1329 OPSTR_READ_CALL_LOG,
1330 OPSTR_WRITE_CALL_LOG,
1331 OPSTR_READ_CALENDAR,
1332 OPSTR_WRITE_CALENDAR,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001333 OPSTR_WIFI_SCAN,
1334 OPSTR_POST_NOTIFICATION,
1335 OPSTR_NEIGHBORING_CELLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001336 OPSTR_CALL_PHONE,
1337 OPSTR_READ_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001338 OPSTR_WRITE_SMS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001339 OPSTR_RECEIVE_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001340 OPSTR_RECEIVE_EMERGENCY_BROADCAST,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001341 OPSTR_RECEIVE_MMS,
1342 OPSTR_RECEIVE_WAP_PUSH,
1343 OPSTR_SEND_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001344 OPSTR_READ_ICC_SMS,
1345 OPSTR_WRITE_ICC_SMS,
Billy Lau24b9c832015-07-20 17:34:09 +01001346 OPSTR_WRITE_SETTINGS,
1347 OPSTR_SYSTEM_ALERT_WINDOW,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001348 OPSTR_ACCESS_NOTIFICATIONS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001349 OPSTR_CAMERA,
1350 OPSTR_RECORD_AUDIO,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001351 OPSTR_PLAY_AUDIO,
1352 OPSTR_READ_CLIPBOARD,
1353 OPSTR_WRITE_CLIPBOARD,
1354 OPSTR_TAKE_MEDIA_BUTTONS,
1355 OPSTR_TAKE_AUDIO_FOCUS,
1356 OPSTR_AUDIO_MASTER_VOLUME,
1357 OPSTR_AUDIO_VOICE_VOLUME,
1358 OPSTR_AUDIO_RING_VOLUME,
1359 OPSTR_AUDIO_MEDIA_VOLUME,
1360 OPSTR_AUDIO_ALARM_VOLUME,
1361 OPSTR_AUDIO_NOTIFICATION_VOLUME,
1362 OPSTR_AUDIO_BLUETOOTH_VOLUME,
1363 OPSTR_WAKE_LOCK,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001364 OPSTR_MONITOR_LOCATION,
1365 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -07001366 OPSTR_GET_USAGE_STATS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001367 OPSTR_MUTE_MICROPHONE,
1368 OPSTR_TOAST_WINDOW,
1369 OPSTR_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -07001370 OPSTR_ACTIVATE_VPN,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001371 OPSTR_WRITE_WALLPAPER,
1372 OPSTR_ASSIST_STRUCTURE,
1373 OPSTR_ASSIST_SCREENSHOT,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001374 OPSTR_READ_PHONE_STATE,
1375 OPSTR_ADD_VOICEMAIL,
1376 OPSTR_USE_SIP,
Svet Ganov824ad6e2016-09-22 19:36:53 -07001377 OPSTR_PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001378 OPSTR_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001379 OPSTR_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001380 OPSTR_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001381 OPSTR_MOCK_LOCATION,
1382 OPSTR_READ_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001383 OPSTR_WRITE_EXTERNAL_STORAGE,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001384 OPSTR_TURN_SCREEN_ON,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001385 OPSTR_GET_ACCOUNTS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001386 OPSTR_RUN_IN_BACKGROUND,
1387 OPSTR_AUDIO_ACCESSIBILITY_VOLUME,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001388 OPSTR_READ_PHONE_NUMBERS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001389 OPSTR_REQUEST_INSTALL_PACKAGES,
Winson Chungf4ac0632017-03-17 12:34:12 -07001390 OPSTR_PICTURE_IN_PICTURE,
Chad Brubaker97b383f2017-02-02 15:04:35 -08001391 OPSTR_INSTANT_APP_START_FOREGROUND,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001392 OPSTR_ANSWER_PHONE_CALLS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001393 OPSTR_RUN_ANY_IN_BACKGROUND,
1394 OPSTR_CHANGE_WIFI_STATE,
1395 OPSTR_REQUEST_DELETE_PACKAGES,
1396 OPSTR_BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001397 OPSTR_ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001398 OPSTR_MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001399 OPSTR_START_FOREGROUND,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001400 OPSTR_BLUETOOTH_SCAN,
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001401 OPSTR_USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001402 OPSTR_ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001403 OPSTR_SMS_FINANCIAL_TRANSACTIONS,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001404 OPSTR_READ_MEDIA_AUDIO,
1405 OPSTR_WRITE_MEDIA_AUDIO,
1406 OPSTR_READ_MEDIA_VIDEO,
1407 OPSTR_WRITE_MEDIA_VIDEO,
1408 OPSTR_READ_MEDIA_IMAGES,
1409 OPSTR_WRITE_MEDIA_IMAGES,
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001410 OPSTR_LEGACY_STORAGE,
Jackal Guo8dc791e2019-01-14 10:26:42 +08001411 OPSTR_ACCESS_ACCESSIBILITY,
Michael Groover656ef912019-04-09 17:09:57 -07001412 OPSTR_READ_DEVICE_IDENTIFIERS,
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001413 OPSTR_ACCESS_MEDIA_LOCATION,
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001414 OPSTR_QUERY_ALL_PACKAGES,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001415 };
1416
1417 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001418 * This provides a simple name for each operation to be used
1419 * in debug output.
1420 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001421 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001422 "COARSE_LOCATION",
1423 "FINE_LOCATION",
1424 "GPS",
1425 "VIBRATE",
1426 "READ_CONTACTS",
1427 "WRITE_CONTACTS",
1428 "READ_CALL_LOG",
1429 "WRITE_CALL_LOG",
1430 "READ_CALENDAR",
1431 "WRITE_CALENDAR",
1432 "WIFI_SCAN",
1433 "POST_NOTIFICATION",
1434 "NEIGHBORING_CELLS",
1435 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001436 "READ_SMS",
1437 "WRITE_SMS",
1438 "RECEIVE_SMS",
1439 "RECEIVE_EMERGECY_SMS",
1440 "RECEIVE_MMS",
1441 "RECEIVE_WAP_PUSH",
1442 "SEND_SMS",
1443 "READ_ICC_SMS",
1444 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -08001445 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -08001446 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001447 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001448 "CAMERA",
1449 "RECORD_AUDIO",
1450 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001451 "READ_CLIPBOARD",
1452 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001453 "TAKE_MEDIA_BUTTONS",
1454 "TAKE_AUDIO_FOCUS",
1455 "AUDIO_MASTER_VOLUME",
1456 "AUDIO_VOICE_VOLUME",
1457 "AUDIO_RING_VOLUME",
1458 "AUDIO_MEDIA_VOLUME",
1459 "AUDIO_ALARM_VOLUME",
1460 "AUDIO_NOTIFICATION_VOLUME",
1461 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -07001462 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001463 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -07001464 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -04001465 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001466 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -04001467 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001468 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -07001469 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +00001470 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001471 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -07001472 "ASSIST_SCREENSHOT",
Eugene Suslae4ee2c22018-11-05 12:23:30 -08001473 "READ_PHONE_STATE",
Svetoslav5335b672015-04-29 12:00:51 -07001474 "ADD_VOICEMAIL",
Svetoslavc656e6f2015-04-29 14:08:16 -07001475 "USE_SIP",
Svetoslav4af76a52015-04-29 15:29:46 -07001476 "PROCESS_OUTGOING_CALLS",
Svet Ganovb9d71a62015-04-30 10:38:13 -07001477 "USE_FINGERPRINT",
Svet Ganovede43162015-05-02 17:42:44 -07001478 "BODY_SENSORS",
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001479 "READ_CELL_BROADCASTS",
Svet Ganov921c7df2015-06-29 21:51:41 -07001480 "MOCK_LOCATION",
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001481 "READ_EXTERNAL_STORAGE",
1482 "WRITE_EXTERNAL_STORAGE",
1483 "TURN_ON_SCREEN",
Svetoslavf3f02ac2015-09-08 14:36:35 -07001484 "GET_ACCOUNTS",
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001485 "RUN_IN_BACKGROUND",
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001486 "AUDIO_ACCESSIBILITY_VOLUME",
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001487 "READ_PHONE_NUMBERS",
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001488 "REQUEST_INSTALL_PACKAGES",
Winson Chungf4ac0632017-03-17 12:34:12 -07001489 "PICTURE_IN_PICTURE",
Chad Brubaker97b383f2017-02-02 15:04:35 -08001490 "INSTANT_APP_START_FOREGROUND",
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001491 "ANSWER_PHONE_CALLS",
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001492 "RUN_ANY_IN_BACKGROUND",
Peter Visontay1246d9e2017-10-17 17:02:45 +01001493 "CHANGE_WIFI_STATE",
Peter Visontayf2e38362017-11-27 15:27:16 +00001494 "REQUEST_DELETE_PACKAGES",
Peter Visontay11950832017-11-14 19:34:59 +00001495 "BIND_ACCESSIBILITY_SERVICE",
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001496 "ACCEPT_HANDOVER",
Nathan Harold1bb420672018-03-14 17:08:53 -07001497 "MANAGE_IPSEC_TUNNELS",
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001498 "START_FOREGROUND",
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001499 "BLUETOOTH_SCAN",
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001500 "USE_BIOMETRIC",
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001501 "ACTIVITY_RECOGNITION",
Hongming Jin228cd012018-11-09 14:47:50 -08001502 "SMS_FINANCIAL_TRANSACTIONS",
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001503 "READ_MEDIA_AUDIO",
1504 "WRITE_MEDIA_AUDIO",
1505 "READ_MEDIA_VIDEO",
1506 "WRITE_MEDIA_VIDEO",
1507 "READ_MEDIA_IMAGES",
1508 "WRITE_MEDIA_IMAGES",
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001509 "LEGACY_STORAGE",
Jackal Guo8dc791e2019-01-14 10:26:42 +08001510 "ACCESS_ACCESSIBILITY",
Michael Groover656ef912019-04-09 17:09:57 -07001511 "READ_DEVICE_IDENTIFIERS",
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001512 "ACCESS_MEDIA_LOCATION",
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001513 "QUERY_ALL_PACKAGES",
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001514 };
1515
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001516 /**
1517 * This optionally maps a permission to an operation. If there
1518 * is no permission associated with an operation, it is null.
1519 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001520 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001521 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001522 android.Manifest.permission.ACCESS_COARSE_LOCATION,
1523 android.Manifest.permission.ACCESS_FINE_LOCATION,
1524 null,
1525 android.Manifest.permission.VIBRATE,
1526 android.Manifest.permission.READ_CONTACTS,
1527 android.Manifest.permission.WRITE_CONTACTS,
1528 android.Manifest.permission.READ_CALL_LOG,
1529 android.Manifest.permission.WRITE_CALL_LOG,
1530 android.Manifest.permission.READ_CALENDAR,
1531 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001532 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -04001533 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001534 null, // neighboring cells shares the coarse location perm
1535 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001536 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001537 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001538 android.Manifest.permission.RECEIVE_SMS,
1539 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
1540 android.Manifest.permission.RECEIVE_MMS,
1541 android.Manifest.permission.RECEIVE_WAP_PUSH,
1542 android.Manifest.permission.SEND_SMS,
1543 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001544 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -08001545 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -08001546 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001547 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001548 android.Manifest.permission.CAMERA,
1549 android.Manifest.permission.RECORD_AUDIO,
1550 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001551 null, // no permission for reading clipboard
1552 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001553 null, // no permission for taking media buttons
1554 null, // no permission for taking audio focus
1555 null, // no permission for changing master volume
1556 null, // no permission for changing voice volume
1557 null, // no permission for changing ring volume
1558 null, // no permission for changing media volume
1559 null, // no permission for changing alarm volume
1560 null, // no permission for changing notification volume
1561 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -07001562 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001563 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -07001564 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -07001565 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -04001566 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -04001567 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -07001568 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -07001569 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +00001570 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001571 null, // no permission for receiving assist structure
1572 null, // no permission for receiving assist screenshot
Svet Ganovc3300092015-04-17 09:07:22 -07001573 Manifest.permission.READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -07001574 Manifest.permission.ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -07001575 Manifest.permission.USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -07001576 Manifest.permission.PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001577 Manifest.permission.USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001578 Manifest.permission.BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001579 Manifest.permission.READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001580 null,
1581 Manifest.permission.READ_EXTERNAL_STORAGE,
1582 Manifest.permission.WRITE_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001583 null, // no permission for turning the screen on
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001584 Manifest.permission.GET_ACCOUNTS,
1585 null, // no permission for running in background
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001586 null, // no permission for changing accessibility volume
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001587 Manifest.permission.READ_PHONE_NUMBERS,
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001588 Manifest.permission.REQUEST_INSTALL_PACKAGES,
Winson Chung59fda9e2017-01-20 16:14:51 -08001589 null, // no permission for entering picture-in-picture on hide
Chad Brubaker97b383f2017-02-02 15:04:35 -08001590 Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001591 Manifest.permission.ANSWER_PHONE_CALLS,
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001592 null, // no permission for OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001593 Manifest.permission.CHANGE_WIFI_STATE,
Peter Visontayf2e38362017-11-27 15:27:16 +00001594 Manifest.permission.REQUEST_DELETE_PACKAGES,
Peter Visontay11950832017-11-14 19:34:59 +00001595 Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001596 Manifest.permission.ACCEPT_HANDOVER,
Philip P. Moltmann4b38fbe2019-09-13 21:33:07 -07001597 Manifest.permission.MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001598 Manifest.permission.FOREGROUND_SERVICE,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001599 null, // no permission for OP_BLUETOOTH_SCAN
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001600 Manifest.permission.USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001601 Manifest.permission.ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001602 Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001603 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001604 null, // no permission for OP_WRITE_MEDIA_AUDIO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001605 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001606 null, // no permission for OP_WRITE_MEDIA_VIDEO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001607 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001608 null, // no permission for OP_WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001609 null, // no permission for OP_LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001610 null, // no permission for OP_ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001611 null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001612 Manifest.permission.ACCESS_MEDIA_LOCATION,
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001613 null, // no permission for OP_QUERY_ALL_PACKAGES
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001614 };
1615
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001616 /**
Jason Monk62062992014-05-06 09:55:28 -04001617 * Specifies whether an Op should be restricted by a user restriction.
1618 * Each Op should be filled with a restriction string from UserManager or
1619 * null to specify it is not affected by any user restriction.
1620 */
1621 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -04001622 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
1623 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
1624 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -04001625 null, //VIBRATE
1626 null, //READ_CONTACTS
1627 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -07001628 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
1629 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -04001630 null, //READ_CALENDAR
1631 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001632 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -04001633 null, //POST_NOTIFICATION
1634 null, //NEIGHBORING_CELLS
1635 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001636 UserManager.DISALLOW_SMS, //READ_SMS
1637 UserManager.DISALLOW_SMS, //WRITE_SMS
1638 UserManager.DISALLOW_SMS, //RECEIVE_SMS
1639 null, //RECEIVE_EMERGENCY_SMS
1640 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -04001641 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001642 UserManager.DISALLOW_SMS, //SEND_SMS
1643 UserManager.DISALLOW_SMS, //READ_ICC_SMS
1644 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -04001645 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -04001646 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -04001647 null, //ACCESS_NOTIFICATIONS
Makoto Onuki759a7632015-10-28 16:43:10 -07001648 UserManager.DISALLOW_CAMERA, //CAMERA
Fyodor Kupolovb5013302015-04-17 17:59:14 -07001649 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
Jason Monk62062992014-05-06 09:55:28 -04001650 null, //PLAY_AUDIO
1651 null, //READ_CLIPBOARD
1652 null, //WRITE_CLIPBOARD
1653 null, //TAKE_MEDIA_BUTTONS
1654 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -04001655 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
1656 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
1657 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
1658 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
1659 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
1660 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
1661 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -04001662 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -04001663 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
1664 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -04001665 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -04001666 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -04001667 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -07001668 null, //PROJECT_MEDIA
Tony Mak33d03a92016-06-02 15:01:16 +01001669 null, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001670 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001671 null, // ASSIST_STRUCTURE
1672 null, // ASSIST_SCREENSHOT
Svet Ganovc3300092015-04-17 09:07:22 -07001673 null, // READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001674 null, // ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001675 null, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001676 null, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001677 null, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001678 null, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001679 null, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001680 null, // MOCK_LOCATION
1681 null, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001682 null, // WRITE_EXTERNAL_STORAGE
1683 null, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001684 null, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001685 null, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001686 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001687 null, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001688 null, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001689 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001690 null, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001691 null, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001692 null, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001693 null, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001694 null, // REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001695 null, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001696 null, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001697 null, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001698 null, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001699 null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001700 null, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001701 null, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001702 UserManager.DISALLOW_SMS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001703 null, // READ_MEDIA_AUDIO
1704 null, // WRITE_MEDIA_AUDIO
1705 null, // READ_MEDIA_VIDEO
1706 null, // WRITE_MEDIA_VIDEO
1707 null, // READ_MEDIA_IMAGES
1708 null, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001709 null, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001710 null, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001711 null, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001712 null, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001713 null, // QUERY_ALL_PACKAGES
Jason Monk1c7c3192014-06-26 12:52:18 -04001714 };
1715
1716 /**
1717 * This specifies whether each option should allow the system
1718 * (and system ui) to bypass the user restriction when active.
1719 */
1720 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
Fyodor Kupolov639e73d2016-02-25 11:58:21 -08001721 true, //COARSE_LOCATION
1722 true, //FINE_LOCATION
Jason Monk1c7c3192014-06-26 12:52:18 -04001723 false, //GPS
1724 false, //VIBRATE
1725 false, //READ_CONTACTS
1726 false, //WRITE_CONTACTS
1727 false, //READ_CALL_LOG
1728 false, //WRITE_CALL_LOG
1729 false, //READ_CALENDAR
1730 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001731 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -04001732 false, //POST_NOTIFICATION
1733 false, //NEIGHBORING_CELLS
1734 false, //CALL_PHONE
1735 false, //READ_SMS
1736 false, //WRITE_SMS
1737 false, //RECEIVE_SMS
1738 false, //RECEIVE_EMERGECY_SMS
1739 false, //RECEIVE_MMS
1740 false, //RECEIVE_WAP_PUSH
1741 false, //SEND_SMS
1742 false, //READ_ICC_SMS
1743 false, //WRITE_ICC_SMS
1744 false, //WRITE_SETTINGS
1745 true, //SYSTEM_ALERT_WINDOW
1746 false, //ACCESS_NOTIFICATIONS
1747 false, //CAMERA
1748 false, //RECORD_AUDIO
1749 false, //PLAY_AUDIO
1750 false, //READ_CLIPBOARD
1751 false, //WRITE_CLIPBOARD
1752 false, //TAKE_MEDIA_BUTTONS
1753 false, //TAKE_AUDIO_FOCUS
1754 false, //AUDIO_MASTER_VOLUME
1755 false, //AUDIO_VOICE_VOLUME
1756 false, //AUDIO_RING_VOLUME
1757 false, //AUDIO_MEDIA_VOLUME
1758 false, //AUDIO_ALARM_VOLUME
1759 false, //AUDIO_NOTIFICATION_VOLUME
1760 false, //AUDIO_BLUETOOTH_VOLUME
1761 false, //WAKE_LOCK
1762 false, //MONITOR_LOCATION
1763 false, //MONITOR_HIGH_POWER_LOCATION
1764 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -07001765 false, //MUTE_MICROPHONE
1766 true, //TOAST_WINDOW
1767 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -07001768 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001769 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001770 false, //ASSIST_STRUCTURE
1771 false, //ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -07001772 false, //READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001773 false, //ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001774 false, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001775 false, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001776 false, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001777 false, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001778 false, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001779 false, // MOCK_LOCATION
1780 false, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001781 false, // WRITE_EXTERNAL_STORAGE
1782 false, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001783 false, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001784 false, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001785 false, // AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001786 false, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001787 false, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001788 false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001789 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001790 false, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001791 false, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001792 false, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001793 false, // OP_REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001794 false, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001795 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001796 false, // MANAGE_IPSEC_HANDOVERS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001797 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001798 true, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001799 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001800 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001801 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001802 false, // READ_MEDIA_AUDIO
1803 false, // WRITE_MEDIA_AUDIO
1804 false, // READ_MEDIA_VIDEO
1805 false, // WRITE_MEDIA_VIDEO
1806 false, // READ_MEDIA_IMAGES
1807 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001808 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001809 false, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001810 false, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001811 false, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001812 false, // QUERY_ALL_PACKAGES
Jason Monk62062992014-05-06 09:55:28 -04001813 };
1814
1815 /**
David Braunf5d83192013-09-16 13:43:51 -07001816 * This specifies the default mode for each operation.
1817 */
1818 private static int[] sOpDefaultMode = new int[] {
Eugene Susla93519852018-06-13 16:44:31 -07001819 AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION
1820 AppOpsManager.MODE_ALLOWED, // FINE_LOCATION
1821 AppOpsManager.MODE_ALLOWED, // GPS
1822 AppOpsManager.MODE_ALLOWED, // VIBRATE
1823 AppOpsManager.MODE_ALLOWED, // READ_CONTACTS
1824 AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS
Svet Ganovd563e932019-04-14 13:07:41 -07001825 AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG
1826 AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG
Eugene Susla93519852018-06-13 16:44:31 -07001827 AppOpsManager.MODE_ALLOWED, // READ_CALENDAR
1828 AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR
1829 AppOpsManager.MODE_ALLOWED, // WIFI_SCAN
1830 AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION
1831 AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS
1832 AppOpsManager.MODE_ALLOWED, // CALL_PHONE
Svet Ganovd563e932019-04-14 13:07:41 -07001833 AppOpsManager.MODE_ALLOWED, // READ_SMS
Eugene Suslaaaff0072018-10-30 13:35:03 -07001834 AppOpsManager.MODE_IGNORED, // WRITE_SMS
Svet Ganovd563e932019-04-14 13:07:41 -07001835 AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001836 AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST
Svet Ganovd563e932019-04-14 13:07:41 -07001837 AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS
1838 AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH
1839 AppOpsManager.MODE_ALLOWED, // SEND_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001840 AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS
1841 AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS
1842 AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS
Ng Zhi An65a99b62018-10-01 11:57:53 -07001843 getSystemAlertWindowDefault(), // SYSTEM_ALERT_WINDOW
Eugene Susla93519852018-06-13 16:44:31 -07001844 AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS
1845 AppOpsManager.MODE_ALLOWED, // CAMERA
1846 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO
1847 AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO
1848 AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD
1849 AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD
1850 AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS
1851 AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS
1852 AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME
1853 AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME
1854 AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME
1855 AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME
1856 AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME
1857 AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME
1858 AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME
1859 AppOpsManager.MODE_ALLOWED, // WAKE_LOCK
1860 AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION
1861 AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION
1862 AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS
1863 AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE
1864 AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW
1865 AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA
1866 AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN
1867 AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER
1868 AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE
1869 AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT
1870 AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE
1871 AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL
1872 AppOpsManager.MODE_ALLOWED, // USE_SIP
Svet Ganovd563e932019-04-14 13:07:41 -07001873 AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07001874 AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT
1875 AppOpsManager.MODE_ALLOWED, // BODY_SENSORS
Svet Ganovd563e932019-04-14 13:07:41 -07001876 AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS
Eugene Susla93519852018-06-13 16:44:31 -07001877 AppOpsManager.MODE_ERRORED, // MOCK_LOCATION
1878 AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE
1879 AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE
1880 AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON
1881 AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS
1882 AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND
1883 AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME
1884 AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS
1885 AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES
1886 AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE
1887 AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND
1888 AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
1889 AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND
1890 AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE
1891 AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES
1892 AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE
1893 AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER
1894 AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS
1895 AppOpsManager.MODE_ALLOWED, // START_FOREGROUND
1896 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN
1897 AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001898 AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001899 AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001900 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001901 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001902 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001903 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001904 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001905 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001906 AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001907 AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001908 AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001909 AppOpsManager.MODE_ALLOWED, // ALLOW_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001910 AppOpsManager.MODE_DEFAULT, // QUERY_ALL_PACKAGES
David Braunf5d83192013-09-16 13:43:51 -07001911 };
1912
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001913 /**
1914 * This specifies whether each option is allowed to be reset
1915 * when resetting all app preferences. Disable reset for
1916 * app ops that are under strong control of some part of the
1917 * system (such as OP_WRITE_SMS, which should be allowed only
1918 * for whichever app is selected as the current SMS app).
1919 */
1920 private static boolean[] sOpDisableReset = new boolean[] {
Eugene Susla93519852018-06-13 16:44:31 -07001921 false, // COARSE_LOCATION
1922 false, // FINE_LOCATION
1923 false, // GPS
1924 false, // VIBRATE
1925 false, // READ_CONTACTS
1926 false, // WRITE_CONTACTS
1927 false, // READ_CALL_LOG
1928 false, // WRITE_CALL_LOG
1929 false, // READ_CALENDAR
1930 false, // WRITE_CALENDAR
1931 false, // WIFI_SCAN
1932 false, // POST_NOTIFICATION
1933 false, // NEIGHBORING_CELLS
1934 false, // CALL_PHONE
1935 true, // READ_SMS
1936 true, // WRITE_SMS
1937 true, // RECEIVE_SMS
1938 false, // RECEIVE_EMERGENCY_BROADCAST
1939 false, // RECEIVE_MMS
1940 true, // RECEIVE_WAP_PUSH
1941 true, // SEND_SMS
1942 false, // READ_ICC_SMS
1943 false, // WRITE_ICC_SMS
1944 false, // WRITE_SETTINGS
1945 false, // SYSTEM_ALERT_WINDOW
1946 false, // ACCESS_NOTIFICATIONS
1947 false, // CAMERA
1948 false, // RECORD_AUDIO
1949 false, // PLAY_AUDIO
1950 false, // READ_CLIPBOARD
1951 false, // WRITE_CLIPBOARD
1952 false, // TAKE_MEDIA_BUTTONS
1953 false, // TAKE_AUDIO_FOCUS
1954 false, // AUDIO_MASTER_VOLUME
1955 false, // AUDIO_VOICE_VOLUME
1956 false, // AUDIO_RING_VOLUME
1957 false, // AUDIO_MEDIA_VOLUME
1958 false, // AUDIO_ALARM_VOLUME
1959 false, // AUDIO_NOTIFICATION_VOLUME
1960 false, // AUDIO_BLUETOOTH_VOLUME
1961 false, // WAKE_LOCK
1962 false, // MONITOR_LOCATION
1963 false, // MONITOR_HIGH_POWER_LOCATION
1964 false, // GET_USAGE_STATS
1965 false, // MUTE_MICROPHONE
1966 false, // TOAST_WINDOW
1967 false, // PROJECT_MEDIA
1968 false, // ACTIVATE_VPN
1969 false, // WRITE_WALLPAPER
1970 false, // ASSIST_STRUCTURE
1971 false, // ASSIST_SCREENSHOT
1972 false, // READ_PHONE_STATE
1973 false, // ADD_VOICEMAIL
1974 false, // USE_SIP
1975 false, // PROCESS_OUTGOING_CALLS
1976 false, // USE_FINGERPRINT
1977 false, // BODY_SENSORS
1978 true, // READ_CELL_BROADCASTS
1979 false, // MOCK_LOCATION
1980 false, // READ_EXTERNAL_STORAGE
1981 false, // WRITE_EXTERNAL_STORAGE
1982 false, // TURN_SCREEN_ON
1983 false, // GET_ACCOUNTS
1984 false, // RUN_IN_BACKGROUND
1985 false, // AUDIO_ACCESSIBILITY_VOLUME
1986 false, // READ_PHONE_NUMBERS
1987 false, // REQUEST_INSTALL_PACKAGES
1988 false, // PICTURE_IN_PICTURE
1989 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001990 false, // ANSWER_PHONE_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07001991 false, // RUN_ANY_IN_BACKGROUND
1992 false, // CHANGE_WIFI_STATE
1993 false, // REQUEST_DELETE_PACKAGES
1994 false, // BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001995 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001996 false, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001997 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001998 false, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001999 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01002000 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08002001 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07002002 false, // READ_MEDIA_AUDIO
2003 false, // WRITE_MEDIA_AUDIO
2004 false, // READ_MEDIA_VIDEO
2005 false, // WRITE_MEDIA_VIDEO
2006 false, // READ_MEDIA_IMAGES
2007 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07002008 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08002009 false, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07002010 false, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07002011 false, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07002012 false, // QUERY_ALL_PACKAGES
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002013 };
2014
Svet Ganovfbf01f72015-04-28 18:39:06 -07002015 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07002016 * Mapping from an app op name to the app op code.
Svet Ganovfbf01f72015-04-28 18:39:06 -07002017 */
Svet Ganovb9d71a62015-04-30 10:38:13 -07002018 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
Svet Ganovfbf01f72015-04-28 18:39:06 -07002019
Svet Ganovb9d71a62015-04-30 10:38:13 -07002020 /**
2021 * Mapping from a permission to the corresponding app op.
2022 */
Svet Ganovda0acdf2017-02-15 10:28:51 -08002023 private static HashMap<String, Integer> sPermToOp = new HashMap<>();
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002024
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002025 /**
2026 * Set to the uid of the caller if this thread is currently executing a two-way binder
2027 * transaction. Not set if this thread is currently not executing a two way binder transaction.
2028 *
2029 * @see #startNotedAppOpsCollection
2030 * @see #markAppOpNoted
2031 */
2032 private static final ThreadLocal<Integer> sBinderThreadCallingUid = new ThreadLocal<>();
2033
2034 /**
2035 * If a thread is currently executing a two-way binder transaction, this stores the op-codes of
2036 * the app-ops that were noted during this transaction.
2037 *
2038 * @see #markAppOpNoted
2039 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002040 private static final ThreadLocal<ArrayMap<String, long[]>> sAppOpsNotedInThisBinderTransaction =
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002041 new ThreadLocal<>();
2042
2043 /** Whether noting for an appop should be collected */
2044 private static final @ShouldCollectNoteOp byte[] sAppOpsToNote = new byte[_NUM_OP];
2045
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002046 static {
2047 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002048 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002049 + " should be " + _NUM_OP);
2050 }
2051 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002052 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002053 + " should be " + _NUM_OP);
2054 }
2055 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002056 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002057 + " should be " + _NUM_OP);
2058 }
2059 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002060 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002061 + " should be " + _NUM_OP);
2062 }
2063 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002064 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
2065 + " should be " + _NUM_OP);
2066 }
2067 if (sOpDisableReset.length != _NUM_OP) {
2068 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002069 + " should be " + _NUM_OP);
2070 }
Jason Monk62062992014-05-06 09:55:28 -04002071 if (sOpRestrictions.length != _NUM_OP) {
2072 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
2073 + " should be " + _NUM_OP);
2074 }
Jason Monk1c7c3192014-06-26 12:52:18 -04002075 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
2076 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
2077 + sOpRestrictions.length + " should be " + _NUM_OP);
2078 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002079 for (int i=0; i<_NUM_OP; i++) {
2080 if (sOpToString[i] != null) {
2081 sOpStrToOp.put(sOpToString[i], i);
2082 }
2083 }
Svet Ganovda0acdf2017-02-15 10:28:51 -08002084 for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07002085 if (sOpPerms[op] != null) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002086 sPermToOp.put(sOpPerms[op], op);
Svet Ganovb9d71a62015-04-30 10:38:13 -07002087 }
2088 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002089
2090 if ((_NUM_OP + Long.SIZE - 1) / Long.SIZE != 2) {
2091 // The code currently assumes that the length of sAppOpsNotedInThisBinderTransaction is
2092 // two longs
2093 throw new IllegalStateException("notedAppOps collection code assumes < 128 appops");
2094 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002095 }
2096
Svet Ganov8455ba22019-01-02 13:05:56 -08002097 /** @hide */
2098 public static final String KEY_HISTORICAL_OPS = "historical_ops";
2099
Chad Brubaker7c6dba62019-01-23 15:51:43 -08002100 /** System properties for debug logging of noteOp call sites */
2101 private static final String DEBUG_LOGGING_ENABLE_PROP = "appops.logging_enabled";
2102 private static final String DEBUG_LOGGING_PACKAGES_PROP = "appops.logging_packages";
2103 private static final String DEBUG_LOGGING_OPS_PROP = "appops.logging_ops";
2104 private static final String DEBUG_LOGGING_TAG = "AppOpsManager";
2105
David Braunf5d83192013-09-16 13:43:51 -07002106 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002107 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002108 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002109 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002110 @UnsupportedAppUsage
Dianne Hackbornf265ea92013-01-31 15:00:51 -08002111 public static int opToSwitch(int op) {
2112 return sOpToSwitch[op];
2113 }
2114
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002115 /**
2116 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002117 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002118 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002119 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002120 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08002121 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002122 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
2123 }
2124
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002125 /**
Svet Ganov65f1b9e2019-01-17 19:19:40 -08002126 * Retrieve a non-localized public name for the operation.
2127 *
2128 * @hide
2129 */
2130 public static @NonNull String opToPublicName(int op) {
2131 return sOpToString[op];
2132 }
2133
2134 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08002135 * @hide
2136 */
2137 public static int strDebugOpToOp(String op) {
2138 for (int i=0; i<sOpNames.length; i++) {
2139 if (sOpNames[i].equals(op)) {
2140 return i;
2141 }
2142 }
2143 throw new IllegalArgumentException("Unknown operation string: " + op);
2144 }
2145
2146 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002147 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002148 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002149 */
Philip P. Moltmann33115152018-04-11 13:39:36 -07002150 @TestApi
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002151 public static String opToPermission(int op) {
2152 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002153 }
2154
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002155 /**
Hai Zhangb7776682018-09-25 15:10:57 -07002156 * Retrieve the permission associated with an operation, or null if there is not one.
2157 *
2158 * @param op The operation name.
2159 *
2160 * @hide
2161 */
2162 @Nullable
2163 @SystemApi
2164 public static String opToPermission(@NonNull String op) {
2165 return opToPermission(strOpToOp(op));
2166 }
2167
2168 /**
Jason Monk62062992014-05-06 09:55:28 -04002169 * Retrieve the user restriction associated with an operation, or null if there is not one.
2170 * @hide
2171 */
2172 public static String opToRestriction(int op) {
2173 return sOpRestrictions[op];
2174 }
2175
2176 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07002177 * Retrieve the app op code for a permission, or null if there is not one.
Svet Ganovda0acdf2017-02-15 10:28:51 -08002178 * This API is intended to be used for mapping runtime or appop permissions
2179 * to the corresponding app op.
Svet Ganovb9d71a62015-04-30 10:38:13 -07002180 * @hide
2181 */
Philip P. Moltmann33115152018-04-11 13:39:36 -07002182 @TestApi
Svet Ganovb9d71a62015-04-30 10:38:13 -07002183 public static int permissionToOpCode(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002184 Integer boxedOpCode = sPermToOp.get(permission);
Svet Ganov019d2302015-05-04 11:07:38 -07002185 return boxedOpCode != null ? boxedOpCode : OP_NONE;
Svet Ganovb9d71a62015-04-30 10:38:13 -07002186 }
2187
2188 /**
Jason Monk1c7c3192014-06-26 12:52:18 -04002189 * Retrieve whether the op allows the system (and system ui) to
2190 * bypass the user restriction.
2191 * @hide
2192 */
2193 public static boolean opAllowSystemBypassRestriction(int op) {
2194 return sOpAllowSystemRestrictionBypass[op];
2195 }
2196
2197 /**
David Braunf5d83192013-09-16 13:43:51 -07002198 * Retrieve the default mode for the operation.
2199 * @hide
2200 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002201 public static @Mode int opToDefaultMode(int op) {
David Braunf5d83192013-09-16 13:43:51 -07002202 return sOpDefaultMode[op];
2203 }
2204
2205 /**
Hai Zhangc595f112018-11-06 14:20:38 -08002206 * Retrieve the default mode for the app op.
2207 *
2208 * @param appOp The app op name
2209 *
2210 * @return the default mode for the app op
2211 *
2212 * @hide
2213 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07002214 @TestApi
Hai Zhangc595f112018-11-06 14:20:38 -08002215 @SystemApi
2216 public static int opToDefaultMode(@NonNull String appOp) {
2217 return opToDefaultMode(strOpToOp(appOp));
2218 }
2219
2220 /**
Svet Ganov82f09bc2018-01-12 22:08:40 -08002221 * Retrieve the human readable mode.
2222 * @hide
2223 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002224 public static String modeToName(@Mode int mode) {
Dianne Hackbornc216a262018-04-26 13:46:22 -07002225 if (mode >= 0 && mode < MODE_NAMES.length) {
2226 return MODE_NAMES[mode];
Svet Ganov82f09bc2018-01-12 22:08:40 -08002227 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07002228 return "mode=" + mode;
Svet Ganov82f09bc2018-01-12 22:08:40 -08002229 }
2230
2231 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002232 * Retrieve whether the op allows itself to be reset.
2233 * @hide
2234 */
2235 public static boolean opAllowsReset(int op) {
2236 return !sOpDisableReset[op];
2237 }
2238
2239 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002240 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002241 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002242 */
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002243 @SystemApi
2244 public static final class PackageOps implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002245 private final String mPackageName;
2246 private final int mUid;
2247 private final List<OpEntry> mEntries;
2248
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002249 /**
2250 * @hide
2251 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002252 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002253 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
2254 mPackageName = packageName;
2255 mUid = uid;
2256 mEntries = entries;
2257 }
2258
Svet Ganovaf189e32019-02-15 18:45:29 -08002259 /**
2260 * @return The name of the package.
2261 */
2262 public @NonNull String getPackageName() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002263 return mPackageName;
2264 }
2265
Svet Ganovaf189e32019-02-15 18:45:29 -08002266 /**
2267 * @return The uid of the package.
2268 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002269 public int getUid() {
2270 return mUid;
2271 }
2272
Svet Ganovaf189e32019-02-15 18:45:29 -08002273 /**
2274 * @return The ops of the package.
2275 */
Dianne Hackborn62878492019-03-11 15:57:07 -07002276 public @NonNull List<OpEntry> getOps() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002277 return mEntries;
2278 }
2279
2280 @Override
2281 public int describeContents() {
2282 return 0;
2283 }
2284
2285 @Override
2286 public void writeToParcel(Parcel dest, int flags) {
2287 dest.writeString(mPackageName);
2288 dest.writeInt(mUid);
2289 dest.writeInt(mEntries.size());
2290 for (int i=0; i<mEntries.size(); i++) {
2291 mEntries.get(i).writeToParcel(dest, flags);
2292 }
2293 }
2294
2295 PackageOps(Parcel source) {
2296 mPackageName = source.readString();
2297 mUid = source.readInt();
2298 mEntries = new ArrayList<OpEntry>();
2299 final int N = source.readInt();
2300 for (int i=0; i<N; i++) {
2301 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
2302 }
2303 }
2304
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07002305 public static final @android.annotation.NonNull Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002306 @Override public PackageOps createFromParcel(Parcel source) {
2307 return new PackageOps(source);
2308 }
2309
2310 @Override public PackageOps[] newArray(int size) {
2311 return new PackageOps[size];
2312 }
2313 };
2314 }
2315
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002316 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002317 * Class holding the information about one unique operation of a
2318 * {@link Context#createFeatureContext(String) feature}.
2319 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002320 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002321 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002322 @TestApi
2323 @Immutable
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002324 @SystemApi
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002325 public static final class OpFeatureEntry {
2326 private final @NonNull OpEntry mParent;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002327 private final boolean mRunning;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002328
Svet Ganovaf189e32019-02-15 18:45:29 -08002329 private final @Nullable LongSparseLongArray mAccessTimes;
2330 private final @Nullable LongSparseLongArray mRejectTimes;
2331 private final @Nullable LongSparseLongArray mDurations;
2332 private final @Nullable LongSparseLongArray mProxyUids;
2333 private final @Nullable LongSparseArray<String> mProxyPackageNames;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002334 private final @Nullable LongSparseArray<String> mProxyFeatureIds;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002335
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002336 /**
2337 * @hide
2338 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002339 public OpFeatureEntry(@NonNull OpEntry parent, boolean running,
2340 @Nullable LongSparseLongArray accessTimes,
2341 @Nullable LongSparseLongArray rejectTimes,
Svet Ganovaf189e32019-02-15 18:45:29 -08002342 @Nullable LongSparseLongArray durations, @Nullable LongSparseLongArray proxyUids,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002343 @Nullable LongSparseArray<String> proxyPackageNames,
2344 @Nullable LongSparseArray<String> proxyFeatureIds) {
2345 mParent = Preconditions.checkNotNull(parent);
Amith Yamasania1ce9632018-05-28 20:50:48 -07002346 mRunning = running;
Svet Ganovaf189e32019-02-15 18:45:29 -08002347 mAccessTimes = accessTimes;
2348 mRejectTimes = rejectTimes;
2349 mDurations = durations;
2350 mProxyUids = proxyUids;
2351 mProxyPackageNames = proxyPackageNames;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002352 mProxyFeatureIds = proxyFeatureIds;
Svet Ganovaf189e32019-02-15 18:45:29 -08002353 }
2354
2355 /**
2356 * Returns all keys for which we have mapped state in any of the data buckets -
2357 * access time, reject time, duration.
2358 * @hide */
2359 public @Nullable LongSparseArray<Object> collectKeys() {
2360 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessTimes, null);
2361 result = AppOpsManager.collectKeys(mRejectTimes, result);
2362 result = AppOpsManager.collectKeys(mDurations, result);
2363 return result;
Amith Yamasania1ce9632018-05-28 20:50:48 -07002364 }
2365
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002366 /**
2367 * @hide
2368 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002369 public long getTime() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002370 return getLastAccessTime(OP_FLAGS_ALL);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002371 }
2372
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002373 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002374 * Return the last wall clock time in milliseconds this op was accessed.
2375 *
2376 * @param flags The flags which are any combination of
2377 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2378 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2379 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2380 * for any flag.
2381 * @return the last access time in milliseconds since
2382 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2383 *
2384 * @see #getLastAccessForegroundTime(int)
2385 * @see #getLastAccessBackgroundTime(int)
2386 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002387 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002388 public long getLastAccessTime(@OpFlags int flags) {
2389 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
2390 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002391 }
2392
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002393 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002394 * Return the last wall clock time in milliseconds this op was accessed
2395 * by the app while in the foreground.
2396 *
2397 * @param flags The flags which are any combination of
2398 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2399 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2400 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2401 * for any flag.
2402 * @return the last foreground access time in milliseconds since
2403 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2404 *
2405 * @see #getLastAccessBackgroundTime(int)
2406 * @see #getLastAccessTime(int)
2407 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002408 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002409 public long getLastAccessForegroundTime(@OpFlags int flags) {
2410 return maxForFlagsInStates(mAccessTimes, MAX_PRIORITY_UID_STATE,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002411 resolveFirstUnrestrictedUidState(mParent.mOp), flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002412 }
2413
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002414 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002415 * Return the last wall clock time in milliseconds this op was accessed
2416 * by the app while in the background.
2417 *
2418 * @param flags The flags which are any combination of
2419 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2420 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2421 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2422 * for any flag.
2423 * @return the last foreground access time in milliseconds since
2424 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2425 *
2426 * @see #getLastAccessForegroundTime(int)
2427 * @see #getLastAccessTime(int)
2428 * @see #getLastAccessTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002429 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002430 public long getLastAccessBackgroundTime(@OpFlags int flags) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002431 return maxForFlagsInStates(mAccessTimes, resolveLastRestrictedUidState(mParent.mOp),
Svet Ganovaf189e32019-02-15 18:45:29 -08002432 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002433 }
2434
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002435 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002436 * Return the last wall clock time in milliseconds this op was accessed
2437 * by the app for a given range of UID states.
2438 *
2439 * @param fromUidState The UID state for which to query. Could be one of
2440 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2441 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2442 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2443 * @param toUidState The UID state for which to query.
2444 * @param flags The flags which are any combination of
2445 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2446 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2447 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2448 * for any flag.
2449 *
2450 * @return the last foreground access time in milliseconds since
2451 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2452 *
2453 * @see #getLastAccessForegroundTime(int)
2454 * @see #getLastAccessBackgroundTime(int)
2455 * @see #getLastAccessTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002456 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002457 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
2458 @OpFlags int flags) {
2459 return maxForFlagsInStates(mAccessTimes, fromUidState, toUidState, flags);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002460 }
2461
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002462 /**
2463 * @hide
2464 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002465 public long getRejectTime() {
Svet Ganovaf189e32019-02-15 18:45:29 -08002466 return getLastRejectTime(OP_FLAGS_ALL);
Dianne Hackborncd1f30b2018-04-23 17:38:09 -07002467 }
2468
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002469 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002470 * Return the last wall clock time in milliseconds the app made an attempt
2471 * to access this op but was rejected.
2472 *
2473 * @param flags The flags which are any combination of
2474 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2475 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2476 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2477 * for any flag.
2478 * @return the last reject time in milliseconds since
2479 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2480 *
2481 * @see #getLastRejectBackgroundTime(int)
2482 * @see #getLastRejectForegroundTime(int)
2483 * @see #getLastRejectTime(int, int, int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002484 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002485 public long getLastRejectTime(@OpFlags int flags) {
2486 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
2487 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002488 }
2489
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002490 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002491 * Return the last wall clock time in milliseconds the app made an attempt
2492 * to access this op while in the foreground but was rejected.
2493 *
2494 * @param flags The flags which are any combination of
2495 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2496 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2497 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2498 * for any flag.
2499 * @return the last foreground reject time in milliseconds since
2500 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2501 *
2502 * @see #getLastRejectBackgroundTime(int)
2503 * @see #getLastRejectTime(int, int, int)
2504 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002505 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002506 public long getLastRejectForegroundTime(@OpFlags int flags) {
2507 return maxForFlagsInStates(mRejectTimes, MAX_PRIORITY_UID_STATE,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002508 resolveFirstUnrestrictedUidState(mParent.mOp), flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002509 }
2510
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002511 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002512 * Return the last wall clock time in milliseconds the app made an attempt
2513 * to access this op while in the background but was rejected.
2514 *
2515 * @param flags The flags which are any combination of
2516 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2517 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2518 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2519 * for any flag.
2520 * @return the last background reject time in milliseconds since
2521 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2522 *
2523 * @see #getLastRejectForegroundTime(int)
2524 * @see #getLastRejectTime(int, int, int)
2525 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002526 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002527 public long getLastRejectBackgroundTime(@OpFlags int flags) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002528 return maxForFlagsInStates(mRejectTimes, resolveLastRestrictedUidState(mParent.mOp),
Svet Ganovaf189e32019-02-15 18:45:29 -08002529 MIN_PRIORITY_UID_STATE, flags);
Dianne Hackbornc216a262018-04-26 13:46:22 -07002530 }
2531
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002532 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08002533 * Return the last wall clock time state in milliseconds the app made an
2534 * attempt to access this op for a given range of UID states.
2535 *
2536 * @param fromUidState The UID state from which to query. Could be one of
2537 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2538 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2539 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2540 * @param toUidState The UID state to which to query.
2541 * @param flags The flags which are any combination of
2542 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2543 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2544 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2545 * for any flag.
2546 * @return the last foreground access time in milliseconds since
2547 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2548 *
2549 * @see #getLastRejectForegroundTime(int)
2550 * @see #getLastRejectBackgroundTime(int)
2551 * @see #getLastRejectTime(int)
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002552 */
Svet Ganovaf189e32019-02-15 18:45:29 -08002553 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
2554 @OpFlags int flags) {
2555 return maxForFlagsInStates(mRejectTimes, fromUidState, toUidState, flags);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002556 }
2557
Svet Ganovaf189e32019-02-15 18:45:29 -08002558 /**
2559 * @return Whether the operation is running.
2560 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002561 public boolean isRunning() {
Amith Yamasania1ce9632018-05-28 20:50:48 -07002562 return mRunning;
Dianne Hackborn35654b62013-01-14 17:38:02 -08002563 }
2564
Svet Ganovaf189e32019-02-15 18:45:29 -08002565 /**
Svet Ganov6f672a32019-07-08 16:40:42 -07002566 * @return The duration of the operation in milliseconds. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002567 */
2568 public long getDuration() {
2569 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
Dianne Hackborn35654b62013-01-14 17:38:02 -08002570 }
2571
Svet Ganovaf189e32019-02-15 18:45:29 -08002572 /**
2573 * Return the duration in milliseconds the app accessed this op while
Svet Ganov6f672a32019-07-08 16:40:42 -07002574 * in the foreground. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002575 *
2576 * @param flags The flags which are any combination of
2577 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2578 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2579 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2580 * for any flag.
2581 * @return the foreground access duration in milliseconds.
2582 *
2583 * @see #getLastBackgroundDuration(int)
2584 * @see #getLastDuration(int, int, int)
2585 */
2586 public long getLastForegroundDuration(@OpFlags int flags) {
2587 return sumForFlagsInStates(mDurations, MAX_PRIORITY_UID_STATE,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002588 resolveFirstUnrestrictedUidState(mParent.mOp), flags);
Svet Ganovaf189e32019-02-15 18:45:29 -08002589 }
2590
2591 /**
2592 * Return the duration in milliseconds the app accessed this op while
Svet Ganov6f672a32019-07-08 16:40:42 -07002593 * in the background. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002594 *
2595 * @param flags The flags which are any combination of
2596 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2597 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2598 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2599 * for any flag.
2600 * @return the background access duration in milliseconds.
2601 *
2602 * @see #getLastForegroundDuration(int)
2603 * @see #getLastDuration(int, int, int)
2604 */
2605 public long getLastBackgroundDuration(@OpFlags int flags) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002606 return sumForFlagsInStates(mDurations, resolveLastRestrictedUidState(mParent.mOp),
Svet Ganovaf189e32019-02-15 18:45:29 -08002607 MIN_PRIORITY_UID_STATE, flags);
2608 }
2609
2610 /**
2611 * Return the duration in milliseconds the app accessed this op for
Svet Ganov6f672a32019-07-08 16:40:42 -07002612 * a given range of UID states. The duration is in wall time.
Svet Ganovaf189e32019-02-15 18:45:29 -08002613 *
2614 * @param fromUidState The UID state for which to query. Could be one of
2615 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2616 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2617 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2618 * @param toUidState The UID state for which to query.
2619 * @param flags The flags which are any combination of
2620 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2621 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2622 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2623 * for any flag.
2624 * @return the access duration in milliseconds.
2625 */
2626 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
2627 @OpFlags int flags) {
2628 return sumForFlagsInStates(mDurations, fromUidState, toUidState, flags);
2629 }
2630
2631 /**
2632 * Gets the UID of the app that performed the op on behalf of this app and
2633 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2634 * there is no proxy.
2635 *
2636 * @return The proxy UID.
2637 */
Svet Ganov99b60432015-06-27 13:15:22 -07002638 public int getProxyUid() {
Philip P. Moltmann4052d362019-09-19 14:52:38 -07002639 return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
Svet Ganovaf189e32019-02-15 18:45:29 -08002640 MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
Svet Ganov99b60432015-06-27 13:15:22 -07002641 }
2642
Svet Ganovaf189e32019-02-15 18:45:29 -08002643 /**
2644 * Gets the UID of the app that performed the op on behalf of this app and
2645 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
2646 * there is no proxy.
2647 *
2648 * @param uidState The UID state for which to query. Could be one of
2649 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2650 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2651 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2652 * @param flags The flags which are any combination of
2653 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2654 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2655 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2656 * for any flag.
2657 *
2658 * @return The proxy UID.
2659 */
2660 public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
Philip P. Moltmann4052d362019-09-19 14:52:38 -07002661 return (int) findFirstNonNegativeForFlagsInStates(mProxyUids,
Svet Ganovaf189e32019-02-15 18:45:29 -08002662 uidState, uidState, flags);
2663 }
2664
2665 /**
2666 * Gets the package name of the app that performed the op on behalf of this
2667 * app and as a result blamed the op on this app or {@code null}
2668 * if there is no proxy.
2669 *
2670 * @return The proxy package name.
2671 */
2672 public @Nullable String getProxyPackageName() {
2673 return findFirstNonNullForFlagsInStates(mProxyPackageNames, MAX_PRIORITY_UID_STATE,
2674 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
2675 }
2676
2677 /**
2678 * Gets the package name of the app that performed the op on behalf of this
2679 * app and as a result blamed the op on this app for a UID state or
2680 * {@code null} if there is no proxy.
2681 *
2682 * @param uidState The UID state for which to query. Could be one of
2683 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2684 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2685 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2686 * @param flags The flags which are any combination of
2687 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2688 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2689 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2690 * for any flag.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002691 * @return The feature id.
Svet Ganovaf189e32019-02-15 18:45:29 -08002692 */
2693 public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
2694 return findFirstNonNullForFlagsInStates(mProxyPackageNames, uidState, uidState, flags);
Svet Ganov99b60432015-06-27 13:15:22 -07002695 }
2696
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002697 /**
2698 * Gets the feature of the app that performed the op on behalf of this
2699 * app and as a result blamed the op on this app or {@code null}
2700 * if there is no proxy.
2701 *
2702 * @return The proxy package name.
2703 */
2704 public @Nullable String getProxyFeatureId() {
2705 return findFirstNonNullForFlagsInStates(mProxyFeatureIds, MAX_PRIORITY_UID_STATE,
2706 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
2707 }
2708
2709 /**
2710 * Gets the feature of the app that performed the op on behalf of this
2711 * app and as a result blamed the op on this app for a UID state or
2712 * {@code null} if there is no proxy.
2713 *
2714 * @param uidState The UID state for which to query. Could be one of
2715 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2716 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2717 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2718 * @param flags The flags which are any combination of
2719 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2720 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2721 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2722 * for any flag.
2723 * @return The feature id.
2724 */
2725 public @Nullable String getProxyFeatureId(@UidState int uidState, @OpFlags int flags) {
2726 return findFirstNonNullForFlagsInStates(mProxyFeatureIds, uidState, uidState, flags);
2727 }
2728
2729 /**
2730 * @hide
2731 */
2732 public static class Builder {
2733 private final boolean mRunning;
2734
2735 private final @Nullable LongSparseLongArray mAccessTimes;
2736 private final @Nullable LongSparseLongArray mRejectTimes;
2737 private final @Nullable LongSparseLongArray mDurations;
2738 private final @Nullable LongSparseLongArray mProxyUids;
2739 private final @Nullable LongSparseArray<String> mProxyPackageNames;
2740 private final @Nullable LongSparseArray<String> mProxyFeatureIds;
2741 private @NonNull OpEntry mParent;
2742
2743 public Builder(boolean running, @Nullable LongSparseLongArray accessTimes,
2744 @Nullable LongSparseLongArray rejectTimes,
2745 @Nullable LongSparseLongArray durations,
2746 @Nullable LongSparseLongArray proxyUids,
2747 @Nullable LongSparseArray<String> proxyPackageNames,
2748 @Nullable LongSparseArray<String> proxyFeatureIds) {
2749 mRunning = running;
2750 mAccessTimes = accessTimes;
2751 mRejectTimes = rejectTimes;
2752 mDurations = durations;
2753 mProxyUids = proxyUids;
2754 mProxyPackageNames = proxyPackageNames;
2755 mProxyFeatureIds = proxyFeatureIds;
2756 }
2757
2758 public Builder setParent(@NonNull OpEntry parent) {
2759 mParent = parent;
2760
2761 return this;
2762 }
2763
2764 /**
2765 * Create OpFeatureEntry from builder
2766 */
2767 public OpFeatureEntry build() {
2768 Preconditions.checkNotNull(mParent);
2769
2770 return new OpFeatureEntry(mParent, mRunning, mAccessTimes, mRejectTimes,
2771 mDurations, mProxyUids, mProxyPackageNames, mProxyFeatureIds);
2772 }
2773 }
2774
2775 /**
2776 * @hide
2777 */
2778 public void writeToParcel(@NonNull Parcel dest, int flags) {
2779 LongSparseLongArray.Parcelling longSparseLongArrayParcelling =
2780 LongSparseLongArray.Parcelling.Cache.getOrCreate(
2781 LongSparseLongArray.Parcelling.class);
2782 LongSparseArray.StringParcelling longSparseStringArrayParcelling =
2783 LongSparseArray.StringParcelling.Cache.getOrCreate(
2784 LongSparseArray.StringParcelling.class);
2785
2786 dest.writeBoolean(mRunning);
2787 longSparseLongArrayParcelling.parcel(mAccessTimes, dest, flags);
2788 longSparseLongArrayParcelling.parcel(mRejectTimes, dest, flags);
2789 longSparseLongArrayParcelling.parcel(mDurations, dest, flags);
2790 longSparseLongArrayParcelling.parcel(mProxyUids, dest, flags);
2791 longSparseStringArrayParcelling.parcel(mProxyPackageNames, dest, flags);
2792 longSparseStringArrayParcelling.parcel(mProxyFeatureIds, dest, flags);
2793 }
2794
2795 /**
2796 * @hide
2797 */
2798 public static OpFeatureEntry.Builder createFromParcel(@NonNull Parcel source) {
2799 LongSparseLongArray.Parcelling longSparseLongArrayParcelling =
2800 LongSparseLongArray.Parcelling.Cache.getOrCreate(
2801 LongSparseLongArray.Parcelling.class);
2802 LongSparseArray.StringParcelling longSparseStringArrayParcelling =
2803 LongSparseArray.StringParcelling.Cache.getOrCreate(
2804 LongSparseArray.StringParcelling.class);
2805
2806 return new OpFeatureEntry.Builder(source.readBoolean(),
Philip P. Moltmannbadc09c2019-10-23 10:28:27 -07002807 longSparseLongArrayParcelling.unparcel(source),
2808 longSparseLongArrayParcelling.unparcel(source),
2809 longSparseLongArrayParcelling.unparcel(source),
2810 longSparseLongArrayParcelling.unparcel(source),
2811 longSparseStringArrayParcelling.unparcel(source),
2812 longSparseStringArrayParcelling.unparcel(source));
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002813 }
2814 }
2815
2816 /**
2817 * Class holding the information about one unique operation of an application.
2818 * @hide
2819 */
2820 @TestApi
2821 @Immutable
2822 @SystemApi
2823 public static final class OpEntry implements Parcelable {
2824 private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp;
2825 private final @Mode int mMode;
2826 private final @NonNull ArrayMap<String, OpFeatureEntry> mFeatures;
2827
2828 /**
2829 * @hide
2830 */
2831 public OpEntry(@IntRange(from = 0, to = _NUM_OP - 1) int op, @Mode int mode,
2832 @NonNull Pair<String, OpFeatureEntry.Builder>[] featureBuilders) {
2833 mOp = Preconditions.checkArgumentInRange(op, 0, _NUM_OP - 1, "op");
2834 mMode = Preconditions.checkArgumentInRange(mode, 0, MODE_FOREGROUND, "mode");
2835
2836 mFeatures = new ArrayMap<>(featureBuilders.length);
2837 for (Pair<String, OpFeatureEntry.Builder> feature : featureBuilders) {
2838 mFeatures.put(feature.first, feature.second.setParent(this).build());
2839 }
2840 }
2841
2842 /**
2843 * @return The mapping from the feature ids to the feature state
2844 */
2845 public @NonNull Map<String, OpFeatureEntry> getFeatures() {
2846 return mFeatures;
2847 }
2848
2849 /**
2850 * @hide
2851 */
2852 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
2853 + "#getOpStr()}")
2854 public int getOp() {
2855 return mOp;
2856 }
2857
2858 /**
2859 * @return This entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}.
2860 */
2861 public @NonNull String getOpStr() {
2862 return sOpToString[mOp];
2863 }
2864
2865 /**
2866 * @return this entry's current mode, such as {@link #MODE_ALLOWED}.
2867 */
2868 public @Mode int getMode() {
2869 return mMode;
2870 }
2871
2872 /**
2873 * @deprecated Use {@link OpEntry#getLastAccessTime(int)} instead
2874 *
2875 * @hide
2876 */
2877 @Deprecated
2878 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
2879 + "#getLastAccessTime(int)}")
2880 public long getTime() {
2881 return getLastAccessTime(OP_FLAGS_ALL);
2882 }
2883
2884 private long getMaxOfFeatures(@NonNull ToLongFunction<OpFeatureEntry> timeGetter) {
2885 long max = 0;
2886
2887 int numFeatures = mFeatures.size();
2888 for (int i = 0; i < numFeatures; i++) {
2889 max = Math.max(max, timeGetter.applyAsLong(mFeatures.valueAt(i)));
2890 }
2891
2892 return max;
2893 }
2894
2895 private long getSumOfFeatures(@NonNull ToLongFunction<OpFeatureEntry> getter) {
2896 long sum = 0;
2897
2898 int numFeatures = mFeatures.size();
2899 for (int i = 0; i < numFeatures; i++) {
2900 sum += getter.applyAsLong(mFeatures.valueAt(i));
2901 }
2902
2903 return sum;
2904 }
2905
2906 /**
2907 * Return the last wall clock time in milliseconds this op was accessed
2908 * by the app for a given range of UID states.
2909 *
2910 * @param fromUidState The UID state for which to query. Could be one of
2911 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2912 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2913 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2914 * @param toUidState The UID state for which to query.
2915 * @param flags The flags which are any combination of
2916 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2917 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2918 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2919 * for any flag.
2920 *
2921 * @return the last foreground access time in milliseconds since
2922 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2923 *
2924 * @see #getLastAccessForegroundTime(int)
2925 * @see #getLastAccessBackgroundTime(int)
2926 * @see #getLastAccessTime(int)
2927 */
2928 public long getLastAccessTime(@OpFlags int flags) {
2929 return getMaxOfFeatures(
2930 (featureEntry -> featureEntry.getLastAccessTime(flags)));
2931 }
2932
2933 /**
2934 * Return the last wall clock time in milliseconds this op was accessed
2935 * by the app while in the foreground.
2936 *
2937 * @param flags The flags which are any combination of
2938 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2939 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2940 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2941 * for any flag.
2942 * @return the last foreground access time in milliseconds since
2943 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2944 *
2945 * @see #getLastAccessBackgroundTime(int)
2946 * @see #getLastAccessTime(int)
2947 * @see #getLastAccessTime(int, int, int)
2948 */
2949 public long getLastAccessForegroundTime(@OpFlags int flags) {
2950 return getMaxOfFeatures(
2951 (featureEntry -> featureEntry.getLastAccessForegroundTime(flags)));
2952 }
2953
2954 /**
2955 * Return the last wall clock time in milliseconds this op was accessed
2956 * by the app while in the background.
2957 *
2958 * @param flags The flags which are any combination of
2959 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2960 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2961 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2962 * for any flag.
2963 * @return the last foreground access time in milliseconds since
2964 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2965 *
2966 * @see #getLastAccessForegroundTime(int)
2967 * @see #getLastAccessTime(int)
2968 * @see #getLastAccessTime(int, int, int)
2969 */
2970 public long getLastAccessBackgroundTime(@OpFlags int flags) {
2971 return getMaxOfFeatures(
2972 (featureEntry -> featureEntry.getLastAccessBackgroundTime(flags)));
2973 }
2974
2975 /**
2976 * Return the last wall clock time in milliseconds this op was accessed
2977 * by the app for a given range of UID states.
2978 *
2979 * @param fromUidState The UID state for which to query. Could be one of
2980 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
2981 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
2982 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
2983 * @param toUidState The UID state for which to query.
2984 * @param flags The flags which are any combination of
2985 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
2986 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
2987 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
2988 * for any flag.
2989 *
2990 * @return the last foreground access time in milliseconds since
2991 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
2992 *
2993 * @see #getLastAccessForegroundTime(int)
2994 * @see #getLastAccessBackgroundTime(int)
2995 * @see #getLastAccessTime(int)
2996 */
2997 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
2998 @OpFlags int flags) {
2999 return getMaxOfFeatures(
3000 (featureEntry -> featureEntry.getLastAccessTime(fromUidState,
3001 toUidState, flags)));
3002 }
3003
3004 /**
3005 * @deprecated Use {@link OpEntry#getLastRejectTime(int)} instead
3006 *
3007 * @hide
3008 */
3009 @Deprecated
3010 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
3011 + "#getLastRejectTime(int)}")
3012 public long getRejectTime() {
3013 return getLastRejectTime(OP_FLAGS_ALL);
3014 }
3015
3016 /**
3017 * Return the last wall clock time in milliseconds the app made an attempt
3018 * to access this op but was rejected.
3019 *
3020 * @param flags The flags which are any combination of
3021 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3022 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3023 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3024 * for any flag.
3025 * @return the last reject time in milliseconds since
3026 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3027 *
3028 * @see #getLastRejectBackgroundTime(int)
3029 * @see #getLastRejectForegroundTime(int)
3030 * @see #getLastRejectTime(int, int, int)
3031 */
3032 public long getLastRejectTime(@OpFlags int flags) {
3033 return getMaxOfFeatures(
3034 (featureEntry -> featureEntry.getLastRejectTime(flags)));
3035 }
3036
3037 /**
3038 * Return the last wall clock time in milliseconds the app made an attempt
3039 * to access this op while in the foreground but was rejected.
3040 *
3041 * @param flags The flags which are any combination of
3042 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3043 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3044 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3045 * for any flag.
3046 * @return the last foreground reject time in milliseconds since
3047 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3048 *
3049 * @see #getLastRejectBackgroundTime(int)
3050 * @see #getLastRejectTime(int, int, int)
3051 * @see #getLastRejectTime(int)
3052 */
3053 public long getLastRejectForegroundTime(@OpFlags int flags) {
3054 return getMaxOfFeatures(
3055 (featureEntry -> featureEntry.getLastRejectForegroundTime(flags)));
3056 }
3057
3058 /**
3059 * Return the last wall clock time in milliseconds the app made an attempt
3060 * to access this op while in the background but was rejected.
3061 *
3062 * @param flags The flags which are any combination of
3063 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3064 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3065 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3066 * for any flag.
3067 * @return the last background reject time in milliseconds since
3068 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3069 *
3070 * @see #getLastRejectForegroundTime(int)
3071 * @see #getLastRejectTime(int, int, int)
3072 * @see #getLastRejectTime(int)
3073 */
3074 public long getLastRejectBackgroundTime(@OpFlags int flags) {
3075 return getMaxOfFeatures(
3076 (featureEntry -> featureEntry.getLastRejectBackgroundTime(flags)));
3077 }
3078
3079 /**
3080 * Return the last wall clock time state in milliseconds the app made an
3081 * attempt to access this op for a given range of UID states.
3082 *
3083 * @param fromUidState The UID state from which to query. Could be one of
3084 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
3085 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3086 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3087 * @param toUidState The UID state to which to query.
3088 * @param flags The flags which are any combination of
3089 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3090 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3091 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3092 * for any flag.
3093 * @return the last foreground access time in milliseconds since
3094 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3095 *
3096 * @see #getLastRejectForegroundTime(int)
3097 * @see #getLastRejectBackgroundTime(int)
3098 * @see #getLastRejectTime(int)
3099 */
3100 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
3101 @OpFlags int flags) {
3102 return getMaxOfFeatures(
3103 (featureEntry -> featureEntry.getLastRejectTime(fromUidState,
3104 toUidState, flags)));
3105 }
3106
3107 /**
3108 * @return Whether the operation is running.
3109 */
3110 public boolean isRunning() {
3111 int numFeatures = mFeatures.size();
3112 if (mFeatures.isEmpty()) {
3113 return false;
3114 }
3115
3116 for (int i = 0; i < numFeatures; i++) {
3117 if (mFeatures.valueAt(i).mRunning) {
3118 return true;
3119 }
3120 }
3121
3122 return false;
3123 }
3124
3125 /**
3126 * @return The duration of the operation in milliseconds. The duration is in wall time.
3127 */
3128 public long getDuration() {
3129 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
3130 }
3131
3132 /**
3133 * Return the duration in milliseconds the app accessed this op while
3134 * in the foreground. The duration is in wall time.
3135 *
3136 * @param flags The flags which are any combination of
3137 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3138 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3139 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3140 * for any flag.
3141 * @return the foreground access duration in milliseconds.
3142 *
3143 * @see #getLastBackgroundDuration(int)
3144 * @see #getLastDuration(int, int, int)
3145 */
3146 public long getLastForegroundDuration(@OpFlags int flags) {
3147 return getSumOfFeatures((featureEntry) ->
3148 featureEntry.getLastForegroundDuration(flags));
3149 }
3150
3151 /**
3152 * Return the duration in milliseconds the app accessed this op while
3153 * in the background. The duration is in wall time.
3154 *
3155 * @param flags The flags which are any combination of
3156 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3157 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3158 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3159 * for any flag.
3160 * @return the background access duration in milliseconds.
3161 *
3162 * @see #getLastForegroundDuration(int)
3163 * @see #getLastDuration(int, int, int)
3164 */
3165 public long getLastBackgroundDuration(@OpFlags int flags) {
3166 return getSumOfFeatures((featureEntry) ->
3167 featureEntry.getLastBackgroundDuration(flags));
3168 }
3169
3170 /**
3171 * Return the duration in milliseconds the app accessed this op for
3172 * a given range of UID states. The duration is in wall time.
3173 *
3174 * @param fromUidState The UID state for which to query. Could be one of
3175 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
3176 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3177 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3178 * @param toUidState The UID state for which to query.
3179 * @param flags The flags which are any combination of
3180 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3181 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3182 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3183 * for any flag.
3184 * @return the access duration in milliseconds.
3185 */
3186 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
3187 @OpFlags int flags) {
3188 return getSumOfFeatures((featureEntry) ->
3189 featureEntry.getLastDuration(fromUidState, toUidState, flags));
3190 }
3191
3192 /**
3193 * Like {@link #findFirstNonNegativeForFlagsInStates(LongSparseLongArray, int, int, int)}
3194 * but for all proxy uid in all features.
3195 */
3196 private long findFirstNonNegativeProxyUidInFeatureStates(@UidState int beginUidState,
3197 @UidState int endUidState, @OpFlags int flags) {
3198 int numFeatures = mFeatures.size();
3199
3200 if (numFeatures == 0) {
3201 return -1;
3202 }
3203
3204 while (flags != 0) {
3205 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
3206 flags &= ~flag;
3207 for (int uidState : UID_STATES) {
3208 if (uidState < beginUidState || uidState > endUidState) {
3209 continue;
3210 }
3211
3212 final long key = makeKey(uidState, flag);
3213
3214 for (int i = 0; i < numFeatures; i++) {
3215 OpFeatureEntry featureEntry = mFeatures.valueAt(i);
3216
3217 if (featureEntry.mProxyUids == null) {
3218 continue;
3219 }
3220
3221 final long proxyUid = featureEntry.mProxyUids.get(key);
3222 if (proxyUid >= 0) {
3223 return proxyUid;
3224 }
3225 }
3226 }
3227 }
3228
3229 return -1;
3230 }
3231
3232 /**
3233 * Like {@link #findFirstNonNullForFlagsInStates(LongSparseArray, int, int, int)} but
3234 * for all proxyPackageNames in all features.
3235 */
3236 private @Nullable String findFirstNonNullProxyPackageNameInFeatureStates(
3237 @OpFlags int flags, @UidState int beginUidState, @UidState int endUidState) {
3238 int numFeatures = mFeatures.size();
3239
3240 if (numFeatures == 0) {
3241 return null;
3242 }
3243
3244 while (flags != 0) {
3245 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
3246 flags &= ~flag;
3247 for (int uidState : UID_STATES) {
3248 if (uidState < beginUidState || uidState > endUidState) {
3249 continue;
3250 }
3251 final long key = makeKey(uidState, flag);
3252
3253 for (int i = 0; i < numFeatures; i++) {
3254 OpFeatureEntry featureEntry = mFeatures.valueAt(i);
3255
3256 if (featureEntry.mProxyPackageNames == null) {
3257 continue;
3258 }
3259
3260 final String proxyName = featureEntry.mProxyPackageNames.get(key);
3261 if (proxyName != null) {
3262 return proxyName;
3263 }
3264 }
3265 }
3266 }
3267 return null;
3268 }
3269
3270 /**
3271 * @deprecated Use {@link #getProxyUid(int, int)} instead
3272 */
3273 @Deprecated
3274 public int getProxyUid() {
3275 return (int) findFirstNonNegativeProxyUidInFeatureStates(MAX_PRIORITY_UID_STATE,
3276 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
3277 }
3278
3279 /**
3280 * Gets the UID of the app that performed the op on behalf of this app and
3281 * as a result blamed the op on this app or {@link Process#INVALID_UID} if
3282 * there is no proxy.
3283 *
3284 * @param uidState The UID state for which to query. Could be one of
3285 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
3286 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3287 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3288 * @param flags The flags which are any combination of
3289 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3290 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3291 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3292 * for any flag.
3293 *
3294 * @return The proxy UID.
3295 */
3296 public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
3297 return (int) findFirstNonNegativeProxyUidInFeatureStates(uidState, uidState, flags);
3298 }
3299
3300 /**
3301 * @deprecated Use {@link #getProxyPackageName(int, int)} instead
3302 */
3303 @Deprecated
3304 public @Nullable String getProxyPackageName() {
3305 return findFirstNonNullProxyPackageNameInFeatureStates(MAX_PRIORITY_UID_STATE,
3306 MIN_PRIORITY_UID_STATE, OP_FLAGS_ALL);
3307 }
3308
3309 /**
3310 * Gets the package name of the app that performed the op on behalf of this
3311 * app and as a result blamed the op on this app for a UID state or
3312 * {@code null} if there is no proxy.
3313 *
3314 * @param uidState The UID state for which to query. Could be one of
3315 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
3316 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
3317 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
3318 * @param flags The flags which are any combination of
3319 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3320 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3321 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3322 * for any flag.
3323 * @return The proxy package name.
3324 */
3325 public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
3326 return findFirstNonNullProxyPackageNameInFeatureStates(uidState, uidState, flags);
3327 }
3328
3329 /**
3330 * Create OpEntry from parcel.
3331 *
3332 * @hide
3333 */
3334 public static OpEntry createFromParcel(@NonNull Parcel source) {
3335 int op = source.readInt();
3336 int mode = source.readInt();
3337
3338 int numFeatures = source.readInt();
3339 Pair<String, OpFeatureEntry.Builder>[] features = new Pair[numFeatures];
3340 for (int i = 0; i < numFeatures; i++) {
3341 features[i] = new Pair<>(source.readString(),
3342 OpFeatureEntry.createFromParcel(source));
3343 }
3344
3345 return new OpEntry(op, mode, features);
3346 }
3347
Dianne Hackborn35654b62013-01-14 17:38:02 -08003348 @Override
3349 public int describeContents() {
3350 return 0;
3351 }
3352
3353 @Override
3354 public void writeToParcel(Parcel dest, int flags) {
3355 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08003356 dest.writeInt(mMode);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003357
3358 int numFeatures = mFeatures.size();
3359 dest.writeInt(numFeatures);
3360 for (int i = 0; i < numFeatures; i++) {
3361 dest.writeString(mFeatures.keyAt(i));
3362 mFeatures.valueAt(i).writeToParcel(dest, flags);
3363 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08003364 }
3365
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003366 public static final @NonNull Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
3367 @Override
3368 public @NonNull OpEntry createFromParcel(@NonNull Parcel parcel) {
3369 return OpEntry.createFromParcel(parcel);
Dianne Hackborn35654b62013-01-14 17:38:02 -08003370 }
3371
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003372 @Override
3373 public @NonNull OpEntry[] newArray(int size) {
Dianne Hackborn35654b62013-01-14 17:38:02 -08003374 return new OpEntry[size];
3375 }
3376 };
3377 }
3378
Svet Ganov8455ba22019-01-02 13:05:56 -08003379 /** @hide */
3380 public interface HistoricalOpsVisitor {
3381 void visitHistoricalOps(@NonNull HistoricalOps ops);
3382 void visitHistoricalUidOps(@NonNull HistoricalUidOps ops);
3383 void visitHistoricalPackageOps(@NonNull HistoricalPackageOps ops);
3384 void visitHistoricalOp(@NonNull HistoricalOp ops);
3385 }
3386
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08003387 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08003388 * Request for getting historical app op usage. The request acts
3389 * as a filtering criteria when querying historical op usage.
3390 *
3391 * @hide
3392 */
3393 @Immutable
3394 @TestApi
3395 @SystemApi
3396 public static final class HistoricalOpsRequest {
3397 private final int mUid;
3398 private final @Nullable String mPackageName;
3399 private final @Nullable List<String> mOpNames;
3400 private final long mBeginTimeMillis;
3401 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08003402 private final @OpFlags int mFlags;
Svet Ganov23c88db2019-01-22 20:38:11 -08003403
3404 private HistoricalOpsRequest(int uid, @Nullable String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003405 @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
3406 @OpFlags int flags) {
Svet Ganov23c88db2019-01-22 20:38:11 -08003407 mUid = uid;
3408 mPackageName = packageName;
3409 mOpNames = opNames;
3410 mBeginTimeMillis = beginTimeMillis;
3411 mEndTimeMillis = endTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08003412 mFlags = flags;
Svet Ganov23c88db2019-01-22 20:38:11 -08003413 }
3414
3415 /**
3416 * Builder for creating a {@link HistoricalOpsRequest}.
3417 *
3418 * @hide
3419 */
3420 @TestApi
3421 @SystemApi
3422 public static final class Builder {
3423 private int mUid = Process.INVALID_UID;
3424 private @Nullable String mPackageName;
3425 private @Nullable List<String> mOpNames;
3426 private final long mBeginTimeMillis;
3427 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08003428 private @OpFlags int mFlags = OP_FLAGS_ALL;
Svet Ganov23c88db2019-01-22 20:38:11 -08003429
3430 /**
3431 * Creates a new builder.
3432 *
3433 * @param beginTimeMillis The beginning of the interval in milliseconds since
3434 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non
3435 * negative.
3436 * @param endTimeMillis The end of the interval in milliseconds since
3437 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after
3438 * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent
3439 * history including ops that happen while this call is in flight.
3440 */
3441 public Builder(long beginTimeMillis, long endTimeMillis) {
3442 Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
3443 "beginTimeMillis must be non negative and lesser than endTimeMillis");
3444 mBeginTimeMillis = beginTimeMillis;
3445 mEndTimeMillis = endTimeMillis;
3446 }
3447
3448 /**
3449 * Sets the UID to query for.
3450 *
3451 * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid.
3452 * @return This builder.
3453 */
3454 public @NonNull Builder setUid(int uid) {
3455 Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
3456 "uid must be " + Process.INVALID_UID + " or non negative");
3457 mUid = uid;
3458 return this;
3459 }
3460
3461 /**
3462 * Sets the package to query for.
3463 *
3464 * @param packageName The package name. <code>Null</code> for any package.
3465 * @return This builder.
3466 */
3467 public @NonNull Builder setPackageName(@Nullable String packageName) {
3468 mPackageName = packageName;
3469 return this;
3470 }
3471
3472 /**
3473 * Sets the op names to query for.
3474 *
3475 * @param opNames The op names. <code>Null</code> for any op.
3476 * @return This builder.
3477 */
3478 public @NonNull Builder setOpNames(@Nullable List<String> opNames) {
3479 if (opNames != null) {
3480 final int opCount = opNames.size();
3481 for (int i = 0; i < opCount; i++) {
3482 Preconditions.checkArgument(AppOpsManager.strOpToOp(
3483 opNames.get(i)) != AppOpsManager.OP_NONE);
3484 }
3485 }
3486 mOpNames = opNames;
3487 return this;
3488 }
3489
3490 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08003491 * Sets the op flags to query for. The flags specify the type of
3492 * op data being queried.
3493 *
3494 * @param flags The flags which are any combination of
3495 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
3496 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
3497 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
3498 * for any flag.
3499 * @return This builder.
3500 */
3501 public @NonNull Builder setFlags(@OpFlags int flags) {
3502 Preconditions.checkFlagsArgument(flags, OP_FLAGS_ALL);
3503 mFlags = flags;
3504 return this;
3505 }
3506
3507 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08003508 * @return a new {@link HistoricalOpsRequest}.
3509 */
3510 public @NonNull HistoricalOpsRequest build() {
3511 return new HistoricalOpsRequest(mUid, mPackageName, mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08003512 mBeginTimeMillis, mEndTimeMillis, mFlags);
Svet Ganov23c88db2019-01-22 20:38:11 -08003513 }
3514 }
3515 }
3516
3517 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08003518 * This class represents historical app op state of all UIDs for a given time interval.
3519 *
3520 * @hide
3521 */
3522 @TestApi
3523 @SystemApi
3524 public static final class HistoricalOps implements Parcelable {
3525 private long mBeginTimeMillis;
3526 private long mEndTimeMillis;
3527 private @Nullable SparseArray<HistoricalUidOps> mHistoricalUidOps;
3528
3529 /** @hide */
3530 @TestApi
3531 public HistoricalOps(long beginTimeMillis, long endTimeMillis) {
3532 Preconditions.checkState(beginTimeMillis <= endTimeMillis);
3533 mBeginTimeMillis = beginTimeMillis;
3534 mEndTimeMillis = endTimeMillis;
3535 }
3536
3537 /** @hide */
3538 public HistoricalOps(@NonNull HistoricalOps other) {
3539 mBeginTimeMillis = other.mBeginTimeMillis;
3540 mEndTimeMillis = other.mEndTimeMillis;
3541 Preconditions.checkState(mBeginTimeMillis <= mEndTimeMillis);
3542 if (other.mHistoricalUidOps != null) {
3543 final int opCount = other.getUidCount();
3544 for (int i = 0; i < opCount; i++) {
3545 final HistoricalUidOps origOps = other.getUidOpsAt(i);
3546 final HistoricalUidOps clonedOps = new HistoricalUidOps(origOps);
3547 if (mHistoricalUidOps == null) {
3548 mHistoricalUidOps = new SparseArray<>(opCount);
3549 }
3550 mHistoricalUidOps.put(clonedOps.getUid(), clonedOps);
3551 }
3552 }
3553 }
3554
3555 private HistoricalOps(Parcel parcel) {
3556 mBeginTimeMillis = parcel.readLong();
3557 mEndTimeMillis = parcel.readLong();
3558 final int[] uids = parcel.createIntArray();
3559 if (!ArrayUtils.isEmpty(uids)) {
3560 final ParceledListSlice<HistoricalUidOps> listSlice = parcel.readParcelable(
3561 HistoricalOps.class.getClassLoader());
3562 final List<HistoricalUidOps> uidOps = (listSlice != null)
3563 ? listSlice.getList() : null;
3564 if (uidOps == null) {
3565 return;
3566 }
3567 for (int i = 0; i < uids.length; i++) {
3568 if (mHistoricalUidOps == null) {
3569 mHistoricalUidOps = new SparseArray<>();
3570 }
3571 mHistoricalUidOps.put(uids[i], uidOps.get(i));
3572 }
3573 }
3574 }
3575
3576 /**
3577 * Splice a piece from the beginning of these ops.
3578 *
3579 * @param splicePoint The fraction of the data to be spliced off.
3580 *
3581 * @hide
3582 */
3583 public @NonNull HistoricalOps spliceFromBeginning(double splicePoint) {
3584 return splice(splicePoint, true);
3585 }
3586
3587 /**
3588 * Splice a piece from the end of these ops.
3589 *
3590 * @param fractionToRemove The fraction of the data to be spliced off.
3591 *
3592 * @hide
3593 */
3594 public @NonNull HistoricalOps spliceFromEnd(double fractionToRemove) {
3595 return splice(fractionToRemove, false);
3596 }
3597
3598 /**
3599 * Splice a piece from the beginning or end of these ops.
3600 *
3601 * @param fractionToRemove The fraction of the data to be spliced off.
3602 * @param beginning Whether to splice off the beginning or the end.
3603 *
3604 * @return The spliced off part.
3605 *
3606 * @hide
3607 */
3608 private @Nullable HistoricalOps splice(double fractionToRemove, boolean beginning) {
3609 final long spliceBeginTimeMills;
3610 final long spliceEndTimeMills;
3611 if (beginning) {
3612 spliceBeginTimeMills = mBeginTimeMillis;
3613 spliceEndTimeMills = (long) (mBeginTimeMillis
3614 + getDurationMillis() * fractionToRemove);
3615 mBeginTimeMillis = spliceEndTimeMills;
3616 } else {
3617 spliceBeginTimeMills = (long) (mEndTimeMillis
3618 - getDurationMillis() * fractionToRemove);
3619 spliceEndTimeMills = mEndTimeMillis;
3620 mEndTimeMillis = spliceBeginTimeMills;
3621 }
3622
3623 HistoricalOps splice = null;
3624 final int uidCount = getUidCount();
3625 for (int i = 0; i < uidCount; i++) {
3626 final HistoricalUidOps origOps = getUidOpsAt(i);
3627 final HistoricalUidOps spliceOps = origOps.splice(fractionToRemove);
3628 if (spliceOps != null) {
3629 if (splice == null) {
3630 splice = new HistoricalOps(spliceBeginTimeMills, spliceEndTimeMills);
3631 }
3632 if (splice.mHistoricalUidOps == null) {
3633 splice.mHistoricalUidOps = new SparseArray<>();
3634 }
3635 splice.mHistoricalUidOps.put(spliceOps.getUid(), spliceOps);
3636 }
3637 }
3638 return splice;
3639 }
3640
3641 /**
3642 * Merge the passed ops into the current ones. The time interval is a
3643 * union of the current and passed in one and the passed in data is
3644 * folded into the data of this instance.
3645 *
3646 * @hide
3647 */
3648 public void merge(@NonNull HistoricalOps other) {
3649 mBeginTimeMillis = Math.min(mBeginTimeMillis, other.mBeginTimeMillis);
3650 mEndTimeMillis = Math.max(mEndTimeMillis, other.mEndTimeMillis);
3651 final int uidCount = other.getUidCount();
3652 for (int i = 0; i < uidCount; i++) {
3653 final HistoricalUidOps otherUidOps = other.getUidOpsAt(i);
3654 final HistoricalUidOps thisUidOps = getUidOps(otherUidOps.getUid());
3655 if (thisUidOps != null) {
3656 thisUidOps.merge(otherUidOps);
3657 } else {
3658 if (mHistoricalUidOps == null) {
3659 mHistoricalUidOps = new SparseArray<>();
3660 }
3661 mHistoricalUidOps.put(otherUidOps.getUid(), otherUidOps);
3662 }
3663 }
3664 }
3665
3666 /**
3667 * AppPermissionUsage the ops to leave only the data we filter for.
3668 *
3669 * @param uid Uid to filter for or {@link android.os.Process#INCIDENTD_UID} for all.
3670 * @param packageName Package to filter for or null for all.
3671 * @param opNames Ops to filter for or null for all.
3672 * @param beginTimeMillis The begin time to filter for or {@link Long#MIN_VALUE} for all.
3673 * @param endTimeMillis The end time to filter for or {@link Long#MAX_VALUE} for all.
3674 *
3675 * @hide
3676 */
3677 public void filter(int uid, @Nullable String packageName, @Nullable String[] opNames,
3678 long beginTimeMillis, long endTimeMillis) {
3679 final long durationMillis = getDurationMillis();
3680 mBeginTimeMillis = Math.max(mBeginTimeMillis, beginTimeMillis);
3681 mEndTimeMillis = Math.min(mEndTimeMillis, endTimeMillis);
3682 final double scaleFactor = Math.min((double) (endTimeMillis - beginTimeMillis)
3683 / (double) durationMillis, 1);
3684 final int uidCount = getUidCount();
3685 for (int i = uidCount - 1; i >= 0; i--) {
3686 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
3687 if (uid != Process.INVALID_UID && uid != uidOp.getUid()) {
3688 mHistoricalUidOps.removeAt(i);
3689 } else {
3690 uidOp.filter(packageName, opNames, scaleFactor);
3691 }
3692 }
3693 }
3694
3695 /** @hide */
3696 public boolean isEmpty() {
3697 if (getBeginTimeMillis() >= getEndTimeMillis()) {
3698 return true;
3699 }
3700 final int uidCount = getUidCount();
3701 for (int i = uidCount - 1; i >= 0; i--) {
3702 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
3703 if (!uidOp.isEmpty()) {
3704 return false;
3705 }
3706 }
3707 return true;
3708 }
3709
3710 /** @hide */
3711 public long getDurationMillis() {
3712 return mEndTimeMillis - mBeginTimeMillis;
3713 }
3714
3715 /** @hide */
3716 @TestApi
3717 public void increaseAccessCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003718 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003719 getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003720 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003721 }
3722
3723 /** @hide */
3724 @TestApi
3725 public void increaseRejectCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003726 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003727 getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003728 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003729 }
3730
3731 /** @hide */
3732 @TestApi
3733 public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003734 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003735 getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08003736 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08003737 }
3738
3739 /** @hide */
3740 @TestApi
3741 public void offsetBeginAndEndTime(long offsetMillis) {
3742 mBeginTimeMillis += offsetMillis;
3743 mEndTimeMillis += offsetMillis;
3744 }
3745
3746 /** @hide */
3747 public void setBeginAndEndTime(long beginTimeMillis, long endTimeMillis) {
3748 mBeginTimeMillis = beginTimeMillis;
3749 mEndTimeMillis = endTimeMillis;
3750 }
3751
3752 /** @hide */
3753 public void setBeginTime(long beginTimeMillis) {
3754 mBeginTimeMillis = beginTimeMillis;
3755 }
3756
3757 /** @hide */
3758 public void setEndTime(long endTimeMillis) {
3759 mEndTimeMillis = endTimeMillis;
3760 }
3761
3762 /**
3763 * @return The beginning of the interval in milliseconds since
3764 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3765 */
3766 public long getBeginTimeMillis() {
3767 return mBeginTimeMillis;
3768 }
3769
3770 /**
3771 * @return The end of the interval in milliseconds since
3772 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
3773 */
3774 public long getEndTimeMillis() {
3775 return mEndTimeMillis;
3776 }
3777
3778 /**
3779 * Gets number of UIDs with historical ops.
3780 *
3781 * @return The number of UIDs with historical ops.
3782 *
3783 * @see #getUidOpsAt(int)
3784 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003785 public @IntRange(from = 0) int getUidCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003786 if (mHistoricalUidOps == null) {
3787 return 0;
3788 }
3789 return mHistoricalUidOps.size();
3790 }
3791
3792 /**
3793 * Gets the historical UID ops at a given index.
3794 *
3795 * @param index The index.
3796 *
3797 * @return The historical UID ops at the given index.
3798 *
3799 * @see #getUidCount()
3800 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07003801 public @NonNull HistoricalUidOps getUidOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003802 if (mHistoricalUidOps == null) {
3803 throw new IndexOutOfBoundsException();
3804 }
3805 return mHistoricalUidOps.valueAt(index);
3806 }
3807
3808 /**
3809 * Gets the historical UID ops for a given UID.
3810 *
3811 * @param uid The UID.
3812 *
3813 * @return The historical ops for the UID.
3814 */
3815 public @Nullable HistoricalUidOps getUidOps(int uid) {
3816 if (mHistoricalUidOps == null) {
3817 return null;
3818 }
3819 return mHistoricalUidOps.get(uid);
3820 }
3821
Winson4e3b4352019-05-07 16:29:59 -07003822 /** @hide */
3823 public void clearHistory(int uid, @NonNull String packageName) {
3824 HistoricalUidOps historicalUidOps = getOrCreateHistoricalUidOps(uid);
3825 historicalUidOps.clearHistory(packageName);
3826 if (historicalUidOps.isEmpty()) {
3827 mHistoricalUidOps.remove(uid);
3828 }
3829 }
3830
Svet Ganov8455ba22019-01-02 13:05:56 -08003831 @Override
3832 public int describeContents() {
3833 return 0;
3834 }
3835
3836 @Override
3837 public void writeToParcel(Parcel parcel, int flags) {
3838 parcel.writeLong(mBeginTimeMillis);
3839 parcel.writeLong(mEndTimeMillis);
3840 if (mHistoricalUidOps != null) {
3841 final int uidCount = mHistoricalUidOps.size();
3842 parcel.writeInt(uidCount);
3843 for (int i = 0; i < uidCount; i++) {
3844 parcel.writeInt(mHistoricalUidOps.keyAt(i));
3845 }
3846 final List<HistoricalUidOps> opsList = new ArrayList<>(uidCount);
3847 for (int i = 0; i < uidCount; i++) {
3848 opsList.add(mHistoricalUidOps.valueAt(i));
3849 }
3850 parcel.writeParcelable(new ParceledListSlice<>(opsList), flags);
3851 } else {
3852 parcel.writeInt(-1);
3853 }
3854 }
3855
3856 /**
3857 * Accepts a visitor to traverse the ops tree.
3858 *
3859 * @param visitor The visitor.
3860 *
3861 * @hide
3862 */
3863 public void accept(@NonNull HistoricalOpsVisitor visitor) {
3864 visitor.visitHistoricalOps(this);
3865 final int uidCount = getUidCount();
3866 for (int i = 0; i < uidCount; i++) {
3867 getUidOpsAt(i).accept(visitor);
3868 }
3869 }
3870
3871 private @NonNull HistoricalUidOps getOrCreateHistoricalUidOps(int uid) {
3872 if (mHistoricalUidOps == null) {
3873 mHistoricalUidOps = new SparseArray<>();
3874 }
3875 HistoricalUidOps historicalUidOp = mHistoricalUidOps.get(uid);
3876 if (historicalUidOp == null) {
3877 historicalUidOp = new HistoricalUidOps(uid);
3878 mHistoricalUidOps.put(uid, historicalUidOp);
3879 }
3880 return historicalUidOp;
3881 }
3882
3883 /**
3884 * @return Rounded value up at the 0.5 boundary.
3885 *
3886 * @hide
3887 */
3888 public static double round(double value) {
3889 final BigDecimal decimalScale = new BigDecimal(value);
3890 return decimalScale.setScale(0, RoundingMode.HALF_UP).doubleValue();
3891 }
3892
3893 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07003894 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08003895 if (this == obj) {
3896 return true;
3897 }
3898 if (obj == null || getClass() != obj.getClass()) {
3899 return false;
3900 }
3901 final HistoricalOps other = (HistoricalOps) obj;
3902 if (mBeginTimeMillis != other.mBeginTimeMillis) {
3903 return false;
3904 }
3905 if (mEndTimeMillis != other.mEndTimeMillis) {
3906 return false;
3907 }
3908 if (mHistoricalUidOps == null) {
3909 if (other.mHistoricalUidOps != null) {
3910 return false;
3911 }
3912 } else if (!mHistoricalUidOps.equals(other.mHistoricalUidOps)) {
3913 return false;
3914 }
3915 return true;
3916 }
3917
3918 @Override
3919 public int hashCode() {
3920 int result = (int) (mBeginTimeMillis ^ (mBeginTimeMillis >>> 32));
3921 result = 31 * result + mHistoricalUidOps.hashCode();
3922 return result;
3923 }
3924
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07003925 @NonNull
Svet Ganov8455ba22019-01-02 13:05:56 -08003926 @Override
3927 public String toString() {
3928 return getClass().getSimpleName() + "[from:"
3929 + mBeginTimeMillis + " to:" + mEndTimeMillis + "]";
3930 }
3931
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07003932 public static final @android.annotation.NonNull Creator<HistoricalOps> CREATOR = new Creator<HistoricalOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08003933 @Override
3934 public @NonNull HistoricalOps createFromParcel(@NonNull Parcel parcel) {
3935 return new HistoricalOps(parcel);
3936 }
3937
3938 @Override
3939 public @NonNull HistoricalOps[] newArray(int size) {
3940 return new HistoricalOps[size];
3941 }
3942 };
3943 }
3944
3945 /**
3946 * This class represents historical app op state for a UID.
3947 *
3948 * @hide
3949 */
3950 @TestApi
3951 @SystemApi
3952 public static final class HistoricalUidOps implements Parcelable {
3953 private final int mUid;
3954 private @Nullable ArrayMap<String, HistoricalPackageOps> mHistoricalPackageOps;
3955
3956 /** @hide */
3957 public HistoricalUidOps(int uid) {
3958 mUid = uid;
3959 }
3960
3961 private HistoricalUidOps(@NonNull HistoricalUidOps other) {
3962 mUid = other.mUid;
3963 final int opCount = other.getPackageCount();
3964 for (int i = 0; i < opCount; i++) {
3965 final HistoricalPackageOps origOps = other.getPackageOpsAt(i);
3966 final HistoricalPackageOps cloneOps = new HistoricalPackageOps(origOps);
3967 if (mHistoricalPackageOps == null) {
3968 mHistoricalPackageOps = new ArrayMap<>(opCount);
3969 }
3970 mHistoricalPackageOps.put(cloneOps.getPackageName(), cloneOps);
3971 }
3972 }
3973
3974 private HistoricalUidOps(@NonNull Parcel parcel) {
3975 // No arg check since we always read from a trusted source.
3976 mUid = parcel.readInt();
3977 mHistoricalPackageOps = parcel.createTypedArrayMap(HistoricalPackageOps.CREATOR);
3978 }
3979
3980 private @Nullable HistoricalUidOps splice(double fractionToRemove) {
3981 HistoricalUidOps splice = null;
3982 final int packageCount = getPackageCount();
3983 for (int i = 0; i < packageCount; i++) {
3984 final HistoricalPackageOps origOps = getPackageOpsAt(i);
3985 final HistoricalPackageOps spliceOps = origOps.splice(fractionToRemove);
3986 if (spliceOps != null) {
3987 if (splice == null) {
3988 splice = new HistoricalUidOps(mUid);
3989 }
3990 if (splice.mHistoricalPackageOps == null) {
3991 splice.mHistoricalPackageOps = new ArrayMap<>();
3992 }
3993 splice.mHistoricalPackageOps.put(spliceOps.getPackageName(), spliceOps);
3994 }
3995 }
3996 return splice;
3997 }
3998
3999 private void merge(@NonNull HistoricalUidOps other) {
4000 final int packageCount = other.getPackageCount();
4001 for (int i = 0; i < packageCount; i++) {
4002 final HistoricalPackageOps otherPackageOps = other.getPackageOpsAt(i);
4003 final HistoricalPackageOps thisPackageOps = getPackageOps(
4004 otherPackageOps.getPackageName());
4005 if (thisPackageOps != null) {
4006 thisPackageOps.merge(otherPackageOps);
4007 } else {
4008 if (mHistoricalPackageOps == null) {
4009 mHistoricalPackageOps = new ArrayMap<>();
4010 }
4011 mHistoricalPackageOps.put(otherPackageOps.getPackageName(), otherPackageOps);
4012 }
4013 }
4014 }
4015
4016 private void filter(@Nullable String packageName, @Nullable String[] opNames,
4017 double fractionToRemove) {
4018 final int packageCount = getPackageCount();
4019 for (int i = packageCount - 1; i >= 0; i--) {
4020 final HistoricalPackageOps packageOps = getPackageOpsAt(i);
4021 if (packageName != null && !packageName.equals(packageOps.getPackageName())) {
4022 mHistoricalPackageOps.removeAt(i);
4023 } else {
4024 packageOps.filter(opNames, fractionToRemove);
4025 }
4026 }
4027 }
4028
4029 private boolean isEmpty() {
4030 final int packageCount = getPackageCount();
4031 for (int i = packageCount - 1; i >= 0; i--) {
4032 final HistoricalPackageOps packageOps = mHistoricalPackageOps.valueAt(i);
4033 if (!packageOps.isEmpty()) {
4034 return false;
4035 }
4036 }
4037 return true;
4038 }
4039
4040 private void increaseAccessCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004041 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004042 getOrCreateHistoricalPackageOps(packageName).increaseAccessCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08004043 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004044 }
4045
4046 private void increaseRejectCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004047 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004048 getOrCreateHistoricalPackageOps(packageName).increaseRejectCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08004049 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004050 }
4051
4052 private void increaseAccessDuration(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004053 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004054 getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration(
Svet Ganovaf189e32019-02-15 18:45:29 -08004055 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004056 }
4057
4058 /**
4059 * @return The UID for which the data is related.
4060 */
4061 public int getUid() {
4062 return mUid;
4063 }
4064
4065 /**
4066 * Gets number of packages with historical ops.
4067 *
4068 * @return The number of packages with historical ops.
4069 *
4070 * @see #getPackageOpsAt(int)
4071 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004072 public @IntRange(from = 0) int getPackageCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004073 if (mHistoricalPackageOps == null) {
4074 return 0;
4075 }
4076 return mHistoricalPackageOps.size();
4077 }
4078
4079 /**
4080 * Gets the historical package ops at a given index.
4081 *
4082 * @param index The index.
4083 *
4084 * @return The historical package ops at the given index.
4085 *
4086 * @see #getPackageCount()
4087 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004088 public @NonNull HistoricalPackageOps getPackageOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004089 if (mHistoricalPackageOps == null) {
4090 throw new IndexOutOfBoundsException();
4091 }
4092 return mHistoricalPackageOps.valueAt(index);
4093 }
4094
4095 /**
4096 * Gets the historical package ops for a given package.
4097 *
4098 * @param packageName The package.
4099 *
4100 * @return The historical ops for the package.
4101 */
4102 public @Nullable HistoricalPackageOps getPackageOps(@NonNull String packageName) {
4103 if (mHistoricalPackageOps == null) {
4104 return null;
4105 }
4106 return mHistoricalPackageOps.get(packageName);
4107 }
4108
Winson4e3b4352019-05-07 16:29:59 -07004109 private void clearHistory(@NonNull String packageName) {
4110 if (mHistoricalPackageOps != null) {
4111 mHistoricalPackageOps.remove(packageName);
4112 }
4113 }
4114
Svet Ganov8455ba22019-01-02 13:05:56 -08004115 @Override
4116 public int describeContents() {
4117 return 0;
4118 }
4119
4120 @Override
4121 public void writeToParcel(Parcel parcel, int flags) {
4122 parcel.writeInt(mUid);
4123 parcel.writeTypedArrayMap(mHistoricalPackageOps, flags);
4124 }
4125
4126 private void accept(@NonNull HistoricalOpsVisitor visitor) {
4127 visitor.visitHistoricalUidOps(this);
4128 final int packageCount = getPackageCount();
4129 for (int i = 0; i < packageCount; i++) {
4130 getPackageOpsAt(i).accept(visitor);
4131 }
4132 }
4133
4134 private @NonNull HistoricalPackageOps getOrCreateHistoricalPackageOps(
4135 @NonNull String packageName) {
4136 if (mHistoricalPackageOps == null) {
4137 mHistoricalPackageOps = new ArrayMap<>();
4138 }
4139 HistoricalPackageOps historicalPackageOp = mHistoricalPackageOps.get(packageName);
4140 if (historicalPackageOp == null) {
4141 historicalPackageOp = new HistoricalPackageOps(packageName);
4142 mHistoricalPackageOps.put(packageName, historicalPackageOp);
4143 }
4144 return historicalPackageOp;
4145 }
4146
4147
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07004148 public static final @android.annotation.NonNull Creator<HistoricalUidOps> CREATOR = new Creator<HistoricalUidOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004149 @Override
4150 public @NonNull HistoricalUidOps createFromParcel(@NonNull Parcel parcel) {
4151 return new HistoricalUidOps(parcel);
4152 }
4153
4154 @Override
4155 public @NonNull HistoricalUidOps[] newArray(int size) {
4156 return new HistoricalUidOps[size];
4157 }
4158 };
4159
4160 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004161 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004162 if (this == obj) {
4163 return true;
4164 }
4165 if (obj == null || getClass() != obj.getClass()) {
4166 return false;
4167 }
4168 final HistoricalUidOps other = (HistoricalUidOps) obj;
4169 if (mUid != other.mUid) {
4170 return false;
4171 }
4172 if (mHistoricalPackageOps == null) {
4173 if (other.mHistoricalPackageOps != null) {
4174 return false;
4175 }
4176 } else if (!mHistoricalPackageOps.equals(other.mHistoricalPackageOps)) {
4177 return false;
4178 }
4179 return true;
4180 }
4181
4182 @Override
4183 public int hashCode() {
4184 int result = mUid;
4185 result = 31 * result + (mHistoricalPackageOps != null
4186 ? mHistoricalPackageOps.hashCode() : 0);
4187 return result;
4188 }
4189 }
4190
4191 /**
4192 * This class represents historical app op information about a package.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004193 *
4194 * @hide
4195 */
4196 @TestApi
4197 @SystemApi
4198 public static final class HistoricalPackageOps implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004199 private final @NonNull String mPackageName;
Svet Ganov8455ba22019-01-02 13:05:56 -08004200 private @Nullable ArrayMap<String, HistoricalOp> mHistoricalOps;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004201
Svet Ganov8455ba22019-01-02 13:05:56 -08004202 /** @hide */
4203 public HistoricalPackageOps(@NonNull String packageName) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004204 mPackageName = packageName;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004205 }
4206
Svet Ganov8455ba22019-01-02 13:05:56 -08004207 private HistoricalPackageOps(@NonNull HistoricalPackageOps other) {
4208 mPackageName = other.mPackageName;
4209 final int opCount = other.getOpCount();
4210 for (int i = 0; i < opCount; i++) {
4211 final HistoricalOp origOp = other.getOpAt(i);
4212 final HistoricalOp cloneOp = new HistoricalOp(origOp);
4213 if (mHistoricalOps == null) {
4214 mHistoricalOps = new ArrayMap<>(opCount);
4215 }
4216 mHistoricalOps.put(cloneOp.getOpName(), cloneOp);
4217 }
4218 }
4219
4220 private HistoricalPackageOps(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004221 mPackageName = parcel.readString();
Svet Ganov8455ba22019-01-02 13:05:56 -08004222 mHistoricalOps = parcel.createTypedArrayMap(HistoricalOp.CREATOR);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004223 }
4224
Svet Ganov8455ba22019-01-02 13:05:56 -08004225 private @Nullable HistoricalPackageOps splice(double fractionToRemove) {
4226 HistoricalPackageOps splice = null;
4227 final int opCount = getOpCount();
4228 for (int i = 0; i < opCount; i++) {
4229 final HistoricalOp origOps = getOpAt(i);
4230 final HistoricalOp spliceOps = origOps.splice(fractionToRemove);
4231 if (spliceOps != null) {
4232 if (splice == null) {
4233 splice = new HistoricalPackageOps(mPackageName);
4234 }
4235 if (splice.mHistoricalOps == null) {
4236 splice.mHistoricalOps = new ArrayMap<>();
4237 }
4238 splice.mHistoricalOps.put(spliceOps.getOpName(), spliceOps);
4239 }
4240 }
4241 return splice;
4242 }
4243
4244 private void merge(@NonNull HistoricalPackageOps other) {
4245 final int opCount = other.getOpCount();
4246 for (int i = 0; i < opCount; i++) {
4247 final HistoricalOp otherOp = other.getOpAt(i);
4248 final HistoricalOp thisOp = getOp(otherOp.getOpName());
4249 if (thisOp != null) {
4250 thisOp.merge(otherOp);
4251 } else {
4252 if (mHistoricalOps == null) {
4253 mHistoricalOps = new ArrayMap<>();
4254 }
4255 mHistoricalOps.put(otherOp.getOpName(), otherOp);
4256 }
4257 }
4258 }
4259
4260 private void filter(@Nullable String[] opNames, double scaleFactor) {
4261 final int opCount = getOpCount();
4262 for (int i = opCount - 1; i >= 0; i--) {
4263 final HistoricalOp op = mHistoricalOps.valueAt(i);
4264 if (opNames != null && !ArrayUtils.contains(opNames, op.getOpName())) {
4265 mHistoricalOps.removeAt(i);
4266 } else {
4267 op.filter(scaleFactor);
4268 }
4269 }
4270 }
4271
4272 private boolean isEmpty() {
4273 final int opCount = getOpCount();
4274 for (int i = opCount - 1; i >= 0; i--) {
4275 final HistoricalOp op = mHistoricalOps.valueAt(i);
4276 if (!op.isEmpty()) {
4277 return false;
4278 }
4279 }
4280 return true;
4281 }
4282
Svet Ganovaf189e32019-02-15 18:45:29 -08004283 private void increaseAccessCount(int opCode, @UidState int uidState,
4284 @OpFlags int flags, long increment) {
4285 getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004286 }
4287
Svet Ganovaf189e32019-02-15 18:45:29 -08004288 private void increaseRejectCount(int opCode, @UidState int uidState,
4289 @OpFlags int flags, long increment) {
4290 getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004291 }
4292
Svet Ganovaf189e32019-02-15 18:45:29 -08004293 private void increaseAccessDuration(int opCode, @UidState int uidState,
4294 @OpFlags int flags, long increment) {
4295 getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, flags, increment);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004296 }
4297
4298 /**
4299 * Gets the package name which the data represents.
4300 *
4301 * @return The package name which the data represents.
4302 */
4303 public @NonNull String getPackageName() {
4304 return mPackageName;
4305 }
4306
4307 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004308 * Gets number historical app ops.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004309 *
Svet Ganov8455ba22019-01-02 13:05:56 -08004310 * @return The number historical app ops.
Svet Ganov8455ba22019-01-02 13:05:56 -08004311 * @see #getOpAt(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004312 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004313 public @IntRange(from = 0) int getOpCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004314 if (mHistoricalOps == null) {
4315 return 0;
4316 }
4317 return mHistoricalOps.size();
Svet Ganovad0a49b2018-10-29 10:07:08 -07004318 }
4319
4320 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004321 * Gets the historical op at a given index.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004322 *
4323 * @param index The index to lookup.
Svet Ganov8455ba22019-01-02 13:05:56 -08004324 * @return The op at the given index.
Svet Ganov8455ba22019-01-02 13:05:56 -08004325 * @see #getOpCount()
Svet Ganovad0a49b2018-10-29 10:07:08 -07004326 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004327 public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004328 if (mHistoricalOps == null) {
4329 throw new IndexOutOfBoundsException();
4330 }
4331 return mHistoricalOps.valueAt(index);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004332 }
4333
4334 /**
4335 * Gets the historical entry for a given op name.
4336 *
4337 * @param opName The op name.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004338 * @return The historical entry for that op name.
4339 */
Svet Ganov8455ba22019-01-02 13:05:56 -08004340 public @Nullable HistoricalOp getOp(@NonNull String opName) {
4341 if (mHistoricalOps == null) {
4342 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004343 }
Svet Ganov8455ba22019-01-02 13:05:56 -08004344 return mHistoricalOps.get(opName);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004345 }
4346
4347 @Override
4348 public int describeContents() {
4349 return 0;
4350 }
4351
4352 @Override
4353 public void writeToParcel(@NonNull Parcel parcel, int flags) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004354 parcel.writeString(mPackageName);
Svet Ganov8455ba22019-01-02 13:05:56 -08004355 parcel.writeTypedArrayMap(mHistoricalOps, flags);
4356 }
4357
4358 private void accept(@NonNull HistoricalOpsVisitor visitor) {
4359 visitor.visitHistoricalPackageOps(this);
4360 final int opCount = getOpCount();
4361 for (int i = 0; i < opCount; i++) {
4362 getOpAt(i).accept(visitor);
4363 }
4364 }
4365
4366 private @NonNull HistoricalOp getOrCreateHistoricalOp(int opCode) {
4367 if (mHistoricalOps == null) {
4368 mHistoricalOps = new ArrayMap<>();
4369 }
4370 final String opStr = sOpToString[opCode];
4371 HistoricalOp op = mHistoricalOps.get(opStr);
4372 if (op == null) {
4373 op = new HistoricalOp(opCode);
4374 mHistoricalOps.put(opStr, op);
4375 }
4376 return op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004377 }
4378
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07004379 public static final @android.annotation.NonNull Creator<HistoricalPackageOps> CREATOR =
Svet Ganovad0a49b2018-10-29 10:07:08 -07004380 new Creator<HistoricalPackageOps>() {
4381 @Override
4382 public @NonNull HistoricalPackageOps createFromParcel(@NonNull Parcel parcel) {
4383 return new HistoricalPackageOps(parcel);
4384 }
4385
4386 @Override
4387 public @NonNull HistoricalPackageOps[] newArray(int size) {
4388 return new HistoricalPackageOps[size];
4389 }
4390 };
Svet Ganov8455ba22019-01-02 13:05:56 -08004391
4392 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004393 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004394 if (this == obj) {
4395 return true;
4396 }
4397 if (obj == null || getClass() != obj.getClass()) {
4398 return false;
4399 }
4400 final HistoricalPackageOps other = (HistoricalPackageOps) obj;
4401 if (!mPackageName.equals(other.mPackageName)) {
4402 return false;
4403 }
4404 if (mHistoricalOps == null) {
4405 if (other.mHistoricalOps != null) {
4406 return false;
4407 }
4408 } else if (!mHistoricalOps.equals(other.mHistoricalOps)) {
4409 return false;
4410 }
4411 return true;
4412 }
4413
4414 @Override
4415 public int hashCode() {
4416 int result = mPackageName != null ? mPackageName.hashCode() : 0;
4417 result = 31 * result + (mHistoricalOps != null ? mHistoricalOps.hashCode() : 0);
4418 return result;
4419 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07004420 }
4421
4422 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004423 * This class represents historical information about an app op.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004424 *
4425 * @hide
4426 */
4427 @TestApi
4428 @SystemApi
Svet Ganov8455ba22019-01-02 13:05:56 -08004429 public static final class HistoricalOp implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004430 private final int mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08004431 private @Nullable LongSparseLongArray mAccessCount;
4432 private @Nullable LongSparseLongArray mRejectCount;
4433 private @Nullable LongSparseLongArray mAccessDuration;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004434
Svet Ganov8455ba22019-01-02 13:05:56 -08004435 /** @hide */
4436 public HistoricalOp(int op) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004437 mOp = op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004438 }
4439
Svet Ganov8455ba22019-01-02 13:05:56 -08004440 private HistoricalOp(@NonNull HistoricalOp other) {
4441 mOp = other.mOp;
4442 if (other.mAccessCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004443 mAccessCount = other.mAccessCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08004444 }
4445 if (other.mRejectCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004446 mRejectCount = other.mRejectCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08004447 }
4448 if (other.mAccessDuration != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004449 mAccessDuration = other.mAccessDuration.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08004450 }
4451 }
4452
4453 private HistoricalOp(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004454 mOp = parcel.readInt();
Svet Ganovaf189e32019-02-15 18:45:29 -08004455 mAccessCount = readLongSparseLongArrayFromParcel(parcel);
4456 mRejectCount = readLongSparseLongArrayFromParcel(parcel);
4457 mAccessDuration = readLongSparseLongArrayFromParcel(parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004458 }
4459
Svet Ganov8455ba22019-01-02 13:05:56 -08004460 private void filter(double scaleFactor) {
4461 scale(mAccessCount, scaleFactor);
4462 scale(mRejectCount, scaleFactor);
4463 scale(mAccessDuration, scaleFactor);
4464 }
4465
4466 private boolean isEmpty() {
4467 return !hasData(mAccessCount)
4468 && !hasData(mRejectCount)
4469 && !hasData(mAccessDuration);
4470 }
4471
Svet Ganovaf189e32019-02-15 18:45:29 -08004472 private boolean hasData(@NonNull LongSparseLongArray array) {
4473 return (array != null && array.size() > 0);
Svet Ganov8455ba22019-01-02 13:05:56 -08004474 }
4475
4476 private @Nullable HistoricalOp splice(double fractionToRemove) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004477 final HistoricalOp splice = new HistoricalOp(mOp);
4478 splice(mAccessCount, splice::getOrCreateAccessCount, fractionToRemove);
4479 splice(mRejectCount, splice::getOrCreateRejectCount, fractionToRemove);
4480 splice(mAccessDuration, splice::getOrCreateAccessDuration, fractionToRemove);
Svet Ganov8455ba22019-01-02 13:05:56 -08004481 return splice;
4482 }
4483
Svet Ganovaf189e32019-02-15 18:45:29 -08004484 private static void splice(@Nullable LongSparseLongArray sourceContainer,
4485 @NonNull Supplier<LongSparseLongArray> destContainerProvider,
4486 double fractionToRemove) {
4487 if (sourceContainer != null) {
4488 final int size = sourceContainer.size();
4489 for (int i = 0; i < size; i++) {
4490 final long key = sourceContainer.keyAt(i);
4491 final long value = sourceContainer.valueAt(i);
4492 final long removedFraction = Math.round(value * fractionToRemove);
4493 if (removedFraction > 0) {
4494 destContainerProvider.get().put(key, removedFraction);
4495 sourceContainer.put(key, value - removedFraction);
4496 }
4497 }
4498 }
4499 }
4500
Svet Ganov8455ba22019-01-02 13:05:56 -08004501 private void merge(@NonNull HistoricalOp other) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004502 merge(this::getOrCreateAccessCount, other.mAccessCount);
4503 merge(this::getOrCreateRejectCount, other.mRejectCount);
4504 merge(this::getOrCreateAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004505 }
4506
Svet Ganovaf189e32019-02-15 18:45:29 -08004507 private void increaseAccessCount(@UidState int uidState, @OpFlags int flags,
4508 long increment) {
4509 increaseCount(getOrCreateAccessCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004510 }
4511
Svet Ganovaf189e32019-02-15 18:45:29 -08004512 private void increaseRejectCount(@UidState int uidState, @OpFlags int flags,
4513 long increment) {
4514 increaseCount(getOrCreateRejectCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004515 }
4516
Svet Ganovaf189e32019-02-15 18:45:29 -08004517 private void increaseAccessDuration(@UidState int uidState, @OpFlags int flags,
4518 long increment) {
4519 increaseCount(getOrCreateAccessDuration(), uidState, flags, increment);
4520 }
4521
4522 private void increaseCount(@NonNull LongSparseLongArray counts,
4523 @UidState int uidState, @OpFlags int flags, long increment) {
4524 while (flags != 0) {
4525 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4526 flags &= ~flag;
4527 final long key = makeKey(uidState, flag);
4528 counts.put(key, counts.get(key) + increment);
4529 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07004530 }
4531
4532 /**
4533 * Gets the op name.
4534 *
4535 * @return The op name.
4536 */
Svet Ganov8455ba22019-01-02 13:05:56 -08004537 public @NonNull String getOpName() {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004538 return sOpToString[mOp];
4539 }
4540
Svet Ganov8455ba22019-01-02 13:05:56 -08004541 /** @hide */
4542 public int getOpCode() {
4543 return mOp;
4544 }
4545
Svet Ganovad0a49b2018-10-29 10:07:08 -07004546 /**
4547 * Gets the number times the op was accessed (performed) in the foreground.
4548 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004549 * @param flags The flags which are any combination of
4550 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4551 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4552 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4553 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004554 * @return The times the op was accessed in the foreground.
4555 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004556 * @see #getBackgroundAccessCount(int)
4557 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004558 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004559 public long getForegroundAccessCount(@OpFlags int flags) {
4560 return sumForFlagsInStates(mAccessCount, MAX_PRIORITY_UID_STATE,
4561 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004562 }
4563
4564 /**
4565 * Gets the number times the op was accessed (performed) in the background.
4566 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004567 * @param flags The flags which are any combination of
4568 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4569 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4570 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4571 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004572 * @return The times the op was accessed in the background.
4573 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004574 * @see #getForegroundAccessCount(int)
4575 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004576 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004577 public long getBackgroundAccessCount(@OpFlags int flags) {
4578 return sumForFlagsInStates(mAccessCount, resolveLastRestrictedUidState(mOp),
4579 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004580 }
4581
4582 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08004583 * Gets the number times the op was accessed (performed) for a
4584 * range of uid states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004585 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004586 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07004587 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
4588 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
4589 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08004590 * @param toUidState The UID state to which to query.
4591 * @param flags The flags which are any combination of
4592 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4593 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4594 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4595 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004596 *
4597 * @return The times the op was accessed for the given UID state.
4598 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004599 * @see #getForegroundAccessCount(int)
4600 * @see #getBackgroundAccessCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004601 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004602 public long getAccessCount(@UidState int fromUidState, @UidState int toUidState,
4603 @OpFlags int flags) {
4604 return sumForFlagsInStates(mAccessCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004605 }
4606
4607 /**
4608 * Gets the number times the op was rejected in the foreground.
4609 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004610 * @param flags The flags which are any combination of
4611 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4612 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4613 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4614 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004615 * @return The times the op was rejected in the foreground.
4616 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004617 * @see #getBackgroundRejectCount(int)
4618 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004619 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004620 public long getForegroundRejectCount(@OpFlags int flags) {
4621 return sumForFlagsInStates(mRejectCount, MAX_PRIORITY_UID_STATE,
4622 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004623 }
4624
4625 /**
4626 * Gets the number times the op was rejected in the background.
4627 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004628 * @param flags The flags which are any combination of
4629 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4630 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4631 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4632 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004633 * @return The times the op was rejected in the background.
4634 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004635 * @see #getForegroundRejectCount(int)
4636 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004637 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004638 public long getBackgroundRejectCount(@OpFlags int flags) {
4639 return sumForFlagsInStates(mRejectCount, resolveLastRestrictedUidState(mOp),
4640 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004641 }
4642
4643 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08004644 * Gets the number times the op was rejected for a given range of UID states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004645 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004646 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07004647 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
4648 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
4649 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08004650 * @param toUidState The UID state to which to query.
4651 * @param flags The flags which are any combination of
4652 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4653 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4654 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4655 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004656 *
4657 * @return The times the op was rejected for the given UID state.
4658 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004659 * @see #getForegroundRejectCount(int)
4660 * @see #getBackgroundRejectCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004661 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004662 public long getRejectCount(@UidState int fromUidState, @UidState int toUidState,
4663 @OpFlags int flags) {
4664 return sumForFlagsInStates(mRejectCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004665 }
4666
4667 /**
4668 * Gets the total duration the app op was accessed (performed) in the foreground.
Svet Ganov6f672a32019-07-08 16:40:42 -07004669 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004670 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004671 * @param flags The flags which are any combination of
4672 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4673 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4674 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4675 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004676 * @return The total duration the app op was accessed in the foreground.
4677 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004678 * @see #getBackgroundAccessDuration(int)
4679 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004680 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004681 public long getForegroundAccessDuration(@OpFlags int flags) {
4682 return sumForFlagsInStates(mAccessDuration, MAX_PRIORITY_UID_STATE,
4683 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004684 }
4685
4686 /**
4687 * Gets the total duration the app op was accessed (performed) in the background.
Svet Ganov6f672a32019-07-08 16:40:42 -07004688 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004689 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004690 * @param flags The flags which are any combination of
4691 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4692 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4693 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4694 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004695 * @return The total duration the app op was accessed in the background.
4696 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004697 * @see #getForegroundAccessDuration(int)
4698 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004699 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004700 public long getBackgroundAccessDuration(@OpFlags int flags) {
4701 return sumForFlagsInStates(mAccessDuration, resolveLastRestrictedUidState(mOp),
4702 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004703 }
4704
4705 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08004706 * Gets the total duration the app op was accessed (performed) for a given
Svet Ganov6f672a32019-07-08 16:40:42 -07004707 * range of UID states. The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004708 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004709 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07004710 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
4711 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
4712 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08004713 * @param toUidState The UID state from which to query.
4714 * @param flags The flags which are any combination of
4715 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4716 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4717 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4718 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004719 *
4720 * @return The total duration the app op was accessed for the given UID state.
4721 *
Svet Ganovaf189e32019-02-15 18:45:29 -08004722 * @see #getForegroundAccessDuration(int)
4723 * @see #getBackgroundAccessDuration(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004724 */
Svet Ganovaf189e32019-02-15 18:45:29 -08004725 public long getAccessDuration(@UidState int fromUidState, @UidState int toUidState,
4726 @OpFlags int flags) {
4727 return sumForFlagsInStates(mAccessDuration, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004728 }
4729
4730 @Override
4731 public int describeContents() {
4732 return 0;
4733 }
4734
4735 @Override
4736 public void writeToParcel(Parcel parcel, int flags) {
4737 parcel.writeInt(mOp);
Svet Ganovaf189e32019-02-15 18:45:29 -08004738 writeLongSparseLongArrayToParcel(mAccessCount, parcel);
4739 writeLongSparseLongArrayToParcel(mRejectCount, parcel);
4740 writeLongSparseLongArrayToParcel(mAccessDuration, parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004741 }
4742
Svet Ganov8455ba22019-01-02 13:05:56 -08004743 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004744 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004745 if (this == obj) {
4746 return true;
4747 }
4748 if (obj == null || getClass() != obj.getClass()) {
4749 return false;
4750 }
4751 final HistoricalOp other = (HistoricalOp) obj;
4752 if (mOp != other.mOp) {
4753 return false;
4754 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004755 if (!Objects.equals(mAccessCount, other.mAccessCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004756 return false;
4757 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004758 if (!Objects.equals(mRejectCount, other.mRejectCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004759 return false;
4760 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004761 return Objects.equals(mAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004762 }
4763
4764 @Override
4765 public int hashCode() {
4766 int result = mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08004767 result = 31 * result + Objects.hashCode(mAccessCount);
4768 result = 31 * result + Objects.hashCode(mRejectCount);
4769 result = 31 * result + Objects.hashCode(mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08004770 return result;
4771 }
Svet Ganovaf189e32019-02-15 18:45:29 -08004772
4773 private void accept(@NonNull HistoricalOpsVisitor visitor) {
4774 visitor.visitHistoricalOp(this);
4775 }
4776
4777 private @NonNull LongSparseLongArray getOrCreateAccessCount() {
4778 if (mAccessCount == null) {
4779 mAccessCount = new LongSparseLongArray();
4780 }
4781 return mAccessCount;
4782 }
4783
4784 private @NonNull LongSparseLongArray getOrCreateRejectCount() {
4785 if (mRejectCount == null) {
4786 mRejectCount = new LongSparseLongArray();
4787 }
4788 return mRejectCount;
4789 }
4790
4791 private @NonNull LongSparseLongArray getOrCreateAccessDuration() {
4792 if (mAccessDuration == null) {
4793 mAccessDuration = new LongSparseLongArray();
4794 }
4795 return mAccessDuration;
4796 }
4797
4798 /**
4799 * Multiplies the entries in the array with the passed in scale factor and
4800 * rounds the result at up 0.5 boundary.
4801 *
4802 * @param data The data to scale.
4803 * @param scaleFactor The scale factor.
4804 */
4805 private static void scale(@NonNull LongSparseLongArray data, double scaleFactor) {
4806 if (data != null) {
4807 final int size = data.size();
4808 for (int i = 0; i < size; i++) {
4809 data.put(data.keyAt(i), (long) HistoricalOps.round(
4810 (double) data.valueAt(i) * scaleFactor));
4811 }
4812 }
4813 }
4814
4815 /**
4816 * Merges two arrays while lazily acquiring the destination.
4817 *
4818 * @param thisSupplier The destination supplier.
4819 * @param other The array to merge in.
4820 */
4821 private static void merge(@NonNull Supplier<LongSparseLongArray> thisSupplier,
4822 @Nullable LongSparseLongArray other) {
4823 if (other != null) {
4824 final int otherSize = other.size();
4825 for (int i = 0; i < otherSize; i++) {
4826 final LongSparseLongArray that = thisSupplier.get();
4827 final long otherKey = other.keyAt(i);
4828 final long otherValue = other.valueAt(i);
4829 that.put(otherKey, that.get(otherKey) + otherValue);
4830 }
4831 }
4832 }
4833
4834 /** @hide */
4835 public @Nullable LongSparseArray<Object> collectKeys() {
4836 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessCount,
4837 null /*result*/);
4838 result = AppOpsManager.collectKeys(mRejectCount, result);
4839 result = AppOpsManager.collectKeys(mAccessDuration, result);
4840 return result;
4841 }
4842
4843 public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR =
4844 new Creator<HistoricalOp>() {
4845 @Override
4846 public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) {
4847 return new HistoricalOp(source);
4848 }
4849
4850 @Override
4851 public @NonNull HistoricalOp[] newArray(int size) {
4852 return new HistoricalOp[size];
4853 }
4854 };
4855 }
4856
4857 /**
4858 * Computes the sum of the counts for the given flags in between the begin and
4859 * end UID states.
4860 *
4861 * @param counts The data array.
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004862 * @param beginUidState The beginning UID state (inclusive).
4863 * @param endUidState The end UID state (inclusive).
Svet Ganovaf189e32019-02-15 18:45:29 -08004864 * @param flags The UID flags.
4865 * @return The sum.
4866 */
4867 private static long sumForFlagsInStates(@Nullable LongSparseLongArray counts,
4868 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
4869 if (counts == null) {
4870 return 0;
4871 }
4872 long sum = 0;
4873 while (flags != 0) {
4874 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4875 flags &= ~flag;
4876 for (int uidState : UID_STATES) {
4877 if (uidState < beginUidState || uidState > endUidState) {
4878 continue;
4879 }
4880 final long key = makeKey(uidState, flag);
4881 sum += counts.get(key);
4882 }
4883 }
4884 return sum;
4885 }
4886
4887 /**
4888 * Finds the first non-negative value for the given flags in between the begin and
4889 * end UID states.
4890 *
4891 * @param counts The data array.
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004892 * @param beginUidState The beginning UID state (inclusive).
4893 * @param endUidState The end UID state (inclusive).
Svet Ganovaf189e32019-02-15 18:45:29 -08004894 * @param flags The UID flags.
Svet Ganovaf189e32019-02-15 18:45:29 -08004895 * @return The non-negative value or -1.
4896 */
4897 private static long findFirstNonNegativeForFlagsInStates(@Nullable LongSparseLongArray counts,
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004898 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004899 if (counts == null) {
4900 return -1;
4901 }
4902 while (flags != 0) {
4903 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4904 flags &= ~flag;
4905 for (int uidState : UID_STATES) {
4906 if (uidState < beginUidState || uidState > endUidState) {
4907 continue;
4908 }
4909 final long key = makeKey(uidState, flag);
4910 final long value = counts.get(key);
4911 if (value >= 0) {
4912 return value;
4913 }
4914 }
4915 }
4916 return -1;
4917 }
4918
4919 /**
4920 * Finds the first non-null value for the given flags in between the begin and
4921 * end UID states.
4922 *
4923 * @param counts The data array.
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004924 * @param beginUidState The beginning UID state (inclusive).
4925 * @param endUidState The end UID state (inclusive).
Svet Ganovaf189e32019-02-15 18:45:29 -08004926 * @param flags The UID flags.
Svet Ganovaf189e32019-02-15 18:45:29 -08004927 * @return The non-negative value or -1.
4928 */
4929 private static @Nullable String findFirstNonNullForFlagsInStates(
Philip P. Moltmann4052d362019-09-19 14:52:38 -07004930 @Nullable LongSparseArray<String> counts, @UidState int beginUidState,
4931 @UidState int endUidState, @OpFlags int flags) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004932 if (counts == null) {
4933 return null;
4934 }
4935 while (flags != 0) {
4936 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
4937 flags &= ~flag;
4938 for (int uidState : UID_STATES) {
4939 if (uidState < beginUidState || uidState > endUidState) {
4940 continue;
4941 }
4942 final long key = makeKey(uidState, flag);
4943 final String value = counts.get(key);
4944 if (value != null) {
4945 return value;
4946 }
4947 }
4948 }
4949 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004950 }
4951
4952 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004953 * Callback for notification of changes to operation state.
4954 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004955 public interface OnOpChangedListener {
4956 public void onOpChanged(String op, String packageName);
4957 }
4958
4959 /**
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004960 * Callback for notification of changes to operation active state.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004961 */
4962 public interface OnOpActiveChangedListener {
4963 /**
4964 * Called when the active state of an app op changes.
4965 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06004966 * @param op The operation that changed.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004967 * @param packageName The package performing the operation.
4968 * @param active Whether the operation became active or inactive.
4969 */
Jeff Sharkey7095ab92019-08-20 16:50:28 -06004970 void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName,
4971 boolean active);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08004972 }
4973
4974 /**
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004975 * Callback for notification of an op being noted.
4976 *
4977 * @hide
4978 */
4979 public interface OnOpNotedListener {
4980 /**
4981 * Called when an op was noted.
4982 *
4983 * @param code The op code.
4984 * @param uid The UID performing the operation.
4985 * @param packageName The package performing the operation.
4986 * @param result The result of the note.
4987 */
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05004988 void onOpNoted(int code, int uid, String packageName, int result);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08004989 }
4990
4991 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07004992 * Callback for notification of changes to operation state.
4993 * This allows you to see the raw op codes instead of strings.
4994 * @hide
4995 */
4996 public static class OnOpChangedInternalListener implements OnOpChangedListener {
4997 public void onOpChanged(String op, String packageName) { }
4998 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -08004999 }
5000
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005001 /**
5002 * Callback for notification of changes to operation state.
5003 * This allows you to see the raw op codes instead of strings.
5004 * @hide
5005 */
5006 public interface OnOpActiveChangedInternalListener extends OnOpActiveChangedListener {
5007 default void onOpActiveChanged(String op, int uid, String packageName, boolean active) { }
5008 default void onOpActiveChanged(int op, int uid, String packageName, boolean active) { }
5009 }
5010
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005011 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005012 mContext = context;
5013 mService = service;
5014 }
5015
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005016 /**
5017 * Retrieve current operation state for all applications.
5018 *
Winson6a864b52019-05-10 10:34:14 -07005019 * The mode of the ops returned are set for the package but may not reflect their effective
5020 * state due to UID policy or because it's controlled by a different master op.
5021 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005022 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005023 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005024 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005025 * @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 -07005026 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005027 */
Svet Ganov8455ba22019-01-02 13:05:56 -08005028 @SystemApi
5029 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
5030 public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops) {
5031 final int opCount = ops.length;
5032 final int[] opCodes = new int[opCount];
5033 for (int i = 0; i < opCount; i++) {
5034 opCodes[i] = sOpStrToOp.get(ops[i]);
5035 }
5036 final List<AppOpsManager.PackageOps> result = getPackagesForOps(opCodes);
5037 return (result != null) ? result : Collections.emptyList();
5038 }
5039
5040 /**
5041 * Retrieve current operation state for all applications.
5042 *
Winson6a864b52019-05-10 10:34:14 -07005043 * The mode of the ops returned are set for the package but may not reflect their effective
5044 * state due to UID policy or because it's controlled by a different master op.
5045 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005046 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005047 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005048 *
Svet Ganov8455ba22019-01-02 13:05:56 -08005049 * @param ops The set of operations you are interested in, or null if you want all of them.
5050 * @hide
5051 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07005052 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005053 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08005054 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
5055 try {
5056 return mService.getPackagesForOps(ops);
5057 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005058 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08005059 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08005060 }
5061
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005062 /**
5063 * Retrieve current operation state for one application.
5064 *
Winson6a864b52019-05-10 10:34:14 -07005065 * The mode of the ops returned are set for the package but may not reflect their effective
5066 * state due to UID policy or because it's controlled by a different master op.
5067 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005068 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005069 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005070 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005071 * @param uid The uid of the application of interest.
5072 * @param packageName The name of the application of interest.
5073 * @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 -08005074 *
5075 * @deprecated The int op codes are not stable and you should use the string based op
5076 * names which are stable and namespaced. Use
5077 * {@link #getOpsForPackage(int, String, String...)})}.
5078 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005079 * @hide
Suprabh Shukla169bed72019-05-13 13:54:58 -07005080 * @removed
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005081 */
Svet Ganov8455ba22019-01-02 13:05:56 -08005082 @Deprecated
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07005083 @SystemApi
Dianne Hackbornc216a262018-04-26 13:46:22 -07005084 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Dianne Hackborn62878492019-03-11 15:57:07 -07005085 public @NonNull List<PackageOps> getOpsForPackage(int uid, @NonNull String packageName,
5086 @Nullable int[] ops) {
Dianne Hackborn72e39832013-01-18 18:36:09 -08005087 try {
5088 return mService.getOpsForPackage(uid, packageName, ops);
5089 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005090 throw e.rethrowFromSystemServer();
Dianne Hackborn72e39832013-01-18 18:36:09 -08005091 }
Dianne Hackborn72e39832013-01-18 18:36:09 -08005092 }
5093
Svet Ganovae0e03a2016-02-25 18:22:10 -08005094 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005095 * Retrieve current operation state for one application. The UID and the
5096 * package must match.
5097 *
Winson6a864b52019-05-10 10:34:14 -07005098 * The mode of the ops returned are set for the package but may not reflect their effective
5099 * state due to UID policy or because it's controlled by a different master op.
5100 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005101 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005102 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005103 *
Svet Ganov8455ba22019-01-02 13:05:56 -08005104 * @param uid The uid of the application of interest.
5105 * @param packageName The name of the application of interest.
5106 * @param ops The set of operations you are interested in, or null if you want all of them.
5107 *
5108 * @hide
5109 */
5110 @SystemApi
5111 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
5112 public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid,
5113 @NonNull String packageName, @Nullable String... ops) {
5114 int[] opCodes = null;
5115 if (ops != null) {
5116 opCodes = new int[ops.length];
5117 for (int i = 0; i < ops.length; i++) {
5118 opCodes[i] = strOpToOp(ops[i]);
5119 }
5120 }
5121 try {
5122 final List<PackageOps> result = mService.getOpsForPackage(uid, packageName, opCodes);
5123 if (result == null) {
5124 return Collections.emptyList();
5125 }
5126 return result;
5127 } catch (RemoteException e) {
5128 throw e.rethrowFromSystemServer();
5129 }
5130 }
5131
5132 /**
5133 * Retrieve historical app op stats for a period.
5134 *
Svet Ganov23c88db2019-01-22 20:38:11 -08005135 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08005136 * @param executor Executor on which to run the callback. If <code>null</code>
5137 * the callback is executed on the default executor running on the main thread.
5138 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005139 *
5140 * @throws IllegalArgumentException If any of the argument contracts is violated.
5141 *
5142 * @hide
5143 */
5144 @TestApi
5145 @SystemApi
5146 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov23c88db2019-01-22 20:38:11 -08005147 public void getHistoricalOps(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08005148 @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) {
5149 Preconditions.checkNotNull(executor, "executor cannot be null");
5150 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07005151 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08005152 mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08005153 request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags,
Svet Ganov8455ba22019-01-02 13:05:56 -08005154 new RemoteCallback((result) -> {
5155 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
5156 final long identity = Binder.clearCallingIdentity();
5157 try {
5158 executor.execute(() -> callback.accept(ops));
5159 } finally {
5160 Binder.restoreCallingIdentity(identity);
5161 }
5162 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07005163 } catch (RemoteException e) {
5164 throw e.rethrowFromSystemServer();
5165 }
5166 }
5167
5168 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005169 * Retrieve historical app op stats for a period.
Svet Ganov8455ba22019-01-02 13:05:56 -08005170 * <p>
5171 * This method queries only the on disk state and the returned ops are raw,
5172 * which is their times are relative to the history start as opposed to the
5173 * epoch start.
5174 *
Svet Ganov23c88db2019-01-22 20:38:11 -08005175 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08005176 * @param executor Executor on which to run the callback. If <code>null</code>
5177 * the callback is executed on the default executor running on the main thread.
5178 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005179 *
5180 * @throws IllegalArgumentException If any of the argument contracts is violated.
5181 *
5182 * @hide
5183 */
5184 @TestApi
Svet Ganov8e5bf962019-03-19 23:59:03 -07005185 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
Svet Ganov23c88db2019-01-22 20:38:11 -08005186 public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08005187 @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) {
5188 Preconditions.checkNotNull(executor, "executor cannot be null");
5189 Preconditions.checkNotNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07005190 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08005191 mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName,
5192 request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis,
Svet Ganovaf189e32019-02-15 18:45:29 -08005193 request.mFlags, new RemoteCallback((result) -> {
Svet Ganov23c88db2019-01-22 20:38:11 -08005194 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
Svet Ganov8455ba22019-01-02 13:05:56 -08005195 final long identity = Binder.clearCallingIdentity();
5196 try {
5197 executor.execute(() -> callback.accept(ops));
5198 } finally {
5199 Binder.restoreCallingIdentity(identity);
5200 }
5201 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07005202 } catch (RemoteException e) {
5203 throw e.rethrowFromSystemServer();
5204 }
5205 }
5206
5207 /**
Svet Ganov8e5bf962019-03-19 23:59:03 -07005208 * Reloads the non historical state to allow testing the read/write path.
5209 *
5210 * @hide
5211 */
5212 @TestApi
5213 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5214 public void reloadNonHistoricalState() {
5215 try {
5216 mService.reloadNonHistoricalState();
5217 } catch (RemoteException e) {
5218 throw e.rethrowFromSystemServer();
5219 }
5220 }
5221
5222 /**
Svet Ganovae0e03a2016-02-25 18:22:10 -08005223 * Sets given app op in the specified mode for app ops in the UID.
5224 * This applies to all apps currently in the UID or installed in
5225 * this UID in the future.
5226 *
5227 * @param code The app op.
5228 * @param uid The UID for which to set the app.
5229 * @param mode The app op mode to set.
5230 * @hide
5231 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005232 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005233 public void setUidMode(int code, int uid, @Mode int mode) {
Svet Ganov2af57082015-07-30 08:44:20 -07005234 try {
5235 mService.setUidMode(code, uid, mode);
5236 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005237 throw e.rethrowFromSystemServer();
Svet Ganov2af57082015-07-30 08:44:20 -07005238 }
5239 }
5240
Svet Ganovae0e03a2016-02-25 18:22:10 -08005241 /**
5242 * Sets given app op in the specified mode for app ops in the UID.
5243 * This applies to all apps currently in the UID or installed in
5244 * this UID in the future.
5245 *
5246 * @param appOp The app op.
5247 * @param uid The UID for which to set the app.
5248 * @param mode The app op mode to set.
5249 * @hide
5250 */
5251 @SystemApi
Eugene Susla93519852018-06-13 16:44:31 -07005252 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005253 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005254 public void setUidMode(String appOp, int uid, @Mode int mode) {
Svet Ganovae0e03a2016-02-25 18:22:10 -08005255 try {
5256 mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
5257 } catch (RemoteException e) {
5258 throw e.rethrowFromSystemServer();
5259 }
5260 }
5261
Svet Ganov2af57082015-07-30 08:44:20 -07005262 /** @hide */
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005263 public void setUserRestriction(int code, boolean restricted, IBinder token) {
Ruben Brunk29931bc2016-03-11 00:24:26 -08005264 setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
5265 }
5266
5267 /** @hide */
5268 public void setUserRestriction(int code, boolean restricted, IBinder token,
5269 String[] exceptionPackages) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07005270 setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
5271 }
5272
5273 /** @hide */
5274 public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
5275 String[] exceptionPackages, int userId) {
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005276 try {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07005277 mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005278 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005279 throw e.rethrowFromSystemServer();
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005280 }
5281 }
5282
5283 /** @hide */
Peter Visontayb97fbc82017-12-21 16:23:55 +00005284 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005285 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005286 public void setMode(int code, int uid, String packageName, @Mode int mode) {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08005287 try {
5288 mService.setMode(code, uid, packageName, mode);
5289 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005290 throw e.rethrowFromSystemServer();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08005291 }
5292 }
5293
John Spurlock1af30c72014-03-10 08:33:35 -04005294 /**
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005295 * Change the operating mode for the given op in the given app package. You must pass
5296 * in both the uid and name of the application whose mode is being modified; if these
5297 * do not match, the modification will not be applied.
5298 *
5299 * @param op The operation to modify. One of the OPSTR_* constants.
5300 * @param uid The user id of the application whose mode will be changed.
5301 * @param packageName The name of the application package name whose mode will
5302 * be changed.
5303 * @hide
5304 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07005305 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005306 @SystemApi
5307 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005308 public void setMode(String op, int uid, String packageName, @Mode int mode) {
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005309 try {
5310 mService.setMode(strOpToOp(op), uid, packageName, mode);
5311 } catch (RemoteException e) {
5312 throw e.rethrowFromSystemServer();
5313 }
5314 }
5315
5316 /**
John Spurlock1af30c72014-03-10 08:33:35 -04005317 * Set a non-persisted restriction on an audio operation at a stream-level.
5318 * Restrictions are temporary additional constraints imposed on top of the persisted rules
5319 * defined by {@link #setMode}.
5320 *
5321 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04005322 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04005323 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
5324 * @param exceptionPackages Optional list of packages to exclude from the restriction.
5325 * @hide
5326 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005327 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005328 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -08005329 public void setRestriction(int code, @AttributeUsage int usage, @Mode int mode,
John Spurlock7b414672014-07-18 13:02:39 -04005330 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04005331 try {
5332 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04005333 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04005334 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005335 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04005336 }
5337 }
5338
Dianne Hackborn607b4142013-08-02 18:10:10 -07005339 /** @hide */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005340 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005341 @UnsupportedAppUsage
Dianne Hackborn607b4142013-08-02 18:10:10 -07005342 public void resetAllModes() {
5343 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -07005344 mService.resetAllModes(mContext.getUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07005345 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005346 throw e.rethrowFromSystemServer();
Dianne Hackborn607b4142013-08-02 18:10:10 -07005347 }
5348 }
5349
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005350 /**
Svet Ganovfbf01f72015-04-28 18:39:06 -07005351 * Gets the app op name associated with a given permission.
5352 * The app op name is one of the public constants defined
5353 * in this class such as {@link #OPSTR_COARSE_LOCATION}.
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07005354 * This API is intended to be used for mapping runtime
5355 * permissions to the corresponding app op.
Svet Ganovfbf01f72015-04-28 18:39:06 -07005356 *
5357 * @param permission The permission.
5358 * @return The app op associated with the permission or null.
Svet Ganovfbf01f72015-04-28 18:39:06 -07005359 */
Svet Ganovfbf01f72015-04-28 18:39:06 -07005360 public static String permissionToOp(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08005361 final Integer opCode = sPermToOp.get(permission);
Svet Ganovb9d71a62015-04-30 10:38:13 -07005362 if (opCode == null) {
5363 return null;
5364 }
5365 return sOpToString[opCode];
Svet Ganovfbf01f72015-04-28 18:39:06 -07005366 }
5367
5368 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005369 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005370 * You can watch op changes only for your UID.
5371 *
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07005372 * @param op The operation to monitor, one of OPSTR_*.
5373 * @param packageName The name of the application to monitor.
5374 * @param callback Where to report changes.
5375 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005376 public void startWatchingMode(@NonNull String op, @Nullable String packageName,
5377 @NonNull final OnOpChangedListener callback) {
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07005378 startWatchingMode(strOpToOp(op), packageName, callback);
5379 }
5380
5381 /**
5382 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005383 * You can watch op changes only for your UID.
5384 *
5385 * @param op The operation to monitor, one of OPSTR_*.
5386 * @param packageName The name of the application to monitor.
5387 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
5388 * @param callback Where to report changes.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005389 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005390 public void startWatchingMode(@NonNull String op, @Nullable String packageName, int flags,
5391 @NonNull final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005392 startWatchingMode(strOpToOp(op), packageName, flags, callback);
5393 }
5394
5395 /**
5396 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005397 *
5398 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08005399 * you can watch changes only for your UID.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005400 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005401 * @param op The operation to monitor, one of OP_*.
5402 * @param packageName The name of the application to monitor.
5403 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07005404 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005405 */
Jeff Sharkeybf6b2132018-02-27 11:16:37 -07005406 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005407 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005408 startWatchingMode(op, packageName, 0, callback);
5409 }
5410
5411 /**
5412 * Monitor for changes to the operating mode for the given op in the given app package.
5413 *
5414 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
5415 * you can watch changes only for your UID.
5416 *
5417 * @param op The operation to monitor, one of OP_*.
5418 * @param packageName The name of the application to monitor.
5419 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
5420 * @param callback Where to report changes.
5421 * @hide
5422 */
5423 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
5424 public void startWatchingMode(int op, String packageName, int flags,
5425 final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08005426 synchronized (mModeWatchers) {
5427 IAppOpsCallback cb = mModeWatchers.get(callback);
5428 if (cb == null) {
5429 cb = new IAppOpsCallback.Stub() {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07005430 public void opChanged(int op, int uid, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005431 if (callback instanceof OnOpChangedInternalListener) {
5432 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
5433 }
5434 if (sOpToString[op] != null) {
5435 callback.onOpChanged(sOpToString[op], packageName);
5436 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08005437 }
5438 };
5439 mModeWatchers.put(callback, cb);
5440 }
5441 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005442 mService.startWatchingModeWithFlags(op, packageName, flags, cb);
Dianne Hackbornc2293022013-02-06 23:14:49 -08005443 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005444 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08005445 }
5446 }
5447 }
5448
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005449 /**
5450 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
5451 * monitoring associated with this callback will be removed.
5452 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005453 public void stopWatchingMode(@NonNull OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08005454 synchronized (mModeWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005455 IAppOpsCallback cb = mModeWatchers.remove(callback);
Dianne Hackbornc2293022013-02-06 23:14:49 -08005456 if (cb != null) {
5457 try {
5458 mService.stopWatchingMode(cb);
5459 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005460 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08005461 }
5462 }
5463 }
5464 }
5465
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005466 /** {@hide} */
5467 @Deprecated
5468 public void startWatchingActive(@NonNull int[] ops,
5469 @NonNull OnOpActiveChangedListener callback) {
5470 final String[] strOps = new String[ops.length];
5471 for (int i = 0; i < ops.length; i++) {
5472 strOps[i] = opToPublicName(ops[i]);
5473 }
5474 startWatchingActive(strOps, mContext.getMainExecutor(), callback);
5475 }
5476
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005477 /**
5478 * Start watching for changes to the active state of app ops. An app op may be
5479 * long running and it has a clear start and stop delimiters. If an op is being
5480 * started or stopped by any package you will get a callback. To change the
5481 * watched ops for a registered callback you need to unregister and register it
5482 * again.
5483 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005484 * <p> If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08005485 * you can watch changes only for your UID.
5486 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005487 * @param ops The operations to watch.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005488 * @param callback Where to report changes.
5489 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005490 * @see #isOperationActive
5491 * @see #stopWatchingActive
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005492 * @see #startOp(int, int, String, boolean, String, String)
5493 * @see #finishOp(int, int, String, String)
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005494 */
Svet Ganovf7b47252018-02-26 11:11:27 -08005495 // TODO: Uncomment below annotation once b/73559440 is fixed
5496 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005497 public void startWatchingActive(@NonNull String[] ops,
5498 @CallbackExecutor @NonNull Executor executor,
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005499 @NonNull OnOpActiveChangedListener callback) {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005500 Objects.requireNonNull(ops);
5501 Objects.requireNonNull(executor);
5502 Objects.requireNonNull(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005503 IAppOpsActiveCallback cb;
5504 synchronized (mActiveWatchers) {
5505 cb = mActiveWatchers.get(callback);
5506 if (cb != null) {
5507 return;
5508 }
5509 cb = new IAppOpsActiveCallback.Stub() {
5510 @Override
5511 public void opActiveChanged(int op, int uid, String packageName, boolean active) {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005512 executor.execute(() -> {
5513 if (callback instanceof OnOpActiveChangedInternalListener) {
5514 ((OnOpActiveChangedInternalListener) callback).onOpActiveChanged(op,
5515 uid, packageName, active);
5516 }
5517 if (sOpToString[op] != null) {
5518 callback.onOpActiveChanged(sOpToString[op], uid, packageName, active);
5519 }
5520 });
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005521 }
5522 };
5523 mActiveWatchers.put(callback, cb);
5524 }
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005525 final int[] rawOps = new int[ops.length];
5526 for (int i = 0; i < ops.length; i++) {
5527 rawOps[i] = strOpToOp(ops[i]);
5528 }
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005529 try {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005530 mService.startWatchingActive(rawOps, cb);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005531 } catch (RemoteException e) {
5532 throw e.rethrowFromSystemServer();
5533 }
5534 }
5535
5536 /**
5537 * Stop watching for changes to the active state of an app op. An app op may be
5538 * long running and it has a clear start and stop delimiters. Unregistering a
5539 * non-registered callback has no effect.
5540 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005541 * @see #isOperationActive
5542 * @see #startWatchingActive
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005543 * @see #startOp(int, int, String, boolean, String, String)
5544 * @see #finishOp(int, int, String, String)
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005545 */
5546 public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
5547 synchronized (mActiveWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005548 final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005549 if (cb != null) {
5550 try {
5551 mService.stopWatchingActive(cb);
5552 } catch (RemoteException e) {
5553 throw e.rethrowFromSystemServer();
5554 }
5555 }
5556 }
5557 }
5558
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005559 /**
5560 * Start watching for noted app ops. An app op may be immediate or long running.
5561 * Immediate ops are noted while long running ones are started and stopped. This
5562 * method allows registering a listener to be notified when an app op is noted. If
5563 * an op is being noted by any package you will get a callback. To change the
5564 * watched ops for a registered callback you need to unregister and register it again.
5565 *
5566 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
5567 * you can watch changes only for your UID.
5568 *
5569 * @param ops The ops to watch.
5570 * @param callback Where to report changes.
5571 *
5572 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
5573 * @see #stopWatchingNoted(OnOpNotedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005574 * @see #noteOp(String, int, String, String, String)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005575 *
5576 * @hide
5577 */
5578 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05005579 public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005580 IAppOpsNotedCallback cb;
5581 synchronized (mNotedWatchers) {
5582 cb = mNotedWatchers.get(callback);
5583 if (cb != null) {
5584 return;
5585 }
5586 cb = new IAppOpsNotedCallback.Stub() {
5587 @Override
5588 public void opNoted(int op, int uid, String packageName, int mode) {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05005589 callback.onOpNoted(op, uid, packageName, mode);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005590 }
5591 };
5592 mNotedWatchers.put(callback, cb);
5593 }
5594 try {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05005595 mService.startWatchingNoted(ops, cb);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005596 } catch (RemoteException e) {
5597 throw e.rethrowFromSystemServer();
5598 }
5599 }
5600
5601 /**
5602 * Stop watching for noted app ops. An app op may be immediate or long running.
5603 * Unregistering a non-registered callback has no effect.
5604 *
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05005605 * @see #startWatchingNoted(int[], OnOpNotedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005606 * @see #noteOp(String, int, String, String, String)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005607 *
5608 * @hide
5609 */
5610 public void stopWatchingNoted(@NonNull OnOpNotedListener callback) {
5611 synchronized (mNotedWatchers) {
5612 final IAppOpsNotedCallback cb = mNotedWatchers.get(callback);
5613 if (cb != null) {
5614 try {
5615 mService.stopWatchingNoted(cb);
5616 } catch (RemoteException e) {
5617 throw e.rethrowFromSystemServer();
5618 }
5619 }
5620 }
5621 }
5622
Dianne Hackborn95d78532013-09-11 09:51:14 -07005623 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
5624 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
5625 }
5626
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07005627 /**
5628 * {@hide}
5629 */
Philip P. Moltmann33115152018-04-11 13:39:36 -07005630 @TestApi
Dianne Hackborn62878492019-03-11 15:57:07 -07005631 public static int strOpToOp(@NonNull String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005632 Integer val = sOpStrToOp.get(op);
5633 if (val == null) {
5634 throw new IllegalArgumentException("Unknown operation string: " + op);
5635 }
5636 return val;
5637 }
5638
5639 /**
5640 * Do a quick check for whether an application might be able to perform an operation.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005641 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005642 * String, String)} or {@link #startOp(String, int, String, String, String)} for your actual
5643 * security checks, which also ensure that the given uid and package name are consistent. This
5644 * function can just be used for a quick check to see if an operation has been disabled for the
5645 * application, as an early reject of some work. This does not modify the time stamp or other
5646 * data about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07005647 *
5648 * <p>Important things this will not do (which you need to ultimate use
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005649 * {@link #noteOp(String, int, String, String, String)} or
5650 * {@link #startOp(String, int, String, String, String)} to cover):</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -07005651 * <ul>
5652 * <li>Verifying the uid and package are consistent, so callers can't spoof
5653 * their identity.</li>
5654 * <li>Taking into account the current foreground/background state of the
5655 * app; apps whose mode varies by this state will always be reported
5656 * as {@link #MODE_ALLOWED}.</li>
5657 * </ul>
5658 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005659 * @param op The operation to check. One of the OPSTR_* constants.
5660 * @param uid The user id of the application attempting to perform the operation.
5661 * @param packageName The name of the application attempting to perform the operation.
5662 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5663 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5664 * causing the app to crash).
5665 * @throws SecurityException If the app has been configured to crash on this op.
5666 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005667 public int unsafeCheckOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07005668 return checkOp(strOpToOp(op), uid, packageName);
5669 }
5670
5671 /**
5672 * @deprecated Renamed to {@link #unsafeCheckOp(String, int, String)}.
5673 */
5674 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07005675 public int checkOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005676 return checkOp(strOpToOp(op), uid, packageName);
5677 }
5678
5679 /**
John Spurlock925b85e2014-03-10 16:52:11 -04005680 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005681 * returns {@link #MODE_ERRORED}.
5682 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005683 public int unsafeCheckOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07005684 return checkOpNoThrow(strOpToOp(op), uid, packageName);
5685 }
5686
5687 /**
5688 * @deprecated Renamed to {@link #unsafeCheckOpNoThrow(String, int, String)}.
5689 */
5690 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07005691 public int checkOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005692 return checkOpNoThrow(strOpToOp(op), uid, packageName);
5693 }
5694
5695 /**
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005696 * Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op.
5697 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005698 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005699 public int unsafeCheckOpRaw(@NonNull String op, int uid, @NonNull String packageName) {
Svet Ganovaf189e32019-02-15 18:45:29 -08005700 try {
5701 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
5702 } catch (RemoteException e) {
5703 throw e.rethrowFromSystemServer();
5704 }
5705 }
5706
5707 /**
5708 * Like {@link #unsafeCheckOpNoThrow(String, int, String)} but returns the <em>raw</em>
5709 * mode associated with the op. Does not throw a security exception, does not translate
5710 * {@link #MODE_FOREGROUND}.
5711 */
5712 public int unsafeCheckOpRawNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005713 try {
Svet Ganov9d528a12018-12-19 17:23:11 -08005714 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005715 } catch (RemoteException e) {
5716 throw e.rethrowFromSystemServer();
5717 }
5718 }
5719
5720 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005721 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005722 */
5723 @Deprecated
5724 public int noteOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005725 return noteOp(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005726 }
5727
5728 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005729 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005730 *
5731 * @hide
5732 */
5733 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005734 + "#noteOp(java.lang.String, int, java.lang.String, java.lang.String, "
5735 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005736 @Deprecated
5737 public int noteOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005738 return noteOp(op, Process.myUid(), mContext.getOpPackageName(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005739 }
5740
5741 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005742 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005743 *
5744 * @hide
5745 */
5746 @Deprecated
5747 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005748 + "#noteOp(java.lang.String, int, java.lang.String, java.lang.String, "
5749 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005750 public int noteOp(int op, int uid, @Nullable String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005751 return noteOp(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005752 }
5753
5754 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005755 * Make note of an application performing an operation. Note that you must pass
5756 * in both the uid and name of the application to be checked; this function will verify
5757 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5758 * succeeds, the last execution time of the operation for this app will be updated to
5759 * the current time.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005760 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005761 * @param op The operation to note. One of the OPSTR_* constants.
5762 * @param uid The user id of the application attempting to perform the operation.
5763 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005764 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005765 * @param message A message describing the reason the op was noted
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005766 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005767 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5768 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5769 * causing the app to crash).
5770 *
5771 * @throws SecurityException If the app has been configured to crash on this op.
Svet Ganov99b60432015-06-27 13:15:22 -07005772 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005773 public int noteOp(@NonNull String op, int uid, @Nullable String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005774 @Nullable String featureId, @Nullable String message) {
5775 return noteOp(strOpToOp(op), uid, packageName, featureId, message);
Svet Ganov99b60432015-06-27 13:15:22 -07005776 }
5777
5778 /**
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005779 * Make note of an application performing an operation. Note that you must pass
5780 * in both the uid and name of the application to be checked; this function will verify
5781 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
5782 * succeeds, the last execution time of the operation for this app will be updated to
5783 * the current time.
5784 *
5785 * @param op The operation to note. One of the OP_* constants.
5786 * @param uid The user id of the application attempting to perform the operation.
5787 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005788 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005789 * @param message A message describing the reason the op was noted
5790 *
5791 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5792 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5793 * causing the app to crash).
5794 *
5795 * @throws SecurityException If the app has been configured to crash on this op.
5796 *
5797 * @hide
5798 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005799 public int noteOp(int op, int uid, @Nullable String packageName, @Nullable String featureId,
5800 @Nullable String message) {
5801 final int mode = noteOpNoThrow(op, uid, packageName, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005802 if (mode == MODE_ERRORED) {
5803 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
5804 }
5805 return mode;
5806 }
5807
5808 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005809 * @deprecated Use {@link #noteOpNoThrow(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005810 */
5811 @Deprecated
5812 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005813 return noteOpNoThrow(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005814 }
5815
5816 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005817 * @deprecated Use {@link #noteOpNoThrow(int, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005818 *
5819 * @hide
5820 */
5821 @Deprecated
5822 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005823 + "#noteOpNoThrow(java.lang.String, int, java.lang.String, java.lang.String, "
5824 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005825 public int noteOpNoThrow(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005826 return noteOpNoThrow(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005827 }
5828
5829 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005830 * Like {@link #noteOp(String, int, String, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005831 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
5832 *
5833 * @param op The operation to note. One of the OPSTR_* constants.
5834 * @param uid The user id of the application attempting to perform the operation.
5835 * @param packageName The name of the application attempting to perform the operation.
5836 * @param message A message describing the reason the op was noted
5837 *
5838 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5839 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5840 * causing the app to crash).
5841 */
5842 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005843 @Nullable String feature, @Nullable String message) {
5844 return noteOpNoThrow(strOpToOp(op), uid, packageName, feature, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005845 }
5846
5847 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005848 * Like {@link #noteOp(String, int, String, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005849 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
5850 *
5851 * @param op The operation to note. One of the OP_* constants.
5852 * @param uid The user id of the application attempting to perform the operation.
5853 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005854 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005855 * @param message A message describing the reason the op was noted
5856 *
5857 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
5858 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
5859 * causing the app to crash).
5860 *
5861 * @hide
5862 */
5863 public int noteOpNoThrow(int op, int uid, @Nullable String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005864 @Nullable String featureId, @Nullable String message) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005865 try {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005866 int mode = mService.noteOperation(op, uid, packageName, featureId);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005867 if (mode == MODE_ALLOWED) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005868 markAppOpNoted(uid, packageName, op, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005869 }
5870
5871 return mode;
5872 } catch (RemoteException e) {
5873 throw e.rethrowFromSystemServer();
5874 }
5875 }
5876
5877 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005878 * @deprecated Use {@link #noteProxyOp(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005879 */
5880 @Deprecated
5881 public int noteProxyOp(@NonNull String op, @NonNull String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005882 return noteProxyOp(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005883 }
5884
5885 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005886 * @deprecated Use {@link #noteProxyOp(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005887 *
5888 * @hide
5889 */
5890 @Deprecated
5891 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005892 + "#noteProxyOp(java.lang.String, java.lang.String, int, java.lang.String, "
5893 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005894 public int noteProxyOp(int op, @Nullable String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005895 return noteProxyOp(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005896 }
5897
5898 /**
5899 * Make note of an application performing an operation on behalf of another application when
5900 * handling an IPC. This function will verify that the calling uid and proxied package name
5901 * match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution
5902 * time of the operation for the proxied app and your app will be updated to the current time.
5903 *
5904 * @param op The operation to note. One of the OP_* constants.
5905 * @param proxiedPackageName The name of the application calling into the proxy application.
5906 * @param proxiedUid The uid of the proxied application
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005907 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
5908 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005909 * @param message A message describing the reason the op was noted
5910 *
5911 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED}
5912 * if it is not allowed and should be silently ignored (without causing the app to crash).
5913 *
5914 * @throws SecurityException If the proxy or proxied app has been configured to crash on this
5915 * op.
5916 *
5917 * @hide
5918 */
5919 public int noteProxyOp(int op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005920 @Nullable String proxiedFeatureId, @Nullable String message) {
5921 int mode = noteProxyOpNoThrow(op, proxiedPackageName, proxiedUid, proxiedFeatureId,
5922 message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005923 if (mode == MODE_ERRORED) {
5924 throw new SecurityException("Proxy package " + mContext.getOpPackageName()
5925 + " from uid " + Process.myUid() + " or calling package " + proxiedPackageName
5926 + " from uid " + proxiedUid + " not allowed to perform " + sOpNames[op]);
5927 }
5928 return mode;
5929 }
5930
5931 /**
5932 * Make note of an application performing an operation on behalf of another application when
5933 * handling an IPC. This function will verify that the calling uid and proxied package name
5934 * match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution
5935 * time of the operation for the proxied app and your app will be updated to the current time.
5936 *
5937 * @param op The operation to note. One of the OPSTR_* constants.
5938 * @param proxiedPackageName The name of the application calling into the proxy application.
5939 * @param proxiedUid The uid of the proxied application
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005940 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
5941 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005942 * @param message A message describing the reason the op was noted
5943 *
5944 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED}
5945 * if it is not allowed and should be silently ignored (without causing the app to crash).
5946 *
5947 * @throws SecurityException If the proxy or proxied app has been configured to crash on this
5948 * op.
5949 */
5950 public int noteProxyOp(@NonNull String op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005951 @Nullable String proxiedFeatureId, @Nullable String message) {
5952 return noteProxyOp(strOpToOp(op), proxiedPackageName, proxiedUid, proxiedFeatureId,
5953 message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005954 }
5955
5956 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005957 * @deprecated Use {@link #noteProxyOpNoThrow(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005958 */
5959 @Deprecated
5960 public int noteProxyOpNoThrow(@NonNull String op, @NonNull String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005961 return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005962 }
5963
5964 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005965 * @deprecated Use {@link #noteProxyOpNoThrow(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005966 */
5967 @Deprecated
5968 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
5969 int proxiedUid) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005970 return noteProxyOpNoThrow(op, proxiedPackageName, proxiedUid, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005971 }
5972
5973 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005974 * Like {@link #noteProxyOp(String, String, int, String, String)} but instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005975 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005976 *
5977 * <p>This API requires package with the {@code proxiedPackageName} to belong to
5978 * {@code proxiedUid}.
5979 *
5980 * @param op The op to note
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005981 * @param proxiedPackageName The package to note the op for
5982 * @param proxiedUid The uid the package belongs to
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005983 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
5984 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005985 * @param message A message describing the reason the op was noted
5986 */
5987 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005988 int proxiedUid, @Nullable String proxiedFeatureId, @Nullable String message) {
5989 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid,
5990 proxiedFeatureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005991 }
5992
5993 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005994 * Like {@link #noteProxyOp(int, String, int, String, String)} but instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005995 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
5996 *
5997 * @param op The op to note
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08005998 * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
5999 * noted for the "android" package
6000 * @param proxiedUid The uid the package belongs to
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006001 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
6002 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006003 * @param message A message describing the reason the op was noted
6004 *
6005 * @hide
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08006006 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006007 public int noteProxyOpNoThrow(int op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006008 @Nullable String proxiedFeatureId, @Nullable String message) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006009 int myUid = Process.myUid();
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08006010
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006011 try {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006012 int mode = mService.noteProxyOperation(op, proxiedUid, proxiedPackageName,
6013 proxiedFeatureId, myUid, mContext.getOpPackageName(),
6014 mContext.getFeatureId());
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006015 if (mode == MODE_ALLOWED
6016 // Only collect app-ops when the proxy is trusted
6017 && mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1, myUid)
6018 == PackageManager.PERMISSION_GRANTED) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006019 markAppOpNoted(proxiedUid, proxiedPackageName, op, proxiedFeatureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006020 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006021
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006022 return mode;
6023 } catch (RemoteException e) {
6024 throw e.rethrowFromSystemServer();
6025 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006026 }
6027
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006028 /**
6029 * Do a quick check for whether an application might be able to perform an operation.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006030 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006031 * String, String)} or {@link #startOp(int, int, String, boolean, String, String)} for your
6032 * actual security checks, which also ensure that the given uid and package name are consistent.
6033 * This function can just be used for a quick check to see if an operation has been disabled for
6034 * the application, as an early reject of some work. This does not modify the time stamp or
6035 * other data about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07006036 *
6037 * <p>Important things this will not do (which you need to ultimate use
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006038 * {@link #noteOp(String, int, String, String, String)} or
6039 * {@link #startOp(int, int, String, boolean, String, String)} to cover):</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -07006040 * <ul>
6041 * <li>Verifying the uid and package are consistent, so callers can't spoof
6042 * their identity.</li>
6043 * <li>Taking into account the current foreground/background state of the
6044 * app; apps whose mode varies by this state will always be reported
6045 * as {@link #MODE_ALLOWED}.</li>
6046 * </ul>
6047 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006048 * @param op The operation to check. One of the OP_* constants.
6049 * @param uid The user id of the application attempting to perform the operation.
6050 * @param packageName The name of the application attempting to perform the operation.
6051 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6052 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6053 * causing the app to crash).
6054 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006055 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006056 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01006057 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08006058 public int checkOp(int op, int uid, String packageName) {
6059 try {
6060 int mode = mService.checkOperation(op, uid, packageName);
6061 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07006062 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08006063 }
6064 return mode;
6065 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006066 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08006067 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08006068 }
6069
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006070 /**
6071 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
6072 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006073 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006074 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01006075 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08006076 public int checkOpNoThrow(int op, int uid, String packageName) {
6077 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006078 int mode = mService.checkOperation(op, uid, packageName);
6079 return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08006080 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006081 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08006082 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08006083 }
6084
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006085 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07006086 * Do a quick check to validate if a package name belongs to a UID.
6087 *
6088 * @throws SecurityException if the package name doesn't belong to the given
6089 * UID, or if ownership cannot be verified.
6090 */
Dianne Hackborn62878492019-03-11 15:57:07 -07006091 public void checkPackage(int uid, @NonNull String packageName) {
Jeff Sharkey911d7f42013-09-05 18:11:45 -07006092 try {
6093 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
6094 throw new SecurityException(
6095 "Package " + packageName + " does not belong to " + uid);
6096 }
6097 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006098 throw e.rethrowFromSystemServer();
Jeff Sharkey911d7f42013-09-05 18:11:45 -07006099 }
6100 }
6101
6102 /**
John Spurlock1af30c72014-03-10 08:33:35 -04006103 * Like {@link #checkOp} but at a stream-level for audio operations.
6104 * @hide
6105 */
6106 public int checkAudioOp(int op, int stream, int uid, String packageName) {
6107 try {
6108 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
6109 if (mode == MODE_ERRORED) {
6110 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
6111 }
6112 return mode;
6113 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006114 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04006115 }
John Spurlock1af30c72014-03-10 08:33:35 -04006116 }
6117
6118 /**
6119 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
6120 * returns {@link #MODE_ERRORED}.
6121 * @hide
6122 */
6123 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
6124 try {
6125 return mService.checkAudioOperation(op, stream, uid, packageName);
6126 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006127 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04006128 }
John Spurlock1af30c72014-03-10 08:33:35 -04006129 }
6130
Dianne Hackborne98f5db2013-07-17 17:23:25 -07006131 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01006132 @UnsupportedAppUsage
Dianne Hackborne98f5db2013-07-17 17:23:25 -07006133 public static IBinder getToken(IAppOpsService service) {
6134 synchronized (AppOpsManager.class) {
6135 if (sToken != null) {
6136 return sToken;
6137 }
6138 try {
6139 sToken = service.getToken(new Binder());
6140 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006141 throw e.rethrowFromSystemServer();
Dianne Hackborne98f5db2013-07-17 17:23:25 -07006142 }
6143 return sToken;
6144 }
6145 }
6146
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006147
6148 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006149 * @deprecated use {@link #startOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006150 */
6151 @Deprecated
6152 public int startOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006153 return startOp(op, uid, packageName, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08006154 }
6155
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006156 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006157 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Svet Ganovf7b47252018-02-26 11:11:27 -08006158 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006159 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006160 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006161 @Deprecated
6162 public int startOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006163 return startOp(op, Process.myUid(), mContext.getOpPackageName(), false, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08006164 }
6165
6166 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006167 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006168 *
6169 * @hide
6170 */
6171 @Deprecated
6172 public int startOp(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006173 return startOp(op, uid, packageName, false, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006174 }
6175
6176 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006177 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006178 *
6179 * @hide
6180 */
6181 @Deprecated
6182 public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006183 return startOp(op, uid, packageName, startIfModeDefault, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006184 }
6185
6186 /**
6187 * Report that an application has started executing a long-running operation.
6188 *
6189 * @param op The operation to start. One of the OPSTR_* constants.
6190 * @param uid The user id of the application attempting to perform the operation.
6191 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006192 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006193 * @param message Description why op was started
6194 *
6195 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6196 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6197 * causing the app to crash).
6198 *
6199 * @throws SecurityException If the app has been configured to crash on this op or
6200 * the package is not in the passed in UID.
6201 */
6202 public int startOp(@NonNull String op, int uid, @Nullable String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006203 @NonNull String featureId, @Nullable String message) {
6204 return startOp(strOpToOp(op), uid, packageName, false, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006205 }
6206
6207 /**
6208 * Report that an application has started executing a long-running operation.
Svet Ganovf7b47252018-02-26 11:11:27 -08006209 *
6210 * @param op The operation to start. One of the OP_* constants.
6211 * @param uid The user id of the application attempting to perform the operation.
6212 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006213 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006214 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
6215 * @param message Description why op was started
6216 *
Svet Ganovf7b47252018-02-26 11:11:27 -08006217 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6218 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6219 * causing the app to crash).
Svet Ganovf7b47252018-02-26 11:11:27 -08006220 *
6221 * @throws SecurityException If the app has been configured to crash on this op or
6222 * the package is not in the passed in UID.
6223 *
6224 * @hide
6225 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006226 public int startOp(int op, int uid, @Nullable String packageName, boolean startIfModeDefault,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006227 @NonNull String featureId, @Nullable String message) {
6228 final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault, featureId,
6229 message);
Svet Ganovf7b47252018-02-26 11:11:27 -08006230 if (mode == MODE_ERRORED) {
6231 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006232 }
Svet Ganovf7b47252018-02-26 11:11:27 -08006233 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006234 }
6235
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006236 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006237 * @deprecated use {@link #startOpNoThrow(String, int, String, String, String)} instead
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006238 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006239 @Deprecated
6240 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006241 return startOpNoThrow(op, uid, packageName, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08006242 }
6243
6244 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006245 * @deprecated Use {@link #startOpNoThrow(int, int, String, boolean, String, String} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006246 *
6247 * @hide
6248 */
6249 @Deprecated
6250 public int startOpNoThrow(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006251 return startOpNoThrow(op, uid, packageName, false, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006252 }
6253
6254 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006255 * @deprecated Use {@link #startOpNoThrow(int, int, String, boolean, String, String} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006256 *
6257 * @hide
6258 */
6259 @Deprecated
6260 public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006261 return startOpNoThrow(op, uid, packageName, startIfModeDefault, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006262 }
6263
6264 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006265 * Like {@link #startOp(String, int, String, String, String)} but instead of throwing a
Svet Ganovf7b47252018-02-26 11:11:27 -08006266 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
6267 *
6268 * @param op The operation to start. One of the OP_* constants.
6269 * @param uid The user id of the application attempting to perform the operation.
6270 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006271 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006272 * @param message Description why op was started
6273 *
Svet Ganovf7b47252018-02-26 11:11:27 -08006274 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6275 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6276 * causing the app to crash).
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006277 */
6278 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006279 @NonNull String featureId, @Nullable String message) {
6280 return startOpNoThrow(strOpToOp(op), uid, packageName, false, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006281 }
6282
6283 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006284 * Like {@link #startOp(int, int, String, boolean, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006285 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
6286 *
6287 * @param op The operation to start. One of the OP_* constants.
6288 * @param uid The user id of the application attempting to perform the operation.
6289 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006290 * @param featureId The feature in the app or {@code null} for default feature
Svet Ganovf7b47252018-02-26 11:11:27 -08006291 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006292 * @param message Description why op was started
6293 *
6294 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6295 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6296 * causing the app to crash).
Svet Ganovf7b47252018-02-26 11:11:27 -08006297 *
6298 * @hide
6299 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006300 public int startOpNoThrow(int op, int uid, @NonNull String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006301 boolean startIfModeDefault, @Nullable String featureId, @Nullable String message) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006302 try {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006303 int mode = mService.startOperation(getToken(mService), op, uid, packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006304 featureId, startIfModeDefault);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006305 if (mode == MODE_ALLOWED) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006306 markAppOpNoted(uid, packageName, op, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006307 }
6308
6309 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006310 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006311 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006312 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006313 }
6314
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006315 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006316 * @deprecated Use {@link #finishOp(String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006317 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006318 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006319 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006320 @Deprecated
6321 public void finishOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006322 finishOp(op, Process.myUid(), mContext.getOpPackageName(), null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006323 }
6324
6325 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006326 * @deprecated Use {@link #finishOp(String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006327 */
6328 public void finishOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006329 finishOp(strOpToOp(op), uid, packageName, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006330 }
6331
6332 /**
6333 * Report that an application is no longer performing an operation that had previously
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006334 * been started with {@link #startOp(String, int, String, String, String)}. There is no
6335 * validation of input or result; the parameters supplied here must be the exact same ones
6336 * previously passed in when starting the operation.
6337 */
6338 public void finishOp(@NonNull String op, int uid, @NonNull String packageName,
6339 @Nullable String featureId) {
6340 finishOp(strOpToOp(op), uid, packageName, featureId);
6341 }
6342
6343 /**
6344 * @deprecated Use {@link #finishOp(int, int, String, String)} instead
6345 *
6346 * @hide
6347 */
6348 public void finishOp(int op, int uid, @NonNull String packageName) {
6349 finishOp(op, uid, packageName, null);
6350 }
6351
6352 /**
6353 * Report that an application is no longer performing an operation that had previously
6354 * been started with {@link #startOp(int, int, String, boolean, String, String)}. There is no
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006355 * validation of input or result; the parameters supplied here must be the exact same ones
6356 * previously passed in when starting the operation.
6357 *
6358 * @hide
6359 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006360 public void finishOp(int op, int uid, @NonNull String packageName,
6361 @Nullable String featureId) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006362 try {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006363 mService.finishOperation(getToken(mService), op, uid, packageName, featureId);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006364 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006365 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006366 }
6367 }
6368
Svet Ganovf7b47252018-02-26 11:11:27 -08006369 /**
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006370 * Checks whether the given op for a package is active.
6371 * <p>
6372 * If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS}
6373 * permission you can query only for your UID.
6374 *
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006375 * @see #finishOp(String, int, String, String)
6376 * @see #startOp(String, int, String, String, String)
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006377 */
6378 public boolean isOpActive(@NonNull String op, int uid, @NonNull String packageName) {
6379 return isOperationActive(strOpToOp(op), uid, packageName);
6380 }
6381
6382 /**
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006383 * Start collection of noted appops on this thread.
6384 *
6385 * <p>Called at the beginning of a two way binder transaction.
6386 *
6387 * @see #finishNotedAppOpsCollection()
6388 *
6389 * @hide
6390 */
6391 public static void startNotedAppOpsCollection(int callingUid) {
6392 sBinderThreadCallingUid.set(callingUid);
6393 }
6394
6395 /**
6396 * State of a temporarily paused noted app-ops collection.
6397 *
6398 * @see #pauseNotedAppOpsCollection()
6399 *
6400 * @hide
6401 */
6402 public static class PausedNotedAppOpsCollection {
6403 final int mUid;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006404 final @Nullable ArrayMap<String, long[]> mCollectedNotedAppOps;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006405
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006406 PausedNotedAppOpsCollection(int uid, @Nullable ArrayMap<String,
6407 long[]> collectedNotedAppOps) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006408 mUid = uid;
6409 mCollectedNotedAppOps = collectedNotedAppOps;
6410 }
6411 }
6412
6413 /**
6414 * Temporarily suspend collection of noted app-ops when binder-thread calls into the other
6415 * process. During such a call there might be call-backs coming back on the same thread which
6416 * should not be accounted to the current collection.
6417 *
6418 * @return a state needed to resume the collection
6419 *
6420 * @hide
6421 */
6422 public static @Nullable PausedNotedAppOpsCollection pauseNotedAppOpsCollection() {
6423 Integer previousUid = sBinderThreadCallingUid.get();
6424 if (previousUid != null) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006425 ArrayMap<String, long[]> previousCollectedNotedAppOps =
6426 sAppOpsNotedInThisBinderTransaction.get();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006427
6428 sBinderThreadCallingUid.remove();
6429 sAppOpsNotedInThisBinderTransaction.remove();
6430
6431 return new PausedNotedAppOpsCollection(previousUid, previousCollectedNotedAppOps);
6432 }
6433
6434 return null;
6435 }
6436
6437 /**
6438 * Resume a collection paused via {@link #pauseNotedAppOpsCollection}.
6439 *
6440 * @param prevCollection The state of the previous collection
6441 *
6442 * @hide
6443 */
6444 public static void resumeNotedAppOpsCollection(
6445 @Nullable PausedNotedAppOpsCollection prevCollection) {
6446 if (prevCollection != null) {
6447 sBinderThreadCallingUid.set(prevCollection.mUid);
6448
6449 if (prevCollection.mCollectedNotedAppOps != null) {
6450 sAppOpsNotedInThisBinderTransaction.set(prevCollection.mCollectedNotedAppOps);
6451 }
6452 }
6453 }
6454
6455 /**
6456 * Finish collection of noted appops on this thread.
6457 *
6458 * <p>Called at the end of a two way binder transaction.
6459 *
6460 * @see #startNotedAppOpsCollection(int)
6461 *
6462 * @hide
6463 */
6464 public static void finishNotedAppOpsCollection() {
6465 sBinderThreadCallingUid.remove();
6466 sAppOpsNotedInThisBinderTransaction.remove();
6467 }
6468
6469 /**
6470 * Mark an app-op as noted
6471 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006472 private void markAppOpNoted(int uid, @Nullable String packageName, int code,
6473 @Nullable String featureId, @Nullable String message) {
6474 if (packageName == null) {
6475 packageName = "android";
6476 }
6477
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006478 // check it the appops needs to be collected and cache result
6479 if (sAppOpsToNote[code] == SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED) {
6480 boolean shouldCollectNotes;
6481 try {
6482 shouldCollectNotes = mService.shouldCollectNotes(code);
6483 } catch (RemoteException e) {
6484 return;
6485 }
6486
6487 if (shouldCollectNotes) {
6488 sAppOpsToNote[code] = SHOULD_COLLECT_NOTE_OP;
6489 } else {
6490 sAppOpsToNote[code] = SHOULD_NOT_COLLECT_NOTE_OP;
6491 }
6492 }
6493
6494 if (sAppOpsToNote[code] != SHOULD_COLLECT_NOTE_OP) {
6495 return;
6496 }
6497
6498 Integer binderUid = sBinderThreadCallingUid.get();
6499
6500 synchronized (sLock) {
6501 if (sNotedAppOpsCollector != null && uid == Process.myUid() && packageName.equals(
6502 ActivityThread.currentOpPackageName())) {
6503 // This app is noting an app-op for itself. Deliver immediately.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006504 sNotedAppOpsCollector.onSelfNoted(new SyncNotedAppOp(code, featureId));
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006505
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006506 return;
6507 }
6508 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006509
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006510 if (binderUid != null && binderUid == uid) {
6511 // If this is inside of a two-way binder call: Delivered to caller via
6512 // {@link #prefixParcelWithAppOpsIfNeeded}
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006513 // We are inside of a two-way binder call. Delivered to caller via
6514 // {@link #prefixParcelWithAppOpsIfNeeded}
6515 ArrayMap<String, long[]> appOpsNoted = sAppOpsNotedInThisBinderTransaction.get();
6516 if (appOpsNoted == null) {
6517 appOpsNoted = new ArrayMap<>(1);
6518 sAppOpsNotedInThisBinderTransaction.set(appOpsNoted);
6519 }
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006520
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006521 long[] appOpsNotedForFeature = appOpsNoted.get(featureId);
6522 if (appOpsNotedForFeature == null) {
6523 appOpsNotedForFeature = new long[2];
6524 appOpsNoted.put(featureId, appOpsNotedForFeature);
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006525 }
6526
6527 if (code < 64) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006528 appOpsNotedForFeature[0] |= 1L << code;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006529 } else {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006530 appOpsNotedForFeature[1] |= 1L << (code - 64);
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006531 }
6532 } else {
6533 // Cannot deliver the note synchronous: Hence send it to the system server to
6534 // notify the noted process.
6535 if (message == null) {
6536 // Default message is a stack trace
6537 message = getFormattedStackTrace();
6538 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006539
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006540 long token = Binder.clearCallingIdentity();
6541 try {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006542 mService.noteAsyncOp(mContext.getOpPackageName(), uid, packageName, code,
6543 featureId, message);
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07006544 } catch (RemoteException e) {
6545 e.rethrowFromSystemServer();
6546 } finally {
6547 Binder.restoreCallingIdentity(token);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006548 }
6549 }
6550 }
6551
6552 /**
6553 * Append app-ops noted in the current two-way binder transaction to parcel.
6554 *
6555 * <p>This is called on the callee side of a two way binder transaction just before the
6556 * transaction returns.
6557 *
6558 * @param p the parcel to append the noted app-ops to
6559 *
6560 * @hide
6561 */
6562 public static void prefixParcelWithAppOpsIfNeeded(@NonNull Parcel p) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006563 ArrayMap<String, long[]> notedAppOps = sAppOpsNotedInThisBinderTransaction.get();
6564 if (notedAppOps == null) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006565 return;
6566 }
6567
6568 p.writeInt(Parcel.EX_HAS_NOTED_APPOPS_REPLY_HEADER);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006569
6570 int numFeatureWithNotesAppOps = notedAppOps.size();
6571 p.writeInt(numFeatureWithNotesAppOps);
6572
6573 for (int i = 0; i < numFeatureWithNotesAppOps; i++) {
6574 p.writeString(notedAppOps.keyAt(i));
6575 p.writeLong(notedAppOps.valueAt(i)[0]);
6576 p.writeLong(notedAppOps.valueAt(i)[1]);
6577 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006578 }
6579
6580 /**
6581 * Read app-ops noted during a two-way binder transaction from parcel.
6582 *
6583 * <p>This is called on the calling side of a two way binder transaction just after the
6584 * transaction returns.
6585 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006586 * @param p The parcel to read from
6587 *
6588 * @hide
6589 */
6590 public static void readAndLogNotedAppops(@NonNull Parcel p) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006591 int numFeaturesWithNotedAppOps = p.readInt();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006592
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006593 for (int i = 0; i < numFeaturesWithNotedAppOps; i++) {
6594 String featureId = p.readString();
6595 long[] rawNotedAppOps = new long[2];
6596 rawNotedAppOps[0] = p.readLong();
6597 rawNotedAppOps[1] = p.readLong();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006598
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006599 if (rawNotedAppOps[0] != 0 || rawNotedAppOps[1] != 0) {
6600 BitSet notedAppOps = BitSet.valueOf(rawNotedAppOps);
6601
6602 synchronized (sLock) {
6603 for (int code = notedAppOps.nextSetBit(0); code != -1;
6604 code = notedAppOps.nextSetBit(code + 1)) {
6605 if (sNotedAppOpsCollector != null) {
6606 sNotedAppOpsCollector.onNoted(new SyncNotedAppOp(code, featureId));
6607 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006608 }
6609 }
6610 }
6611 }
6612 }
6613
6614 /**
6615 * Register a new {@link AppOpsCollector}.
6616 *
6617 * <p>There can only ever be one collector per process. If there currently is a collector
6618 * registered, it will be unregistered.
6619 *
6620 * <p><b>Only appops related to dangerous permissions are collected.</b>
6621 *
6622 * @param collector The collector to set or {@code null} to unregister.
6623 */
6624 public void setNotedAppOpsCollector(@Nullable AppOpsCollector collector) {
6625 synchronized (sLock) {
6626 if (sNotedAppOpsCollector != null) {
6627 try {
6628 mService.stopWatchingAsyncNoted(mContext.getPackageName(),
6629 sNotedAppOpsCollector.mAsyncCb);
6630 } catch (RemoteException e) {
6631 e.rethrowFromSystemServer();
6632 }
6633 }
6634
6635 sNotedAppOpsCollector = collector;
6636
6637 if (sNotedAppOpsCollector != null) {
6638 List<AsyncNotedAppOp> missedAsyncOps = null;
6639 try {
6640 mService.startWatchingAsyncNoted(mContext.getPackageName(),
6641 sNotedAppOpsCollector.mAsyncCb);
6642 missedAsyncOps = mService.extractAsyncOps(mContext.getPackageName());
6643 } catch (RemoteException e) {
6644 e.rethrowFromSystemServer();
6645 }
6646
6647 if (missedAsyncOps != null) {
6648 int numMissedAsyncOps = missedAsyncOps.size();
6649 for (int i = 0; i < numMissedAsyncOps; i++) {
6650 final AsyncNotedAppOp asyncNotedAppOp = missedAsyncOps.get(i);
6651 if (sNotedAppOpsCollector != null) {
6652 sNotedAppOpsCollector.getAsyncNotedExecutor().execute(
6653 () -> sNotedAppOpsCollector.onAsyncNoted(
6654 asyncNotedAppOp));
6655 }
6656 }
6657 }
6658 }
6659 }
6660 }
6661
6662 /**
6663 * @return {@code true} iff the process currently is currently collecting noted appops.
6664 *
6665 * @see #setNotedAppOpsCollector(AppOpsCollector)
6666 *
6667 * @hide
6668 */
6669 public static boolean isCollectingNotedAppOps() {
6670 synchronized (sLock) {
6671 return sNotedAppOpsCollector != null;
6672 }
6673 }
6674
6675 /**
6676 * Callback an app can choose to {@link #setNotedAppOpsCollector register} to monitor it's noted
6677 * appops.
6678 *
6679 * <p><b>Only appops related to dangerous permissions are collected.</b>
6680 */
6681 public abstract static class AppOpsCollector {
6682 /** Callback registered with the system. This will receive the async notes ops */
6683 private final IAppOpsAsyncNotedCallback mAsyncCb = new IAppOpsAsyncNotedCallback.Stub() {
6684 @Override
6685 public void opNoted(AsyncNotedAppOp op) {
6686 Preconditions.checkNotNull(op);
6687
6688 getAsyncNotedExecutor().execute(() -> onAsyncNoted(op));
6689 }
6690 };
6691
6692 /**
6693 * @return The executor for the system to use when calling {@link #onAsyncNoted}.
6694 */
6695 public @NonNull Executor getAsyncNotedExecutor() {
6696 return new HandlerExecutor(Handler.getMain());
6697 }
6698
6699 /**
6700 * Called when an app-op was noted for this package inside of a two-way binder-call.
6701 *
6702 * <p>Called on the calling thread just after executing the binder-call. This allows
6703 * the app to e.g. collect stack traces to figure out where the access came from.
6704 *
6705 * @param op The op noted
6706 */
6707 public abstract void onNoted(@NonNull SyncNotedAppOp op);
6708
6709 /**
6710 * Called when this app noted an app-op for its own package.
6711 *
6712 * <p>Called on the thread the noted the op. This allows the app to e.g. collect stack
6713 * traces to figure out where the access came from.
6714 *
6715 * @param op The op noted
6716 */
6717 public abstract void onSelfNoted(@NonNull SyncNotedAppOp op);
6718
6719 /**
6720 * Called when an app-op was noted for this package which cannot be delivered via the other
6721 * two mechanisms.
6722 *
6723 * <p>Called as soon as possible after the app-op was noted, but the delivery delay is not
6724 * guaranteed. Due to how async calls work in Android this might even be delivered slightly
6725 * before the private data is delivered to the app.
6726 *
6727 * <p>If the app is not running or no {@link AppOpsCollector} is registered a small amount
6728 * of noted app-ops are buffered and then delivered as soon as a collector is registered.
6729 *
6730 * @param asyncOp The op noted
6731 */
6732 public abstract void onAsyncNoted(@NonNull AsyncNotedAppOp asyncOp);
6733 }
6734
6735 /**
6736 * Generate a stack trace used for noted app-ops logging.
6737 *
6738 * <p>This strips away the first few and last few stack trace elements as they are not
6739 * interesting to apps.
6740 */
6741 private static String getFormattedStackTrace() {
6742 StackTraceElement[] trace = new Exception().getStackTrace();
6743
6744 int firstInteresting = 0;
6745 for (int i = 0; i < trace.length; i++) {
6746 if (trace[i].getClassName().startsWith(AppOpsManager.class.getName())
6747 || trace[i].getClassName().startsWith(Parcel.class.getName())
6748 || trace[i].getClassName().contains("$Stub$Proxy")
6749 || trace[i].getClassName().startsWith(DatabaseUtils.class.getName())
6750 || trace[i].getClassName().startsWith("android.content.ContentProviderProxy")
6751 || trace[i].getClassName().startsWith(ContentResolver.class.getName())) {
6752 firstInteresting = i;
6753 } else {
6754 break;
6755 }
6756 }
6757
6758 int lastInteresting = trace.length - 1;
6759 for (int i = trace.length - 1; i >= 0; i--) {
6760 if (trace[i].getClassName().startsWith(HandlerThread.class.getName())
6761 || trace[i].getClassName().startsWith(Handler.class.getName())
6762 || trace[i].getClassName().startsWith(Looper.class.getName())
6763 || trace[i].getClassName().startsWith(Binder.class.getName())
6764 || trace[i].getClassName().startsWith(RuntimeInit.class.getName())
6765 || trace[i].getClassName().startsWith(ZygoteInit.class.getName())
6766 || trace[i].getClassName().startsWith(ActivityThread.class.getName())
6767 || trace[i].getClassName().startsWith(Method.class.getName())
6768 || trace[i].getClassName().startsWith("com.android.server.SystemServer")) {
6769 lastInteresting = i;
6770 } else {
6771 break;
6772 }
6773 }
6774
6775 StringBuilder sb = new StringBuilder();
6776 for (int i = firstInteresting; i <= lastInteresting; i++) {
6777 sb.append(trace[i]);
6778 if (i != lastInteresting) {
6779 sb.append('\n');
6780 }
6781 }
6782
6783 return sb.toString();
6784 }
6785
6786 /**
Svet Ganovf7b47252018-02-26 11:11:27 -08006787 * Checks whether the given op for a UID and package is active.
6788 *
6789 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
6790 * you can query only for your UID.
6791 *
6792 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
6793 * @see #stopWatchingMode(OnOpChangedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006794 * @see #finishOp(int, int, String, String)
6795 * @see #startOp(int, int, String, boolean, String, String)
Svet Ganovf7b47252018-02-26 11:11:27 -08006796 *
6797 * @hide */
6798 @TestApi
6799 // TODO: Uncomment below annotation once b/73559440 is fixed
6800 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey35e46d22017-06-09 10:01:20 -06006801 public boolean isOperationActive(int code, int uid, String packageName) {
6802 try {
6803 return mService.isOperationActive(code, uid, packageName);
6804 } catch (RemoteException e) {
6805 throw e.rethrowFromSystemServer();
6806 }
6807 }
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00006808
6809 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08006810 * Configures the app ops persistence for testing.
6811 *
6812 * @param mode The mode in which the historical registry operates.
6813 * @param baseSnapshotInterval The base interval on which we would be persisting a snapshot of
6814 * the historical data. The history is recursive where every subsequent step encompasses
6815 * {@code compressionStep} longer interval with {@code compressionStep} distance between
6816 * snapshots.
6817 * @param compressionStep The compression step in every iteration.
6818 *
6819 * @see #HISTORICAL_MODE_DISABLED
6820 * @see #HISTORICAL_MODE_ENABLED_ACTIVE
6821 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
6822 *
6823 * @hide
6824 */
6825 @TestApi
6826 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
6827 public void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval,
6828 int compressionStep) {
6829 try {
6830 mService.setHistoryParameters(mode, baseSnapshotInterval, compressionStep);
6831 } catch (RemoteException e) {
6832 throw e.rethrowFromSystemServer();
6833 }
6834 }
6835
6836 /**
6837 * Offsets the history by the given duration.
6838 *
6839 * @param offsetMillis The offset duration.
6840 *
6841 * @hide
6842 */
6843 @TestApi
6844 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
6845 public void offsetHistory(long offsetMillis) {
6846 try {
6847 mService.offsetHistory(offsetMillis);
6848 } catch (RemoteException e) {
6849 throw e.rethrowFromSystemServer();
6850 }
6851 }
6852
6853 /**
6854 * Adds ops to the history directly. This could be useful for testing especially
6855 * when the historical registry operates in {@link #HISTORICAL_MODE_ENABLED_PASSIVE}
6856 * mode.
6857 *
6858 * @param ops The ops to add to the history.
6859 *
6860 * @see #setHistoryParameters(int, long, int)
6861 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
6862 *
6863 * @hide
6864 */
6865 @TestApi
6866 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
6867 public void addHistoricalOps(@NonNull HistoricalOps ops) {
6868 try {
6869 mService.addHistoricalOps(ops);
6870 } catch (RemoteException e) {
6871 throw e.rethrowFromSystemServer();
6872 }
6873 }
6874
6875 /**
6876 * Resets the app ops persistence for testing.
6877 *
6878 * @see #setHistoryParameters(int, long, int)
6879 *
6880 * @hide
6881 */
6882 @TestApi
6883 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
6884 public void resetHistoryParameters() {
6885 try {
6886 mService.resetHistoryParameters();
6887 } catch (RemoteException e) {
6888 throw e.rethrowFromSystemServer();
6889 }
6890 }
6891
6892 /**
6893 * Clears all app ops history.
6894 *
6895 * @hide
6896 */
6897 @TestApi
6898 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
6899 public void clearHistory() {
6900 try {
6901 mService.clearHistory();
6902 } catch (RemoteException e) {
6903 throw e.rethrowFromSystemServer();
6904 }
6905 }
6906
6907 /**
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00006908 * Returns all supported operation names.
6909 * @hide
6910 */
6911 @SystemApi
6912 @TestApi
6913 public static String[] getOpStrs() {
6914 return Arrays.copyOf(sOpToString, sOpToString.length);
6915 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07006916
Philip P. Moltmann24576812018-05-07 10:42:05 -07006917
6918 /**
6919 * @return number of App ops
6920 * @hide
6921 */
6922 @TestApi
6923 public static int getNumOps() {
6924 return _NUM_OP;
6925 }
6926
Dianne Hackbornc216a262018-04-26 13:46:22 -07006927 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08006928 * Computes the max for the given flags in between the begin and
6929 * end UID states.
6930 *
6931 * @param counts The data array.
6932 * @param flags The UID flags.
6933 * @param beginUidState The beginning UID state (exclusive).
6934 * @param endUidState The end UID state.
6935 * @return The sum.
Dianne Hackbornc216a262018-04-26 13:46:22 -07006936 */
Svet Ganovaf189e32019-02-15 18:45:29 -08006937 private static long maxForFlagsInStates(@Nullable LongSparseLongArray counts,
6938 @UidState int beginUidState, @UidState int endUidState,
6939 @OpFlags int flags) {
6940 if (counts == null) {
6941 return 0;
6942 }
6943 long max = 0;
6944 while (flags != 0) {
6945 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
6946 flags &= ~flag;
6947 for (int uidState : UID_STATES) {
6948 if (uidState < beginUidState || uidState > endUidState) {
6949 continue;
6950 }
6951 final long key = makeKey(uidState, flag);
6952 max = Math.max(max, counts.get(key));
Dianne Hackbornc216a262018-04-26 13:46:22 -07006953 }
6954 }
Svet Ganovaf189e32019-02-15 18:45:29 -08006955 return max;
6956 }
6957
6958
6959 private static void writeLongSparseLongArrayToParcel(
6960 @Nullable LongSparseLongArray array, @NonNull Parcel parcel) {
6961 if (array != null) {
6962 final int size = array.size();
6963 parcel.writeInt(size);
6964 for (int i = 0; i < size; i++) {
6965 parcel.writeLong(array.keyAt(i));
6966 parcel.writeLong(array.valueAt(i));
6967 }
6968 } else {
6969 parcel.writeInt(-1);
6970 }
6971 }
6972
6973 private static @Nullable LongSparseLongArray readLongSparseLongArrayFromParcel(
6974 @NonNull Parcel parcel) {
6975 final int size = parcel.readInt();
6976 if (size < 0) {
6977 return null;
6978 }
6979 final LongSparseLongArray array = new LongSparseLongArray(size);
6980 for (int i = 0; i < size; i++) {
6981 array.append(parcel.readLong(), parcel.readLong());
6982 }
6983 return array;
6984 }
6985
6986 private static void writeLongSparseStringArrayToParcel(
6987 @Nullable LongSparseArray<String> array, @NonNull Parcel parcel) {
6988 if (array != null) {
6989 final int size = array.size();
6990 parcel.writeInt(size);
6991 for (int i = 0; i < size; i++) {
6992 parcel.writeLong(array.keyAt(i));
6993 parcel.writeString(array.valueAt(i));
6994 }
6995 } else {
6996 parcel.writeInt(-1);
6997 }
6998 }
6999
7000 private static @Nullable LongSparseArray<String> readLongSparseStringArrayFromParcel(
7001 @NonNull Parcel parcel) {
7002 final int size = parcel.readInt();
7003 if (size < 0) {
7004 return null;
7005 }
7006 final LongSparseArray<String> array = new LongSparseArray<>(size);
7007 for (int i = 0; i < size; i++) {
7008 array.append(parcel.readLong(), parcel.readString());
7009 }
7010 return array;
7011 }
7012
7013 /**
7014 * Collects the keys from an array to the result creating the result if needed.
7015 *
7016 * @param array The array whose keys to collect.
7017 * @param result The optional result store collected keys.
7018 * @return The result collected keys array.
7019 */
7020 private static LongSparseArray<Object> collectKeys(@Nullable LongSparseLongArray array,
7021 @Nullable LongSparseArray<Object> result) {
7022 if (array != null) {
7023 if (result == null) {
7024 result = new LongSparseArray<>();
7025 }
7026 final int accessSize = array.size();
7027 for (int i = 0; i < accessSize; i++) {
7028 result.put(array.keyAt(i), null);
7029 }
7030 }
7031 return result;
Dianne Hackbornc216a262018-04-26 13:46:22 -07007032 }
Svet Ganov8455ba22019-01-02 13:05:56 -08007033
7034 /** @hide */
7035 public static String uidStateToString(@UidState int uidState) {
7036 switch (uidState) {
7037 case UID_STATE_PERSISTENT: {
7038 return "UID_STATE_PERSISTENT";
7039 }
7040 case UID_STATE_TOP: {
7041 return "UID_STATE_TOP";
7042 }
Amith Yamasania0a30a12019-01-22 11:38:06 -08007043 case UID_STATE_FOREGROUND_SERVICE_LOCATION: {
7044 return "UID_STATE_FOREGROUND_SERVICE_LOCATION";
7045 }
Svet Ganov8455ba22019-01-02 13:05:56 -08007046 case UID_STATE_FOREGROUND_SERVICE: {
7047 return "UID_STATE_FOREGROUND_SERVICE";
7048 }
7049 case UID_STATE_FOREGROUND: {
7050 return "UID_STATE_FOREGROUND";
7051 }
7052 case UID_STATE_BACKGROUND: {
7053 return "UID_STATE_BACKGROUND";
7054 }
7055 case UID_STATE_CACHED: {
7056 return "UID_STATE_CACHED";
7057 }
7058 default: {
7059 return "UNKNOWN";
7060 }
7061 }
7062 }
7063
7064 /** @hide */
7065 public static int parseHistoricalMode(@NonNull String mode) {
7066 switch (mode) {
7067 case "HISTORICAL_MODE_ENABLED_ACTIVE": {
7068 return HISTORICAL_MODE_ENABLED_ACTIVE;
7069 }
7070 case "HISTORICAL_MODE_ENABLED_PASSIVE": {
7071 return HISTORICAL_MODE_ENABLED_PASSIVE;
7072 }
7073 default: {
7074 return HISTORICAL_MODE_DISABLED;
7075 }
7076 }
7077 }
7078
7079 /** @hide */
7080 public static String historicalModeToString(@HistoricalMode int mode) {
7081 switch (mode) {
7082 case HISTORICAL_MODE_DISABLED: {
7083 return "HISTORICAL_MODE_DISABLED";
7084 }
7085 case HISTORICAL_MODE_ENABLED_ACTIVE: {
7086 return "HISTORICAL_MODE_ENABLED_ACTIVE";
7087 }
7088 case HISTORICAL_MODE_ENABLED_PASSIVE: {
7089 return "HISTORICAL_MODE_ENABLED_PASSIVE";
7090 }
7091 default: {
7092 return "UNKNOWN";
7093 }
7094 }
7095 }
Ng Zhi An65a99b62018-10-01 11:57:53 -07007096
7097 private static int getSystemAlertWindowDefault() {
7098 final Context context = ActivityThread.currentApplication();
7099 if (context == null) {
7100 return AppOpsManager.MODE_DEFAULT;
7101 }
7102
7103 // system alert window is disable on low ram phones starting from Q
7104 final PackageManager pm = context.getPackageManager();
7105 // TVs are constantly plugged in and has less concern for memory/power
7106 if (ActivityManager.isLowRamDeviceStatic()
7107 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) {
7108 return AppOpsManager.MODE_IGNORED;
7109 }
7110
7111 return AppOpsManager.MODE_DEFAULT;
7112 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007113}