blob: c942a46b59dbd5906e6ad5d5ef24e377414d91bd [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;
Jeff Davidson05542602014-08-11 14:07:27 -070029import android.app.usage.UsageStatsManager;
Artur Satayevc895b1b2019-12-10 17:47:51 +000030import android.compat.annotation.UnsupportedAppUsage;
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;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -080051import android.util.ArraySet;
Svet Ganovaf189e32019-02-15 18:45:29 -080052import android.util.LongSparseArray;
53import android.util.LongSparseLongArray;
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -080054import android.util.Pools;
Ng Zhi An65a99b62018-10-01 11:57:53 -070055import android.util.SparseArray;
Jeff Davidson05542602014-08-11 14:07:27 -070056
Svet Ganovb3d2ae22018-12-17 22:06:15 -080057import com.android.internal.annotations.GuardedBy;
Svet Ganov23c88db2019-01-22 20:38:11 -080058import com.android.internal.annotations.Immutable;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080059import com.android.internal.app.IAppOpsActiveCallback;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070060import com.android.internal.app.IAppOpsAsyncNotedCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070061import com.android.internal.app.IAppOpsCallback;
Svet Ganovb3d2ae22018-12-17 22:06:15 -080062import com.android.internal.app.IAppOpsNotedCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070063import com.android.internal.app.IAppOpsService;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070064import com.android.internal.os.RuntimeInit;
65import com.android.internal.os.ZygoteInit;
Svet Ganov8455ba22019-01-02 13:05:56 -080066import com.android.internal.util.ArrayUtils;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -080067import com.android.internal.util.DataClass;
68import com.android.internal.util.Parcelling;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080069import com.android.internal.util.Preconditions;
Jeff Davidson05542602014-08-11 14:07:27 -070070
Svet Ganovaf189e32019-02-15 18:45:29 -080071import java.lang.annotation.ElementType;
Svet Ganovad0a49b2018-10-29 10:07:08 -070072import java.lang.annotation.Retention;
73import java.lang.annotation.RetentionPolicy;
Svet Ganovaf189e32019-02-15 18:45:29 -080074import java.lang.annotation.Target;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070075import java.lang.reflect.Method;
Svet Ganov8455ba22019-01-02 13:05:56 -080076import java.math.BigDecimal;
77import java.math.RoundingMode;
Jeff Davidson05542602014-08-11 14:07:27 -070078import java.util.ArrayList;
Peter Visontay5a2a1ef2017-12-18 20:34:03 +000079import java.util.Arrays;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070080import java.util.BitSet;
Svet Ganovad0a49b2018-10-29 10:07:08 -070081import java.util.Collections;
Jeff Davidson05542602014-08-11 14:07:27 -070082import java.util.HashMap;
83import java.util.List;
Philip P. Moltmann59076d82019-08-19 15:00:40 -070084import java.util.Map;
Svet Ganovaf189e32019-02-15 18:45:29 -080085import java.util.Objects;
Svet Ganov8455ba22019-01-02 13:05:56 -080086import java.util.concurrent.Executor;
87import java.util.function.Consumer;
Svet Ganovaf189e32019-02-15 18:45:29 -080088import java.util.function.Supplier;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080089
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080090/**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070091 * API for interacting with "application operation" tracking.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080092 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070093 * <p>This API is not generally intended for third party application developers; most
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060094 * features are only available to system applications.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080095 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060096@SystemService(Context.APP_OPS_SERVICE)
Dianne Hackborna06de0f2012-12-11 16:34:47 -080097public class AppOpsManager {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -070098 /**
99 * <p>App ops allows callers to:</p>
100 *
101 * <ul>
102 * <li> Note when operations are happening, and find out if they are allowed for the current
103 * caller.</li>
104 * <li> Disallow specific apps from doing specific operations.</li>
105 * <li> Collect all of the current information about operations that have been executed or
106 * are not being allowed.</li>
107 * <li> Monitor for changes in whether an operation is allowed.</li>
108 * </ul>
109 *
110 * <p>Each operation is identified by a single integer; these integers are a fixed set of
111 * operations, enumerated by the OP_* constants.
112 *
113 * <p></p>When checking operations, the result is a "mode" integer indicating the current
114 * setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute
115 * the operation but fake its behavior enough so that the caller doesn't crash),
116 * MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls
117 * will do this for you).
118 */
119
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800120 final Context mContext;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800121
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100122 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800123 final IAppOpsService mService;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800124
125 @GuardedBy("mModeWatchers")
126 private final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers =
127 new ArrayMap<>();
128
129 @GuardedBy("mActiveWatchers")
130 private final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers =
131 new ArrayMap<>();
132
133 @GuardedBy("mNotedWatchers")
134 private final ArrayMap<OnOpNotedListener, IAppOpsNotedCallback> mNotedWatchers =
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -0800135 new ArrayMap<>();
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800136
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -0700137 private static final Object sLock = new Object();
138
139 /** Current {@link AppOpsCollector}. Change via {@link #setNotedAppOpsCollector} */
140 @GuardedBy("sLock")
141 private static @Nullable AppOpsCollector sNotedAppOpsCollector;
142
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -0800143 static IBinder sClientId;
Dianne Hackborne98f5db2013-07-17 17:23:25 -0700144
Svet Ganov8455ba22019-01-02 13:05:56 -0800145 /** @hide */
146 @Retention(RetentionPolicy.SOURCE)
147 @IntDef(flag = true, prefix = { "HISTORICAL_MODE_" }, value = {
148 HISTORICAL_MODE_DISABLED,
149 HISTORICAL_MODE_ENABLED_ACTIVE,
150 HISTORICAL_MODE_ENABLED_PASSIVE
151 })
152 public @interface HistoricalMode {}
153
154 /**
155 * Mode in which app op history is completely disabled.
156 * @hide
157 */
158 @TestApi
159 public static final int HISTORICAL_MODE_DISABLED = 0;
160
161 /**
162 * Mode in which app op history is enabled and app ops performed by apps would
163 * be tracked. This is the mode in which the feature is completely enabled.
164 * @hide
165 */
166 @TestApi
167 public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1;
168
169 /**
170 * Mode in which app op history is enabled but app ops performed by apps would
171 * not be tracked and the only way to add ops to the history is via explicit calls
172 * to dedicated APIs. This mode is useful for testing to allow full control of
173 * the historical content.
174 * @hide
175 */
176 @TestApi
177 public static final int HISTORICAL_MODE_ENABLED_PASSIVE = 2;
178
179 /** @hide */
180 @Retention(RetentionPolicy.SOURCE)
181 @IntDef(flag = true, prefix = { "MODE_" }, value = {
182 MODE_ALLOWED,
183 MODE_IGNORED,
184 MODE_ERRORED,
185 MODE_DEFAULT,
186 MODE_FOREGROUND
187 })
188 public @interface Mode {}
189
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700190 /**
191 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
192 * allowed to perform the given operation.
193 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800194 public static final int MODE_ALLOWED = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700195
196 /**
197 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
198 * not allowed to perform the given operation, and this attempt should
199 * <em>silently fail</em> (it should not cause the app to crash).
200 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800201 public static final int MODE_IGNORED = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700202
203 /**
204 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
205 * given caller is not allowed to perform the given operation, and this attempt should
206 * cause it to have a fatal error, typically a {@link SecurityException}.
207 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800208 public static final int MODE_ERRORED = 2;
209
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -0700210 /**
211 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
212 * use its default security check. This mode is not normally used; it should only be used
213 * with appop permissions, and callers must explicitly check for it and deal with it.
214 */
215 public static final int MODE_DEFAULT = 3;
216
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700217 /**
Dianne Hackbornc216a262018-04-26 13:46:22 -0700218 * Special mode that means "allow only when app is in foreground." This is <b>not</b>
Dianne Hackbornf8709f52019-02-04 16:31:24 -0800219 * returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}. Rather,
220 * {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always
221 * possible for it to be ultimately allowed, depending on the app's background state),
222 * and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app
223 * being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}.
224 *
225 * <p>The only place you will this normally see this value is through
226 * {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op. Note that because
227 * you can't know the current state of the app being checked (and it can change at any
228 * point), you can only treat the result here as an indication that it will vary between
229 * {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background
230 * state of the app. You thus must always use {@link #noteOp} or {@link #startOp} to do
231 * the actual check for access to the op.</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -0700232 */
233 public static final int MODE_FOREGROUND = 4;
234
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700235 /**
236 * Flag for {@link #startWatchingMode(String, String, int, OnOpChangedListener)}:
237 * Also get reports if the foreground state of an op's uid changes. This only works
238 * when watching a particular op, not when watching a package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700239 */
240 public static final int WATCH_FOREGROUND_CHANGES = 1 << 0;
Dianne Hackbornc216a262018-04-26 13:46:22 -0700241
242 /**
243 * @hide
244 */
245 public static final String[] MODE_NAMES = new String[] {
246 "allow", // MODE_ALLOWED
247 "ignore", // MODE_IGNORED
248 "deny", // MODE_ERRORED
249 "default", // MODE_DEFAULT
250 "foreground", // MODE_FOREGROUND
251 };
252
Svet Ganovad0a49b2018-10-29 10:07:08 -0700253 /** @hide */
254 @Retention(RetentionPolicy.SOURCE)
Svet Ganovaf189e32019-02-15 18:45:29 -0800255 @IntDef(prefix = { "UID_STATE_" }, value = {
Svet Ganovad0a49b2018-10-29 10:07:08 -0700256 UID_STATE_PERSISTENT,
257 UID_STATE_TOP,
Amith Yamasania0a30a12019-01-22 11:38:06 -0800258 UID_STATE_FOREGROUND_SERVICE_LOCATION,
Svet Ganovad0a49b2018-10-29 10:07:08 -0700259 UID_STATE_FOREGROUND_SERVICE,
260 UID_STATE_FOREGROUND,
261 UID_STATE_BACKGROUND,
262 UID_STATE_CACHED
263 })
264 public @interface UidState {}
265
Dianne Hackbornc216a262018-04-26 13:46:22 -0700266 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700267 * Uid state: The UID is a foreground persistent app. The lower the UID
268 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700269 * @hide
270 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800271 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700272 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800273 public static final int UID_STATE_PERSISTENT = 100;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700274
275 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700276 * Uid state: The UID is top foreground app. The lower the UID
277 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700278 * @hide
279 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800280 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700281 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800282 public static final int UID_STATE_TOP = 200;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700283
284 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800285 * Uid state: The UID is running a foreground service of location type.
Svet Ganov05fcd222019-07-08 16:30:45 -0700286 * The lower the UID state the more important the UID is for the user.
Hui Yu26969322019-08-21 14:56:35 -0700287 * This uid state is a counterpart to PROCESS_STATE_FOREGROUND_SERVICE_LOCATION which has been
288 * deprecated.
Amith Yamasania0a30a12019-01-22 11:38:06 -0800289 * @hide
Hui Yu26969322019-08-21 14:56:35 -0700290 * @deprecated
Amith Yamasania0a30a12019-01-22 11:38:06 -0800291 */
292 @TestApi
293 @SystemApi
Hui Yu26969322019-08-21 14:56:35 -0700294 @Deprecated
Svet Ganovaf189e32019-02-15 18:45:29 -0800295 public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800296
297 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700298 * Uid state: The UID is running a foreground service. The lower the UID
299 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700300 * @hide
301 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800302 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700303 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800304 public static final int UID_STATE_FOREGROUND_SERVICE = 400;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700305
306 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700307 * Uid state: The UID is a foreground app. The lower the UID
308 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700309 * @hide
310 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800311 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700312 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800313 public static final int UID_STATE_FOREGROUND = 500;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700314
315 /**
Hui Yu26969322019-08-21 14:56:35 -0700316 * The max, which is min priority, UID state for which any app op
317 * would be considered as performed in the foreground.
318 * @hide
319 */
320 public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND;
321
322 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700323 * Uid state: The UID is a background app. The lower the UID
324 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700325 * @hide
326 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800327 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700328 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800329 public static final int UID_STATE_BACKGROUND = 600;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700330
331 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700332 * Uid state: The UID is a cached app. The lower the UID
333 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700334 * @hide
335 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800336 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700337 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800338 public static final int UID_STATE_CACHED = 700;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700339
340 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800341 * Uid state: The UID state with the highest priority.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700342 * @hide
343 */
Svet Ganovaf189e32019-02-15 18:45:29 -0800344 public static final int MAX_PRIORITY_UID_STATE = UID_STATE_PERSISTENT;
345
346 /**
347 * Uid state: The UID state with the lowest priority.
348 * @hide
349 */
350 public static final int MIN_PRIORITY_UID_STATE = UID_STATE_CACHED;
351
352 /**
Hui Yu26969322019-08-21 14:56:35 -0700353 * Resolves the first unrestricted state given an app op.
Svet Ganovaf189e32019-02-15 18:45:29 -0800354 * @param op The op to resolve.
355 * @return The last restricted UID state.
356 *
357 * @hide
358 */
359 public static int resolveFirstUnrestrictedUidState(int op) {
Hui Yu26969322019-08-21 14:56:35 -0700360 return UID_STATE_FOREGROUND;
Svet Ganovaf189e32019-02-15 18:45:29 -0800361 }
362
363 /**
Hui Yu26969322019-08-21 14:56:35 -0700364 * Resolves the last restricted state given an app op.
Svet Ganovaf189e32019-02-15 18:45:29 -0800365 * @param op The op to resolve.
366 * @return The last restricted UID state.
367 *
368 * @hide
369 */
370 public static int resolveLastRestrictedUidState(int op) {
Hui Yu26969322019-08-21 14:56:35 -0700371 return UID_STATE_BACKGROUND;
Svet Ganovaf189e32019-02-15 18:45:29 -0800372 }
373
374 /** @hide Note: Keep these sorted */
375 public static final int[] UID_STATES = {
376 UID_STATE_PERSISTENT,
377 UID_STATE_TOP,
378 UID_STATE_FOREGROUND_SERVICE_LOCATION,
379 UID_STATE_FOREGROUND_SERVICE,
380 UID_STATE_FOREGROUND,
381 UID_STATE_BACKGROUND,
382 UID_STATE_CACHED
383 };
384
385 /** @hide */
386 public static String getUidStateName(@UidState int uidState) {
387 switch (uidState) {
388 case UID_STATE_PERSISTENT:
389 return "pers";
390 case UID_STATE_TOP:
391 return "top";
392 case UID_STATE_FOREGROUND_SERVICE_LOCATION:
393 return "fgsvcl";
394 case UID_STATE_FOREGROUND_SERVICE:
395 return "fgsvc";
396 case UID_STATE_FOREGROUND:
397 return "fg";
398 case UID_STATE_BACKGROUND:
399 return "bg";
400 case UID_STATE_CACHED:
401 return "cch";
402 default:
403 return "unknown";
404 }
405 }
406
407 /**
408 * Flag: non proxy operations. These are operations
409 * performed on behalf of the app itself and not on behalf of
410 * another one.
411 *
412 * @hide
413 */
414 @TestApi
415 @SystemApi
416 public static final int OP_FLAG_SELF = 0x1;
417
418 /**
419 * Flag: trusted proxy operations. These are operations
420 * performed on behalf of another app by a trusted app.
421 * Which is work a trusted app blames on another app.
422 *
423 * @hide
424 */
425 @TestApi
426 @SystemApi
427 public static final int OP_FLAG_TRUSTED_PROXY = 0x2;
428
429 /**
430 * Flag: untrusted proxy operations. These are operations
431 * performed on behalf of another app by an untrusted app.
432 * Which is work an untrusted app blames on another app.
433 *
434 * @hide
435 */
436 @TestApi
437 @SystemApi
438 public static final int OP_FLAG_UNTRUSTED_PROXY = 0x4;
439
440 /**
441 * Flag: trusted proxied operations. These are operations
442 * performed by a trusted other app on behalf of an app.
443 * Which is work an app was blamed for by a trusted app.
444 *
445 * @hide
446 */
447 @TestApi
448 @SystemApi
449 public static final int OP_FLAG_TRUSTED_PROXIED = 0x8;
450
451 /**
452 * Flag: untrusted proxied operations. These are operations
453 * performed by an untrusted other app on behalf of an app.
454 * Which is work an app was blamed for by an untrusted app.
455 *
456 * @hide
457 */
458 @TestApi
459 @SystemApi
460 public static final int OP_FLAG_UNTRUSTED_PROXIED = 0x10;
461
462 /**
463 * Flags: all operations. These include operations matched
464 * by {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXIED},
465 * {@link #OP_FLAG_UNTRUSTED_PROXIED}, {@link #OP_FLAG_TRUSTED_PROXIED},
466 * {@link #OP_FLAG_UNTRUSTED_PROXIED}.
467 *
468 * @hide
469 */
470 @TestApi
471 @SystemApi
472 public static final int OP_FLAGS_ALL =
473 OP_FLAG_SELF
474 | OP_FLAG_TRUSTED_PROXY
475 | OP_FLAG_UNTRUSTED_PROXY
476 | OP_FLAG_TRUSTED_PROXIED
477 | OP_FLAG_UNTRUSTED_PROXIED;
478
479 /**
480 * Flags: all trusted operations which is ones either the app did {@link #OP_FLAG_SELF},
481 * or it was blamed for by a trusted app {@link #OP_FLAG_TRUSTED_PROXIED}, or ones the
482 * app if untrusted blamed on other apps {@link #OP_FLAG_UNTRUSTED_PROXY}.
483 *
484 * @hide
485 */
486 @SystemApi
487 public static final int OP_FLAGS_ALL_TRUSTED = AppOpsManager.OP_FLAG_SELF
488 | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY
489 | AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
490
491 /** @hide */
492 @Retention(RetentionPolicy.SOURCE)
493 @IntDef(flag = true, prefix = { "FLAG_" }, value = {
494 OP_FLAG_SELF,
495 OP_FLAG_TRUSTED_PROXY,
496 OP_FLAG_UNTRUSTED_PROXY,
497 OP_FLAG_TRUSTED_PROXIED,
498 OP_FLAG_UNTRUSTED_PROXIED
499 })
500 public @interface OpFlags {}
501
502
503 /** @hide */
504 public static final String getFlagName(@OpFlags int flag) {
505 switch (flag) {
506 case OP_FLAG_SELF:
507 return "s";
508 case OP_FLAG_TRUSTED_PROXY:
509 return "tp";
510 case OP_FLAG_UNTRUSTED_PROXY:
511 return "up";
512 case OP_FLAG_TRUSTED_PROXIED:
513 return "tpd";
514 case OP_FLAG_UNTRUSTED_PROXIED:
515 return "upd";
516 default:
517 return "unknown";
518 }
519 }
520
521 private static final int UID_STATE_OFFSET = 31;
522 private static final int FLAGS_MASK = 0xFFFFFFFF;
523
524 /**
525 * Key for a data bucket storing app op state. The bucket
526 * is composed of the uid state and state flags. This way
527 * we can query data for given uid state and a set of flags where
528 * the flags control which type of data to get. For example,
529 * one can get the ops an app did on behalf of other apps
530 * while in the background.
531 *
532 * @hide
533 */
534 @Retention(RetentionPolicy.SOURCE)
535 @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
536 public @interface DataBucketKey {
537 }
538
539 /** @hide */
540 public static String keyToString(@DataBucketKey long key) {
541 final int uidState = extractUidStateFromKey(key);
542 final int flags = extractFlagsFromKey(key);
543 return "[" + getUidStateName(uidState) + "-" + flagsToString(flags) + "]";
544 }
545
546 /** @hide */
547 public static @DataBucketKey long makeKey(@UidState int uidState, @OpFlags int flags) {
548 return ((long) uidState << UID_STATE_OFFSET) | flags;
549 }
550
551 /** @hide */
552 public static int extractUidStateFromKey(@DataBucketKey long key) {
553 return (int) (key >> UID_STATE_OFFSET);
554 }
555
556 /** @hide */
557 public static int extractFlagsFromKey(@DataBucketKey long key) {
558 return (int) (key & FLAGS_MASK);
559 }
560
561 /** @hide */
562 public static String flagsToString(@OpFlags int flags) {
563 final StringBuilder flagsBuilder = new StringBuilder();
564 while (flags != 0) {
565 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
566 flags &= ~flag;
567 if (flagsBuilder.length() > 0) {
568 flagsBuilder.append('|');
569 }
570 flagsBuilder.append(getFlagName(flag));
571 }
572 return flagsBuilder.toString();
573 }
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700574
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500575 // when adding one of these:
576 // - increment _NUM_OP
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000577 // - define an OPSTR_* constant (marked as @SystemApi)
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700578 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500579 // - add descriptive strings to Settings/res/values/arrays.xml
David Christie0b837452013-07-29 16:02:13 -0700580 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700581
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700582 /** @hide No operation specified. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100583 @UnsupportedAppUsage
Dianne Hackbornf51f6122013-02-04 18:23:34 -0800584 public static final int OP_NONE = -1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700585 /** @hide Access to coarse location information. */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000586 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -0800587 @TestApi
Dianne Hackborn35654b62013-01-14 17:38:02 -0800588 public static final int OP_COARSE_LOCATION = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700589 /** @hide Access to fine location information. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100590 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800591 public static final int OP_FINE_LOCATION = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700592 /** @hide Causing GPS to run. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100593 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -0800594 public static final int OP_GPS = 2;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800595 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100596 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700597 public static final int OP_VIBRATE = 3;
598 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100599 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700600 public static final int OP_READ_CONTACTS = 4;
601 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100602 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700603 public static final int OP_WRITE_CONTACTS = 5;
604 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100605 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700606 public static final int OP_READ_CALL_LOG = 6;
607 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100608 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700609 public static final int OP_WRITE_CALL_LOG = 7;
610 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100611 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700612 public static final int OP_READ_CALENDAR = 8;
613 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100614 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700615 public static final int OP_WRITE_CALENDAR = 9;
616 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100617 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700618 public static final int OP_WIFI_SCAN = 10;
619 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100620 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700621 public static final int OP_POST_NOTIFICATION = 11;
622 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100623 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700624 public static final int OP_NEIGHBORING_CELLS = 12;
625 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100626 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700627 public static final int OP_CALL_PHONE = 13;
628 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100629 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700630 public static final int OP_READ_SMS = 14;
631 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100632 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700633 public static final int OP_WRITE_SMS = 15;
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_SMS = 16;
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_EMERGECY_SMS = 17;
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_MMS = 18;
643 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100644 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700645 public static final int OP_RECEIVE_WAP_PUSH = 19;
646 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100647 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700648 public static final int OP_SEND_SMS = 20;
649 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100650 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700651 public static final int OP_READ_ICC_SMS = 21;
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_ICC_SMS = 22;
655 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100656 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700657 public static final int OP_WRITE_SETTINGS = 23;
Peter Visontay96449f62017-12-11 18:50:03 +0000658 /** @hide Required to draw on top of other apps. */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000659 @UnsupportedAppUsage
Svet Ganovf7b47252018-02-26 11:11:27 -0800660 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700661 public static final int OP_SYSTEM_ALERT_WINDOW = 24;
662 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100663 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700664 public static final int OP_ACCESS_NOTIFICATIONS = 25;
665 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100666 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700667 public static final int OP_CAMERA = 26;
668 /** @hide */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000669 @UnsupportedAppUsage
Svet Ganova7a0db62018-02-27 20:08:01 -0800670 @TestApi
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700671 public static final int OP_RECORD_AUDIO = 27;
672 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100673 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700674 public static final int OP_PLAY_AUDIO = 28;
675 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100676 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700677 public static final int OP_READ_CLIPBOARD = 29;
678 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100679 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700680 public static final int OP_WRITE_CLIPBOARD = 30;
681 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100682 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700683 public static final int OP_TAKE_MEDIA_BUTTONS = 31;
684 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100685 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700686 public static final int OP_TAKE_AUDIO_FOCUS = 32;
687 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100688 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700689 public static final int OP_AUDIO_MASTER_VOLUME = 33;
690 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100691 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700692 public static final int OP_AUDIO_VOICE_VOLUME = 34;
693 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100694 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700695 public static final int OP_AUDIO_RING_VOLUME = 35;
696 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100697 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700698 public static final int OP_AUDIO_MEDIA_VOLUME = 36;
699 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100700 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700701 public static final int OP_AUDIO_ALARM_VOLUME = 37;
702 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100703 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700704 public static final int OP_AUDIO_NOTIFICATION_VOLUME = 38;
705 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100706 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700707 public static final int OP_AUDIO_BLUETOOTH_VOLUME = 39;
708 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100709 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700710 public static final int OP_WAKE_LOCK = 40;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700711 /** @hide Continually monitoring location data. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100712 @UnsupportedAppUsage
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700713 public static final int OP_MONITOR_LOCATION = 41;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700714 /** @hide Continually monitoring location data with a relatively high power request. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100715 @UnsupportedAppUsage
David Christie0b837452013-07-29 16:02:13 -0700716 public static final int OP_MONITOR_HIGH_POWER_LOCATION = 42;
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700717 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100718 @UnsupportedAppUsage
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700719 public static final int OP_GET_USAGE_STATS = 43;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700720 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100721 @UnsupportedAppUsage
Emily Bernier22c921a2014-05-28 11:01:32 -0400722 public static final int OP_MUTE_MICROPHONE = 44;
723 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100724 @UnsupportedAppUsage
Jason Monk1c7c3192014-06-26 12:52:18 -0400725 public static final int OP_TOAST_WINDOW = 45;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700726 /** @hide Capture the device's display contents and/or audio */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100727 @UnsupportedAppUsage
Michael Wrightc39d47a2014-07-08 18:07:36 -0700728 public static final int OP_PROJECT_MEDIA = 46;
Jeff Davidson05542602014-08-11 14:07:27 -0700729 /** @hide Activate a VPN connection without user intervention. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100730 @UnsupportedAppUsage
Jeff Davidson05542602014-08-11 14:07:27 -0700731 public static final int OP_ACTIVATE_VPN = 47;
Benjamin Franzf3ece362015-02-11 10:51:10 +0000732 /** @hide Access the WallpaperManagerAPI to write wallpapers. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100733 @UnsupportedAppUsage
Benjamin Franzf3ece362015-02-11 10:51:10 +0000734 public static final int OP_WRITE_WALLPAPER = 48;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700735 /** @hide Received the assist structure from an app. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100736 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700737 public static final int OP_ASSIST_STRUCTURE = 49;
738 /** @hide Received a screenshot from assist. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100739 @UnsupportedAppUsage
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700740 public static final int OP_ASSIST_SCREENSHOT = 50;
Svet Ganov16a16892015-04-16 10:32:04 -0700741 /** @hide Read the phone state. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100742 @UnsupportedAppUsage
Svet Ganov16a16892015-04-16 10:32:04 -0700743 public static final int OP_READ_PHONE_STATE = 51;
Svet Ganovc3300092015-04-17 09:07:22 -0700744 /** @hide Add voicemail messages to the voicemail content provider. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100745 @UnsupportedAppUsage
Svet Ganovc3300092015-04-17 09:07:22 -0700746 public static final int OP_ADD_VOICEMAIL = 52;
Svetoslav5335b672015-04-29 12:00:51 -0700747 /** @hide Access APIs for SIP calling over VOIP or WiFi. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100748 @UnsupportedAppUsage
Svetoslav5335b672015-04-29 12:00:51 -0700749 public static final int OP_USE_SIP = 53;
Svetoslavc656e6f2015-04-29 14:08:16 -0700750 /** @hide Intercept outgoing calls. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100751 @UnsupportedAppUsage
Svetoslavc656e6f2015-04-29 14:08:16 -0700752 public static final int OP_PROCESS_OUTGOING_CALLS = 54;
Svetoslav4af76a52015-04-29 15:29:46 -0700753 /** @hide User the fingerprint API. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100754 @UnsupportedAppUsage
Svetoslav4af76a52015-04-29 15:29:46 -0700755 public static final int OP_USE_FINGERPRINT = 55;
Svet Ganovb9d71a62015-04-30 10:38:13 -0700756 /** @hide Access to body sensors such as heart rate, etc. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100757 @UnsupportedAppUsage
Svet Ganovb9d71a62015-04-30 10:38:13 -0700758 public static final int OP_BODY_SENSORS = 56;
Svet Ganovede43162015-05-02 17:42:44 -0700759 /** @hide Read previously received cell broadcast messages. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100760 @UnsupportedAppUsage
Svet Ganovede43162015-05-02 17:42:44 -0700761 public static final int OP_READ_CELL_BROADCASTS = 57;
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700762 /** @hide Inject mock location into the system. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100763 @UnsupportedAppUsage
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700764 public static final int OP_MOCK_LOCATION = 58;
Svet Ganov921c7df2015-06-29 21:51:41 -0700765 /** @hide Read external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100766 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700767 public static final int OP_READ_EXTERNAL_STORAGE = 59;
768 /** @hide Write external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100769 @UnsupportedAppUsage
Svet Ganov921c7df2015-06-29 21:51:41 -0700770 public static final int OP_WRITE_EXTERNAL_STORAGE = 60;
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700771 /** @hide Turned on the screen. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100772 @UnsupportedAppUsage
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700773 public static final int OP_TURN_SCREEN_ON = 61;
Svetoslavf3f02ac2015-09-08 14:36:35 -0700774 /** @hide Get device accounts. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100775 @UnsupportedAppUsage
Svetoslavf3f02ac2015-09-08 14:36:35 -0700776 public static final int OP_GET_ACCOUNTS = 62;
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700777 /** @hide Control whether an application is allowed to run in the background. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100778 @UnsupportedAppUsage
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700779 public static final int OP_RUN_IN_BACKGROUND = 63;
Jason Monk1c7c3192014-06-26 12:52:18 -0400780 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100781 @UnsupportedAppUsage
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800782 public static final int OP_AUDIO_ACCESSIBILITY_VOLUME = 64;
Chad Brubaker73ec8f92016-11-10 11:24:40 -0800783 /** @hide Read the phone number. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100784 @UnsupportedAppUsage
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700785 public static final int OP_READ_PHONE_NUMBERS = 65;
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800786 /** @hide Request package installs through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100787 @UnsupportedAppUsage
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -0800788 public static final int OP_REQUEST_INSTALL_PACKAGES = 66;
Winson Chungf4ac0632017-03-17 12:34:12 -0700789 /** @hide Enter picture-in-picture. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100790 @UnsupportedAppUsage
Winson Chungf4ac0632017-03-17 12:34:12 -0700791 public static final int OP_PICTURE_IN_PICTURE = 67;
Chad Brubaker97b383f2017-02-02 15:04:35 -0800792 /** @hide Instant app start foreground service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100793 @UnsupportedAppUsage
Chad Brubaker97b383f2017-02-02 15:04:35 -0800794 public static final int OP_INSTANT_APP_START_FOREGROUND = 68;
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800795 /** @hide Answer incoming phone calls */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100796 @UnsupportedAppUsage
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800797 public static final int OP_ANSWER_PHONE_CALLS = 69;
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700798 /** @hide Run jobs when in background */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100799 @UnsupportedAppUsage
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -0700800 public static final int OP_RUN_ANY_IN_BACKGROUND = 70;
Peter Visontay1246d9e2017-10-17 17:02:45 +0100801 /** @hide Change Wi-Fi connectivity state */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100802 @UnsupportedAppUsage
Peter Visontay1246d9e2017-10-17 17:02:45 +0100803 public static final int OP_CHANGE_WIFI_STATE = 71;
Peter Visontayf2e38362017-11-27 15:27:16 +0000804 /** @hide Request package deletion through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100805 @UnsupportedAppUsage
Peter Visontayf2e38362017-11-27 15:27:16 +0000806 public static final int OP_REQUEST_DELETE_PACKAGES = 72;
Peter Visontay11950832017-11-14 19:34:59 +0000807 /** @hide Bind an accessibility service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100808 @UnsupportedAppUsage
Peter Visontay11950832017-11-14 19:34:59 +0000809 public static final int OP_BIND_ACCESSIBILITY_SERVICE = 73;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800810 /** @hide Continue handover of a call from another app */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100811 @UnsupportedAppUsage
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800812 public static final int OP_ACCEPT_HANDOVER = 74;
Nathan Harold1bb420672018-03-14 17:08:53 -0700813 /** @hide Create and Manage IPsec Tunnels */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100814 @UnsupportedAppUsage
Nathan Harold1bb420672018-03-14 17:08:53 -0700815 public static final int OP_MANAGE_IPSEC_TUNNELS = 75;
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700816 /** @hide Any app start foreground service. */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000817 @UnsupportedAppUsage
Svet Ganovaf189e32019-02-15 18:45:29 -0800818 @TestApi
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -0700819 public static final int OP_START_FOREGROUND = 76;
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -0800820 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100821 @UnsupportedAppUsage
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700822 public static final int OP_BLUETOOTH_SCAN = 77;
Kevin Chynb3c05aa2018-09-21 16:50:32 -0700823 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
824 public static final int OP_USE_BIOMETRIC = 78;
Zimuzo6cbf9cc2018-10-05 12:05:58 +0100825 /** @hide Physical activity recognition. */
826 public static final int OP_ACTIVITY_RECOGNITION = 79;
Hongming Jin228cd012018-11-09 14:47:50 -0800827 /** @hide Financial app sms read. */
828 public static final int OP_SMS_FINANCIAL_TRANSACTIONS = 80;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -0700829 /** @hide Read media of audio type. */
830 public static final int OP_READ_MEDIA_AUDIO = 81;
831 /** @hide Write media of audio type. */
832 public static final int OP_WRITE_MEDIA_AUDIO = 82;
833 /** @hide Read media of video type. */
834 public static final int OP_READ_MEDIA_VIDEO = 83;
835 /** @hide Write media of video type. */
836 public static final int OP_WRITE_MEDIA_VIDEO = 84;
837 /** @hide Read media of image type. */
838 public static final int OP_READ_MEDIA_IMAGES = 85;
839 /** @hide Write media of image type. */
840 public static final int OP_WRITE_MEDIA_IMAGES = 86;
Jeff Sharkeye82cbb12018-12-06 15:53:11 -0700841 /** @hide Has a legacy (non-isolated) view of storage. */
842 public static final int OP_LEGACY_STORAGE = 87;
Jackal Guo8dc791e2019-01-14 10:26:42 +0800843 /** @hide Accessing accessibility features */
844 public static final int OP_ACCESS_ACCESSIBILITY = 88;
Michael Groover656ef912019-04-09 17:09:57 -0700845 /** @hide Read the device identifiers (IMEI / MEID, IMSI, SIM / Build serial) */
846 public static final int OP_READ_DEVICE_IDENTIFIERS = 89;
Philip P. Moltmann89b044f2019-09-13 15:12:34 -0700847 /** @hide Read location metadata from media */
848 public static final int OP_ACCESS_MEDIA_LOCATION = 90;
Patrick Baumann6c1c8092019-06-27 14:55:44 -0700849 /** @hide Query all apps on device, regardless of declarations in the calling app manifest */
Philip P. Moltmann89b044f2019-09-13 15:12:34 -0700850 public static final int OP_QUERY_ALL_PACKAGES = 91;
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -0800851 /** @hide Access all external storage */
852 public static final int OP_MANAGE_EXTERNAL_STORAGE = 92;
Patrick Baumann6c1c8092019-06-27 14:55:44 -0700853
Dianne Hackborne04f13d2018-05-02 12:51:52 -0700854 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100855 @UnsupportedAppUsage
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -0800856 public static final int _NUM_OP = 93;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800857
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700858 /** Access to coarse location information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700859 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700860 /** Access to fine location information. */
861 public static final String OPSTR_FINE_LOCATION =
862 "android:fine_location";
863 /** Continually monitoring location data. */
864 public static final String OPSTR_MONITOR_LOCATION
865 = "android:monitor_location";
866 /** Continually monitoring location data with a relatively high power request. */
867 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
868 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -0700869 /** Access to {@link android.app.usage.UsageStatsManager}. */
870 public static final String OPSTR_GET_USAGE_STATS
871 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -0700872 /** Activate a VPN connection without user intervention. @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000873 @SystemApi @TestApi
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700874 public static final String OPSTR_ACTIVATE_VPN
875 = "android:activate_vpn";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700876 /** Allows an application to read the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700877 public static final String OPSTR_READ_CONTACTS
878 = "android:read_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700879 /** Allows an application to write to the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700880 public static final String OPSTR_WRITE_CONTACTS
881 = "android:write_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700882 /** Allows an application to read the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700883 public static final String OPSTR_READ_CALL_LOG
884 = "android:read_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700885 /** Allows an application to write to the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700886 public static final String OPSTR_WRITE_CALL_LOG
887 = "android:write_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700888 /** Allows an application to read the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700889 public static final String OPSTR_READ_CALENDAR
890 = "android:read_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700891 /** Allows an application to write to the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700892 public static final String OPSTR_WRITE_CALENDAR
893 = "android:write_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700894 /** Allows an application to initiate a phone call. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700895 public static final String OPSTR_CALL_PHONE
896 = "android:call_phone";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700897 /** Allows an application to read SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700898 public static final String OPSTR_READ_SMS
899 = "android:read_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700900 /** Allows an application to receive SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700901 public static final String OPSTR_RECEIVE_SMS
902 = "android:receive_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700903 /** Allows an application to receive MMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700904 public static final String OPSTR_RECEIVE_MMS
905 = "android:receive_mms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700906 /** Allows an application to receive WAP push messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700907 public static final String OPSTR_RECEIVE_WAP_PUSH
908 = "android:receive_wap_push";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700909 /** Allows an application to send SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700910 public static final String OPSTR_SEND_SMS
911 = "android:send_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700912 /** Required to be able to access the camera device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700913 public static final String OPSTR_CAMERA
914 = "android:camera";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700915 /** Required to be able to access the microphone device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700916 public static final String OPSTR_RECORD_AUDIO
917 = "android:record_audio";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700918 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700919 public static final String OPSTR_READ_PHONE_STATE
920 = "android:read_phone_state";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700921 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -0700922 public static final String OPSTR_ADD_VOICEMAIL
923 = "android:add_voicemail";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700924 /** Access APIs for SIP calling over VOIP or WiFi */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700925 public static final String OPSTR_USE_SIP
926 = "android:use_sip";
Svet Ganove8e89422016-09-22 19:56:50 -0700927 /** Access APIs for diverting outgoing calls */
Svet Ganov824ad6e2016-09-22 19:36:53 -0700928 public static final String OPSTR_PROCESS_OUTGOING_CALLS
929 = "android:process_outgoing_calls";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700930 /** Use the fingerprint API. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700931 public static final String OPSTR_USE_FINGERPRINT
932 = "android:use_fingerprint";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700933 /** Access to body sensors such as heart rate, etc. */
Svet Ganovb9d71a62015-04-30 10:38:13 -0700934 public static final String OPSTR_BODY_SENSORS
935 = "android:body_sensors";
Svet Ganov715cf2a2015-06-13 17:31:29 -0700936 /** Read previously received cell broadcast messages. */
Svet Ganovede43162015-05-02 17:42:44 -0700937 public static final String OPSTR_READ_CELL_BROADCASTS
938 = "android:read_cell_broadcasts";
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700939 /** Inject mock location into the system. */
940 public static final String OPSTR_MOCK_LOCATION
941 = "android:mock_location";
Svet Ganov921c7df2015-06-29 21:51:41 -0700942 /** Read external storage. */
943 public static final String OPSTR_READ_EXTERNAL_STORAGE
944 = "android:read_external_storage";
945 /** Write external storage. */
946 public static final String OPSTR_WRITE_EXTERNAL_STORAGE
947 = "android:write_external_storage";
Billy Lau24b9c832015-07-20 17:34:09 +0100948 /** Required to draw on top of other apps. */
949 public static final String OPSTR_SYSTEM_ALERT_WINDOW
950 = "android:system_alert_window";
951 /** Required to write/modify/update system settingss. */
952 public static final String OPSTR_WRITE_SETTINGS
953 = "android:write_settings";
Svetoslavf3f02ac2015-09-08 14:36:35 -0700954 /** @hide Get device accounts. */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000955 @SystemApi @TestApi
Svetoslavf3f02ac2015-09-08 14:36:35 -0700956 public static final String OPSTR_GET_ACCOUNTS
957 = "android:get_accounts";
Chad Brubaker0c1651f2017-03-30 16:29:10 -0700958 public static final String OPSTR_READ_PHONE_NUMBERS
959 = "android:read_phone_numbers";
Winson Chungf4ac0632017-03-17 12:34:12 -0700960 /** Access to picture-in-picture. */
961 public static final String OPSTR_PICTURE_IN_PICTURE
962 = "android:picture_in_picture";
Chad Brubaker97b383f2017-02-02 15:04:35 -0800963 /** @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000964 @SystemApi @TestApi
Chad Brubaker97b383f2017-02-02 15:04:35 -0800965 public static final String OPSTR_INSTANT_APP_START_FOREGROUND
966 = "android:instant_app_start_foreground";
Eugene Suslacae3d3e2017-01-31 11:08:11 -0800967 /** Answer incoming phone calls */
968 public static final String OPSTR_ANSWER_PHONE_CALLS
969 = "android:answer_phone_calls";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -0800970 /**
971 * Accept call handover
972 * @hide
973 */
974 @SystemApi @TestApi
975 public static final String OPSTR_ACCEPT_HANDOVER
976 = "android:accept_handover";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000977 /** @hide */
978 @SystemApi @TestApi
979 public static final String OPSTR_GPS = "android:gps";
980 /** @hide */
981 @SystemApi @TestApi
982 public static final String OPSTR_VIBRATE = "android:vibrate";
983 /** @hide */
984 @SystemApi @TestApi
985 public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
986 /** @hide */
987 @SystemApi @TestApi
988 public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
989 /** @hide */
990 @SystemApi @TestApi
991 public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
992 /** @hide */
993 @SystemApi @TestApi
994 public static final String OPSTR_WRITE_SMS = "android:write_sms";
995 /** @hide */
996 @SystemApi @TestApi
997 public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST =
998 "android:receive_emergency_broadcast";
999 /** @hide */
1000 @SystemApi @TestApi
1001 public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
1002 /** @hide */
1003 @SystemApi @TestApi
1004 public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
1005 /** @hide */
1006 @SystemApi @TestApi
1007 public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
1008 /** @hide */
1009 @SystemApi @TestApi
1010 public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
1011 /** @hide */
1012 @SystemApi @TestApi
1013 public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
1014 /** @hide */
1015 @SystemApi @TestApi
1016 public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
1017 /** @hide */
1018 @SystemApi @TestApi
1019 public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
1020 /** @hide */
1021 @SystemApi @TestApi
1022 public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
1023 /** @hide */
1024 @SystemApi @TestApi
1025 public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
1026 /** @hide */
1027 @SystemApi @TestApi
1028 public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
1029 /** @hide */
1030 @SystemApi @TestApi
1031 public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
1032 /** @hide */
1033 @SystemApi @TestApi
1034 public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
1035 /** @hide */
1036 @SystemApi @TestApi
1037 public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
1038 /** @hide */
1039 @SystemApi @TestApi
1040 public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME =
1041 "android:audio_notification_volume";
1042 /** @hide */
1043 @SystemApi @TestApi
1044 public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
1045 /** @hide */
1046 @SystemApi @TestApi
1047 public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
1048 /** @hide */
1049 @SystemApi @TestApi
1050 public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
1051 /** @hide */
1052 @SystemApi @TestApi
1053 public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
1054 /** @hide */
1055 @SystemApi @TestApi
1056 public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
1057 /** @hide */
1058 @SystemApi @TestApi
1059 public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
1060 /** @hide */
1061 @SystemApi @TestApi
1062 public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
1063 /** @hide */
1064 @SystemApi @TestApi
1065 public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
1066 /** @hide */
1067 @SystemApi @TestApi
1068 public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
1069 /** @hide */
1070 @SystemApi @TestApi
1071 public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
1072 /** @hide */
1073 @SystemApi @TestApi
1074 public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME =
1075 "android:audio_accessibility_volume";
1076 /** @hide */
1077 @SystemApi @TestApi
1078 public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
1079 /** @hide */
1080 @SystemApi @TestApi
1081 public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
1082 /** @hide */
1083 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001084 public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001085 /** @hide */
1086 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001087 public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001088 /** @hide */
1089 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001090 public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE =
1091 "android:bind_accessibility_service";
Nathan Harold1bb420672018-03-14 17:08:53 -07001092 /** @hide */
1093 @SystemApi @TestApi
1094 public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001095 /** @hide */
1096 @SystemApi @TestApi
1097 public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001098 /** @hide */
1099 public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001100
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001101 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
1102 public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001103
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001104 /** @hide Recognize physical activity. */
1105 public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition";
1106
Hongming Jin228cd012018-11-09 14:47:50 -08001107 /** @hide Financial app read sms. */
1108 public static final String OPSTR_SMS_FINANCIAL_TRANSACTIONS =
1109 "android:sms_financial_transactions";
1110
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001111 /** @hide Read media of audio type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001112 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001113 public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
1114 /** @hide Write media of audio type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001115 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001116 public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
1117 /** @hide Read media of video type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001118 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001119 public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
1120 /** @hide Write media of video type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001121 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001122 public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
1123 /** @hide Read media of image type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001124 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001125 public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
1126 /** @hide Write media of image type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001127 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001128 public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001129 /** @hide Has a legacy (non-isolated) view of storage. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001130 @SystemApi @TestApi
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001131 public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001132 /** @hide Read location metadata from media */
1133 public static final String OPSTR_ACCESS_MEDIA_LOCATION = "android:access_media_location";
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001134
Jackal Guo8dc791e2019-01-14 10:26:42 +08001135 /** @hide Interact with accessibility. */
Joel Galensonff4fe202019-02-06 14:43:58 -08001136 @SystemApi
Jackal Guo8dc791e2019-01-14 10:26:42 +08001137 public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
Michael Groover656ef912019-04-09 17:09:57 -07001138 /** @hide Read device identifiers */
1139 public static final String OPSTR_READ_DEVICE_IDENTIFIERS = "android:read_device_identifiers";
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001140 /** @hide Query all packages on device */
1141 public static final String OPSTR_QUERY_ALL_PACKAGES = "android:query_all_packages";
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001142 /** @hide Access all external storage */
1143 @SystemApi
1144 public static final String OPSTR_MANAGE_EXTERNAL_STORAGE =
1145 "android:manage_external_storage";
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001146
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07001147
1148 /** {@link #sAppOpsToNote} not initialized yet for this op */
1149 private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
1150 /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
1151 private static final byte SHOULD_NOT_COLLECT_NOTE_OP = 1;
1152 /** Should collect noting of this app-op in {@link #sAppOpsToNote} */
1153 private static final byte SHOULD_COLLECT_NOTE_OP = 2;
1154
1155 @Retention(RetentionPolicy.SOURCE)
1156 @IntDef(flag = true, prefix = { "SHOULD_" }, value = {
1157 SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED,
1158 SHOULD_NOT_COLLECT_NOTE_OP,
1159 SHOULD_COLLECT_NOTE_OP
1160 })
1161 private @interface ShouldCollectNoteOp {}
1162
Svet Ganovda0acdf2017-02-15 10:28:51 -08001163 private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
1164 // RUNTIME PERMISSIONS
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001165 // Contacts
1166 OP_READ_CONTACTS,
1167 OP_WRITE_CONTACTS,
1168 OP_GET_ACCOUNTS,
1169 // Calendar
1170 OP_READ_CALENDAR,
1171 OP_WRITE_CALENDAR,
1172 // SMS
1173 OP_SEND_SMS,
1174 OP_RECEIVE_SMS,
1175 OP_READ_SMS,
1176 OP_RECEIVE_WAP_PUSH,
1177 OP_RECEIVE_MMS,
1178 OP_READ_CELL_BROADCASTS,
1179 // Storage
1180 OP_READ_EXTERNAL_STORAGE,
1181 OP_WRITE_EXTERNAL_STORAGE,
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001182 OP_ACCESS_MEDIA_LOCATION,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001183 // Location
1184 OP_COARSE_LOCATION,
1185 OP_FINE_LOCATION,
1186 // Phone
1187 OP_READ_PHONE_STATE,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001188 OP_READ_PHONE_NUMBERS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001189 OP_CALL_PHONE,
1190 OP_READ_CALL_LOG,
1191 OP_WRITE_CALL_LOG,
1192 OP_ADD_VOICEMAIL,
1193 OP_USE_SIP,
1194 OP_PROCESS_OUTGOING_CALLS,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001195 OP_ANSWER_PHONE_CALLS,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001196 OP_ACCEPT_HANDOVER,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001197 // Microphone
1198 OP_RECORD_AUDIO,
1199 // Camera
1200 OP_CAMERA,
1201 // Body sensors
Svet Ganovda0acdf2017-02-15 10:28:51 -08001202 OP_BODY_SENSORS,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001203 // Activity recognition
1204 OP_ACTIVITY_RECOGNITION,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001205 // Aural
1206 OP_READ_MEDIA_AUDIO,
1207 OP_WRITE_MEDIA_AUDIO,
1208 // Visual
1209 OP_READ_MEDIA_VIDEO,
1210 OP_WRITE_MEDIA_VIDEO,
1211 OP_READ_MEDIA_IMAGES,
1212 OP_WRITE_MEDIA_IMAGES,
Svet Ganovda0acdf2017-02-15 10:28:51 -08001213
1214 // APPOP PERMISSIONS
1215 OP_ACCESS_NOTIFICATIONS,
1216 OP_SYSTEM_ALERT_WINDOW,
1217 OP_WRITE_SETTINGS,
1218 OP_REQUEST_INSTALL_PACKAGES,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001219 OP_START_FOREGROUND,
Hongming Jin228cd012018-11-09 14:47:50 -08001220 OP_SMS_FINANCIAL_TRANSACTIONS,
Philip P. Moltmann4b38fbe2019-09-13 21:33:07 -07001221 OP_MANAGE_IPSEC_TUNNELS,
shafik77cabc72020-01-03 16:22:50 +00001222 OP_INSTANT_APP_START_FOREGROUND,
1223 OP_MANAGE_EXTERNAL_STORAGE,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001224 };
1225
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001226 /**
1227 * This maps each operation to the operation that serves as the
1228 * switch to determine whether it is allowed. Generally this is
1229 * a 1:1 mapping, but for some things (like location) that have
1230 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -07001231 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001232 * make them all controlled by the same single operation.
1233 */
1234 private static int[] sOpToSwitch = new int[] {
Dianne Hackbornc216a262018-04-26 13:46:22 -07001235 OP_COARSE_LOCATION, // COARSE_LOCATION
1236 OP_COARSE_LOCATION, // FINE_LOCATION
1237 OP_COARSE_LOCATION, // GPS
1238 OP_VIBRATE, // VIBRATE
1239 OP_READ_CONTACTS, // READ_CONTACTS
1240 OP_WRITE_CONTACTS, // WRITE_CONTACTS
1241 OP_READ_CALL_LOG, // READ_CALL_LOG
1242 OP_WRITE_CALL_LOG, // WRITE_CALL_LOG
1243 OP_READ_CALENDAR, // READ_CALENDAR
1244 OP_WRITE_CALENDAR, // WRITE_CALENDAR
1245 OP_COARSE_LOCATION, // WIFI_SCAN
1246 OP_POST_NOTIFICATION, // POST_NOTIFICATION
1247 OP_COARSE_LOCATION, // NEIGHBORING_CELLS
1248 OP_CALL_PHONE, // CALL_PHONE
1249 OP_READ_SMS, // READ_SMS
1250 OP_WRITE_SMS, // WRITE_SMS
1251 OP_RECEIVE_SMS, // RECEIVE_SMS
1252 OP_RECEIVE_SMS, // RECEIVE_EMERGECY_SMS
1253 OP_RECEIVE_MMS, // RECEIVE_MMS
1254 OP_RECEIVE_WAP_PUSH, // RECEIVE_WAP_PUSH
1255 OP_SEND_SMS, // SEND_SMS
1256 OP_READ_SMS, // READ_ICC_SMS
1257 OP_WRITE_SMS, // WRITE_ICC_SMS
1258 OP_WRITE_SETTINGS, // WRITE_SETTINGS
1259 OP_SYSTEM_ALERT_WINDOW, // SYSTEM_ALERT_WINDOW
1260 OP_ACCESS_NOTIFICATIONS, // ACCESS_NOTIFICATIONS
1261 OP_CAMERA, // CAMERA
1262 OP_RECORD_AUDIO, // RECORD_AUDIO
1263 OP_PLAY_AUDIO, // PLAY_AUDIO
1264 OP_READ_CLIPBOARD, // READ_CLIPBOARD
1265 OP_WRITE_CLIPBOARD, // WRITE_CLIPBOARD
1266 OP_TAKE_MEDIA_BUTTONS, // TAKE_MEDIA_BUTTONS
1267 OP_TAKE_AUDIO_FOCUS, // TAKE_AUDIO_FOCUS
1268 OP_AUDIO_MASTER_VOLUME, // AUDIO_MASTER_VOLUME
1269 OP_AUDIO_VOICE_VOLUME, // AUDIO_VOICE_VOLUME
1270 OP_AUDIO_RING_VOLUME, // AUDIO_RING_VOLUME
1271 OP_AUDIO_MEDIA_VOLUME, // AUDIO_MEDIA_VOLUME
1272 OP_AUDIO_ALARM_VOLUME, // AUDIO_ALARM_VOLUME
1273 OP_AUDIO_NOTIFICATION_VOLUME, // AUDIO_NOTIFICATION_VOLUME
1274 OP_AUDIO_BLUETOOTH_VOLUME, // AUDIO_BLUETOOTH_VOLUME
1275 OP_WAKE_LOCK, // WAKE_LOCK
1276 OP_COARSE_LOCATION, // MONITOR_LOCATION
1277 OP_COARSE_LOCATION, // MONITOR_HIGH_POWER_LOCATION
1278 OP_GET_USAGE_STATS, // GET_USAGE_STATS
1279 OP_MUTE_MICROPHONE, // MUTE_MICROPHONE
1280 OP_TOAST_WINDOW, // TOAST_WINDOW
1281 OP_PROJECT_MEDIA, // PROJECT_MEDIA
1282 OP_ACTIVATE_VPN, // ACTIVATE_VPN
1283 OP_WRITE_WALLPAPER, // WRITE_WALLPAPER
1284 OP_ASSIST_STRUCTURE, // ASSIST_STRUCTURE
1285 OP_ASSIST_SCREENSHOT, // ASSIST_SCREENSHOT
1286 OP_READ_PHONE_STATE, // READ_PHONE_STATE
1287 OP_ADD_VOICEMAIL, // ADD_VOICEMAIL
1288 OP_USE_SIP, // USE_SIP
1289 OP_PROCESS_OUTGOING_CALLS, // PROCESS_OUTGOING_CALLS
1290 OP_USE_FINGERPRINT, // USE_FINGERPRINT
1291 OP_BODY_SENSORS, // BODY_SENSORS
1292 OP_READ_CELL_BROADCASTS, // READ_CELL_BROADCASTS
1293 OP_MOCK_LOCATION, // MOCK_LOCATION
1294 OP_READ_EXTERNAL_STORAGE, // READ_EXTERNAL_STORAGE
1295 OP_WRITE_EXTERNAL_STORAGE, // WRITE_EXTERNAL_STORAGE
1296 OP_TURN_SCREEN_ON, // TURN_SCREEN_ON
1297 OP_GET_ACCOUNTS, // GET_ACCOUNTS
1298 OP_RUN_IN_BACKGROUND, // RUN_IN_BACKGROUND
1299 OP_AUDIO_ACCESSIBILITY_VOLUME, // AUDIO_ACCESSIBILITY_VOLUME
1300 OP_READ_PHONE_NUMBERS, // READ_PHONE_NUMBERS
1301 OP_REQUEST_INSTALL_PACKAGES, // REQUEST_INSTALL_PACKAGES
1302 OP_PICTURE_IN_PICTURE, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
1303 OP_INSTANT_APP_START_FOREGROUND, // INSTANT_APP_START_FOREGROUND
1304 OP_ANSWER_PHONE_CALLS, // ANSWER_PHONE_CALLS
1305 OP_RUN_ANY_IN_BACKGROUND, // OP_RUN_ANY_IN_BACKGROUND
1306 OP_CHANGE_WIFI_STATE, // OP_CHANGE_WIFI_STATE
1307 OP_REQUEST_DELETE_PACKAGES, // OP_REQUEST_DELETE_PACKAGES
1308 OP_BIND_ACCESSIBILITY_SERVICE, // OP_BIND_ACCESSIBILITY_SERVICE
1309 OP_ACCEPT_HANDOVER, // ACCEPT_HANDOVER
1310 OP_MANAGE_IPSEC_TUNNELS, // MANAGE_IPSEC_HANDOVERS
1311 OP_START_FOREGROUND, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001312 OP_COARSE_LOCATION, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001313 OP_USE_BIOMETRIC, // BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001314 OP_ACTIVITY_RECOGNITION, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001315 OP_SMS_FINANCIAL_TRANSACTIONS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001316 OP_READ_MEDIA_AUDIO, // READ_MEDIA_AUDIO
1317 OP_WRITE_MEDIA_AUDIO, // WRITE_MEDIA_AUDIO
1318 OP_READ_MEDIA_VIDEO, // READ_MEDIA_VIDEO
1319 OP_WRITE_MEDIA_VIDEO, // WRITE_MEDIA_VIDEO
1320 OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES
1321 OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001322 OP_LEGACY_STORAGE, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001323 OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001324 OP_READ_DEVICE_IDENTIFIERS, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001325 OP_ACCESS_MEDIA_LOCATION, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001326 OP_QUERY_ALL_PACKAGES, // QUERY_ALL_PACKAGES
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001327 OP_MANAGE_EXTERNAL_STORAGE, // MANAGE_EXTERNAL_STORAGE
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001328 };
1329
1330 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001331 * This maps each operation to the public string constant for it.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001332 */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001333 private static String[] sOpToString = new String[]{
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001334 OPSTR_COARSE_LOCATION,
1335 OPSTR_FINE_LOCATION,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001336 OPSTR_GPS,
1337 OPSTR_VIBRATE,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001338 OPSTR_READ_CONTACTS,
1339 OPSTR_WRITE_CONTACTS,
1340 OPSTR_READ_CALL_LOG,
1341 OPSTR_WRITE_CALL_LOG,
1342 OPSTR_READ_CALENDAR,
1343 OPSTR_WRITE_CALENDAR,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001344 OPSTR_WIFI_SCAN,
1345 OPSTR_POST_NOTIFICATION,
1346 OPSTR_NEIGHBORING_CELLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001347 OPSTR_CALL_PHONE,
1348 OPSTR_READ_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001349 OPSTR_WRITE_SMS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001350 OPSTR_RECEIVE_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001351 OPSTR_RECEIVE_EMERGENCY_BROADCAST,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001352 OPSTR_RECEIVE_MMS,
1353 OPSTR_RECEIVE_WAP_PUSH,
1354 OPSTR_SEND_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001355 OPSTR_READ_ICC_SMS,
1356 OPSTR_WRITE_ICC_SMS,
Billy Lau24b9c832015-07-20 17:34:09 +01001357 OPSTR_WRITE_SETTINGS,
1358 OPSTR_SYSTEM_ALERT_WINDOW,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001359 OPSTR_ACCESS_NOTIFICATIONS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001360 OPSTR_CAMERA,
1361 OPSTR_RECORD_AUDIO,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001362 OPSTR_PLAY_AUDIO,
1363 OPSTR_READ_CLIPBOARD,
1364 OPSTR_WRITE_CLIPBOARD,
1365 OPSTR_TAKE_MEDIA_BUTTONS,
1366 OPSTR_TAKE_AUDIO_FOCUS,
1367 OPSTR_AUDIO_MASTER_VOLUME,
1368 OPSTR_AUDIO_VOICE_VOLUME,
1369 OPSTR_AUDIO_RING_VOLUME,
1370 OPSTR_AUDIO_MEDIA_VOLUME,
1371 OPSTR_AUDIO_ALARM_VOLUME,
1372 OPSTR_AUDIO_NOTIFICATION_VOLUME,
1373 OPSTR_AUDIO_BLUETOOTH_VOLUME,
1374 OPSTR_WAKE_LOCK,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001375 OPSTR_MONITOR_LOCATION,
1376 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -07001377 OPSTR_GET_USAGE_STATS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001378 OPSTR_MUTE_MICROPHONE,
1379 OPSTR_TOAST_WINDOW,
1380 OPSTR_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -07001381 OPSTR_ACTIVATE_VPN,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001382 OPSTR_WRITE_WALLPAPER,
1383 OPSTR_ASSIST_STRUCTURE,
1384 OPSTR_ASSIST_SCREENSHOT,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001385 OPSTR_READ_PHONE_STATE,
1386 OPSTR_ADD_VOICEMAIL,
1387 OPSTR_USE_SIP,
Svet Ganov824ad6e2016-09-22 19:36:53 -07001388 OPSTR_PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001389 OPSTR_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001390 OPSTR_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001391 OPSTR_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001392 OPSTR_MOCK_LOCATION,
1393 OPSTR_READ_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001394 OPSTR_WRITE_EXTERNAL_STORAGE,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001395 OPSTR_TURN_SCREEN_ON,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001396 OPSTR_GET_ACCOUNTS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001397 OPSTR_RUN_IN_BACKGROUND,
1398 OPSTR_AUDIO_ACCESSIBILITY_VOLUME,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001399 OPSTR_READ_PHONE_NUMBERS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001400 OPSTR_REQUEST_INSTALL_PACKAGES,
Winson Chungf4ac0632017-03-17 12:34:12 -07001401 OPSTR_PICTURE_IN_PICTURE,
Chad Brubaker97b383f2017-02-02 15:04:35 -08001402 OPSTR_INSTANT_APP_START_FOREGROUND,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001403 OPSTR_ANSWER_PHONE_CALLS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001404 OPSTR_RUN_ANY_IN_BACKGROUND,
1405 OPSTR_CHANGE_WIFI_STATE,
1406 OPSTR_REQUEST_DELETE_PACKAGES,
1407 OPSTR_BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001408 OPSTR_ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001409 OPSTR_MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001410 OPSTR_START_FOREGROUND,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001411 OPSTR_BLUETOOTH_SCAN,
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001412 OPSTR_USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001413 OPSTR_ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001414 OPSTR_SMS_FINANCIAL_TRANSACTIONS,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001415 OPSTR_READ_MEDIA_AUDIO,
1416 OPSTR_WRITE_MEDIA_AUDIO,
1417 OPSTR_READ_MEDIA_VIDEO,
1418 OPSTR_WRITE_MEDIA_VIDEO,
1419 OPSTR_READ_MEDIA_IMAGES,
1420 OPSTR_WRITE_MEDIA_IMAGES,
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001421 OPSTR_LEGACY_STORAGE,
Jackal Guo8dc791e2019-01-14 10:26:42 +08001422 OPSTR_ACCESS_ACCESSIBILITY,
Michael Groover656ef912019-04-09 17:09:57 -07001423 OPSTR_READ_DEVICE_IDENTIFIERS,
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001424 OPSTR_ACCESS_MEDIA_LOCATION,
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001425 OPSTR_QUERY_ALL_PACKAGES,
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001426 OPSTR_MANAGE_EXTERNAL_STORAGE,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001427 };
1428
1429 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001430 * This provides a simple name for each operation to be used
1431 * in debug output.
1432 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001433 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001434 "COARSE_LOCATION",
1435 "FINE_LOCATION",
1436 "GPS",
1437 "VIBRATE",
1438 "READ_CONTACTS",
1439 "WRITE_CONTACTS",
1440 "READ_CALL_LOG",
1441 "WRITE_CALL_LOG",
1442 "READ_CALENDAR",
1443 "WRITE_CALENDAR",
1444 "WIFI_SCAN",
1445 "POST_NOTIFICATION",
1446 "NEIGHBORING_CELLS",
1447 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001448 "READ_SMS",
1449 "WRITE_SMS",
1450 "RECEIVE_SMS",
1451 "RECEIVE_EMERGECY_SMS",
1452 "RECEIVE_MMS",
1453 "RECEIVE_WAP_PUSH",
1454 "SEND_SMS",
1455 "READ_ICC_SMS",
1456 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -08001457 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -08001458 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001459 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001460 "CAMERA",
1461 "RECORD_AUDIO",
1462 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001463 "READ_CLIPBOARD",
1464 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001465 "TAKE_MEDIA_BUTTONS",
1466 "TAKE_AUDIO_FOCUS",
1467 "AUDIO_MASTER_VOLUME",
1468 "AUDIO_VOICE_VOLUME",
1469 "AUDIO_RING_VOLUME",
1470 "AUDIO_MEDIA_VOLUME",
1471 "AUDIO_ALARM_VOLUME",
1472 "AUDIO_NOTIFICATION_VOLUME",
1473 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -07001474 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001475 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -07001476 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -04001477 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001478 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -04001479 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001480 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -07001481 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +00001482 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001483 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -07001484 "ASSIST_SCREENSHOT",
Eugene Suslae4ee2c22018-11-05 12:23:30 -08001485 "READ_PHONE_STATE",
Svetoslav5335b672015-04-29 12:00:51 -07001486 "ADD_VOICEMAIL",
Svetoslavc656e6f2015-04-29 14:08:16 -07001487 "USE_SIP",
Svetoslav4af76a52015-04-29 15:29:46 -07001488 "PROCESS_OUTGOING_CALLS",
Svet Ganovb9d71a62015-04-30 10:38:13 -07001489 "USE_FINGERPRINT",
Svet Ganovede43162015-05-02 17:42:44 -07001490 "BODY_SENSORS",
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001491 "READ_CELL_BROADCASTS",
Svet Ganov921c7df2015-06-29 21:51:41 -07001492 "MOCK_LOCATION",
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001493 "READ_EXTERNAL_STORAGE",
1494 "WRITE_EXTERNAL_STORAGE",
1495 "TURN_ON_SCREEN",
Svetoslavf3f02ac2015-09-08 14:36:35 -07001496 "GET_ACCOUNTS",
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001497 "RUN_IN_BACKGROUND",
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001498 "AUDIO_ACCESSIBILITY_VOLUME",
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001499 "READ_PHONE_NUMBERS",
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001500 "REQUEST_INSTALL_PACKAGES",
Winson Chungf4ac0632017-03-17 12:34:12 -07001501 "PICTURE_IN_PICTURE",
Chad Brubaker97b383f2017-02-02 15:04:35 -08001502 "INSTANT_APP_START_FOREGROUND",
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001503 "ANSWER_PHONE_CALLS",
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001504 "RUN_ANY_IN_BACKGROUND",
Peter Visontay1246d9e2017-10-17 17:02:45 +01001505 "CHANGE_WIFI_STATE",
Peter Visontayf2e38362017-11-27 15:27:16 +00001506 "REQUEST_DELETE_PACKAGES",
Peter Visontay11950832017-11-14 19:34:59 +00001507 "BIND_ACCESSIBILITY_SERVICE",
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001508 "ACCEPT_HANDOVER",
Nathan Harold1bb420672018-03-14 17:08:53 -07001509 "MANAGE_IPSEC_TUNNELS",
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001510 "START_FOREGROUND",
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001511 "BLUETOOTH_SCAN",
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001512 "USE_BIOMETRIC",
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001513 "ACTIVITY_RECOGNITION",
Hongming Jin228cd012018-11-09 14:47:50 -08001514 "SMS_FINANCIAL_TRANSACTIONS",
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001515 "READ_MEDIA_AUDIO",
1516 "WRITE_MEDIA_AUDIO",
1517 "READ_MEDIA_VIDEO",
1518 "WRITE_MEDIA_VIDEO",
1519 "READ_MEDIA_IMAGES",
1520 "WRITE_MEDIA_IMAGES",
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001521 "LEGACY_STORAGE",
Jackal Guo8dc791e2019-01-14 10:26:42 +08001522 "ACCESS_ACCESSIBILITY",
Michael Groover656ef912019-04-09 17:09:57 -07001523 "READ_DEVICE_IDENTIFIERS",
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001524 "ACCESS_MEDIA_LOCATION",
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001525 "QUERY_ALL_PACKAGES",
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001526 "MANAGE_EXTERNAL_STORAGE"
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001527 };
1528
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001529 /**
1530 * This optionally maps a permission to an operation. If there
1531 * is no permission associated with an operation, it is null.
1532 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001533 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001534 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001535 android.Manifest.permission.ACCESS_COARSE_LOCATION,
1536 android.Manifest.permission.ACCESS_FINE_LOCATION,
1537 null,
1538 android.Manifest.permission.VIBRATE,
1539 android.Manifest.permission.READ_CONTACTS,
1540 android.Manifest.permission.WRITE_CONTACTS,
1541 android.Manifest.permission.READ_CALL_LOG,
1542 android.Manifest.permission.WRITE_CALL_LOG,
1543 android.Manifest.permission.READ_CALENDAR,
1544 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001545 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -04001546 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001547 null, // neighboring cells shares the coarse location perm
1548 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001549 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001550 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001551 android.Manifest.permission.RECEIVE_SMS,
1552 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
1553 android.Manifest.permission.RECEIVE_MMS,
1554 android.Manifest.permission.RECEIVE_WAP_PUSH,
1555 android.Manifest.permission.SEND_SMS,
1556 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001557 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -08001558 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -08001559 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001560 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001561 android.Manifest.permission.CAMERA,
1562 android.Manifest.permission.RECORD_AUDIO,
1563 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001564 null, // no permission for reading clipboard
1565 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001566 null, // no permission for taking media buttons
1567 null, // no permission for taking audio focus
1568 null, // no permission for changing master volume
1569 null, // no permission for changing voice volume
1570 null, // no permission for changing ring volume
1571 null, // no permission for changing media volume
1572 null, // no permission for changing alarm volume
1573 null, // no permission for changing notification volume
1574 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -07001575 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001576 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -07001577 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -07001578 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -04001579 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -04001580 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -07001581 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -07001582 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +00001583 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001584 null, // no permission for receiving assist structure
1585 null, // no permission for receiving assist screenshot
Svet Ganovc3300092015-04-17 09:07:22 -07001586 Manifest.permission.READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -07001587 Manifest.permission.ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -07001588 Manifest.permission.USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -07001589 Manifest.permission.PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001590 Manifest.permission.USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001591 Manifest.permission.BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001592 Manifest.permission.READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001593 null,
1594 Manifest.permission.READ_EXTERNAL_STORAGE,
1595 Manifest.permission.WRITE_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001596 null, // no permission for turning the screen on
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001597 Manifest.permission.GET_ACCOUNTS,
1598 null, // no permission for running in background
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001599 null, // no permission for changing accessibility volume
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001600 Manifest.permission.READ_PHONE_NUMBERS,
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001601 Manifest.permission.REQUEST_INSTALL_PACKAGES,
Winson Chung59fda9e2017-01-20 16:14:51 -08001602 null, // no permission for entering picture-in-picture on hide
Chad Brubaker97b383f2017-02-02 15:04:35 -08001603 Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001604 Manifest.permission.ANSWER_PHONE_CALLS,
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001605 null, // no permission for OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001606 Manifest.permission.CHANGE_WIFI_STATE,
Peter Visontayf2e38362017-11-27 15:27:16 +00001607 Manifest.permission.REQUEST_DELETE_PACKAGES,
Peter Visontay11950832017-11-14 19:34:59 +00001608 Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001609 Manifest.permission.ACCEPT_HANDOVER,
Philip P. Moltmann4b38fbe2019-09-13 21:33:07 -07001610 Manifest.permission.MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001611 Manifest.permission.FOREGROUND_SERVICE,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001612 null, // no permission for OP_BLUETOOTH_SCAN
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001613 Manifest.permission.USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001614 Manifest.permission.ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001615 Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001616 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001617 null, // no permission for OP_WRITE_MEDIA_AUDIO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001618 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001619 null, // no permission for OP_WRITE_MEDIA_VIDEO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001620 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001621 null, // no permission for OP_WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001622 null, // no permission for OP_LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001623 null, // no permission for OP_ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001624 null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001625 Manifest.permission.ACCESS_MEDIA_LOCATION,
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001626 null, // no permission for OP_QUERY_ALL_PACKAGES
shafik77cabc72020-01-03 16:22:50 +00001627 Manifest.permission.MANAGE_EXTERNAL_STORAGE,
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001628 };
1629
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001630 /**
Jason Monk62062992014-05-06 09:55:28 -04001631 * Specifies whether an Op should be restricted by a user restriction.
1632 * Each Op should be filled with a restriction string from UserManager or
1633 * null to specify it is not affected by any user restriction.
1634 */
1635 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -04001636 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
1637 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
1638 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -04001639 null, //VIBRATE
1640 null, //READ_CONTACTS
1641 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -07001642 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
1643 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -04001644 null, //READ_CALENDAR
1645 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001646 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -04001647 null, //POST_NOTIFICATION
1648 null, //NEIGHBORING_CELLS
1649 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001650 UserManager.DISALLOW_SMS, //READ_SMS
1651 UserManager.DISALLOW_SMS, //WRITE_SMS
1652 UserManager.DISALLOW_SMS, //RECEIVE_SMS
1653 null, //RECEIVE_EMERGENCY_SMS
1654 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -04001655 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001656 UserManager.DISALLOW_SMS, //SEND_SMS
1657 UserManager.DISALLOW_SMS, //READ_ICC_SMS
1658 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -04001659 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -04001660 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -04001661 null, //ACCESS_NOTIFICATIONS
Makoto Onuki759a7632015-10-28 16:43:10 -07001662 UserManager.DISALLOW_CAMERA, //CAMERA
Fyodor Kupolovb5013302015-04-17 17:59:14 -07001663 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
Jason Monk62062992014-05-06 09:55:28 -04001664 null, //PLAY_AUDIO
1665 null, //READ_CLIPBOARD
1666 null, //WRITE_CLIPBOARD
1667 null, //TAKE_MEDIA_BUTTONS
1668 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -04001669 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
1670 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
1671 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
1672 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
1673 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
1674 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
1675 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -04001676 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -04001677 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
1678 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -04001679 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -04001680 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -04001681 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -07001682 null, //PROJECT_MEDIA
Tony Mak33d03a92016-06-02 15:01:16 +01001683 null, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001684 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001685 null, // ASSIST_STRUCTURE
1686 null, // ASSIST_SCREENSHOT
Svet Ganovc3300092015-04-17 09:07:22 -07001687 null, // READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001688 null, // ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001689 null, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001690 null, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001691 null, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001692 null, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001693 null, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001694 null, // MOCK_LOCATION
1695 null, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001696 null, // WRITE_EXTERNAL_STORAGE
1697 null, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001698 null, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001699 null, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001700 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001701 null, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001702 null, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001703 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001704 null, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001705 null, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001706 null, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001707 null, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001708 null, // REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001709 null, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001710 null, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001711 null, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001712 null, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001713 null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001714 null, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001715 null, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001716 UserManager.DISALLOW_SMS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001717 null, // READ_MEDIA_AUDIO
1718 null, // WRITE_MEDIA_AUDIO
1719 null, // READ_MEDIA_VIDEO
1720 null, // WRITE_MEDIA_VIDEO
1721 null, // READ_MEDIA_IMAGES
1722 null, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001723 null, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001724 null, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001725 null, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001726 null, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001727 null, // QUERY_ALL_PACKAGES
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001728 null, // MANAGE_EXTERNAL_STORAGE
Jason Monk1c7c3192014-06-26 12:52:18 -04001729 };
1730
1731 /**
1732 * This specifies whether each option should allow the system
1733 * (and system ui) to bypass the user restriction when active.
1734 */
1735 private static boolean[] sOpAllowSystemRestrictionBypass = new boolean[] {
Fyodor Kupolov639e73d2016-02-25 11:58:21 -08001736 true, //COARSE_LOCATION
1737 true, //FINE_LOCATION
Jason Monk1c7c3192014-06-26 12:52:18 -04001738 false, //GPS
1739 false, //VIBRATE
1740 false, //READ_CONTACTS
1741 false, //WRITE_CONTACTS
1742 false, //READ_CALL_LOG
1743 false, //WRITE_CALL_LOG
1744 false, //READ_CALENDAR
1745 false, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001746 true, //WIFI_SCAN
Jason Monk1c7c3192014-06-26 12:52:18 -04001747 false, //POST_NOTIFICATION
1748 false, //NEIGHBORING_CELLS
1749 false, //CALL_PHONE
1750 false, //READ_SMS
1751 false, //WRITE_SMS
1752 false, //RECEIVE_SMS
1753 false, //RECEIVE_EMERGECY_SMS
1754 false, //RECEIVE_MMS
1755 false, //RECEIVE_WAP_PUSH
1756 false, //SEND_SMS
1757 false, //READ_ICC_SMS
1758 false, //WRITE_ICC_SMS
1759 false, //WRITE_SETTINGS
1760 true, //SYSTEM_ALERT_WINDOW
1761 false, //ACCESS_NOTIFICATIONS
1762 false, //CAMERA
1763 false, //RECORD_AUDIO
1764 false, //PLAY_AUDIO
1765 false, //READ_CLIPBOARD
1766 false, //WRITE_CLIPBOARD
1767 false, //TAKE_MEDIA_BUTTONS
1768 false, //TAKE_AUDIO_FOCUS
1769 false, //AUDIO_MASTER_VOLUME
1770 false, //AUDIO_VOICE_VOLUME
1771 false, //AUDIO_RING_VOLUME
1772 false, //AUDIO_MEDIA_VOLUME
1773 false, //AUDIO_ALARM_VOLUME
1774 false, //AUDIO_NOTIFICATION_VOLUME
1775 false, //AUDIO_BLUETOOTH_VOLUME
1776 false, //WAKE_LOCK
1777 false, //MONITOR_LOCATION
1778 false, //MONITOR_HIGH_POWER_LOCATION
1779 false, //GET_USAGE_STATS
Michael Wrightc39d47a2014-07-08 18:07:36 -07001780 false, //MUTE_MICROPHONE
1781 true, //TOAST_WINDOW
1782 false, //PROJECT_MEDIA
Jeff Davidson05542602014-08-11 14:07:27 -07001783 false, //ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00001784 false, //WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001785 false, //ASSIST_STRUCTURE
1786 false, //ASSIST_SCREENSHOT
Svet Ganov16a16892015-04-16 10:32:04 -07001787 false, //READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07001788 false, //ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07001789 false, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07001790 false, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07001791 false, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07001792 false, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001793 false, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07001794 false, // MOCK_LOCATION
1795 false, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001796 false, // WRITE_EXTERNAL_STORAGE
1797 false, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07001798 false, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001799 false, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001800 false, // AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001801 false, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001802 false, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08001803 false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08001804 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001805 false, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001806 false, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001807 false, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00001808 false, // OP_REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00001809 false, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001810 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07001811 false, // MANAGE_IPSEC_HANDOVERS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001812 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001813 true, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001814 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001815 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001816 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001817 false, // READ_MEDIA_AUDIO
1818 false, // WRITE_MEDIA_AUDIO
1819 false, // READ_MEDIA_VIDEO
1820 false, // WRITE_MEDIA_VIDEO
1821 false, // READ_MEDIA_IMAGES
1822 false, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001823 false, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001824 false, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001825 false, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001826 false, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001827 false, // QUERY_ALL_PACKAGES
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001828 false, // MANAGE_EXTERNAL_STORAGE
Jason Monk62062992014-05-06 09:55:28 -04001829 };
1830
1831 /**
David Braunf5d83192013-09-16 13:43:51 -07001832 * This specifies the default mode for each operation.
1833 */
1834 private static int[] sOpDefaultMode = new int[] {
Eugene Susla93519852018-06-13 16:44:31 -07001835 AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION
1836 AppOpsManager.MODE_ALLOWED, // FINE_LOCATION
1837 AppOpsManager.MODE_ALLOWED, // GPS
1838 AppOpsManager.MODE_ALLOWED, // VIBRATE
1839 AppOpsManager.MODE_ALLOWED, // READ_CONTACTS
1840 AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS
Svet Ganovd563e932019-04-14 13:07:41 -07001841 AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG
1842 AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG
Eugene Susla93519852018-06-13 16:44:31 -07001843 AppOpsManager.MODE_ALLOWED, // READ_CALENDAR
1844 AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR
1845 AppOpsManager.MODE_ALLOWED, // WIFI_SCAN
1846 AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION
1847 AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS
1848 AppOpsManager.MODE_ALLOWED, // CALL_PHONE
Svet Ganovd563e932019-04-14 13:07:41 -07001849 AppOpsManager.MODE_ALLOWED, // READ_SMS
Eugene Suslaaaff0072018-10-30 13:35:03 -07001850 AppOpsManager.MODE_IGNORED, // WRITE_SMS
Svet Ganovd563e932019-04-14 13:07:41 -07001851 AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001852 AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST
Svet Ganovd563e932019-04-14 13:07:41 -07001853 AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS
1854 AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH
1855 AppOpsManager.MODE_ALLOWED, // SEND_SMS
Eugene Susla93519852018-06-13 16:44:31 -07001856 AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS
1857 AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS
1858 AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS
Ng Zhi An65a99b62018-10-01 11:57:53 -07001859 getSystemAlertWindowDefault(), // SYSTEM_ALERT_WINDOW
Eugene Susla93519852018-06-13 16:44:31 -07001860 AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS
1861 AppOpsManager.MODE_ALLOWED, // CAMERA
1862 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO
1863 AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO
1864 AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD
1865 AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD
1866 AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS
1867 AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS
1868 AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME
1869 AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME
1870 AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME
1871 AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME
1872 AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME
1873 AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME
1874 AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME
1875 AppOpsManager.MODE_ALLOWED, // WAKE_LOCK
1876 AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION
1877 AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION
1878 AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS
1879 AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE
1880 AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW
1881 AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA
1882 AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN
1883 AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER
1884 AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE
1885 AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT
1886 AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE
1887 AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL
1888 AppOpsManager.MODE_ALLOWED, // USE_SIP
Svet Ganovd563e932019-04-14 13:07:41 -07001889 AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07001890 AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT
1891 AppOpsManager.MODE_ALLOWED, // BODY_SENSORS
Svet Ganovd563e932019-04-14 13:07:41 -07001892 AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS
Eugene Susla93519852018-06-13 16:44:31 -07001893 AppOpsManager.MODE_ERRORED, // MOCK_LOCATION
1894 AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE
1895 AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE
1896 AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON
1897 AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS
1898 AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND
1899 AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME
1900 AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS
1901 AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES
1902 AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE
1903 AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND
1904 AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
1905 AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND
1906 AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE
1907 AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES
1908 AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE
1909 AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER
1910 AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS
1911 AppOpsManager.MODE_ALLOWED, // START_FOREGROUND
1912 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN
1913 AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001914 AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001915 AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001916 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001917 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001918 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001919 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001920 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001921 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001922 AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001923 AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001924 AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001925 AppOpsManager.MODE_ALLOWED, // ALLOW_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001926 AppOpsManager.MODE_DEFAULT, // QUERY_ALL_PACKAGES
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001927 AppOpsManager.MODE_DEFAULT, // MANAGE_EXTERNAL_STORAGE
David Braunf5d83192013-09-16 13:43:51 -07001928 };
1929
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07001930 /**
1931 * This specifies whether each option is allowed to be reset
1932 * when resetting all app preferences. Disable reset for
1933 * app ops that are under strong control of some part of the
1934 * system (such as OP_WRITE_SMS, which should be allowed only
1935 * for whichever app is selected as the current SMS app).
1936 */
1937 private static boolean[] sOpDisableReset = new boolean[] {
Eugene Susla93519852018-06-13 16:44:31 -07001938 false, // COARSE_LOCATION
1939 false, // FINE_LOCATION
1940 false, // GPS
1941 false, // VIBRATE
1942 false, // READ_CONTACTS
1943 false, // WRITE_CONTACTS
1944 false, // READ_CALL_LOG
1945 false, // WRITE_CALL_LOG
1946 false, // READ_CALENDAR
1947 false, // WRITE_CALENDAR
1948 false, // WIFI_SCAN
1949 false, // POST_NOTIFICATION
1950 false, // NEIGHBORING_CELLS
1951 false, // CALL_PHONE
1952 true, // READ_SMS
1953 true, // WRITE_SMS
1954 true, // RECEIVE_SMS
1955 false, // RECEIVE_EMERGENCY_BROADCAST
1956 false, // RECEIVE_MMS
1957 true, // RECEIVE_WAP_PUSH
1958 true, // SEND_SMS
1959 false, // READ_ICC_SMS
1960 false, // WRITE_ICC_SMS
1961 false, // WRITE_SETTINGS
1962 false, // SYSTEM_ALERT_WINDOW
1963 false, // ACCESS_NOTIFICATIONS
1964 false, // CAMERA
1965 false, // RECORD_AUDIO
1966 false, // PLAY_AUDIO
1967 false, // READ_CLIPBOARD
1968 false, // WRITE_CLIPBOARD
1969 false, // TAKE_MEDIA_BUTTONS
1970 false, // TAKE_AUDIO_FOCUS
1971 false, // AUDIO_MASTER_VOLUME
1972 false, // AUDIO_VOICE_VOLUME
1973 false, // AUDIO_RING_VOLUME
1974 false, // AUDIO_MEDIA_VOLUME
1975 false, // AUDIO_ALARM_VOLUME
1976 false, // AUDIO_NOTIFICATION_VOLUME
1977 false, // AUDIO_BLUETOOTH_VOLUME
1978 false, // WAKE_LOCK
1979 false, // MONITOR_LOCATION
1980 false, // MONITOR_HIGH_POWER_LOCATION
1981 false, // GET_USAGE_STATS
1982 false, // MUTE_MICROPHONE
1983 false, // TOAST_WINDOW
1984 false, // PROJECT_MEDIA
1985 false, // ACTIVATE_VPN
1986 false, // WRITE_WALLPAPER
1987 false, // ASSIST_STRUCTURE
1988 false, // ASSIST_SCREENSHOT
1989 false, // READ_PHONE_STATE
1990 false, // ADD_VOICEMAIL
1991 false, // USE_SIP
1992 false, // PROCESS_OUTGOING_CALLS
1993 false, // USE_FINGERPRINT
1994 false, // BODY_SENSORS
1995 true, // READ_CELL_BROADCASTS
1996 false, // MOCK_LOCATION
1997 false, // READ_EXTERNAL_STORAGE
1998 false, // WRITE_EXTERNAL_STORAGE
1999 false, // TURN_SCREEN_ON
2000 false, // GET_ACCOUNTS
2001 false, // RUN_IN_BACKGROUND
2002 false, // AUDIO_ACCESSIBILITY_VOLUME
2003 false, // READ_PHONE_NUMBERS
2004 false, // REQUEST_INSTALL_PACKAGES
2005 false, // PICTURE_IN_PICTURE
2006 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08002007 false, // ANSWER_PHONE_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07002008 false, // RUN_ANY_IN_BACKGROUND
2009 false, // CHANGE_WIFI_STATE
2010 false, // REQUEST_DELETE_PACKAGES
2011 false, // BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002012 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07002013 false, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07002014 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07002015 false, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07002016 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01002017 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08002018 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07002019 false, // READ_MEDIA_AUDIO
2020 false, // WRITE_MEDIA_AUDIO
2021 false, // READ_MEDIA_VIDEO
2022 false, // WRITE_MEDIA_VIDEO
2023 false, // READ_MEDIA_IMAGES
2024 false, // WRITE_MEDIA_IMAGES
Zimc72c9d12019-11-27 15:49:33 +00002025 true, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08002026 false, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07002027 false, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07002028 false, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07002029 false, // QUERY_ALL_PACKAGES
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08002030 false, // MANAGE_EXTERNAL_STORAGE
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002031 };
2032
Svet Ganovfbf01f72015-04-28 18:39:06 -07002033 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07002034 * Mapping from an app op name to the app op code.
Svet Ganovfbf01f72015-04-28 18:39:06 -07002035 */
Svet Ganovb9d71a62015-04-30 10:38:13 -07002036 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
Svet Ganovfbf01f72015-04-28 18:39:06 -07002037
Svet Ganovb9d71a62015-04-30 10:38:13 -07002038 /**
2039 * Mapping from a permission to the corresponding app op.
2040 */
Svet Ganovda0acdf2017-02-15 10:28:51 -08002041 private static HashMap<String, Integer> sPermToOp = new HashMap<>();
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002042
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002043 /**
2044 * Set to the uid of the caller if this thread is currently executing a two-way binder
2045 * transaction. Not set if this thread is currently not executing a two way binder transaction.
2046 *
2047 * @see #startNotedAppOpsCollection
Philip P. Moltmannda554e42019-12-20 11:21:02 -08002048 * @see #getNotedOpCollectionMode
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002049 */
2050 private static final ThreadLocal<Integer> sBinderThreadCallingUid = new ThreadLocal<>();
2051
2052 /**
2053 * If a thread is currently executing a two-way binder transaction, this stores the op-codes of
2054 * the app-ops that were noted during this transaction.
2055 *
Philip P. Moltmannda554e42019-12-20 11:21:02 -08002056 * @see #getNotedOpCollectionMode
2057 * @see #collectNotedOpSync
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002058 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002059 private static final ThreadLocal<ArrayMap<String, long[]>> sAppOpsNotedInThisBinderTransaction =
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002060 new ThreadLocal<>();
2061
2062 /** Whether noting for an appop should be collected */
2063 private static final @ShouldCollectNoteOp byte[] sAppOpsToNote = new byte[_NUM_OP];
2064
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002065 static {
2066 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002067 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002068 + " should be " + _NUM_OP);
2069 }
2070 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002071 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002072 + " should be " + _NUM_OP);
2073 }
2074 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002075 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002076 + " should be " + _NUM_OP);
2077 }
2078 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002079 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002080 + " should be " + _NUM_OP);
2081 }
2082 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002083 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
2084 + " should be " + _NUM_OP);
2085 }
2086 if (sOpDisableReset.length != _NUM_OP) {
2087 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002088 + " should be " + _NUM_OP);
2089 }
Jason Monk62062992014-05-06 09:55:28 -04002090 if (sOpRestrictions.length != _NUM_OP) {
2091 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
2092 + " should be " + _NUM_OP);
2093 }
Jason Monk1c7c3192014-06-26 12:52:18 -04002094 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
2095 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
2096 + sOpRestrictions.length + " should be " + _NUM_OP);
2097 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002098 for (int i=0; i<_NUM_OP; i++) {
2099 if (sOpToString[i] != null) {
2100 sOpStrToOp.put(sOpToString[i], i);
2101 }
2102 }
Svet Ganovda0acdf2017-02-15 10:28:51 -08002103 for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07002104 if (sOpPerms[op] != null) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002105 sPermToOp.put(sOpPerms[op], op);
Svet Ganovb9d71a62015-04-30 10:38:13 -07002106 }
2107 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002108
2109 if ((_NUM_OP + Long.SIZE - 1) / Long.SIZE != 2) {
2110 // The code currently assumes that the length of sAppOpsNotedInThisBinderTransaction is
2111 // two longs
2112 throw new IllegalStateException("notedAppOps collection code assumes < 128 appops");
2113 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002114 }
2115
Svet Ganov8455ba22019-01-02 13:05:56 -08002116 /** @hide */
2117 public static final String KEY_HISTORICAL_OPS = "historical_ops";
2118
Chad Brubaker7c6dba62019-01-23 15:51:43 -08002119 /** System properties for debug logging of noteOp call sites */
2120 private static final String DEBUG_LOGGING_ENABLE_PROP = "appops.logging_enabled";
2121 private static final String DEBUG_LOGGING_PACKAGES_PROP = "appops.logging_packages";
2122 private static final String DEBUG_LOGGING_OPS_PROP = "appops.logging_ops";
2123 private static final String DEBUG_LOGGING_TAG = "AppOpsManager";
2124
David Braunf5d83192013-09-16 13:43:51 -07002125 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002126 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002127 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002128 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002129 @UnsupportedAppUsage
Dianne Hackbornf265ea92013-01-31 15:00:51 -08002130 public static int opToSwitch(int op) {
2131 return sOpToSwitch[op];
2132 }
2133
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002134 /**
2135 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002136 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002137 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002138 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002139 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08002140 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002141 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
2142 }
2143
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002144 /**
Svet Ganov65f1b9e2019-01-17 19:19:40 -08002145 * Retrieve a non-localized public name for the operation.
2146 *
2147 * @hide
2148 */
2149 public static @NonNull String opToPublicName(int op) {
2150 return sOpToString[op];
2151 }
2152
2153 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08002154 * @hide
2155 */
2156 public static int strDebugOpToOp(String op) {
2157 for (int i=0; i<sOpNames.length; i++) {
2158 if (sOpNames[i].equals(op)) {
2159 return i;
2160 }
2161 }
2162 throw new IllegalArgumentException("Unknown operation string: " + op);
2163 }
2164
2165 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002166 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002167 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002168 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00002169 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07002170 @TestApi
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002171 public static String opToPermission(int op) {
2172 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002173 }
2174
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002175 /**
Hai Zhangb7776682018-09-25 15:10:57 -07002176 * Retrieve the permission associated with an operation, or null if there is not one.
2177 *
2178 * @param op The operation name.
2179 *
2180 * @hide
2181 */
2182 @Nullable
2183 @SystemApi
2184 public static String opToPermission(@NonNull String op) {
2185 return opToPermission(strOpToOp(op));
2186 }
2187
2188 /**
Jason Monk62062992014-05-06 09:55:28 -04002189 * Retrieve the user restriction associated with an operation, or null if there is not one.
2190 * @hide
2191 */
2192 public static String opToRestriction(int op) {
2193 return sOpRestrictions[op];
2194 }
2195
2196 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07002197 * Retrieve the app op code for a permission, or null if there is not one.
Svet Ganovda0acdf2017-02-15 10:28:51 -08002198 * This API is intended to be used for mapping runtime or appop permissions
2199 * to the corresponding app op.
Svet Ganovb9d71a62015-04-30 10:38:13 -07002200 * @hide
2201 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00002202 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07002203 @TestApi
Svet Ganovb9d71a62015-04-30 10:38:13 -07002204 public static int permissionToOpCode(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002205 Integer boxedOpCode = sPermToOp.get(permission);
Svet Ganov019d2302015-05-04 11:07:38 -07002206 return boxedOpCode != null ? boxedOpCode : OP_NONE;
Svet Ganovb9d71a62015-04-30 10:38:13 -07002207 }
2208
2209 /**
Jason Monk1c7c3192014-06-26 12:52:18 -04002210 * Retrieve whether the op allows the system (and system ui) to
2211 * bypass the user restriction.
2212 * @hide
2213 */
2214 public static boolean opAllowSystemBypassRestriction(int op) {
2215 return sOpAllowSystemRestrictionBypass[op];
2216 }
2217
2218 /**
David Braunf5d83192013-09-16 13:43:51 -07002219 * Retrieve the default mode for the operation.
2220 * @hide
2221 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002222 public static @Mode int opToDefaultMode(int op) {
David Braunf5d83192013-09-16 13:43:51 -07002223 return sOpDefaultMode[op];
2224 }
2225
2226 /**
Hai Zhangc595f112018-11-06 14:20:38 -08002227 * Retrieve the default mode for the app op.
2228 *
2229 * @param appOp The app op name
2230 *
2231 * @return the default mode for the app op
2232 *
2233 * @hide
2234 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07002235 @TestApi
Hai Zhangc595f112018-11-06 14:20:38 -08002236 @SystemApi
2237 public static int opToDefaultMode(@NonNull String appOp) {
2238 return opToDefaultMode(strOpToOp(appOp));
2239 }
2240
2241 /**
Svet Ganov82f09bc2018-01-12 22:08:40 -08002242 * Retrieve the human readable mode.
2243 * @hide
2244 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002245 public static String modeToName(@Mode int mode) {
Dianne Hackbornc216a262018-04-26 13:46:22 -07002246 if (mode >= 0 && mode < MODE_NAMES.length) {
2247 return MODE_NAMES[mode];
Svet Ganov82f09bc2018-01-12 22:08:40 -08002248 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07002249 return "mode=" + mode;
Svet Ganov82f09bc2018-01-12 22:08:40 -08002250 }
2251
2252 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002253 * Retrieve whether the op allows itself to be reset.
2254 * @hide
2255 */
2256 public static boolean opAllowsReset(int op) {
2257 return !sOpDisableReset[op];
2258 }
2259
2260 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002261 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002262 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002263 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002264 @TestApi
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002265 @SystemApi
2266 public static final class PackageOps implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002267 private final String mPackageName;
2268 private final int mUid;
2269 private final List<OpEntry> mEntries;
2270
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002271 /**
2272 * @hide
2273 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002274 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002275 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
2276 mPackageName = packageName;
2277 mUid = uid;
2278 mEntries = entries;
2279 }
2280
Svet Ganovaf189e32019-02-15 18:45:29 -08002281 /**
2282 * @return The name of the package.
2283 */
2284 public @NonNull String getPackageName() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002285 return mPackageName;
2286 }
2287
Svet Ganovaf189e32019-02-15 18:45:29 -08002288 /**
2289 * @return The uid of the package.
2290 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002291 public int getUid() {
2292 return mUid;
2293 }
2294
Svet Ganovaf189e32019-02-15 18:45:29 -08002295 /**
2296 * @return The ops of the package.
2297 */
Dianne Hackborn62878492019-03-11 15:57:07 -07002298 public @NonNull List<OpEntry> getOps() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002299 return mEntries;
2300 }
2301
2302 @Override
2303 public int describeContents() {
2304 return 0;
2305 }
2306
2307 @Override
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002308 public void writeToParcel(@NonNull Parcel dest, int flags) {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002309 dest.writeString(mPackageName);
2310 dest.writeInt(mUid);
2311 dest.writeInt(mEntries.size());
2312 for (int i=0; i<mEntries.size(); i++) {
2313 mEntries.get(i).writeToParcel(dest, flags);
2314 }
2315 }
2316
2317 PackageOps(Parcel source) {
2318 mPackageName = source.readString();
2319 mUid = source.readInt();
2320 mEntries = new ArrayList<OpEntry>();
2321 final int N = source.readInt();
2322 for (int i=0; i<N; i++) {
2323 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
2324 }
2325 }
2326
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07002327 public static final @android.annotation.NonNull Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002328 @Override public PackageOps createFromParcel(Parcel source) {
2329 return new PackageOps(source);
2330 }
2331
2332 @Override public PackageOps[] newArray(int size) {
2333 return new PackageOps[size];
2334 }
2335 };
2336 }
2337
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002338 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002339 * Proxy information for a {@link #noteOp} event
2340 *
2341 * @hide
2342 */
2343 @TestApi
2344 @SystemApi
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002345 // @DataClass(genHiddenConstructor = true, genHiddenCopyConstructor = true)
2346 // genHiddenCopyConstructor does not work for @hide @SystemApi classes
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002347 public static final class OpEventProxyInfo implements Parcelable {
2348 /** UID of the proxy app that noted the op */
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002349 private @IntRange(from = 0) int mUid;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002350 /** Package of the proxy that noted the op */
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002351 private @Nullable String mPackageName;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002352 /** ID of the feature of the proxy that noted the op */
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002353 private @Nullable String mFeatureId;
2354
2355 /**
2356 * Reinit existing object with new state.
2357 *
2358 * @param uid UID of the proxy app that noted the op
2359 * @param packageName Package of the proxy that noted the op
2360 * @param featureId ID of the feature of the proxy that noted the op
2361 *
2362 * @hide
2363 */
2364 public void reinit(@IntRange(from = 0) int uid, @Nullable String packageName,
2365 @Nullable String featureId) {
2366 mUid = Preconditions.checkArgumentNonnegative(uid);
2367 mPackageName = packageName;
2368 mFeatureId = featureId;
2369 }
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002370
2371
2372
2373 // Code below generated by codegen v1.0.14.
2374 //
2375 // DO NOT MODIFY!
2376 // CHECKSTYLE:OFF Generated code
2377 //
2378 // To regenerate run:
2379 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
2380 //
2381 // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
2382 // Settings > Editor > Code Style > Formatter Control
2383 //@formatter:off
2384
2385
2386 /**
2387 * Creates a new OpEventProxyInfo.
2388 *
2389 * @param uid
2390 * UID of the proxy app that noted the op
2391 * @param packageName
2392 * Package of the proxy that noted the op
2393 * @param featureId
2394 * ID of the feature of the proxy that noted the op
2395 * @hide
2396 */
2397 @DataClass.Generated.Member
2398 public OpEventProxyInfo(
2399 @IntRange(from = 0) int uid,
2400 @Nullable String packageName,
2401 @Nullable String featureId) {
2402 this.mUid = uid;
2403 com.android.internal.util.AnnotationValidations.validate(
2404 IntRange.class, null, mUid,
2405 "from", 0);
2406 this.mPackageName = packageName;
2407 this.mFeatureId = featureId;
2408
2409 // onConstructed(); // You can define this method to get a callback
2410 }
2411
2412 /**
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002413 * Copy constructor
2414 *
2415 * @hide
2416 */
2417 @DataClass.Generated.Member
2418 public OpEventProxyInfo(@NonNull OpEventProxyInfo orig) {
2419 mUid = orig.mUid;
2420 mPackageName = orig.mPackageName;
2421 mFeatureId = orig.mFeatureId;
2422 }
2423
2424 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002425 * UID of the proxy app that noted the op
2426 */
2427 @DataClass.Generated.Member
2428 public @IntRange(from = 0) int getUid() {
2429 return mUid;
2430 }
2431
2432 /**
2433 * Package of the proxy that noted the op
2434 */
2435 @DataClass.Generated.Member
2436 public @Nullable String getPackageName() {
2437 return mPackageName;
2438 }
2439
2440 /**
2441 * ID of the feature of the proxy that noted the op
2442 */
2443 @DataClass.Generated.Member
2444 public @Nullable String getFeatureId() {
2445 return mFeatureId;
2446 }
2447
2448 @Override
2449 @DataClass.Generated.Member
2450 public void writeToParcel(@NonNull Parcel dest, int flags) {
2451 // You can override field parcelling by defining methods like:
2452 // void parcelFieldName(Parcel dest, int flags) { ... }
2453
2454 byte flg = 0;
2455 if (mPackageName != null) flg |= 0x2;
2456 if (mFeatureId != null) flg |= 0x4;
2457 dest.writeByte(flg);
2458 dest.writeInt(mUid);
2459 if (mPackageName != null) dest.writeString(mPackageName);
2460 if (mFeatureId != null) dest.writeString(mFeatureId);
2461 }
2462
2463 @Override
2464 @DataClass.Generated.Member
2465 public int describeContents() { return 0; }
2466
2467 /** @hide */
2468 @SuppressWarnings({"unchecked", "RedundantCast"})
2469 @DataClass.Generated.Member
2470 /* package-private */ OpEventProxyInfo(@NonNull Parcel in) {
2471 // You can override field unparcelling by defining methods like:
2472 // static FieldType unparcelFieldName(Parcel in) { ... }
2473
2474 byte flg = in.readByte();
2475 int uid = in.readInt();
2476 String packageName = (flg & 0x2) == 0 ? null : in.readString();
2477 String featureId = (flg & 0x4) == 0 ? null : in.readString();
2478
2479 this.mUid = uid;
2480 com.android.internal.util.AnnotationValidations.validate(
2481 IntRange.class, null, mUid,
2482 "from", 0);
2483 this.mPackageName = packageName;
2484 this.mFeatureId = featureId;
2485
2486 // onConstructed(); // You can define this method to get a callback
2487 }
2488
2489 @DataClass.Generated.Member
2490 public static final @NonNull Parcelable.Creator<OpEventProxyInfo> CREATOR
2491 = new Parcelable.Creator<OpEventProxyInfo>() {
2492 @Override
2493 public OpEventProxyInfo[] newArray(int size) {
2494 return new OpEventProxyInfo[size];
2495 }
2496
2497 @Override
2498 public OpEventProxyInfo createFromParcel(@NonNull Parcel in) {
2499 return new OpEventProxyInfo(in);
2500 }
2501 };
2502
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002503 /*
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002504 @DataClass.Generated(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002505 time = 1576814974615L,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002506 codegenVersion = "1.0.14",
2507 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002508 inputSignatures = "private @android.annotation.IntRange(from=0L) int mUid\nprivate @android.annotation.Nullable java.lang.String mPackageName\nprivate @android.annotation.Nullable java.lang.String mFeatureId\npublic void reinit(int,java.lang.String,java.lang.String)\nclass OpEventProxyInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genHiddenCopyConstructor=true)")
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002509 @Deprecated
2510 private void __metadata() {}
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002511 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002512
2513 //@formatter:on
2514 // End of generated code
2515
2516 }
2517
2518 /**
2519 * Description of a {@link #noteOp} or {@link #startOp} event
2520 *
2521 * @hide
2522 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002523 //@DataClass codegen verifier is broken
2524 public static final class NoteOpEvent implements Parcelable {
2525 /** Time of noteOp event */
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002526 private @IntRange(from = 0) long mNoteTime;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002527 /** The duration of this event (in case this is a startOp event, -1 otherwise). */
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002528 private @IntRange(from = -1) long mDuration;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002529 /** Proxy information of the noteOp event */
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002530 private @Nullable OpEventProxyInfo mProxy;
2531
2532 /**
2533 * Reinit existing object with new state.
2534 *
2535 * @param noteTime Time of noteOp event
2536 * @param duration The duration of this event (in case this is a startOp event,
2537 * -1 otherwise).
2538 * @param proxy Proxy information of the noteOp event
2539 * @param proxyPool The pool to release previous {@link OpEventProxyInfo} to
2540 */
2541 public void reinit(@IntRange(from = 0) long noteTime,
2542 @IntRange(from = -1) long duration,
2543 @Nullable OpEventProxyInfo proxy,
2544 @NonNull Pools.Pool<OpEventProxyInfo> proxyPool) {
2545 mNoteTime = Preconditions.checkArgumentNonnegative(noteTime);
2546 mDuration = Preconditions.checkArgumentInRange(duration, -1L, Long.MAX_VALUE,
2547 "duration");
2548
2549 if (mProxy != null) {
2550 proxyPool.release(mProxy);
2551 }
2552 mProxy = proxy;
2553 }
2554
2555 /**
2556 * Copy constructor
2557 *
2558 * @hide
2559 */
2560 public NoteOpEvent(@NonNull NoteOpEvent original) {
2561 this(original.mNoteTime, original.mDuration,
2562 original.mProxy != null ? new OpEventProxyInfo(original.mProxy) : null);
2563 }
2564
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002565
2566
2567 // Code below generated by codegen v1.0.14.
2568 //
2569 // DO NOT MODIFY!
2570 // CHECKSTYLE:OFF Generated code
2571 //
2572 // To regenerate run:
2573 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
2574 //
2575 // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
2576 // Settings > Editor > Code Style > Formatter Control
2577 //@formatter:off
2578
2579
2580 /**
2581 * Creates a new NoteOpEvent.
2582 *
2583 * @param noteTime
2584 * Time of noteOp event
2585 * @param duration
2586 * The duration of this event (in case this is a startOp event, -1 otherwise).
2587 * @param proxy
2588 * Proxy information of the noteOp event
2589 */
2590 @DataClass.Generated.Member
2591 public NoteOpEvent(
2592 @IntRange(from = 0) long noteTime,
2593 @IntRange(from = -1) long duration,
2594 @Nullable OpEventProxyInfo proxy) {
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002595 this.mNoteTime = noteTime;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002596 com.android.internal.util.AnnotationValidations.validate(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002597 IntRange.class, null, mNoteTime,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002598 "from", 0);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002599 this.mDuration = duration;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002600 com.android.internal.util.AnnotationValidations.validate(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002601 IntRange.class, null, mDuration,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002602 "from", -1);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002603 this.mProxy = proxy;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002604
2605 // onConstructed(); // You can define this method to get a callback
2606 }
2607
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002608 /**
2609 * Time of noteOp event
2610 */
2611 @DataClass.Generated.Member
2612 public @IntRange(from = 0) long getNoteTime() {
2613 return mNoteTime;
2614 }
2615
2616 /**
2617 * The duration of this event (in case this is a startOp event, -1 otherwise).
2618 */
2619 @DataClass.Generated.Member
2620 public @IntRange(from = -1) long getDuration() {
2621 return mDuration;
2622 }
2623
2624 /**
2625 * Proxy information of the noteOp event
2626 */
2627 @DataClass.Generated.Member
2628 public @Nullable OpEventProxyInfo getProxy() {
2629 return mProxy;
2630 }
2631
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002632 @Override
2633 @DataClass.Generated.Member
2634 public void writeToParcel(@NonNull Parcel dest, int flags) {
2635 // You can override field parcelling by defining methods like:
2636 // void parcelFieldName(Parcel dest, int flags) { ... }
2637
2638 byte flg = 0;
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002639 if (mProxy != null) flg |= 0x4;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002640 dest.writeByte(flg);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002641 dest.writeLong(mNoteTime);
2642 dest.writeLong(mDuration);
2643 if (mProxy != null) dest.writeTypedObject(mProxy, flags);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002644 }
2645
2646 @Override
2647 @DataClass.Generated.Member
2648 public int describeContents() { return 0; }
2649
2650 /** @hide */
2651 @SuppressWarnings({"unchecked", "RedundantCast"})
2652 @DataClass.Generated.Member
2653 /* package-private */ NoteOpEvent(@NonNull Parcel in) {
2654 // You can override field unparcelling by defining methods like:
2655 // static FieldType unparcelFieldName(Parcel in) { ... }
2656
2657 byte flg = in.readByte();
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002658 long noteTime = in.readLong();
2659 long duration = in.readLong();
2660 OpEventProxyInfo proxy = (flg & 0x4) == 0 ? null : (OpEventProxyInfo) in.readTypedObject(OpEventProxyInfo.CREATOR);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002661
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002662 this.mNoteTime = noteTime;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002663 com.android.internal.util.AnnotationValidations.validate(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002664 IntRange.class, null, mNoteTime,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002665 "from", 0);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002666 this.mDuration = duration;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002667 com.android.internal.util.AnnotationValidations.validate(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002668 IntRange.class, null, mDuration,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002669 "from", -1);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002670 this.mProxy = proxy;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002671
2672 // onConstructed(); // You can define this method to get a callback
2673 }
2674
2675 @DataClass.Generated.Member
2676 public static final @NonNull Parcelable.Creator<NoteOpEvent> CREATOR
2677 = new Parcelable.Creator<NoteOpEvent>() {
2678 @Override
2679 public NoteOpEvent[] newArray(int size) {
2680 return new NoteOpEvent[size];
2681 }
2682
2683 @Override
2684 public NoteOpEvent createFromParcel(@NonNull Parcel in) {
2685 return new NoteOpEvent(in);
2686 }
2687 };
2688
2689 /*
2690 @DataClass.Generated(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002691 time = 1576811792274L,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002692 codegenVersion = "1.0.14",
2693 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002694 inputSignatures = "private @android.annotation.IntRange(from=0L) long mNoteTime\nprivate @android.annotation.IntRange(from=-1) long mDuration\nprivate @android.annotation.Nullable android.app.OpEventProxyInfo mProxy\npublic void reinit(long,long,android.app.OpEventProxyInfo,android.util.Pools.Pool<android.app.OpEventProxyInfo>)\npublic @java.lang.Override java.lang.Object clone()\nclass NoteOpEvent extends java.lang.Object implements [android.os.Parcelable, java.lang.Cloneable]\n@com.android.internal.util.DataClass")
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002695 @Deprecated
2696 private void __metadata() {}
2697 */
2698
2699
2700 //@formatter:on
2701 // End of generated code
2702
2703 }
2704
2705 /**
2706 * Last {@link #noteOp} and {@link #startOp} events performed for a single op and a specific
2707 * {@link Context#createFeatureContext(String) feature} for all uidModes and opFlags.
2708 *
2709 * @hide
2710 */
2711 @TestApi
2712 @SystemApi
2713 @Immutable
2714 // @DataClass(genHiddenConstructor = true) codegen verifier is broken
2715 @DataClass.Suppress({"getAccessEvents", "getRejectEvents", "getOp"})
2716 public static final class OpFeatureEntry implements Parcelable {
2717 /** The code of the op */
2718 private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp;
2719 /** Whether the op is running */
2720 private final boolean mRunning;
2721 /** The access events */
2722 @DataClass.ParcelWith(LongSparseArrayParceling.class)
2723 private final @Nullable LongSparseArray<NoteOpEvent> mAccessEvents;
2724 /** The rejection events */
2725 @DataClass.ParcelWith(LongSparseArrayParceling.class)
2726 private final @Nullable LongSparseArray<NoteOpEvent> mRejectEvents;
2727
2728 /**
2729 * Returns all keys for which we have events.
2730 *
2731 * @hide
2732 */
2733 public @NonNull ArraySet<Long> collectKeys() {
2734 ArraySet<Long> keys = new ArraySet<>();
2735
2736 if (mAccessEvents != null) {
2737 int numEvents = mAccessEvents.size();
2738 for (int i = 0; i < numEvents; i++) {
2739 keys.add(mAccessEvents.keyAt(i));
2740 }
2741 }
2742
2743 if (mRejectEvents != null) {
2744 int numEvents = mRejectEvents.size();
2745 for (int i = 0; i < numEvents; i++) {
2746 keys.add(mRejectEvents.keyAt(i));
2747 }
2748 }
2749
2750 return keys;
2751 }
2752
2753 /**
2754 * Return the last access time.
2755 *
2756 * @param flags The op flags
2757 *
2758 * @return the last access time (in milliseconds since epoch start (January 1, 1970
2759 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
2760 *
2761 * @see #getLastAccessForegroundTime(int)
2762 * @see #getLastAccessBackgroundTime(int)
2763 * @see #getLastAccessTime(int, int, int)
2764 * @see OpEntry#getLastAccessTime(int)
2765 */
2766 public long getLastAccessTime(@OpFlags int flags) {
2767 return getLastAccessTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
2768 }
2769
2770 /**
2771 * Return the last foreground access time.
2772 *
2773 * @param flags The op flags
2774 *
2775 * @return the last access time (in milliseconds since epoch start (January 1, 1970
2776 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
2777 *
2778 * @see #getLastAccessTime(int)
2779 * @see #getLastAccessBackgroundTime(int)
2780 * @see #getLastAccessTime(int, int, int)
2781 * @see OpEntry#getLastAccessForegroundTime(int)
2782 */
2783 public long getLastAccessForegroundTime(@OpFlags int flags) {
2784 return getLastAccessTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
2785 flags);
2786 }
2787
2788 /**
2789 * Return the last background access time.
2790 *
2791 * @param flags The op flags
2792 *
2793 * @return the last access time (in milliseconds since epoch start (January 1, 1970
2794 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
2795 *
2796 * @see #getLastAccessTime(int)
2797 * @see #getLastAccessForegroundTime(int)
2798 * @see #getLastAccessTime(int, int, int)
2799 * @see OpEntry#getLastAccessBackgroundTime(int)
2800 */
2801 public long getLastAccessBackgroundTime(@OpFlags int flags) {
2802 return getLastAccessTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
2803 flags);
2804 }
2805
2806 /**
2807 * Return the last access event.
2808 *
2809 * @param flags The op flags
2810 *
2811 * @return the last access event of {@code null}
2812 */
2813 private @Nullable NoteOpEvent getLastAccessEvent(@UidState int fromUidState,
2814 @UidState int toUidState, @OpFlags int flags) {
2815 return getLastEvent(mAccessEvents, fromUidState, toUidState, flags);
2816 }
2817
2818 /**
2819 * Return the last access time.
2820 *
2821 * @param fromUidState The lowest UID state for which to query
2822 * @param toUidState The highest UID state for which to query (inclusive)
2823 * @param flags The op flags
2824 *
2825 * @return the last access time (in milliseconds since epoch start (January 1, 1970
2826 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
2827 *
2828 * @see #getLastAccessTime(int)
2829 * @see #getLastAccessForegroundTime(int)
2830 * @see #getLastAccessBackgroundTime(int)
2831 * @see OpEntry#getLastAccessTime(int, int, int)
2832 */
2833 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
2834 @OpFlags int flags) {
2835 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
2836 if (lastEvent == null) {
2837 return -1;
2838 }
2839
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002840 return lastEvent.getNoteTime();
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002841 }
2842
2843 /**
2844 * Return the last rejection time.
2845 *
2846 * @param flags The op flags
2847 *
2848 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
2849 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
2850 *
2851 * @see #getLastRejectForegroundTime(int)
2852 * @see #getLastRejectBackgroundTime(int)
2853 * @see #getLastRejectTime(int, int, int)
2854 * @see OpEntry#getLastRejectTime(int)
2855 */
2856 public long getLastRejectTime(@OpFlags int flags) {
2857 return getLastRejectTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
2858 }
2859
2860 /**
2861 * Return the last foreground rejection time.
2862 *
2863 * @param flags The op flags
2864 *
2865 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
2866 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
2867 *
2868 * @see #getLastRejectTime(int)
2869 * @see #getLastRejectBackgroundTime(int)
2870 * @see #getLastRejectTime(int, int, int)
2871 * @see OpEntry#getLastRejectForegroundTime(int)
2872 */
2873 public long getLastRejectForegroundTime(@OpFlags int flags) {
2874 return getLastRejectTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
2875 flags);
2876 }
2877
2878 /**
2879 * Return the last background rejection time.
2880 *
2881 * @param flags The op flags
2882 *
2883 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
2884 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
2885 *
2886 * @see #getLastRejectTime(int)
2887 * @see #getLastRejectForegroundTime(int)
2888 * @see #getLastRejectTime(int, int, int)
2889 * @see OpEntry#getLastRejectBackgroundTime(int)
2890 */
2891 public long getLastRejectBackgroundTime(@OpFlags int flags) {
2892 return getLastRejectTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
2893 flags);
2894 }
2895
2896 /**
2897 * Return the last background rejection event.
2898 *
2899 * @param flags The op flags
2900 *
2901 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
2902 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
2903 *
2904 * @see #getLastRejectTime(int)
2905 * @see #getLastRejectForegroundTime(int)
2906 * @see #getLastRejectBackgroundTime(int)
2907 * @see OpEntry#getLastRejectTime(int, int, int)
2908 */
2909 private @Nullable NoteOpEvent getLastRejectEvent(@UidState int fromUidState,
2910 @UidState int toUidState, @OpFlags int flags) {
2911 return getLastEvent(mRejectEvents, fromUidState, toUidState, flags);
2912 }
2913
2914 /**
2915 * Return the last rejection time.
2916 *
2917 * @param fromUidState The lowest UID state for which to query
2918 * @param toUidState The highest UID state for which to query (inclusive)
2919 * @param flags The op flags
2920 *
2921 * @return the last access time (in milliseconds since epoch) or {@code -1}
2922 *
2923 * @see #getLastRejectTime(int)
2924 * @see #getLastRejectForegroundTime(int)
2925 * @see #getLastRejectForegroundTime(int)
2926 * @see #getLastRejectTime(int, int, int)
2927 * @see OpEntry#getLastRejectTime(int, int, int)
2928 */
2929 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
2930 @OpFlags int flags) {
2931 NoteOpEvent lastEvent = getLastRejectEvent(fromUidState, toUidState, flags);
2932 if (lastEvent == null) {
2933 return -1;
2934 }
2935
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002936 return lastEvent.getNoteTime();
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002937 }
2938
2939 /**
2940 * Return the duration in milliseconds of the last the access.
2941 *
2942 * @param flags The op flags
2943 *
2944 * @return the duration in milliseconds or {@code -1}
2945 *
2946 * @see #getLastForegroundDuration(int)
2947 * @see #getLastBackgroundDuration(int)
2948 * @see #getLastDuration(int, int, int)
2949 * @see OpEntry#getLastDuration(int)
2950 */
2951 public long getLastDuration(@OpFlags int flags) {
2952 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
2953 }
2954
2955 /**
2956 * Return the duration in milliseconds of the last foreground access.
2957 *
2958 * @param flags The op flags
2959 *
2960 * @return the duration in milliseconds or {@code -1}
2961 *
2962 * @see #getLastDuration(int)
2963 * @see #getLastBackgroundDuration(int)
2964 * @see #getLastDuration(int, int, int)
2965 * @see OpEntry#getLastForegroundDuration(int)
2966 */
2967 public long getLastForegroundDuration(@OpFlags int flags) {
2968 return getLastDuration(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
2969 flags);
2970 }
2971
2972 /**
2973 * Return the duration in milliseconds of the last background access.
2974 *
2975 * @param flags The op flags
2976 *
2977 * @return the duration in milliseconds or {@code -1}
2978 *
2979 * @see #getLastDuration(int)
2980 * @see #getLastForegroundDuration(int)
2981 * @see #getLastDuration(int, int, int)
2982 * @see OpEntry#getLastBackgroundDuration(int)
2983 */
2984 public long getLastBackgroundDuration(@OpFlags int flags) {
2985 return getLastDuration(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
2986 flags);
2987 }
2988
2989 /**
2990 * Return the duration in milliseconds of the last access.
2991 *
2992 * @param fromUidState The lowest UID state for which to query
2993 * @param toUidState The highest UID state for which to query (inclusive)
2994 * @param flags The op flags
2995 *
2996 * @return the duration in milliseconds or {@code -1}
2997 *
2998 * @see #getLastDuration(int)
2999 * @see #getLastForegroundDuration(int)
3000 * @see #getLastBackgroundDuration(int)
3001 * @see #getLastDuration(int, int, int)
3002 * @see OpEntry#getLastDuration(int, int, int)
3003 */
3004 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
3005 @OpFlags int flags) {
3006 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);;
3007 if (lastEvent == null) {
3008 return -1;
3009 }
3010
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003011 return lastEvent.getDuration();
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003012 }
3013
3014 /**
3015 * Gets the proxy info of the app that performed the last access on behalf of this feature
3016 * and as a result blamed the op on this app.
3017 *
3018 * @param flags The op flags
3019 *
3020 * @return The proxy name or {@code null}
3021 *
3022 * @see #getLastForegroundProxyInfo(int)
3023 * @see #getLastBackgroundProxyInfo(int)
3024 * @see #getLastProxyInfo(int, int, int)
3025 * @see OpEntry#getLastProxyInfo(int)
3026 */
3027 public @Nullable OpEventProxyInfo getLastProxyInfo(@OpFlags int flags) {
3028 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
3029 }
3030
3031 /**
3032 * Gets the proxy info of the app that performed the last foreground access on behalf of
3033 * this feature and as a result blamed the op on this app.
3034 *
3035 * @param flags The op flags
3036 *
3037 * @return The proxy name or {@code null}
3038 *
3039 * @see #getLastProxyInfo(int)
3040 * @see #getLastBackgroundProxyInfo(int)
3041 * @see #getLastProxyInfo(int, int, int)
3042 * @see OpEntry#getLastForegroundProxyInfo(int)
3043 */
3044 public @Nullable OpEventProxyInfo getLastForegroundProxyInfo(@OpFlags int flags) {
3045 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
3046 flags);
3047 }
3048
3049 /**
3050 * Gets the proxy info of the app that performed the last background access on behalf of
3051 * this feature and as a result blamed the op on this app.
3052 *
3053 * @param flags The op flags
3054 *
3055 * @return The proxy name or {@code null}
3056 *
3057 * @see #getLastProxyInfo(int)
3058 * @see #getLastForegroundProxyInfo(int)
3059 * @see #getLastProxyInfo(int, int, int)
3060 * @see OpEntry#getLastBackgroundProxyInfo(int)
3061 */
3062 public @Nullable OpEventProxyInfo getLastBackgroundProxyInfo(@OpFlags int flags) {
3063 return getLastProxyInfo(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
3064 flags);
3065 }
3066
3067 /**
3068 * Gets the proxy info of the app that performed the last access on behalf of this feature
3069 * and as a result blamed the op on this app.
3070 *
3071 * @param fromUidState The lowest UID state for which to query
3072 * @param toUidState The highest UID state for which to query (inclusive)
3073 * @param flags The op flags
3074 *
3075 * @return The proxy name or {@code null}
3076 *
3077 * @see #getLastProxyInfo(int)
3078 * @see #getLastForegroundProxyInfo(int)
3079 * @see #getLastBackgroundProxyInfo(int)
3080 * @see OpEntry#getLastProxyInfo(int, int, int)
3081 */
3082 public @Nullable OpEventProxyInfo getLastProxyInfo(@UidState int fromUidState,
3083 @UidState int toUidState, @OpFlags int flags) {
3084 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
3085 if (lastEvent == null) {
3086 return null;
3087 }
3088
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003089 return lastEvent.getProxy();
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003090 }
3091
3092 private static class LongSparseArrayParceling implements
3093 Parcelling<LongSparseArray<NoteOpEvent>> {
3094 @Override
3095 public void parcel(@Nullable LongSparseArray<NoteOpEvent> array, @NonNull Parcel dest,
3096 int parcelFlags) {
3097 if (array == null) {
3098 dest.writeInt(-1);
3099 return;
3100 }
3101
3102 int numEntries = array.size();
3103 dest.writeInt(numEntries);
3104
3105 for (int i = 0; i < numEntries; i++) {
3106 dest.writeLong(array.keyAt(i));
3107 dest.writeParcelable(array.valueAt(i), parcelFlags);
3108 }
3109 }
3110
3111 @Override
3112 public @Nullable LongSparseArray<NoteOpEvent> unparcel(@NonNull Parcel source) {
3113 int numEntries = source.readInt();
3114 if (numEntries == -1) {
3115 return null;
3116 }
3117
3118 LongSparseArray<NoteOpEvent> array = new LongSparseArray<>(numEntries);
3119
3120 for (int i = 0; i < numEntries; i++) {
3121 array.put(source.readLong(), source.readParcelable(null));
3122 }
3123
3124 return array;
3125 }
3126 }
3127
3128
3129
3130 // Code below generated by codegen v1.0.14.
3131 //
3132 // DO NOT MODIFY!
3133 // CHECKSTYLE:OFF Generated code
3134 //
3135 // To regenerate run:
3136 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
3137 //
3138 // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
3139 // Settings > Editor > Code Style > Formatter Control
3140 //@formatter:off
3141
3142
3143 /**
3144 * Creates a new OpFeatureEntry.
3145 *
3146 * @param op
3147 * The code of the op
3148 * @param running
3149 * Whether the op is running
3150 * @param accessEvents
3151 * The access events
3152 * @param rejectEvents
3153 * The rejection events
3154 * @hide
3155 */
3156 @DataClass.Generated.Member
3157 public OpFeatureEntry(
3158 @IntRange(from = 0, to = _NUM_OP - 1) int op,
3159 boolean running,
3160 @Nullable LongSparseArray<NoteOpEvent> accessEvents,
3161 @Nullable LongSparseArray<NoteOpEvent> rejectEvents) {
3162 this.mOp = op;
3163 com.android.internal.util.AnnotationValidations.validate(
3164 IntRange.class, null, mOp,
3165 "from", 0,
3166 "to", _NUM_OP - 1);
3167 this.mRunning = running;
3168 this.mAccessEvents = accessEvents;
3169 this.mRejectEvents = rejectEvents;
3170
3171 // onConstructed(); // You can define this method to get a callback
3172 }
3173
3174 /**
3175 * Whether the op is running
3176 */
3177 @DataClass.Generated.Member
3178 public boolean isRunning() {
3179 return mRunning;
3180 }
3181
3182 @DataClass.Generated.Member
3183 static Parcelling<LongSparseArray<NoteOpEvent>> sParcellingForAccessEvents =
3184 Parcelling.Cache.get(
3185 LongSparseArrayParceling.class);
3186 static {
3187 if (sParcellingForAccessEvents == null) {
3188 sParcellingForAccessEvents = Parcelling.Cache.put(
3189 new LongSparseArrayParceling());
3190 }
3191 }
3192
3193 @DataClass.Generated.Member
3194 static Parcelling<LongSparseArray<NoteOpEvent>> sParcellingForRejectEvents =
3195 Parcelling.Cache.get(
3196 LongSparseArrayParceling.class);
3197 static {
3198 if (sParcellingForRejectEvents == null) {
3199 sParcellingForRejectEvents = Parcelling.Cache.put(
3200 new LongSparseArrayParceling());
3201 }
3202 }
3203
3204 @Override
3205 @DataClass.Generated.Member
3206 public void writeToParcel(@NonNull Parcel dest, int flags) {
3207 // You can override field parcelling by defining methods like:
3208 // void parcelFieldName(Parcel dest, int flags) { ... }
3209
3210 byte flg = 0;
3211 if (mRunning) flg |= 0x2;
3212 if (mAccessEvents != null) flg |= 0x4;
3213 if (mRejectEvents != null) flg |= 0x8;
3214 dest.writeByte(flg);
3215 dest.writeInt(mOp);
3216 sParcellingForAccessEvents.parcel(mAccessEvents, dest, flags);
3217 sParcellingForRejectEvents.parcel(mRejectEvents, dest, flags);
3218 }
3219
3220 @Override
3221 @DataClass.Generated.Member
3222 public int describeContents() { return 0; }
3223
3224 /** @hide */
3225 @SuppressWarnings({"unchecked", "RedundantCast"})
3226 @DataClass.Generated.Member
3227 /* package-private */ OpFeatureEntry(@NonNull Parcel in) {
3228 // You can override field unparcelling by defining methods like:
3229 // static FieldType unparcelFieldName(Parcel in) { ... }
3230
3231 byte flg = in.readByte();
3232 boolean running = (flg & 0x2) != 0;
3233 int op = in.readInt();
3234 LongSparseArray<NoteOpEvent> accessEvents = sParcellingForAccessEvents.unparcel(in);
3235 LongSparseArray<NoteOpEvent> rejectEvents = sParcellingForRejectEvents.unparcel(in);
3236
3237 this.mOp = op;
3238 com.android.internal.util.AnnotationValidations.validate(
3239 IntRange.class, null, mOp,
3240 "from", 0,
3241 "to", _NUM_OP - 1);
3242 this.mRunning = running;
3243 this.mAccessEvents = accessEvents;
3244 this.mRejectEvents = rejectEvents;
3245
3246 // onConstructed(); // You can define this method to get a callback
3247 }
3248
3249 @DataClass.Generated.Member
3250 public static final @NonNull Parcelable.Creator<OpFeatureEntry> CREATOR
3251 = new Parcelable.Creator<OpFeatureEntry>() {
3252 @Override
3253 public OpFeatureEntry[] newArray(int size) {
3254 return new OpFeatureEntry[size];
3255 }
3256
3257 @Override
3258 public OpFeatureEntry createFromParcel(@NonNull Parcel in) {
3259 return new OpFeatureEntry(in);
3260 }
3261 };
3262
3263 /*
3264 @DataClass.Generated(
3265 time = 1574809856239L,
3266 codegenVersion = "1.0.14",
3267 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
3268 inputSignatures = "private final @android.annotation.IntRange(from=0L, to=_NUM_OP - 1) int mOp\nprivate final boolean mRunning\nprivate final @com.android.internal.util.DataClass.ParcelWith(android.app.OpFeatureEntry.LongSparseArrayParceling.class) @android.annotation.Nullable android.util.LongSparseArray<android.app.NoteOpEvent> mAccessEvents\nprivate final @com.android.internal.util.DataClass.ParcelWith(android.app.OpFeatureEntry.LongSparseArrayParceling.class) @android.annotation.Nullable android.util.LongSparseArray<android.app.NoteOpEvent> mRejectEvents\npublic @android.annotation.NonNull android.util.ArraySet<java.lang.Long> collectKeys()\npublic @android.app.UidState int getLastAccessUidState(int)\npublic @android.app.UidState int getLastForegroundAccessUidState(int)\npublic @android.app.UidState int getLastBackgroundAccessUidState(int)\npublic @android.app.UidState int getLastRejectUidState(int)\npublic @android.app.UidState int getLastForegroundRejectUidState(int)\npublic @android.app.UidState int getLastBackgroundRejectUidState(int)\npublic long getAccessTime(int,int)\npublic long getRejectTime(int,int)\npublic long getDuration(int,int)\npublic int getProxyUid(int,int)\npublic @android.annotation.Nullable java.lang.String getProxyPackageName(int,int)\npublic @android.annotation.Nullable java.lang.String getProxyFeatureId(int,int)\nclass OpFeatureEntry extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
3269 @Deprecated
3270 private void __metadata() {}
3271 */
3272
3273
3274 //@formatter:on
3275 // End of generated code
3276
3277 }
3278
3279 /**
3280 * Last {@link #noteOp} and {@link #startOp} events performed for a single op for all uidModes
3281 * and opFlags.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003282 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07003283 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08003284 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003285 @TestApi
3286 @Immutable
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07003287 @SystemApi
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003288 // @DataClass(genHiddenConstructor = true) codegen verifier is broken
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003289 public static final class OpEntry implements Parcelable {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003290 /** The code of the op */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003291 private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003292 /** The mode of the op */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003293 private final @Mode int mMode;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003294 /** The features that have been used when checking the op */
3295 private final @NonNull Map<String, OpFeatureEntry> mFeatures;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003296
3297 /**
3298 * @hide
3299 */
3300 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
3301 + "#getOpStr()}")
3302 public int getOp() {
3303 return mOp;
3304 }
3305
3306 /**
3307 * @return This entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}.
3308 */
3309 public @NonNull String getOpStr() {
3310 return sOpToString[mOp];
3311 }
3312
3313 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003314 * @hide
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003315 *
3316 * @deprecated Use {@link #getLastAccessTime(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003317 */
3318 @Deprecated
3319 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
3320 + "#getLastAccessTime(int)}")
3321 public long getTime() {
3322 return getLastAccessTime(OP_FLAGS_ALL);
3323 }
3324
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003325 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003326 * Return the last access time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003327 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003328 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003329 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003330 * @return the last access time (in milliseconds since epoch start (January 1, 1970
3331 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003332 *
3333 * @see #getLastAccessForegroundTime(int)
3334 * @see #getLastAccessBackgroundTime(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003335 * @see #getLastAccessTime(int, int, int)
3336 * @see OpFeatureEntry#getLastAccessTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003337 */
3338 public long getLastAccessTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003339 return getLastAccessTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003340 }
3341
3342 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003343 * Return the last foreground access time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003344 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003345 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003346 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003347 * @return the last access time (in milliseconds since epoch start (January 1, 1970
3348 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
3349 *
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003350 * @see #getLastAccessTime(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003351 * @see #getLastAccessBackgroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003352 * @see #getLastAccessTime(int, int, int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003353 * @see OpFeatureEntry#getLastAccessForegroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003354 */
3355 public long getLastAccessForegroundTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003356 return getLastAccessTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
3357 flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003358 }
3359
3360 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003361 * Return the last background access time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003362 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003363 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003364 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003365 * @return the last access time (in milliseconds since epoch start (January 1, 1970
3366 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
3367 *
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003368 * @see #getLastAccessTime(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003369 * @see #getLastAccessForegroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003370 * @see #getLastAccessTime(int, int, int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003371 * @see OpFeatureEntry#getLastAccessBackgroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003372 */
3373 public long getLastAccessBackgroundTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003374 return getLastAccessTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
3375 flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003376 }
3377
3378 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003379 * Return the last access event.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003380 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003381 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003382 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003383 * @return the last access event of {@code null}
3384 */
3385 private @Nullable NoteOpEvent getLastAccessEvent(@UidState int fromUidState,
3386 @UidState int toUidState, @OpFlags int flags) {
3387 NoteOpEvent lastAccessEvent = null;
3388 for (OpFeatureEntry featureEntry : mFeatures.values()) {
3389 NoteOpEvent lastFeatureAccessEvent = featureEntry.getLastAccessEvent(fromUidState,
3390 toUidState, flags);
3391
3392 if (lastAccessEvent == null || (lastFeatureAccessEvent != null
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003393 && lastFeatureAccessEvent.getNoteTime() > lastAccessEvent.getNoteTime())) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003394 lastAccessEvent = lastFeatureAccessEvent;
3395 }
3396 }
3397
3398 return lastAccessEvent;
3399 }
3400
3401 /**
3402 * Return the last access time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003403 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003404 * @param fromUidState the lowest uid state to query
3405 * @param toUidState the highest uid state to query (inclusive)
3406 * @param flags The op flags
3407 *
3408 * @return the last access time (in milliseconds since epoch start (January 1, 1970
3409 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
3410 *
3411 * @see #getLastAccessTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003412 * @see #getLastAccessForegroundTime(int)
3413 * @see #getLastAccessBackgroundTime(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003414 * @see OpFeatureEntry#getLastAccessTime(int, int, int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003415 */
3416 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
3417 @OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003418 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);;
3419
3420 if (lastEvent == null) {
3421 return -1;
3422 }
3423
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003424 return lastEvent.getNoteTime();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003425 }
3426
3427 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003428 * @hide
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003429 *
3430 * @deprecated Use {@link #getLastRejectTime(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003431 */
3432 @Deprecated
3433 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "{@code "
3434 + "#getLastRejectTime(int)}")
3435 public long getRejectTime() {
3436 return getLastRejectTime(OP_FLAGS_ALL);
3437 }
3438
3439 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003440 * Return the last rejection time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003441 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003442 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003443 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003444 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
3445 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
3446 *
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003447 * @see #getLastRejectForegroundTime(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003448 * @see #getLastRejectBackgroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003449 * @see #getLastRejectTime(int, int, int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003450 * @see OpFeatureEntry#getLastRejectTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003451 */
3452 public long getLastRejectTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003453 return getLastRejectTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003454 }
3455
3456 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003457 * Return the last foreground rejection time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003458 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003459 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003460 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003461 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
3462 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
3463 *
3464 * @see #getLastRejectTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003465 * @see #getLastRejectBackgroundTime(int)
3466 * @see #getLastRejectTime(int, int, int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003467 * @see OpFeatureEntry#getLastRejectForegroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003468 */
3469 public long getLastRejectForegroundTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003470 return getLastRejectTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
3471 flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003472 }
3473
3474 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003475 * Return the last background rejection time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003476 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003477 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003478 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003479 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
3480 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
3481 *
3482 * @see #getLastRejectTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003483 * @see #getLastRejectForegroundTime(int)
3484 * @see #getLastRejectTime(int, int, int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003485 * @see OpFeatureEntry#getLastRejectBackgroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003486 */
3487 public long getLastRejectBackgroundTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003488 return getLastRejectTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
3489 flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003490 }
3491
3492 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003493 * Return the last rejection event.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003494 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003495 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003496 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003497 * @return the last reject event of {@code null}
3498 */
3499 private @Nullable NoteOpEvent getLastRejectEvent(@UidState int fromUidState,
3500 @UidState int toUidState, @OpFlags int flags) {
3501 NoteOpEvent lastAccessEvent = null;
3502 for (OpFeatureEntry featureEntry : mFeatures.values()) {
3503 NoteOpEvent lastFeatureAccessEvent = featureEntry.getLastRejectEvent(fromUidState,
3504 toUidState, flags);
3505
3506 if (lastAccessEvent == null || (lastFeatureAccessEvent != null
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003507 && lastFeatureAccessEvent.getNoteTime() > lastAccessEvent.getNoteTime())) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003508 lastAccessEvent = lastFeatureAccessEvent;
3509 }
3510 }
3511
3512 return lastAccessEvent;
3513 }
3514
3515 /**
3516 * Return the last rejection time.
3517 *
3518 * @param fromUidState the lowest uid state to query
3519 * @param toUidState the highest uid state to query (inclusive)
3520 * @param flags The op flags
3521 *
3522 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
3523 * 00:00:00.000 GMT - Gregorian)) or {@code -1}
3524 *
3525 * @see #getLastRejectTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003526 * @see #getLastRejectForegroundTime(int)
3527 * @see #getLastRejectBackgroundTime(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003528 * @see #getLastRejectTime(int, int, int)
3529 * @see OpFeatureEntry#getLastRejectTime(int, int, int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003530 */
3531 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
3532 @OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003533 NoteOpEvent lastEvent = getLastRejectEvent(fromUidState, toUidState, flags);
3534 if (lastEvent == null) {
3535 return -1;
3536 }
3537
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003538 return lastEvent.getNoteTime();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003539 }
3540
3541 /**
3542 * @return Whether the operation is running.
3543 */
3544 public boolean isRunning() {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003545 for (OpFeatureEntry opFeatureEntry : mFeatures.values()) {
3546 if (opFeatureEntry.isRunning()) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003547 return true;
3548 }
3549 }
3550
3551 return false;
3552 }
3553
3554 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003555 * @deprecated Use {@link #getLastDuration(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003556 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003557 @Deprecated
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003558 public long getDuration() {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003559 return getLastDuration(OP_FLAGS_ALL);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003560 }
3561
3562 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003563 * Return the duration in milliseconds of the last the access.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003564 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003565 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003566 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003567 * @return the duration in milliseconds or {@code -1}
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003568 *
3569 * @see #getLastForegroundDuration(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003570 * @see #getLastBackgroundDuration(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003571 * @see #getLastDuration(int, int, int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003572 * @see OpFeatureEntry#getLastDuration(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003573 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003574 public long getLastDuration(@OpFlags int flags) {
3575 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003576 }
3577
3578 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003579 * Return the duration in milliseconds of the last foreground access.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003580 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003581 * @param flags The op flags
3582 *
3583 * @return the duration in milliseconds or {@code -1}
3584 *
3585 * @see #getLastDuration(int)
3586 * @see #getLastBackgroundDuration(int)
3587 * @see #getLastDuration(int, int, int)
3588 * @see OpFeatureEntry#getLastForegroundDuration(int)
3589 */
3590 public long getLastForegroundDuration(@OpFlags int flags) {
3591 return getLastDuration(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
3592 flags);
3593 }
3594
3595 /**
3596 * Return the duration in milliseconds of the last background access.
3597 *
3598 * @param flags The op flags
3599 *
3600 * @return the duration in milliseconds or {@code -1}
3601 *
3602 * @see #getLastDuration(int)
3603 * @see #getLastForegroundDuration(int)
3604 * @see #getLastDuration(int, int, int)
3605 * @see OpFeatureEntry#getLastBackgroundDuration(int)
3606 */
3607 public long getLastBackgroundDuration(@OpFlags int flags) {
3608 return getLastDuration(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
3609 flags);
3610 }
3611
3612 /**
3613 * Return the duration in milliseconds of the last access.
3614 *
3615 * @param fromUidState The lowest UID state for which to query
3616 * @param toUidState The highest UID state for which to query (inclusive)
3617 * @param flags The op flags
3618 *
3619 * @return the duration in milliseconds or {@code -1}
3620 *
3621 * @see #getLastDuration(int)
3622 * @see #getLastForegroundDuration(int)
3623 * @see #getLastBackgroundDuration(int)
3624 * @see OpFeatureEntry#getLastDuration(int, int, int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003625 */
3626 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
3627 @OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003628 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
3629 if (lastEvent == null) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003630 return -1;
3631 }
3632
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003633 return lastEvent.getDuration();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003634 }
3635
3636 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003637 * @deprecated Use {@link #getLastProxyInfo(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003638 */
3639 @Deprecated
3640 public int getProxyUid() {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003641 OpEventProxyInfo proxy = getLastProxyInfo(OP_FLAGS_ALL);
3642 if (proxy == null) {
3643 return Process.INVALID_UID;
3644 }
3645
3646 return proxy.getUid();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003647 }
3648
3649 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003650 * @deprecated Use {@link #getLastProxyInfo(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003651 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003652 @Deprecated
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003653 public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003654 OpEventProxyInfo proxy = getLastProxyInfo(uidState, uidState, flags);
3655 if (proxy == null) {
3656 return Process.INVALID_UID;
3657 }
3658
3659 return proxy.getUid();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003660 }
3661
3662 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003663 * @deprecated Use {@link #getLastProxyInfo(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003664 */
3665 @Deprecated
3666 public @Nullable String getProxyPackageName() {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003667 OpEventProxyInfo proxy = getLastProxyInfo(OP_FLAGS_ALL);
3668 if (proxy == null) {
3669 return null;
3670 }
3671
3672 return proxy.getPackageName();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003673 }
3674
3675 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003676 * @deprecated Use {@link #getLastProxyInfo(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003677 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003678 @Deprecated
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003679 public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003680 OpEventProxyInfo proxy = getLastProxyInfo(uidState, uidState, flags);
3681 if (proxy == null) {
3682 return null;
3683 }
3684
3685 return proxy.getPackageName();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003686 }
3687
3688 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003689 * Gets the proxy info of the app that performed the last access on behalf of this app and
3690 * as a result blamed the op on this app.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003691 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003692 * @param flags The op flags
3693 *
3694 * @return The proxy name or {@code null}
3695 *
3696 * @see #getLastForegroundProxyInfo(int)
3697 * @see #getLastBackgroundProxyInfo(int)
3698 * @see #getLastProxyInfo(int, int, int)
3699 * @see OpFeatureEntry#getLastProxyInfo(int)
3700 */
3701 public @Nullable OpEventProxyInfo getLastProxyInfo(@OpFlags int flags) {
3702 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
3703 }
3704
3705 /**
3706 * Gets the proxy info of the app that performed the last foreground access on behalf of
3707 * this app and as a result blamed the op on this app.
3708 *
3709 * @param flags The op flags
3710 *
3711 * @return The proxy name or {@code null}
3712 *
3713 * @see #getLastProxyInfo(int)
3714 * @see #getLastBackgroundProxyInfo(int)
3715 * @see #getLastProxyInfo(int, int, int)
3716 * @see OpFeatureEntry#getLastForegroundProxyInfo(int)
3717 */
3718 public @Nullable OpEventProxyInfo getLastForegroundProxyInfo(@OpFlags int flags) {
3719 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
3720 flags);
3721 }
3722
3723 /**
3724 * Gets the proxy info of the app that performed the last background access on behalf of
3725 * this app and as a result blamed the op on this app.
3726 *
3727 * @param flags The op flags
3728 *
3729 * @return The proxy name or {@code null}
3730 *
3731 * @see #getLastProxyInfo(int)
3732 * @see #getLastForegroundProxyInfo(int)
3733 * @see #getLastProxyInfo(int, int, int)
3734 * @see OpFeatureEntry#getLastBackgroundProxyInfo(int)
3735 */
3736 public @Nullable OpEventProxyInfo getLastBackgroundProxyInfo(@OpFlags int flags) {
3737 return getLastProxyInfo(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
3738 flags);
3739 }
3740
3741 /**
3742 * Gets the proxy info of the app that performed the last access on behalf of this app and
3743 * as a result blamed the op on this app.
3744 *
3745 * @param fromUidState The lowest UID state for which to query
3746 * @param toUidState The highest UID state for which to query (inclusive)
3747 * @param flags The op flags
3748 *
3749 * @return The proxy name or {@code null}
3750 *
3751 * @see #getLastProxyInfo(int)
3752 * @see #getLastForegroundProxyInfo(int)
3753 * @see #getLastBackgroundProxyInfo(int)
3754 * @see OpFeatureEntry#getLastProxyInfo(int, int, int)
3755 */
3756 public @Nullable OpEventProxyInfo getLastProxyInfo(@UidState int fromUidState,
3757 @UidState int toUidState, @OpFlags int flags) {
3758 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
3759 if (lastEvent == null) {
3760 return null;
3761 }
3762
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003763 return lastEvent.getProxy();
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003764 }
3765
3766
3767
3768 // Code below generated by codegen v1.0.14.
3769 //
3770 // DO NOT MODIFY!
3771 // CHECKSTYLE:OFF Generated code
3772 //
3773 // To regenerate run:
3774 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
3775 //
3776 // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
3777 // Settings > Editor > Code Style > Formatter Control
3778 //@formatter:off
3779
3780
3781 /**
3782 * Creates a new OpEntry.
3783 *
3784 * @param op
3785 * The code of the op
3786 * @param mode
3787 * The mode of the op
3788 * @param features
3789 * The features that have been used when checking the op
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003790 * @hide
3791 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003792 @DataClass.Generated.Member
3793 public OpEntry(
3794 @IntRange(from = 0, to = _NUM_OP - 1) int op,
3795 @Mode int mode,
3796 @NonNull Map<String,OpFeatureEntry> features) {
3797 this.mOp = op;
3798 com.android.internal.util.AnnotationValidations.validate(
3799 IntRange.class, null, mOp,
3800 "from", 0,
3801 "to", _NUM_OP - 1);
3802 this.mMode = mode;
3803 com.android.internal.util.AnnotationValidations.validate(
3804 Mode.class, null, mMode);
3805 this.mFeatures = features;
3806 com.android.internal.util.AnnotationValidations.validate(
3807 NonNull.class, null, mFeatures);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003808
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003809 // onConstructed(); // You can define this method to get a callback
3810 }
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003811
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003812 /**
3813 * The mode of the op
3814 */
3815 @DataClass.Generated.Member
3816 public @Mode int getMode() {
3817 return mMode;
3818 }
3819
3820 /**
3821 * The features that have been used when checking the op
3822 */
3823 @DataClass.Generated.Member
3824 public @NonNull Map<String,OpFeatureEntry> getFeatures() {
3825 return mFeatures;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003826 }
3827
Dianne Hackborn35654b62013-01-14 17:38:02 -08003828 @Override
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003829 @DataClass.Generated.Member
Dianne Hackborn35654b62013-01-14 17:38:02 -08003830 public void writeToParcel(Parcel dest, int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003831 // You can override field parcelling by defining methods like:
3832 // void parcelFieldName(Parcel dest, int flags) { ... }
3833
Dianne Hackborn35654b62013-01-14 17:38:02 -08003834 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08003835 dest.writeInt(mMode);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003836 dest.writeMap(mFeatures);
Dianne Hackborn35654b62013-01-14 17:38:02 -08003837 }
3838
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003839 @Override
3840 @DataClass.Generated.Member
3841 public int describeContents() { return 0; }
3842
3843 /** @hide */
3844 @SuppressWarnings({"unchecked", "RedundantCast"})
3845 @DataClass.Generated.Member
3846 /* package-private */ OpEntry(@NonNull Parcel in) {
3847 // You can override field unparcelling by defining methods like:
3848 // static FieldType unparcelFieldName(Parcel in) { ... }
3849
3850 int op = in.readInt();
3851 int mode = in.readInt();
3852 Map<String,OpFeatureEntry> features = new java.util.LinkedHashMap<>();
3853 in.readMap(features, OpFeatureEntry.class.getClassLoader());
3854
3855 this.mOp = op;
3856 com.android.internal.util.AnnotationValidations.validate(
3857 IntRange.class, null, mOp,
3858 "from", 0,
3859 "to", _NUM_OP - 1);
3860 this.mMode = mode;
3861 com.android.internal.util.AnnotationValidations.validate(
3862 Mode.class, null, mMode);
3863 this.mFeatures = features;
3864 com.android.internal.util.AnnotationValidations.validate(
3865 NonNull.class, null, mFeatures);
3866
3867 // onConstructed(); // You can define this method to get a callback
3868 }
3869
3870 @DataClass.Generated.Member
3871 public static final @NonNull Parcelable.Creator<OpEntry> CREATOR
3872 = new Parcelable.Creator<OpEntry>() {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003873 @Override
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003874 public OpEntry[] newArray(int size) {
3875 return new OpEntry[size];
Dianne Hackborn35654b62013-01-14 17:38:02 -08003876 }
3877
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003878 @Override
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003879 public OpEntry createFromParcel(@NonNull Parcel in) {
3880 return new OpEntry(in);
Dianne Hackborn35654b62013-01-14 17:38:02 -08003881 }
3882 };
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003883
3884 /*
3885 @DataClass.Generated(
3886 time = 1574809856259L,
3887 codegenVersion = "1.0.14",
3888 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
3889 inputSignatures = "private final @android.annotation.IntRange(from=0L, to=_NUM_OP - 1) int mOp\nprivate final @android.app.Mode int mMode\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,android.app.OpFeatureEntry> mFeatures\npublic @android.annotation.UnsupportedAppUsage(maxTargetSdk=Build.VERSION_CODES.Q, publicAlternatives=\"{@code \" + \"#getOpStr()}\") int getOp()\npublic @android.annotation.NonNull java.lang.String getOpStr()\npublic @java.lang.Deprecated @android.annotation.UnsupportedAppUsage(maxTargetSdk=Build.VERSION_CODES.Q, publicAlternatives=\"{@code \" + \"#getAccessTime(int, int)}\") long getTime()\npublic @java.lang.Deprecated long getLastAccessTime(int)\npublic @java.lang.Deprecated long getLastAccessForegroundTime(int)\npublic @java.lang.Deprecated long getLastAccessBackgroundTime(int)\npublic @java.lang.Deprecated long getLastAccessTime(int,int,int)\npublic @java.lang.Deprecated @android.annotation.UnsupportedAppUsage(maxTargetSdk=Build.VERSION_CODES.Q, publicAlternatives=\"{@code \" + \"#getLastRejectTime(int, int, int)}\") long getRejectTime()\npublic @java.lang.Deprecated long getLastRejectTime(int)\npublic @java.lang.Deprecated long getLastRejectForegroundTime(int)\npublic @java.lang.Deprecated long getLastRejectBackgroundTime(int)\npublic @java.lang.Deprecated long getLastRejectTime(int,int,int)\npublic long getAccessTime(int,int)\npublic long getRejectTime(int,int)\npublic boolean isRunning()\nprivate android.app.NoteOpEvent getLastAccessEvent(int,int,int)\npublic @java.lang.Deprecated long getDuration()\npublic @java.lang.Deprecated long getLastForegroundDuration(int)\npublic @java.lang.Deprecated long getLastBackgroundDuration(int)\npublic @java.lang.Deprecated long getLastDuration(int,int,int)\npublic @java.lang.Deprecated int getProxyUid()\npublic @java.lang.Deprecated @android.annotation.Nullable java.lang.String getProxyPackageName()\nprivate @android.app.UidState int getLastAccessUidStateForFlagsInStatesOfAllFeatures(int,int,int)\npublic @android.app.UidState int getLastAccessUidState(int)\npublic @android.app.UidState int getLastForegroundAccessUidState(int)\npublic @android.app.UidState int getLastBackgroundAccessUidState(int)\nprivate @android.app.UidState int getLastRejectUidStateForFlagsInStatesOfAllFeatures(int,int,int)\npublic @android.app.UidState int getLastRejectUidState(int)\npublic @android.app.UidState int getLastForegroundRejectUidState(int)\npublic @android.app.UidState int getLastBackgroundRejectUidState(int)\npublic long getDuration(int,int)\npublic int getProxyUid(int,int)\nprivate int getProxyUid(int,int,int)\npublic @android.annotation.Nullable java.lang.String getProxyPackageName(int,int)\nprivate @android.annotation.Nullable java.lang.String getProxyPackageName(int,int,int)\nclass OpEntry extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
3890 @Deprecated
3891 private void __metadata() {}
3892 */
3893
3894
3895 //@formatter:on
3896 // End of generated code
3897
Dianne Hackborn35654b62013-01-14 17:38:02 -08003898 }
3899
Svet Ganov8455ba22019-01-02 13:05:56 -08003900 /** @hide */
3901 public interface HistoricalOpsVisitor {
3902 void visitHistoricalOps(@NonNull HistoricalOps ops);
3903 void visitHistoricalUidOps(@NonNull HistoricalUidOps ops);
3904 void visitHistoricalPackageOps(@NonNull HistoricalPackageOps ops);
3905 void visitHistoricalOp(@NonNull HistoricalOp ops);
3906 }
3907
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08003908 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08003909 * Request for getting historical app op usage. The request acts
3910 * as a filtering criteria when querying historical op usage.
3911 *
3912 * @hide
3913 */
3914 @Immutable
3915 @TestApi
3916 @SystemApi
3917 public static final class HistoricalOpsRequest {
3918 private final int mUid;
3919 private final @Nullable String mPackageName;
3920 private final @Nullable List<String> mOpNames;
3921 private final long mBeginTimeMillis;
3922 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08003923 private final @OpFlags int mFlags;
Svet Ganov23c88db2019-01-22 20:38:11 -08003924
3925 private HistoricalOpsRequest(int uid, @Nullable String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08003926 @Nullable List<String> opNames, long beginTimeMillis, long endTimeMillis,
3927 @OpFlags int flags) {
Svet Ganov23c88db2019-01-22 20:38:11 -08003928 mUid = uid;
3929 mPackageName = packageName;
3930 mOpNames = opNames;
3931 mBeginTimeMillis = beginTimeMillis;
3932 mEndTimeMillis = endTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08003933 mFlags = flags;
Svet Ganov23c88db2019-01-22 20:38:11 -08003934 }
3935
3936 /**
3937 * Builder for creating a {@link HistoricalOpsRequest}.
3938 *
3939 * @hide
3940 */
3941 @TestApi
3942 @SystemApi
3943 public static final class Builder {
3944 private int mUid = Process.INVALID_UID;
3945 private @Nullable String mPackageName;
3946 private @Nullable List<String> mOpNames;
3947 private final long mBeginTimeMillis;
3948 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08003949 private @OpFlags int mFlags = OP_FLAGS_ALL;
Svet Ganov23c88db2019-01-22 20:38:11 -08003950
3951 /**
3952 * Creates a new builder.
3953 *
3954 * @param beginTimeMillis The beginning of the interval in milliseconds since
3955 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non
3956 * negative.
3957 * @param endTimeMillis The end of the interval in milliseconds since
3958 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after
3959 * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent
3960 * history including ops that happen while this call is in flight.
3961 */
3962 public Builder(long beginTimeMillis, long endTimeMillis) {
3963 Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
3964 "beginTimeMillis must be non negative and lesser than endTimeMillis");
3965 mBeginTimeMillis = beginTimeMillis;
3966 mEndTimeMillis = endTimeMillis;
3967 }
3968
3969 /**
3970 * Sets the UID to query for.
3971 *
3972 * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid.
3973 * @return This builder.
3974 */
3975 public @NonNull Builder setUid(int uid) {
3976 Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
3977 "uid must be " + Process.INVALID_UID + " or non negative");
3978 mUid = uid;
3979 return this;
3980 }
3981
3982 /**
3983 * Sets the package to query for.
3984 *
3985 * @param packageName The package name. <code>Null</code> for any package.
3986 * @return This builder.
3987 */
3988 public @NonNull Builder setPackageName(@Nullable String packageName) {
3989 mPackageName = packageName;
3990 return this;
3991 }
3992
3993 /**
3994 * Sets the op names to query for.
3995 *
3996 * @param opNames The op names. <code>Null</code> for any op.
3997 * @return This builder.
3998 */
3999 public @NonNull Builder setOpNames(@Nullable List<String> opNames) {
4000 if (opNames != null) {
4001 final int opCount = opNames.size();
4002 for (int i = 0; i < opCount; i++) {
4003 Preconditions.checkArgument(AppOpsManager.strOpToOp(
4004 opNames.get(i)) != AppOpsManager.OP_NONE);
4005 }
4006 }
4007 mOpNames = opNames;
4008 return this;
4009 }
4010
4011 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08004012 * Sets the op flags to query for. The flags specify the type of
4013 * op data being queried.
4014 *
4015 * @param flags The flags which are any combination of
4016 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4017 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4018 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4019 * for any flag.
4020 * @return This builder.
4021 */
4022 public @NonNull Builder setFlags(@OpFlags int flags) {
4023 Preconditions.checkFlagsArgument(flags, OP_FLAGS_ALL);
4024 mFlags = flags;
4025 return this;
4026 }
4027
4028 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08004029 * @return a new {@link HistoricalOpsRequest}.
4030 */
4031 public @NonNull HistoricalOpsRequest build() {
4032 return new HistoricalOpsRequest(mUid, mPackageName, mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08004033 mBeginTimeMillis, mEndTimeMillis, mFlags);
Svet Ganov23c88db2019-01-22 20:38:11 -08004034 }
4035 }
4036 }
4037
4038 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004039 * This class represents historical app op state of all UIDs for a given time interval.
4040 *
4041 * @hide
4042 */
4043 @TestApi
4044 @SystemApi
4045 public static final class HistoricalOps implements Parcelable {
4046 private long mBeginTimeMillis;
4047 private long mEndTimeMillis;
4048 private @Nullable SparseArray<HistoricalUidOps> mHistoricalUidOps;
4049
4050 /** @hide */
4051 @TestApi
4052 public HistoricalOps(long beginTimeMillis, long endTimeMillis) {
4053 Preconditions.checkState(beginTimeMillis <= endTimeMillis);
4054 mBeginTimeMillis = beginTimeMillis;
4055 mEndTimeMillis = endTimeMillis;
4056 }
4057
4058 /** @hide */
4059 public HistoricalOps(@NonNull HistoricalOps other) {
4060 mBeginTimeMillis = other.mBeginTimeMillis;
4061 mEndTimeMillis = other.mEndTimeMillis;
4062 Preconditions.checkState(mBeginTimeMillis <= mEndTimeMillis);
4063 if (other.mHistoricalUidOps != null) {
4064 final int opCount = other.getUidCount();
4065 for (int i = 0; i < opCount; i++) {
4066 final HistoricalUidOps origOps = other.getUidOpsAt(i);
4067 final HistoricalUidOps clonedOps = new HistoricalUidOps(origOps);
4068 if (mHistoricalUidOps == null) {
4069 mHistoricalUidOps = new SparseArray<>(opCount);
4070 }
4071 mHistoricalUidOps.put(clonedOps.getUid(), clonedOps);
4072 }
4073 }
4074 }
4075
4076 private HistoricalOps(Parcel parcel) {
4077 mBeginTimeMillis = parcel.readLong();
4078 mEndTimeMillis = parcel.readLong();
4079 final int[] uids = parcel.createIntArray();
4080 if (!ArrayUtils.isEmpty(uids)) {
4081 final ParceledListSlice<HistoricalUidOps> listSlice = parcel.readParcelable(
4082 HistoricalOps.class.getClassLoader());
4083 final List<HistoricalUidOps> uidOps = (listSlice != null)
4084 ? listSlice.getList() : null;
4085 if (uidOps == null) {
4086 return;
4087 }
4088 for (int i = 0; i < uids.length; i++) {
4089 if (mHistoricalUidOps == null) {
4090 mHistoricalUidOps = new SparseArray<>();
4091 }
4092 mHistoricalUidOps.put(uids[i], uidOps.get(i));
4093 }
4094 }
4095 }
4096
4097 /**
4098 * Splice a piece from the beginning of these ops.
4099 *
4100 * @param splicePoint The fraction of the data to be spliced off.
4101 *
4102 * @hide
4103 */
4104 public @NonNull HistoricalOps spliceFromBeginning(double splicePoint) {
4105 return splice(splicePoint, true);
4106 }
4107
4108 /**
4109 * Splice a piece from the end of these ops.
4110 *
4111 * @param fractionToRemove The fraction of the data to be spliced off.
4112 *
4113 * @hide
4114 */
4115 public @NonNull HistoricalOps spliceFromEnd(double fractionToRemove) {
4116 return splice(fractionToRemove, false);
4117 }
4118
4119 /**
4120 * Splice a piece from the beginning or end of these ops.
4121 *
4122 * @param fractionToRemove The fraction of the data to be spliced off.
4123 * @param beginning Whether to splice off the beginning or the end.
4124 *
4125 * @return The spliced off part.
4126 *
4127 * @hide
4128 */
4129 private @Nullable HistoricalOps splice(double fractionToRemove, boolean beginning) {
4130 final long spliceBeginTimeMills;
4131 final long spliceEndTimeMills;
4132 if (beginning) {
4133 spliceBeginTimeMills = mBeginTimeMillis;
4134 spliceEndTimeMills = (long) (mBeginTimeMillis
4135 + getDurationMillis() * fractionToRemove);
4136 mBeginTimeMillis = spliceEndTimeMills;
4137 } else {
4138 spliceBeginTimeMills = (long) (mEndTimeMillis
4139 - getDurationMillis() * fractionToRemove);
4140 spliceEndTimeMills = mEndTimeMillis;
4141 mEndTimeMillis = spliceBeginTimeMills;
4142 }
4143
4144 HistoricalOps splice = null;
4145 final int uidCount = getUidCount();
4146 for (int i = 0; i < uidCount; i++) {
4147 final HistoricalUidOps origOps = getUidOpsAt(i);
4148 final HistoricalUidOps spliceOps = origOps.splice(fractionToRemove);
4149 if (spliceOps != null) {
4150 if (splice == null) {
4151 splice = new HistoricalOps(spliceBeginTimeMills, spliceEndTimeMills);
4152 }
4153 if (splice.mHistoricalUidOps == null) {
4154 splice.mHistoricalUidOps = new SparseArray<>();
4155 }
4156 splice.mHistoricalUidOps.put(spliceOps.getUid(), spliceOps);
4157 }
4158 }
4159 return splice;
4160 }
4161
4162 /**
4163 * Merge the passed ops into the current ones. The time interval is a
4164 * union of the current and passed in one and the passed in data is
4165 * folded into the data of this instance.
4166 *
4167 * @hide
4168 */
4169 public void merge(@NonNull HistoricalOps other) {
4170 mBeginTimeMillis = Math.min(mBeginTimeMillis, other.mBeginTimeMillis);
4171 mEndTimeMillis = Math.max(mEndTimeMillis, other.mEndTimeMillis);
4172 final int uidCount = other.getUidCount();
4173 for (int i = 0; i < uidCount; i++) {
4174 final HistoricalUidOps otherUidOps = other.getUidOpsAt(i);
4175 final HistoricalUidOps thisUidOps = getUidOps(otherUidOps.getUid());
4176 if (thisUidOps != null) {
4177 thisUidOps.merge(otherUidOps);
4178 } else {
4179 if (mHistoricalUidOps == null) {
4180 mHistoricalUidOps = new SparseArray<>();
4181 }
4182 mHistoricalUidOps.put(otherUidOps.getUid(), otherUidOps);
4183 }
4184 }
4185 }
4186
4187 /**
4188 * AppPermissionUsage the ops to leave only the data we filter for.
4189 *
4190 * @param uid Uid to filter for or {@link android.os.Process#INCIDENTD_UID} for all.
4191 * @param packageName Package to filter for or null for all.
4192 * @param opNames Ops to filter for or null for all.
4193 * @param beginTimeMillis The begin time to filter for or {@link Long#MIN_VALUE} for all.
4194 * @param endTimeMillis The end time to filter for or {@link Long#MAX_VALUE} for all.
4195 *
4196 * @hide
4197 */
4198 public void filter(int uid, @Nullable String packageName, @Nullable String[] opNames,
4199 long beginTimeMillis, long endTimeMillis) {
4200 final long durationMillis = getDurationMillis();
4201 mBeginTimeMillis = Math.max(mBeginTimeMillis, beginTimeMillis);
4202 mEndTimeMillis = Math.min(mEndTimeMillis, endTimeMillis);
4203 final double scaleFactor = Math.min((double) (endTimeMillis - beginTimeMillis)
4204 / (double) durationMillis, 1);
4205 final int uidCount = getUidCount();
4206 for (int i = uidCount - 1; i >= 0; i--) {
4207 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
4208 if (uid != Process.INVALID_UID && uid != uidOp.getUid()) {
4209 mHistoricalUidOps.removeAt(i);
4210 } else {
4211 uidOp.filter(packageName, opNames, scaleFactor);
4212 }
4213 }
4214 }
4215
4216 /** @hide */
4217 public boolean isEmpty() {
4218 if (getBeginTimeMillis() >= getEndTimeMillis()) {
4219 return true;
4220 }
4221 final int uidCount = getUidCount();
4222 for (int i = uidCount - 1; i >= 0; i--) {
4223 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
4224 if (!uidOp.isEmpty()) {
4225 return false;
4226 }
4227 }
4228 return true;
4229 }
4230
4231 /** @hide */
4232 public long getDurationMillis() {
4233 return mEndTimeMillis - mBeginTimeMillis;
4234 }
4235
4236 /** @hide */
4237 @TestApi
4238 public void increaseAccessCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004239 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004240 getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08004241 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004242 }
4243
4244 /** @hide */
4245 @TestApi
4246 public void increaseRejectCount(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004247 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004248 getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08004249 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004250 }
4251
4252 /** @hide */
4253 @TestApi
4254 public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004255 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004256 getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode,
Svet Ganovaf189e32019-02-15 18:45:29 -08004257 packageName, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004258 }
4259
4260 /** @hide */
4261 @TestApi
4262 public void offsetBeginAndEndTime(long offsetMillis) {
4263 mBeginTimeMillis += offsetMillis;
4264 mEndTimeMillis += offsetMillis;
4265 }
4266
4267 /** @hide */
4268 public void setBeginAndEndTime(long beginTimeMillis, long endTimeMillis) {
4269 mBeginTimeMillis = beginTimeMillis;
4270 mEndTimeMillis = endTimeMillis;
4271 }
4272
4273 /** @hide */
4274 public void setBeginTime(long beginTimeMillis) {
4275 mBeginTimeMillis = beginTimeMillis;
4276 }
4277
4278 /** @hide */
4279 public void setEndTime(long endTimeMillis) {
4280 mEndTimeMillis = endTimeMillis;
4281 }
4282
4283 /**
4284 * @return The beginning of the interval in milliseconds since
4285 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
4286 */
4287 public long getBeginTimeMillis() {
4288 return mBeginTimeMillis;
4289 }
4290
4291 /**
4292 * @return The end of the interval in milliseconds since
4293 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
4294 */
4295 public long getEndTimeMillis() {
4296 return mEndTimeMillis;
4297 }
4298
4299 /**
4300 * Gets number of UIDs with historical ops.
4301 *
4302 * @return The number of UIDs with historical ops.
4303 *
4304 * @see #getUidOpsAt(int)
4305 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004306 public @IntRange(from = 0) int getUidCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004307 if (mHistoricalUidOps == null) {
4308 return 0;
4309 }
4310 return mHistoricalUidOps.size();
4311 }
4312
4313 /**
4314 * Gets the historical UID ops at a given index.
4315 *
4316 * @param index The index.
4317 *
4318 * @return The historical UID ops at the given index.
4319 *
4320 * @see #getUidCount()
4321 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004322 public @NonNull HistoricalUidOps getUidOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004323 if (mHistoricalUidOps == null) {
4324 throw new IndexOutOfBoundsException();
4325 }
4326 return mHistoricalUidOps.valueAt(index);
4327 }
4328
4329 /**
4330 * Gets the historical UID ops for a given UID.
4331 *
4332 * @param uid The UID.
4333 *
4334 * @return The historical ops for the UID.
4335 */
4336 public @Nullable HistoricalUidOps getUidOps(int uid) {
4337 if (mHistoricalUidOps == null) {
4338 return null;
4339 }
4340 return mHistoricalUidOps.get(uid);
4341 }
4342
Winson4e3b4352019-05-07 16:29:59 -07004343 /** @hide */
4344 public void clearHistory(int uid, @NonNull String packageName) {
4345 HistoricalUidOps historicalUidOps = getOrCreateHistoricalUidOps(uid);
4346 historicalUidOps.clearHistory(packageName);
4347 if (historicalUidOps.isEmpty()) {
4348 mHistoricalUidOps.remove(uid);
4349 }
4350 }
4351
Svet Ganov8455ba22019-01-02 13:05:56 -08004352 @Override
4353 public int describeContents() {
4354 return 0;
4355 }
4356
4357 @Override
4358 public void writeToParcel(Parcel parcel, int flags) {
4359 parcel.writeLong(mBeginTimeMillis);
4360 parcel.writeLong(mEndTimeMillis);
4361 if (mHistoricalUidOps != null) {
4362 final int uidCount = mHistoricalUidOps.size();
4363 parcel.writeInt(uidCount);
4364 for (int i = 0; i < uidCount; i++) {
4365 parcel.writeInt(mHistoricalUidOps.keyAt(i));
4366 }
4367 final List<HistoricalUidOps> opsList = new ArrayList<>(uidCount);
4368 for (int i = 0; i < uidCount; i++) {
4369 opsList.add(mHistoricalUidOps.valueAt(i));
4370 }
4371 parcel.writeParcelable(new ParceledListSlice<>(opsList), flags);
4372 } else {
4373 parcel.writeInt(-1);
4374 }
4375 }
4376
4377 /**
4378 * Accepts a visitor to traverse the ops tree.
4379 *
4380 * @param visitor The visitor.
4381 *
4382 * @hide
4383 */
4384 public void accept(@NonNull HistoricalOpsVisitor visitor) {
4385 visitor.visitHistoricalOps(this);
4386 final int uidCount = getUidCount();
4387 for (int i = 0; i < uidCount; i++) {
4388 getUidOpsAt(i).accept(visitor);
4389 }
4390 }
4391
4392 private @NonNull HistoricalUidOps getOrCreateHistoricalUidOps(int uid) {
4393 if (mHistoricalUidOps == null) {
4394 mHistoricalUidOps = new SparseArray<>();
4395 }
4396 HistoricalUidOps historicalUidOp = mHistoricalUidOps.get(uid);
4397 if (historicalUidOp == null) {
4398 historicalUidOp = new HistoricalUidOps(uid);
4399 mHistoricalUidOps.put(uid, historicalUidOp);
4400 }
4401 return historicalUidOp;
4402 }
4403
4404 /**
4405 * @return Rounded value up at the 0.5 boundary.
4406 *
4407 * @hide
4408 */
4409 public static double round(double value) {
4410 final BigDecimal decimalScale = new BigDecimal(value);
4411 return decimalScale.setScale(0, RoundingMode.HALF_UP).doubleValue();
4412 }
4413
4414 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004415 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004416 if (this == obj) {
4417 return true;
4418 }
4419 if (obj == null || getClass() != obj.getClass()) {
4420 return false;
4421 }
4422 final HistoricalOps other = (HistoricalOps) obj;
4423 if (mBeginTimeMillis != other.mBeginTimeMillis) {
4424 return false;
4425 }
4426 if (mEndTimeMillis != other.mEndTimeMillis) {
4427 return false;
4428 }
4429 if (mHistoricalUidOps == null) {
4430 if (other.mHistoricalUidOps != null) {
4431 return false;
4432 }
4433 } else if (!mHistoricalUidOps.equals(other.mHistoricalUidOps)) {
4434 return false;
4435 }
4436 return true;
4437 }
4438
4439 @Override
4440 public int hashCode() {
4441 int result = (int) (mBeginTimeMillis ^ (mBeginTimeMillis >>> 32));
4442 result = 31 * result + mHistoricalUidOps.hashCode();
4443 return result;
4444 }
4445
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004446 @NonNull
Svet Ganov8455ba22019-01-02 13:05:56 -08004447 @Override
4448 public String toString() {
4449 return getClass().getSimpleName() + "[from:"
4450 + mBeginTimeMillis + " to:" + mEndTimeMillis + "]";
4451 }
4452
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07004453 public static final @android.annotation.NonNull Creator<HistoricalOps> CREATOR = new Creator<HistoricalOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004454 @Override
4455 public @NonNull HistoricalOps createFromParcel(@NonNull Parcel parcel) {
4456 return new HistoricalOps(parcel);
4457 }
4458
4459 @Override
4460 public @NonNull HistoricalOps[] newArray(int size) {
4461 return new HistoricalOps[size];
4462 }
4463 };
4464 }
4465
4466 /**
4467 * This class represents historical app op state for a UID.
4468 *
4469 * @hide
4470 */
4471 @TestApi
4472 @SystemApi
4473 public static final class HistoricalUidOps implements Parcelable {
4474 private final int mUid;
4475 private @Nullable ArrayMap<String, HistoricalPackageOps> mHistoricalPackageOps;
4476
4477 /** @hide */
4478 public HistoricalUidOps(int uid) {
4479 mUid = uid;
4480 }
4481
4482 private HistoricalUidOps(@NonNull HistoricalUidOps other) {
4483 mUid = other.mUid;
4484 final int opCount = other.getPackageCount();
4485 for (int i = 0; i < opCount; i++) {
4486 final HistoricalPackageOps origOps = other.getPackageOpsAt(i);
4487 final HistoricalPackageOps cloneOps = new HistoricalPackageOps(origOps);
4488 if (mHistoricalPackageOps == null) {
4489 mHistoricalPackageOps = new ArrayMap<>(opCount);
4490 }
4491 mHistoricalPackageOps.put(cloneOps.getPackageName(), cloneOps);
4492 }
4493 }
4494
4495 private HistoricalUidOps(@NonNull Parcel parcel) {
4496 // No arg check since we always read from a trusted source.
4497 mUid = parcel.readInt();
4498 mHistoricalPackageOps = parcel.createTypedArrayMap(HistoricalPackageOps.CREATOR);
4499 }
4500
4501 private @Nullable HistoricalUidOps splice(double fractionToRemove) {
4502 HistoricalUidOps splice = null;
4503 final int packageCount = getPackageCount();
4504 for (int i = 0; i < packageCount; i++) {
4505 final HistoricalPackageOps origOps = getPackageOpsAt(i);
4506 final HistoricalPackageOps spliceOps = origOps.splice(fractionToRemove);
4507 if (spliceOps != null) {
4508 if (splice == null) {
4509 splice = new HistoricalUidOps(mUid);
4510 }
4511 if (splice.mHistoricalPackageOps == null) {
4512 splice.mHistoricalPackageOps = new ArrayMap<>();
4513 }
4514 splice.mHistoricalPackageOps.put(spliceOps.getPackageName(), spliceOps);
4515 }
4516 }
4517 return splice;
4518 }
4519
4520 private void merge(@NonNull HistoricalUidOps other) {
4521 final int packageCount = other.getPackageCount();
4522 for (int i = 0; i < packageCount; i++) {
4523 final HistoricalPackageOps otherPackageOps = other.getPackageOpsAt(i);
4524 final HistoricalPackageOps thisPackageOps = getPackageOps(
4525 otherPackageOps.getPackageName());
4526 if (thisPackageOps != null) {
4527 thisPackageOps.merge(otherPackageOps);
4528 } else {
4529 if (mHistoricalPackageOps == null) {
4530 mHistoricalPackageOps = new ArrayMap<>();
4531 }
4532 mHistoricalPackageOps.put(otherPackageOps.getPackageName(), otherPackageOps);
4533 }
4534 }
4535 }
4536
4537 private void filter(@Nullable String packageName, @Nullable String[] opNames,
4538 double fractionToRemove) {
4539 final int packageCount = getPackageCount();
4540 for (int i = packageCount - 1; i >= 0; i--) {
4541 final HistoricalPackageOps packageOps = getPackageOpsAt(i);
4542 if (packageName != null && !packageName.equals(packageOps.getPackageName())) {
4543 mHistoricalPackageOps.removeAt(i);
4544 } else {
4545 packageOps.filter(opNames, fractionToRemove);
4546 }
4547 }
4548 }
4549
4550 private boolean isEmpty() {
4551 final int packageCount = getPackageCount();
4552 for (int i = packageCount - 1; i >= 0; i--) {
4553 final HistoricalPackageOps packageOps = mHistoricalPackageOps.valueAt(i);
4554 if (!packageOps.isEmpty()) {
4555 return false;
4556 }
4557 }
4558 return true;
4559 }
4560
4561 private void increaseAccessCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004562 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004563 getOrCreateHistoricalPackageOps(packageName).increaseAccessCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08004564 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004565 }
4566
4567 private void increaseRejectCount(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004568 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004569 getOrCreateHistoricalPackageOps(packageName).increaseRejectCount(
Svet Ganovaf189e32019-02-15 18:45:29 -08004570 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004571 }
4572
4573 private void increaseAccessDuration(int opCode, @NonNull String packageName,
Svet Ganovaf189e32019-02-15 18:45:29 -08004574 @UidState int uidState, @OpFlags int flags, long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004575 getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration(
Svet Ganovaf189e32019-02-15 18:45:29 -08004576 opCode, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004577 }
4578
4579 /**
4580 * @return The UID for which the data is related.
4581 */
4582 public int getUid() {
4583 return mUid;
4584 }
4585
4586 /**
4587 * Gets number of packages with historical ops.
4588 *
4589 * @return The number of packages with historical ops.
4590 *
4591 * @see #getPackageOpsAt(int)
4592 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004593 public @IntRange(from = 0) int getPackageCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004594 if (mHistoricalPackageOps == null) {
4595 return 0;
4596 }
4597 return mHistoricalPackageOps.size();
4598 }
4599
4600 /**
4601 * Gets the historical package ops at a given index.
4602 *
4603 * @param index The index.
4604 *
4605 * @return The historical package ops at the given index.
4606 *
4607 * @see #getPackageCount()
4608 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004609 public @NonNull HistoricalPackageOps getPackageOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004610 if (mHistoricalPackageOps == null) {
4611 throw new IndexOutOfBoundsException();
4612 }
4613 return mHistoricalPackageOps.valueAt(index);
4614 }
4615
4616 /**
4617 * Gets the historical package ops for a given package.
4618 *
4619 * @param packageName The package.
4620 *
4621 * @return The historical ops for the package.
4622 */
4623 public @Nullable HistoricalPackageOps getPackageOps(@NonNull String packageName) {
4624 if (mHistoricalPackageOps == null) {
4625 return null;
4626 }
4627 return mHistoricalPackageOps.get(packageName);
4628 }
4629
Winson4e3b4352019-05-07 16:29:59 -07004630 private void clearHistory(@NonNull String packageName) {
4631 if (mHistoricalPackageOps != null) {
4632 mHistoricalPackageOps.remove(packageName);
4633 }
4634 }
4635
Svet Ganov8455ba22019-01-02 13:05:56 -08004636 @Override
4637 public int describeContents() {
4638 return 0;
4639 }
4640
4641 @Override
4642 public void writeToParcel(Parcel parcel, int flags) {
4643 parcel.writeInt(mUid);
4644 parcel.writeTypedArrayMap(mHistoricalPackageOps, flags);
4645 }
4646
4647 private void accept(@NonNull HistoricalOpsVisitor visitor) {
4648 visitor.visitHistoricalUidOps(this);
4649 final int packageCount = getPackageCount();
4650 for (int i = 0; i < packageCount; i++) {
4651 getPackageOpsAt(i).accept(visitor);
4652 }
4653 }
4654
4655 private @NonNull HistoricalPackageOps getOrCreateHistoricalPackageOps(
4656 @NonNull String packageName) {
4657 if (mHistoricalPackageOps == null) {
4658 mHistoricalPackageOps = new ArrayMap<>();
4659 }
4660 HistoricalPackageOps historicalPackageOp = mHistoricalPackageOps.get(packageName);
4661 if (historicalPackageOp == null) {
4662 historicalPackageOp = new HistoricalPackageOps(packageName);
4663 mHistoricalPackageOps.put(packageName, historicalPackageOp);
4664 }
4665 return historicalPackageOp;
4666 }
4667
4668
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07004669 public static final @android.annotation.NonNull Creator<HistoricalUidOps> CREATOR = new Creator<HistoricalUidOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004670 @Override
4671 public @NonNull HistoricalUidOps createFromParcel(@NonNull Parcel parcel) {
4672 return new HistoricalUidOps(parcel);
4673 }
4674
4675 @Override
4676 public @NonNull HistoricalUidOps[] newArray(int size) {
4677 return new HistoricalUidOps[size];
4678 }
4679 };
4680
4681 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004682 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004683 if (this == obj) {
4684 return true;
4685 }
4686 if (obj == null || getClass() != obj.getClass()) {
4687 return false;
4688 }
4689 final HistoricalUidOps other = (HistoricalUidOps) obj;
4690 if (mUid != other.mUid) {
4691 return false;
4692 }
4693 if (mHistoricalPackageOps == null) {
4694 if (other.mHistoricalPackageOps != null) {
4695 return false;
4696 }
4697 } else if (!mHistoricalPackageOps.equals(other.mHistoricalPackageOps)) {
4698 return false;
4699 }
4700 return true;
4701 }
4702
4703 @Override
4704 public int hashCode() {
4705 int result = mUid;
4706 result = 31 * result + (mHistoricalPackageOps != null
4707 ? mHistoricalPackageOps.hashCode() : 0);
4708 return result;
4709 }
4710 }
4711
4712 /**
4713 * This class represents historical app op information about a package.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004714 *
4715 * @hide
4716 */
4717 @TestApi
4718 @SystemApi
4719 public static final class HistoricalPackageOps implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004720 private final @NonNull String mPackageName;
Svet Ganov8455ba22019-01-02 13:05:56 -08004721 private @Nullable ArrayMap<String, HistoricalOp> mHistoricalOps;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004722
Svet Ganov8455ba22019-01-02 13:05:56 -08004723 /** @hide */
4724 public HistoricalPackageOps(@NonNull String packageName) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004725 mPackageName = packageName;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004726 }
4727
Svet Ganov8455ba22019-01-02 13:05:56 -08004728 private HistoricalPackageOps(@NonNull HistoricalPackageOps other) {
4729 mPackageName = other.mPackageName;
4730 final int opCount = other.getOpCount();
4731 for (int i = 0; i < opCount; i++) {
4732 final HistoricalOp origOp = other.getOpAt(i);
4733 final HistoricalOp cloneOp = new HistoricalOp(origOp);
4734 if (mHistoricalOps == null) {
4735 mHistoricalOps = new ArrayMap<>(opCount);
4736 }
4737 mHistoricalOps.put(cloneOp.getOpName(), cloneOp);
4738 }
4739 }
4740
4741 private HistoricalPackageOps(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004742 mPackageName = parcel.readString();
Svet Ganov8455ba22019-01-02 13:05:56 -08004743 mHistoricalOps = parcel.createTypedArrayMap(HistoricalOp.CREATOR);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004744 }
4745
Svet Ganov8455ba22019-01-02 13:05:56 -08004746 private @Nullable HistoricalPackageOps splice(double fractionToRemove) {
4747 HistoricalPackageOps splice = null;
4748 final int opCount = getOpCount();
4749 for (int i = 0; i < opCount; i++) {
4750 final HistoricalOp origOps = getOpAt(i);
4751 final HistoricalOp spliceOps = origOps.splice(fractionToRemove);
4752 if (spliceOps != null) {
4753 if (splice == null) {
4754 splice = new HistoricalPackageOps(mPackageName);
4755 }
4756 if (splice.mHistoricalOps == null) {
4757 splice.mHistoricalOps = new ArrayMap<>();
4758 }
4759 splice.mHistoricalOps.put(spliceOps.getOpName(), spliceOps);
4760 }
4761 }
4762 return splice;
4763 }
4764
4765 private void merge(@NonNull HistoricalPackageOps other) {
4766 final int opCount = other.getOpCount();
4767 for (int i = 0; i < opCount; i++) {
4768 final HistoricalOp otherOp = other.getOpAt(i);
4769 final HistoricalOp thisOp = getOp(otherOp.getOpName());
4770 if (thisOp != null) {
4771 thisOp.merge(otherOp);
4772 } else {
4773 if (mHistoricalOps == null) {
4774 mHistoricalOps = new ArrayMap<>();
4775 }
4776 mHistoricalOps.put(otherOp.getOpName(), otherOp);
4777 }
4778 }
4779 }
4780
4781 private void filter(@Nullable String[] opNames, double scaleFactor) {
4782 final int opCount = getOpCount();
4783 for (int i = opCount - 1; i >= 0; i--) {
4784 final HistoricalOp op = mHistoricalOps.valueAt(i);
4785 if (opNames != null && !ArrayUtils.contains(opNames, op.getOpName())) {
4786 mHistoricalOps.removeAt(i);
4787 } else {
4788 op.filter(scaleFactor);
4789 }
4790 }
4791 }
4792
4793 private boolean isEmpty() {
4794 final int opCount = getOpCount();
4795 for (int i = opCount - 1; i >= 0; i--) {
4796 final HistoricalOp op = mHistoricalOps.valueAt(i);
4797 if (!op.isEmpty()) {
4798 return false;
4799 }
4800 }
4801 return true;
4802 }
4803
Svet Ganovaf189e32019-02-15 18:45:29 -08004804 private void increaseAccessCount(int opCode, @UidState int uidState,
4805 @OpFlags int flags, long increment) {
4806 getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004807 }
4808
Svet Ganovaf189e32019-02-15 18:45:29 -08004809 private void increaseRejectCount(int opCode, @UidState int uidState,
4810 @OpFlags int flags, long increment) {
4811 getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004812 }
4813
Svet Ganovaf189e32019-02-15 18:45:29 -08004814 private void increaseAccessDuration(int opCode, @UidState int uidState,
4815 @OpFlags int flags, long increment) {
4816 getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, flags, increment);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004817 }
4818
4819 /**
4820 * Gets the package name which the data represents.
4821 *
4822 * @return The package name which the data represents.
4823 */
4824 public @NonNull String getPackageName() {
4825 return mPackageName;
4826 }
4827
4828 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004829 * Gets number historical app ops.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004830 *
Svet Ganov8455ba22019-01-02 13:05:56 -08004831 * @return The number historical app ops.
Svet Ganov8455ba22019-01-02 13:05:56 -08004832 * @see #getOpAt(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07004833 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004834 public @IntRange(from = 0) int getOpCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004835 if (mHistoricalOps == null) {
4836 return 0;
4837 }
4838 return mHistoricalOps.size();
Svet Ganovad0a49b2018-10-29 10:07:08 -07004839 }
4840
4841 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004842 * Gets the historical op at a given index.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004843 *
4844 * @param index The index to lookup.
Svet Ganov8455ba22019-01-02 13:05:56 -08004845 * @return The op at the given index.
Svet Ganov8455ba22019-01-02 13:05:56 -08004846 * @see #getOpCount()
Svet Ganovad0a49b2018-10-29 10:07:08 -07004847 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004848 public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004849 if (mHistoricalOps == null) {
4850 throw new IndexOutOfBoundsException();
4851 }
4852 return mHistoricalOps.valueAt(index);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004853 }
4854
4855 /**
4856 * Gets the historical entry for a given op name.
4857 *
4858 * @param opName The op name.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004859 * @return The historical entry for that op name.
4860 */
Svet Ganov8455ba22019-01-02 13:05:56 -08004861 public @Nullable HistoricalOp getOp(@NonNull String opName) {
4862 if (mHistoricalOps == null) {
4863 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004864 }
Svet Ganov8455ba22019-01-02 13:05:56 -08004865 return mHistoricalOps.get(opName);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004866 }
4867
4868 @Override
4869 public int describeContents() {
4870 return 0;
4871 }
4872
4873 @Override
4874 public void writeToParcel(@NonNull Parcel parcel, int flags) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004875 parcel.writeString(mPackageName);
Svet Ganov8455ba22019-01-02 13:05:56 -08004876 parcel.writeTypedArrayMap(mHistoricalOps, flags);
4877 }
4878
4879 private void accept(@NonNull HistoricalOpsVisitor visitor) {
4880 visitor.visitHistoricalPackageOps(this);
4881 final int opCount = getOpCount();
4882 for (int i = 0; i < opCount; i++) {
4883 getOpAt(i).accept(visitor);
4884 }
4885 }
4886
4887 private @NonNull HistoricalOp getOrCreateHistoricalOp(int opCode) {
4888 if (mHistoricalOps == null) {
4889 mHistoricalOps = new ArrayMap<>();
4890 }
4891 final String opStr = sOpToString[opCode];
4892 HistoricalOp op = mHistoricalOps.get(opStr);
4893 if (op == null) {
4894 op = new HistoricalOp(opCode);
4895 mHistoricalOps.put(opStr, op);
4896 }
4897 return op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004898 }
4899
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07004900 public static final @android.annotation.NonNull Creator<HistoricalPackageOps> CREATOR =
Svet Ganovad0a49b2018-10-29 10:07:08 -07004901 new Creator<HistoricalPackageOps>() {
4902 @Override
4903 public @NonNull HistoricalPackageOps createFromParcel(@NonNull Parcel parcel) {
4904 return new HistoricalPackageOps(parcel);
4905 }
4906
4907 @Override
4908 public @NonNull HistoricalPackageOps[] newArray(int size) {
4909 return new HistoricalPackageOps[size];
4910 }
4911 };
Svet Ganov8455ba22019-01-02 13:05:56 -08004912
4913 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004914 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004915 if (this == obj) {
4916 return true;
4917 }
4918 if (obj == null || getClass() != obj.getClass()) {
4919 return false;
4920 }
4921 final HistoricalPackageOps other = (HistoricalPackageOps) obj;
4922 if (!mPackageName.equals(other.mPackageName)) {
4923 return false;
4924 }
4925 if (mHistoricalOps == null) {
4926 if (other.mHistoricalOps != null) {
4927 return false;
4928 }
4929 } else if (!mHistoricalOps.equals(other.mHistoricalOps)) {
4930 return false;
4931 }
4932 return true;
4933 }
4934
4935 @Override
4936 public int hashCode() {
4937 int result = mPackageName != null ? mPackageName.hashCode() : 0;
4938 result = 31 * result + (mHistoricalOps != null ? mHistoricalOps.hashCode() : 0);
4939 return result;
4940 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07004941 }
4942
4943 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004944 * This class represents historical information about an app op.
Svet Ganovad0a49b2018-10-29 10:07:08 -07004945 *
4946 * @hide
4947 */
4948 @TestApi
4949 @SystemApi
Svet Ganov8455ba22019-01-02 13:05:56 -08004950 public static final class HistoricalOp implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004951 private final int mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08004952 private @Nullable LongSparseLongArray mAccessCount;
4953 private @Nullable LongSparseLongArray mRejectCount;
4954 private @Nullable LongSparseLongArray mAccessDuration;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004955
Svet Ganov8455ba22019-01-02 13:05:56 -08004956 /** @hide */
4957 public HistoricalOp(int op) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004958 mOp = op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07004959 }
4960
Svet Ganov8455ba22019-01-02 13:05:56 -08004961 private HistoricalOp(@NonNull HistoricalOp other) {
4962 mOp = other.mOp;
4963 if (other.mAccessCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004964 mAccessCount = other.mAccessCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08004965 }
4966 if (other.mRejectCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004967 mRejectCount = other.mRejectCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08004968 }
4969 if (other.mAccessDuration != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004970 mAccessDuration = other.mAccessDuration.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08004971 }
4972 }
4973
4974 private HistoricalOp(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07004975 mOp = parcel.readInt();
Svet Ganovaf189e32019-02-15 18:45:29 -08004976 mAccessCount = readLongSparseLongArrayFromParcel(parcel);
4977 mRejectCount = readLongSparseLongArrayFromParcel(parcel);
4978 mAccessDuration = readLongSparseLongArrayFromParcel(parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07004979 }
4980
Svet Ganov8455ba22019-01-02 13:05:56 -08004981 private void filter(double scaleFactor) {
4982 scale(mAccessCount, scaleFactor);
4983 scale(mRejectCount, scaleFactor);
4984 scale(mAccessDuration, scaleFactor);
4985 }
4986
4987 private boolean isEmpty() {
4988 return !hasData(mAccessCount)
4989 && !hasData(mRejectCount)
4990 && !hasData(mAccessDuration);
4991 }
4992
Svet Ganovaf189e32019-02-15 18:45:29 -08004993 private boolean hasData(@NonNull LongSparseLongArray array) {
4994 return (array != null && array.size() > 0);
Svet Ganov8455ba22019-01-02 13:05:56 -08004995 }
4996
4997 private @Nullable HistoricalOp splice(double fractionToRemove) {
Svet Ganovaf189e32019-02-15 18:45:29 -08004998 final HistoricalOp splice = new HistoricalOp(mOp);
4999 splice(mAccessCount, splice::getOrCreateAccessCount, fractionToRemove);
5000 splice(mRejectCount, splice::getOrCreateRejectCount, fractionToRemove);
5001 splice(mAccessDuration, splice::getOrCreateAccessDuration, fractionToRemove);
Svet Ganov8455ba22019-01-02 13:05:56 -08005002 return splice;
5003 }
5004
Svet Ganovaf189e32019-02-15 18:45:29 -08005005 private static void splice(@Nullable LongSparseLongArray sourceContainer,
5006 @NonNull Supplier<LongSparseLongArray> destContainerProvider,
5007 double fractionToRemove) {
5008 if (sourceContainer != null) {
5009 final int size = sourceContainer.size();
5010 for (int i = 0; i < size; i++) {
5011 final long key = sourceContainer.keyAt(i);
5012 final long value = sourceContainer.valueAt(i);
5013 final long removedFraction = Math.round(value * fractionToRemove);
5014 if (removedFraction > 0) {
5015 destContainerProvider.get().put(key, removedFraction);
5016 sourceContainer.put(key, value - removedFraction);
5017 }
5018 }
5019 }
5020 }
5021
Svet Ganov8455ba22019-01-02 13:05:56 -08005022 private void merge(@NonNull HistoricalOp other) {
Svet Ganovaf189e32019-02-15 18:45:29 -08005023 merge(this::getOrCreateAccessCount, other.mAccessCount);
5024 merge(this::getOrCreateRejectCount, other.mRejectCount);
5025 merge(this::getOrCreateAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08005026 }
5027
Svet Ganovaf189e32019-02-15 18:45:29 -08005028 private void increaseAccessCount(@UidState int uidState, @OpFlags int flags,
5029 long increment) {
5030 increaseCount(getOrCreateAccessCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08005031 }
5032
Svet Ganovaf189e32019-02-15 18:45:29 -08005033 private void increaseRejectCount(@UidState int uidState, @OpFlags int flags,
5034 long increment) {
5035 increaseCount(getOrCreateRejectCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08005036 }
5037
Svet Ganovaf189e32019-02-15 18:45:29 -08005038 private void increaseAccessDuration(@UidState int uidState, @OpFlags int flags,
5039 long increment) {
5040 increaseCount(getOrCreateAccessDuration(), uidState, flags, increment);
5041 }
5042
5043 private void increaseCount(@NonNull LongSparseLongArray counts,
5044 @UidState int uidState, @OpFlags int flags, long increment) {
5045 while (flags != 0) {
5046 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
5047 flags &= ~flag;
5048 final long key = makeKey(uidState, flag);
5049 counts.put(key, counts.get(key) + increment);
5050 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07005051 }
5052
5053 /**
5054 * Gets the op name.
5055 *
5056 * @return The op name.
5057 */
Svet Ganov8455ba22019-01-02 13:05:56 -08005058 public @NonNull String getOpName() {
Svet Ganovad0a49b2018-10-29 10:07:08 -07005059 return sOpToString[mOp];
5060 }
5061
Svet Ganov8455ba22019-01-02 13:05:56 -08005062 /** @hide */
5063 public int getOpCode() {
5064 return mOp;
5065 }
5066
Svet Ganovad0a49b2018-10-29 10:07:08 -07005067 /**
5068 * Gets the number times the op was accessed (performed) in the foreground.
5069 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005070 * @param flags The flags which are any combination of
5071 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
5072 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
5073 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
5074 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005075 * @return The times the op was accessed in the foreground.
5076 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005077 * @see #getBackgroundAccessCount(int)
5078 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07005079 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005080 public long getForegroundAccessCount(@OpFlags int flags) {
5081 return sumForFlagsInStates(mAccessCount, MAX_PRIORITY_UID_STATE,
5082 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005083 }
5084
5085 /**
5086 * Gets the number times the op was accessed (performed) in the background.
5087 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005088 * @param flags The flags which are any combination of
5089 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
5090 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
5091 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
5092 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005093 * @return The times the op was accessed in the background.
5094 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005095 * @see #getForegroundAccessCount(int)
5096 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07005097 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005098 public long getBackgroundAccessCount(@OpFlags int flags) {
5099 return sumForFlagsInStates(mAccessCount, resolveLastRestrictedUidState(mOp),
5100 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005101 }
5102
5103 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08005104 * Gets the number times the op was accessed (performed) for a
5105 * range of uid states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005106 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005107 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07005108 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
5109 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
5110 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08005111 * @param toUidState The UID state to which to query.
5112 * @param flags The flags which are any combination of
5113 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
5114 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
5115 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
5116 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005117 *
5118 * @return The times the op was accessed for the given UID state.
5119 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005120 * @see #getForegroundAccessCount(int)
5121 * @see #getBackgroundAccessCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07005122 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005123 public long getAccessCount(@UidState int fromUidState, @UidState int toUidState,
5124 @OpFlags int flags) {
5125 return sumForFlagsInStates(mAccessCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005126 }
5127
5128 /**
5129 * Gets the number times the op was rejected in the foreground.
5130 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005131 * @param flags The flags which are any combination of
5132 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
5133 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
5134 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
5135 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005136 * @return The times the op was rejected in the foreground.
5137 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005138 * @see #getBackgroundRejectCount(int)
5139 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07005140 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005141 public long getForegroundRejectCount(@OpFlags int flags) {
5142 return sumForFlagsInStates(mRejectCount, MAX_PRIORITY_UID_STATE,
5143 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005144 }
5145
5146 /**
5147 * Gets the number times the op was rejected in the background.
5148 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005149 * @param flags The flags which are any combination of
5150 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
5151 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
5152 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
5153 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005154 * @return The times the op was rejected in the background.
5155 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005156 * @see #getForegroundRejectCount(int)
5157 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07005158 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005159 public long getBackgroundRejectCount(@OpFlags int flags) {
5160 return sumForFlagsInStates(mRejectCount, resolveLastRestrictedUidState(mOp),
5161 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005162 }
5163
5164 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08005165 * Gets the number times the op was rejected for a given range of UID states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005166 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005167 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07005168 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
5169 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
5170 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08005171 * @param toUidState The UID state to which to query.
5172 * @param flags The flags which are any combination of
5173 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
5174 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
5175 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
5176 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005177 *
5178 * @return The times the op was rejected for the given UID state.
5179 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005180 * @see #getForegroundRejectCount(int)
5181 * @see #getBackgroundRejectCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07005182 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005183 public long getRejectCount(@UidState int fromUidState, @UidState int toUidState,
5184 @OpFlags int flags) {
5185 return sumForFlagsInStates(mRejectCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005186 }
5187
5188 /**
5189 * Gets the total duration the app op was accessed (performed) in the foreground.
Svet Ganov6f672a32019-07-08 16:40:42 -07005190 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005191 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005192 * @param flags The flags which are any combination of
5193 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
5194 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
5195 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
5196 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005197 * @return The total duration the app op was accessed in the foreground.
5198 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005199 * @see #getBackgroundAccessDuration(int)
5200 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07005201 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005202 public long getForegroundAccessDuration(@OpFlags int flags) {
5203 return sumForFlagsInStates(mAccessDuration, MAX_PRIORITY_UID_STATE,
5204 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005205 }
5206
5207 /**
5208 * Gets the total duration the app op was accessed (performed) in the background.
Svet Ganov6f672a32019-07-08 16:40:42 -07005209 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005210 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005211 * @param flags The flags which are any combination of
5212 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
5213 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
5214 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
5215 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005216 * @return The total duration the app op was accessed in the background.
5217 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005218 * @see #getForegroundAccessDuration(int)
5219 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07005220 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005221 public long getBackgroundAccessDuration(@OpFlags int flags) {
5222 return sumForFlagsInStates(mAccessDuration, resolveLastRestrictedUidState(mOp),
5223 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005224 }
5225
5226 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08005227 * Gets the total duration the app op was accessed (performed) for a given
Svet Ganov6f672a32019-07-08 16:40:42 -07005228 * range of UID states. The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005229 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005230 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07005231 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
5232 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
5233 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08005234 * @param toUidState The UID state from which to query.
5235 * @param flags The flags which are any combination of
5236 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
5237 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
5238 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
5239 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005240 *
5241 * @return The total duration the app op was accessed for the given UID state.
5242 *
Svet Ganovaf189e32019-02-15 18:45:29 -08005243 * @see #getForegroundAccessDuration(int)
5244 * @see #getBackgroundAccessDuration(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07005245 */
Svet Ganovaf189e32019-02-15 18:45:29 -08005246 public long getAccessDuration(@UidState int fromUidState, @UidState int toUidState,
5247 @OpFlags int flags) {
5248 return sumForFlagsInStates(mAccessDuration, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005249 }
5250
5251 @Override
5252 public int describeContents() {
5253 return 0;
5254 }
5255
5256 @Override
5257 public void writeToParcel(Parcel parcel, int flags) {
5258 parcel.writeInt(mOp);
Svet Ganovaf189e32019-02-15 18:45:29 -08005259 writeLongSparseLongArrayToParcel(mAccessCount, parcel);
5260 writeLongSparseLongArrayToParcel(mRejectCount, parcel);
5261 writeLongSparseLongArrayToParcel(mAccessDuration, parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005262 }
5263
Svet Ganov8455ba22019-01-02 13:05:56 -08005264 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07005265 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005266 if (this == obj) {
5267 return true;
5268 }
5269 if (obj == null || getClass() != obj.getClass()) {
5270 return false;
5271 }
5272 final HistoricalOp other = (HistoricalOp) obj;
5273 if (mOp != other.mOp) {
5274 return false;
5275 }
Svet Ganovaf189e32019-02-15 18:45:29 -08005276 if (!Objects.equals(mAccessCount, other.mAccessCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005277 return false;
5278 }
Svet Ganovaf189e32019-02-15 18:45:29 -08005279 if (!Objects.equals(mRejectCount, other.mRejectCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005280 return false;
5281 }
Svet Ganovaf189e32019-02-15 18:45:29 -08005282 return Objects.equals(mAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08005283 }
5284
5285 @Override
5286 public int hashCode() {
5287 int result = mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08005288 result = 31 * result + Objects.hashCode(mAccessCount);
5289 result = 31 * result + Objects.hashCode(mRejectCount);
5290 result = 31 * result + Objects.hashCode(mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08005291 return result;
5292 }
Svet Ganovaf189e32019-02-15 18:45:29 -08005293
5294 private void accept(@NonNull HistoricalOpsVisitor visitor) {
5295 visitor.visitHistoricalOp(this);
5296 }
5297
5298 private @NonNull LongSparseLongArray getOrCreateAccessCount() {
5299 if (mAccessCount == null) {
5300 mAccessCount = new LongSparseLongArray();
5301 }
5302 return mAccessCount;
5303 }
5304
5305 private @NonNull LongSparseLongArray getOrCreateRejectCount() {
5306 if (mRejectCount == null) {
5307 mRejectCount = new LongSparseLongArray();
5308 }
5309 return mRejectCount;
5310 }
5311
5312 private @NonNull LongSparseLongArray getOrCreateAccessDuration() {
5313 if (mAccessDuration == null) {
5314 mAccessDuration = new LongSparseLongArray();
5315 }
5316 return mAccessDuration;
5317 }
5318
5319 /**
5320 * Multiplies the entries in the array with the passed in scale factor and
5321 * rounds the result at up 0.5 boundary.
5322 *
5323 * @param data The data to scale.
5324 * @param scaleFactor The scale factor.
5325 */
5326 private static void scale(@NonNull LongSparseLongArray data, double scaleFactor) {
5327 if (data != null) {
5328 final int size = data.size();
5329 for (int i = 0; i < size; i++) {
5330 data.put(data.keyAt(i), (long) HistoricalOps.round(
5331 (double) data.valueAt(i) * scaleFactor));
5332 }
5333 }
5334 }
5335
5336 /**
5337 * Merges two arrays while lazily acquiring the destination.
5338 *
5339 * @param thisSupplier The destination supplier.
5340 * @param other The array to merge in.
5341 */
5342 private static void merge(@NonNull Supplier<LongSparseLongArray> thisSupplier,
5343 @Nullable LongSparseLongArray other) {
5344 if (other != null) {
5345 final int otherSize = other.size();
5346 for (int i = 0; i < otherSize; i++) {
5347 final LongSparseLongArray that = thisSupplier.get();
5348 final long otherKey = other.keyAt(i);
5349 final long otherValue = other.valueAt(i);
5350 that.put(otherKey, that.get(otherKey) + otherValue);
5351 }
5352 }
5353 }
5354
5355 /** @hide */
5356 public @Nullable LongSparseArray<Object> collectKeys() {
5357 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessCount,
5358 null /*result*/);
5359 result = AppOpsManager.collectKeys(mRejectCount, result);
5360 result = AppOpsManager.collectKeys(mAccessDuration, result);
5361 return result;
5362 }
5363
5364 public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR =
5365 new Creator<HistoricalOp>() {
5366 @Override
5367 public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) {
5368 return new HistoricalOp(source);
5369 }
5370
5371 @Override
5372 public @NonNull HistoricalOp[] newArray(int size) {
5373 return new HistoricalOp[size];
5374 }
5375 };
5376 }
5377
5378 /**
5379 * Computes the sum of the counts for the given flags in between the begin and
5380 * end UID states.
5381 *
5382 * @param counts The data array.
Philip P. Moltmann4052d362019-09-19 14:52:38 -07005383 * @param beginUidState The beginning UID state (inclusive).
5384 * @param endUidState The end UID state (inclusive).
Svet Ganovaf189e32019-02-15 18:45:29 -08005385 * @param flags The UID flags.
5386 * @return The sum.
5387 */
5388 private static long sumForFlagsInStates(@Nullable LongSparseLongArray counts,
5389 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
5390 if (counts == null) {
5391 return 0;
5392 }
5393 long sum = 0;
5394 while (flags != 0) {
5395 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
5396 flags &= ~flag;
5397 for (int uidState : UID_STATES) {
5398 if (uidState < beginUidState || uidState > endUidState) {
5399 continue;
5400 }
5401 final long key = makeKey(uidState, flag);
5402 sum += counts.get(key);
5403 }
5404 }
5405 return sum;
5406 }
5407
5408 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005409 * Callback for notification of changes to operation state.
5410 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005411 public interface OnOpChangedListener {
5412 public void onOpChanged(String op, String packageName);
5413 }
5414
5415 /**
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005416 * Callback for notification of changes to operation active state.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005417 */
5418 public interface OnOpActiveChangedListener {
5419 /**
5420 * Called when the active state of an app op changes.
5421 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005422 * @param op The operation that changed.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005423 * @param packageName The package performing the operation.
5424 * @param active Whether the operation became active or inactive.
5425 */
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005426 void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName,
5427 boolean active);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005428 }
5429
5430 /**
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005431 * Callback for notification of an op being noted.
5432 *
5433 * @hide
5434 */
5435 public interface OnOpNotedListener {
5436 /**
5437 * Called when an op was noted.
5438 *
5439 * @param code The op code.
5440 * @param uid The UID performing the operation.
5441 * @param packageName The package performing the operation.
5442 * @param result The result of the note.
5443 */
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05005444 void onOpNoted(int code, int uid, String packageName, int result);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005445 }
5446
5447 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005448 * Callback for notification of changes to operation state.
5449 * This allows you to see the raw op codes instead of strings.
5450 * @hide
5451 */
5452 public static class OnOpChangedInternalListener implements OnOpChangedListener {
5453 public void onOpChanged(String op, String packageName) { }
5454 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -08005455 }
5456
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005457 /**
5458 * Callback for notification of changes to operation state.
5459 * This allows you to see the raw op codes instead of strings.
5460 * @hide
5461 */
5462 public interface OnOpActiveChangedInternalListener extends OnOpActiveChangedListener {
5463 default void onOpActiveChanged(String op, int uid, String packageName, boolean active) { }
5464 default void onOpActiveChanged(int op, int uid, String packageName, boolean active) { }
5465 }
5466
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005467 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005468 mContext = context;
5469 mService = service;
5470 }
5471
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005472 /**
5473 * Retrieve current operation state for all applications.
5474 *
Winson6a864b52019-05-10 10:34:14 -07005475 * The mode of the ops returned are set for the package but may not reflect their effective
5476 * state due to UID policy or because it's controlled by a different master op.
5477 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005478 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005479 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005480 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005481 * @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 -07005482 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005483 */
Svet Ganov8455ba22019-01-02 13:05:56 -08005484 @SystemApi
5485 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
5486 public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops) {
5487 final int opCount = ops.length;
5488 final int[] opCodes = new int[opCount];
5489 for (int i = 0; i < opCount; i++) {
5490 opCodes[i] = sOpStrToOp.get(ops[i]);
5491 }
5492 final List<AppOpsManager.PackageOps> result = getPackagesForOps(opCodes);
5493 return (result != null) ? result : Collections.emptyList();
5494 }
5495
5496 /**
5497 * Retrieve current operation state for all applications.
5498 *
Winson6a864b52019-05-10 10:34:14 -07005499 * The mode of the ops returned are set for the package but may not reflect their effective
5500 * state due to UID policy or because it's controlled by a different master op.
5501 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005502 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005503 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005504 *
Svet Ganov8455ba22019-01-02 13:05:56 -08005505 * @param ops The set of operations you are interested in, or null if you want all of them.
5506 * @hide
5507 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07005508 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005509 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08005510 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
5511 try {
5512 return mService.getPackagesForOps(ops);
5513 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005514 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08005515 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08005516 }
5517
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005518 /**
5519 * Retrieve current operation state for one application.
5520 *
Winson6a864b52019-05-10 10:34:14 -07005521 * The mode of the ops returned are set for the package but may not reflect their effective
5522 * state due to UID policy or because it's controlled by a different master op.
5523 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005524 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005525 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005526 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005527 * @param uid The uid of the application of interest.
5528 * @param packageName The name of the application of interest.
5529 * @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 -08005530 *
5531 * @deprecated The int op codes are not stable and you should use the string based op
5532 * names which are stable and namespaced. Use
5533 * {@link #getOpsForPackage(int, String, String...)})}.
5534 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005535 * @hide
Suprabh Shukla169bed72019-05-13 13:54:58 -07005536 * @removed
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08005537 */
Svet Ganov8455ba22019-01-02 13:05:56 -08005538 @Deprecated
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07005539 @SystemApi
Dianne Hackbornc216a262018-04-26 13:46:22 -07005540 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Dianne Hackborn62878492019-03-11 15:57:07 -07005541 public @NonNull List<PackageOps> getOpsForPackage(int uid, @NonNull String packageName,
5542 @Nullable int[] ops) {
Dianne Hackborn72e39832013-01-18 18:36:09 -08005543 try {
5544 return mService.getOpsForPackage(uid, packageName, ops);
5545 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005546 throw e.rethrowFromSystemServer();
Dianne Hackborn72e39832013-01-18 18:36:09 -08005547 }
Dianne Hackborn72e39832013-01-18 18:36:09 -08005548 }
5549
Svet Ganovae0e03a2016-02-25 18:22:10 -08005550 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005551 * Retrieve current operation state for one application. The UID and the
5552 * package must match.
5553 *
Winson6a864b52019-05-10 10:34:14 -07005554 * The mode of the ops returned are set for the package but may not reflect their effective
5555 * state due to UID policy or because it's controlled by a different master op.
5556 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07005557 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005558 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07005559 *
Svet Ganov8455ba22019-01-02 13:05:56 -08005560 * @param uid The uid of the application of interest.
5561 * @param packageName The name of the application of interest.
5562 * @param ops The set of operations you are interested in, or null if you want all of them.
5563 *
5564 * @hide
5565 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08005566 @TestApi
Svet Ganov8455ba22019-01-02 13:05:56 -08005567 @SystemApi
5568 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
5569 public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid,
5570 @NonNull String packageName, @Nullable String... ops) {
5571 int[] opCodes = null;
5572 if (ops != null) {
5573 opCodes = new int[ops.length];
5574 for (int i = 0; i < ops.length; i++) {
5575 opCodes[i] = strOpToOp(ops[i]);
5576 }
5577 }
5578 try {
5579 final List<PackageOps> result = mService.getOpsForPackage(uid, packageName, opCodes);
5580 if (result == null) {
5581 return Collections.emptyList();
5582 }
5583 return result;
5584 } catch (RemoteException e) {
5585 throw e.rethrowFromSystemServer();
5586 }
5587 }
5588
5589 /**
5590 * Retrieve historical app op stats for a period.
5591 *
Svet Ganov23c88db2019-01-22 20:38:11 -08005592 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08005593 * @param executor Executor on which to run the callback. If <code>null</code>
5594 * the callback is executed on the default executor running on the main thread.
5595 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005596 *
5597 * @throws IllegalArgumentException If any of the argument contracts is violated.
5598 *
5599 * @hide
5600 */
5601 @TestApi
5602 @SystemApi
5603 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov23c88db2019-01-22 20:38:11 -08005604 public void getHistoricalOps(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08005605 @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) {
Daulet Zhanguzin0af97d62019-12-30 15:41:28 +00005606 Objects.requireNonNull(executor, "executor cannot be null");
5607 Objects.requireNonNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07005608 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08005609 mService.getHistoricalOps(request.mUid, request.mPackageName, request.mOpNames,
Svet Ganovaf189e32019-02-15 18:45:29 -08005610 request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags,
Svet Ganov8455ba22019-01-02 13:05:56 -08005611 new RemoteCallback((result) -> {
5612 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
5613 final long identity = Binder.clearCallingIdentity();
5614 try {
5615 executor.execute(() -> callback.accept(ops));
5616 } finally {
5617 Binder.restoreCallingIdentity(identity);
5618 }
5619 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07005620 } catch (RemoteException e) {
5621 throw e.rethrowFromSystemServer();
5622 }
5623 }
5624
5625 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005626 * Retrieve historical app op stats for a period.
Svet Ganov8455ba22019-01-02 13:05:56 -08005627 * <p>
5628 * This method queries only the on disk state and the returned ops are raw,
5629 * which is their times are relative to the history start as opposed to the
5630 * epoch start.
5631 *
Svet Ganov23c88db2019-01-22 20:38:11 -08005632 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08005633 * @param executor Executor on which to run the callback. If <code>null</code>
5634 * the callback is executed on the default executor running on the main thread.
5635 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005636 *
5637 * @throws IllegalArgumentException If any of the argument contracts is violated.
5638 *
5639 * @hide
5640 */
5641 @TestApi
Svet Ganov8e5bf962019-03-19 23:59:03 -07005642 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
Svet Ganov23c88db2019-01-22 20:38:11 -08005643 public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08005644 @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) {
Daulet Zhanguzin0af97d62019-12-30 15:41:28 +00005645 Objects.requireNonNull(executor, "executor cannot be null");
5646 Objects.requireNonNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07005647 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08005648 mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName,
5649 request.mOpNames, request.mBeginTimeMillis, request.mEndTimeMillis,
Svet Ganovaf189e32019-02-15 18:45:29 -08005650 request.mFlags, new RemoteCallback((result) -> {
Svet Ganov23c88db2019-01-22 20:38:11 -08005651 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
Svet Ganov8455ba22019-01-02 13:05:56 -08005652 final long identity = Binder.clearCallingIdentity();
5653 try {
5654 executor.execute(() -> callback.accept(ops));
5655 } finally {
5656 Binder.restoreCallingIdentity(identity);
5657 }
5658 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07005659 } catch (RemoteException e) {
5660 throw e.rethrowFromSystemServer();
5661 }
5662 }
5663
5664 /**
Svet Ganov8e5bf962019-03-19 23:59:03 -07005665 * Reloads the non historical state to allow testing the read/write path.
5666 *
5667 * @hide
5668 */
5669 @TestApi
5670 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
5671 public void reloadNonHistoricalState() {
5672 try {
5673 mService.reloadNonHistoricalState();
5674 } catch (RemoteException e) {
5675 throw e.rethrowFromSystemServer();
5676 }
5677 }
5678
5679 /**
Svet Ganovae0e03a2016-02-25 18:22:10 -08005680 * Sets given app op in the specified mode for app ops in the UID.
5681 * This applies to all apps currently in the UID or installed in
5682 * this UID in the future.
5683 *
5684 * @param code The app op.
5685 * @param uid The UID for which to set the app.
5686 * @param mode The app op mode to set.
5687 * @hide
5688 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005689 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005690 public void setUidMode(int code, int uid, @Mode int mode) {
Svet Ganov2af57082015-07-30 08:44:20 -07005691 try {
5692 mService.setUidMode(code, uid, mode);
5693 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005694 throw e.rethrowFromSystemServer();
Svet Ganov2af57082015-07-30 08:44:20 -07005695 }
5696 }
5697
Svet Ganovae0e03a2016-02-25 18:22:10 -08005698 /**
5699 * Sets given app op in the specified mode for app ops in the UID.
5700 * This applies to all apps currently in the UID or installed in
5701 * this UID in the future.
5702 *
5703 * @param appOp The app op.
5704 * @param uid The UID for which to set the app.
5705 * @param mode The app op mode to set.
5706 * @hide
5707 */
5708 @SystemApi
Eugene Susla93519852018-06-13 16:44:31 -07005709 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005710 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005711 public void setUidMode(String appOp, int uid, @Mode int mode) {
Svet Ganovae0e03a2016-02-25 18:22:10 -08005712 try {
5713 mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
5714 } catch (RemoteException e) {
5715 throw e.rethrowFromSystemServer();
5716 }
5717 }
5718
Svet Ganov2af57082015-07-30 08:44:20 -07005719 /** @hide */
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005720 public void setUserRestriction(int code, boolean restricted, IBinder token) {
Ruben Brunk29931bc2016-03-11 00:24:26 -08005721 setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
5722 }
5723
5724 /** @hide */
5725 public void setUserRestriction(int code, boolean restricted, IBinder token,
5726 String[] exceptionPackages) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07005727 setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
5728 }
5729
5730 /** @hide */
5731 public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
5732 String[] exceptionPackages, int userId) {
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005733 try {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07005734 mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005735 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005736 throw e.rethrowFromSystemServer();
Svet Ganov9cea80cd2016-02-16 11:47:00 -08005737 }
5738 }
5739
5740 /** @hide */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00005741 @UnsupportedAppUsage
Peter Visontayb97fbc82017-12-21 16:23:55 +00005742 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005743 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005744 public void setMode(int code, int uid, String packageName, @Mode int mode) {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08005745 try {
5746 mService.setMode(code, uid, packageName, mode);
5747 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005748 throw e.rethrowFromSystemServer();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08005749 }
5750 }
5751
John Spurlock1af30c72014-03-10 08:33:35 -04005752 /**
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005753 * Change the operating mode for the given op in the given app package. You must pass
5754 * in both the uid and name of the application whose mode is being modified; if these
5755 * do not match, the modification will not be applied.
5756 *
5757 * @param op The operation to modify. One of the OPSTR_* constants.
5758 * @param uid The user id of the application whose mode will be changed.
5759 * @param packageName The name of the application package name whose mode will
5760 * be changed.
5761 * @hide
5762 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07005763 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005764 @SystemApi
5765 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08005766 public void setMode(String op, int uid, String packageName, @Mode int mode) {
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005767 try {
5768 mService.setMode(strOpToOp(op), uid, packageName, mode);
5769 } catch (RemoteException e) {
5770 throw e.rethrowFromSystemServer();
5771 }
5772 }
5773
5774 /**
John Spurlock1af30c72014-03-10 08:33:35 -04005775 * Set a non-persisted restriction on an audio operation at a stream-level.
5776 * Restrictions are temporary additional constraints imposed on top of the persisted rules
5777 * defined by {@link #setMode}.
5778 *
5779 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04005780 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04005781 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
5782 * @param exceptionPackages Optional list of packages to exclude from the restriction.
5783 * @hide
5784 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005785 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005786 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -08005787 public void setRestriction(int code, @AttributeUsage int usage, @Mode int mode,
John Spurlock7b414672014-07-18 13:02:39 -04005788 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04005789 try {
5790 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04005791 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04005792 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005793 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04005794 }
5795 }
5796
Dianne Hackborn607b4142013-08-02 18:10:10 -07005797 /** @hide */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08005798 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01005799 @UnsupportedAppUsage
Dianne Hackborn607b4142013-08-02 18:10:10 -07005800 public void resetAllModes() {
5801 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -07005802 mService.resetAllModes(mContext.getUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07005803 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005804 throw e.rethrowFromSystemServer();
Dianne Hackborn607b4142013-08-02 18:10:10 -07005805 }
5806 }
5807
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005808 /**
Svet Ganovfbf01f72015-04-28 18:39:06 -07005809 * Gets the app op name associated with a given permission.
5810 * The app op name is one of the public constants defined
5811 * in this class such as {@link #OPSTR_COARSE_LOCATION}.
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07005812 * This API is intended to be used for mapping runtime
5813 * permissions to the corresponding app op.
Svet Ganovfbf01f72015-04-28 18:39:06 -07005814 *
5815 * @param permission The permission.
5816 * @return The app op associated with the permission or null.
Svet Ganovfbf01f72015-04-28 18:39:06 -07005817 */
Svet Ganovfbf01f72015-04-28 18:39:06 -07005818 public static String permissionToOp(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08005819 final Integer opCode = sPermToOp.get(permission);
Svet Ganovb9d71a62015-04-30 10:38:13 -07005820 if (opCode == null) {
5821 return null;
5822 }
5823 return sOpToString[opCode];
Svet Ganovfbf01f72015-04-28 18:39:06 -07005824 }
5825
5826 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005827 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005828 * You can watch op changes only for your UID.
5829 *
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07005830 * @param op The operation to monitor, one of OPSTR_*.
5831 * @param packageName The name of the application to monitor.
5832 * @param callback Where to report changes.
5833 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005834 public void startWatchingMode(@NonNull String op, @Nullable String packageName,
5835 @NonNull final OnOpChangedListener callback) {
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07005836 startWatchingMode(strOpToOp(op), packageName, callback);
5837 }
5838
5839 /**
5840 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005841 * You can watch op changes only for your UID.
5842 *
5843 * @param op The operation to monitor, one of OPSTR_*.
5844 * @param packageName The name of the application to monitor.
5845 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
5846 * @param callback Where to report changes.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005847 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005848 public void startWatchingMode(@NonNull String op, @Nullable String packageName, int flags,
5849 @NonNull final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005850 startWatchingMode(strOpToOp(op), packageName, flags, callback);
5851 }
5852
5853 /**
5854 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005855 *
5856 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08005857 * you can watch changes only for your UID.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005858 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005859 * @param op The operation to monitor, one of OP_*.
5860 * @param packageName The name of the application to monitor.
5861 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07005862 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005863 */
Jeff Sharkeybf6b2132018-02-27 11:16:37 -07005864 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005865 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005866 startWatchingMode(op, packageName, 0, callback);
5867 }
5868
5869 /**
5870 * Monitor for changes to the operating mode for the given op in the given app package.
5871 *
5872 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
5873 * you can watch changes only for your UID.
5874 *
5875 * @param op The operation to monitor, one of OP_*.
5876 * @param packageName The name of the application to monitor.
5877 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
5878 * @param callback Where to report changes.
5879 * @hide
5880 */
5881 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
5882 public void startWatchingMode(int op, String packageName, int flags,
5883 final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08005884 synchronized (mModeWatchers) {
5885 IAppOpsCallback cb = mModeWatchers.get(callback);
5886 if (cb == null) {
5887 cb = new IAppOpsCallback.Stub() {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07005888 public void opChanged(int op, int uid, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07005889 if (callback instanceof OnOpChangedInternalListener) {
5890 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
5891 }
5892 if (sOpToString[op] != null) {
5893 callback.onOpChanged(sOpToString[op], packageName);
5894 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08005895 }
5896 };
5897 mModeWatchers.put(callback, cb);
5898 }
5899 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07005900 mService.startWatchingModeWithFlags(op, packageName, flags, cb);
Dianne Hackbornc2293022013-02-06 23:14:49 -08005901 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005902 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08005903 }
5904 }
5905 }
5906
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07005907 /**
5908 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
5909 * monitoring associated with this callback will be removed.
5910 */
Dianne Hackborn62878492019-03-11 15:57:07 -07005911 public void stopWatchingMode(@NonNull OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08005912 synchronized (mModeWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08005913 IAppOpsCallback cb = mModeWatchers.remove(callback);
Dianne Hackbornc2293022013-02-06 23:14:49 -08005914 if (cb != null) {
5915 try {
5916 mService.stopWatchingMode(cb);
5917 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07005918 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08005919 }
5920 }
5921 }
5922 }
5923
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005924 /** {@hide} */
5925 @Deprecated
5926 public void startWatchingActive(@NonNull int[] ops,
5927 @NonNull OnOpActiveChangedListener callback) {
5928 final String[] strOps = new String[ops.length];
5929 for (int i = 0; i < ops.length; i++) {
5930 strOps[i] = opToPublicName(ops[i]);
5931 }
5932 startWatchingActive(strOps, mContext.getMainExecutor(), callback);
5933 }
5934
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005935 /**
5936 * Start watching for changes to the active state of app ops. An app op may be
5937 * long running and it has a clear start and stop delimiters. If an op is being
5938 * started or stopped by any package you will get a callback. To change the
5939 * watched ops for a registered callback you need to unregister and register it
5940 * again.
5941 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005942 * <p> If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08005943 * you can watch changes only for your UID.
5944 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005945 * @param ops The operations to watch.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005946 * @param callback Where to report changes.
5947 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005948 * @see #isOperationActive
5949 * @see #stopWatchingActive
Philip P. Moltmann59076d82019-08-19 15:00:40 -07005950 * @see #startOp(int, int, String, boolean, String, String)
5951 * @see #finishOp(int, int, String, String)
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005952 */
Svet Ganovf7b47252018-02-26 11:11:27 -08005953 // TODO: Uncomment below annotation once b/73559440 is fixed
5954 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005955 public void startWatchingActive(@NonNull String[] ops,
5956 @CallbackExecutor @NonNull Executor executor,
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005957 @NonNull OnOpActiveChangedListener callback) {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005958 Objects.requireNonNull(ops);
5959 Objects.requireNonNull(executor);
5960 Objects.requireNonNull(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005961 IAppOpsActiveCallback cb;
5962 synchronized (mActiveWatchers) {
5963 cb = mActiveWatchers.get(callback);
5964 if (cb != null) {
5965 return;
5966 }
5967 cb = new IAppOpsActiveCallback.Stub() {
5968 @Override
5969 public void opActiveChanged(int op, int uid, String packageName, boolean active) {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005970 executor.execute(() -> {
5971 if (callback instanceof OnOpActiveChangedInternalListener) {
5972 ((OnOpActiveChangedInternalListener) callback).onOpActiveChanged(op,
5973 uid, packageName, active);
5974 }
5975 if (sOpToString[op] != null) {
5976 callback.onOpActiveChanged(sOpToString[op], uid, packageName, active);
5977 }
5978 });
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005979 }
5980 };
5981 mActiveWatchers.put(callback, cb);
5982 }
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005983 final int[] rawOps = new int[ops.length];
5984 for (int i = 0; i < ops.length; i++) {
5985 rawOps[i] = strOpToOp(ops[i]);
5986 }
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005987 try {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005988 mService.startWatchingActive(rawOps, cb);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08005989 } catch (RemoteException e) {
5990 throw e.rethrowFromSystemServer();
5991 }
5992 }
5993
5994 /**
5995 * Stop watching for changes to the active state of an app op. An app op may be
5996 * long running and it has a clear start and stop delimiters. Unregistering a
5997 * non-registered callback has no effect.
5998 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06005999 * @see #isOperationActive
6000 * @see #startWatchingActive
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006001 * @see #startOp(int, int, String, boolean, String, String)
6002 * @see #finishOp(int, int, String, String)
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006003 */
6004 public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
6005 synchronized (mActiveWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006006 final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006007 if (cb != null) {
6008 try {
6009 mService.stopWatchingActive(cb);
6010 } catch (RemoteException e) {
6011 throw e.rethrowFromSystemServer();
6012 }
6013 }
6014 }
6015 }
6016
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006017 /**
6018 * Start watching for noted app ops. An app op may be immediate or long running.
6019 * Immediate ops are noted while long running ones are started and stopped. This
6020 * method allows registering a listener to be notified when an app op is noted. If
6021 * an op is being noted by any package you will get a callback. To change the
6022 * watched ops for a registered callback you need to unregister and register it again.
6023 *
6024 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
6025 * you can watch changes only for your UID.
6026 *
6027 * @param ops The ops to watch.
6028 * @param callback Where to report changes.
6029 *
6030 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
6031 * @see #stopWatchingNoted(OnOpNotedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006032 * @see #noteOp(String, int, String, String, String)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006033 *
6034 * @hide
6035 */
6036 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05006037 public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006038 IAppOpsNotedCallback cb;
6039 synchronized (mNotedWatchers) {
6040 cb = mNotedWatchers.get(callback);
6041 if (cb != null) {
6042 return;
6043 }
6044 cb = new IAppOpsNotedCallback.Stub() {
6045 @Override
6046 public void opNoted(int op, int uid, String packageName, int mode) {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05006047 callback.onOpNoted(op, uid, packageName, mode);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006048 }
6049 };
6050 mNotedWatchers.put(callback, cb);
6051 }
6052 try {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05006053 mService.startWatchingNoted(ops, cb);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006054 } catch (RemoteException e) {
6055 throw e.rethrowFromSystemServer();
6056 }
6057 }
6058
6059 /**
6060 * Stop watching for noted app ops. An app op may be immediate or long running.
6061 * Unregistering a non-registered callback has no effect.
6062 *
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05006063 * @see #startWatchingNoted(int[], OnOpNotedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006064 * @see #noteOp(String, int, String, String, String)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006065 *
6066 * @hide
6067 */
6068 public void stopWatchingNoted(@NonNull OnOpNotedListener callback) {
6069 synchronized (mNotedWatchers) {
6070 final IAppOpsNotedCallback cb = mNotedWatchers.get(callback);
6071 if (cb != null) {
6072 try {
6073 mService.stopWatchingNoted(cb);
6074 } catch (RemoteException e) {
6075 throw e.rethrowFromSystemServer();
6076 }
6077 }
6078 }
6079 }
6080
Dianne Hackborn95d78532013-09-11 09:51:14 -07006081 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
6082 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
6083 }
6084
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07006085 /**
6086 * {@hide}
6087 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00006088 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07006089 @TestApi
Dianne Hackborn62878492019-03-11 15:57:07 -07006090 public static int strOpToOp(@NonNull String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006091 Integer val = sOpStrToOp.get(op);
6092 if (val == null) {
6093 throw new IllegalArgumentException("Unknown operation string: " + op);
6094 }
6095 return val;
6096 }
6097
6098 /**
6099 * Do a quick check for whether an application might be able to perform an operation.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006100 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006101 * String, String)} or {@link #startOp(String, int, String, String, String)} for your actual
6102 * security checks, which also ensure that the given uid and package name are consistent. This
6103 * function can just be used for a quick check to see if an operation has been disabled for the
6104 * application, as an early reject of some work. This does not modify the time stamp or other
6105 * data about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07006106 *
6107 * <p>Important things this will not do (which you need to ultimate use
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006108 * {@link #noteOp(String, int, String, String, String)} or
6109 * {@link #startOp(String, int, String, String, String)} to cover):</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -07006110 * <ul>
6111 * <li>Verifying the uid and package are consistent, so callers can't spoof
6112 * their identity.</li>
6113 * <li>Taking into account the current foreground/background state of the
6114 * app; apps whose mode varies by this state will always be reported
6115 * as {@link #MODE_ALLOWED}.</li>
6116 * </ul>
6117 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006118 * @param op The operation to check. One of the OPSTR_* constants.
6119 * @param uid The user id of the application attempting to perform the operation.
6120 * @param packageName The name of the application attempting to perform the operation.
6121 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6122 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6123 * causing the app to crash).
6124 * @throws SecurityException If the app has been configured to crash on this op.
6125 */
Dianne Hackborn62878492019-03-11 15:57:07 -07006126 public int unsafeCheckOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07006127 return checkOp(strOpToOp(op), uid, packageName);
6128 }
6129
6130 /**
6131 * @deprecated Renamed to {@link #unsafeCheckOp(String, int, String)}.
6132 */
6133 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07006134 public int checkOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006135 return checkOp(strOpToOp(op), uid, packageName);
6136 }
6137
6138 /**
John Spurlock925b85e2014-03-10 16:52:11 -04006139 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006140 * returns {@link #MODE_ERRORED}.
6141 */
Dianne Hackborn62878492019-03-11 15:57:07 -07006142 public int unsafeCheckOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07006143 return checkOpNoThrow(strOpToOp(op), uid, packageName);
6144 }
6145
6146 /**
6147 * @deprecated Renamed to {@link #unsafeCheckOpNoThrow(String, int, String)}.
6148 */
6149 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07006150 public int checkOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006151 return checkOpNoThrow(strOpToOp(op), uid, packageName);
6152 }
6153
6154 /**
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006155 * Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op.
6156 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006157 */
Dianne Hackborn62878492019-03-11 15:57:07 -07006158 public int unsafeCheckOpRaw(@NonNull String op, int uid, @NonNull String packageName) {
Svet Ganovaf189e32019-02-15 18:45:29 -08006159 try {
6160 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
6161 } catch (RemoteException e) {
6162 throw e.rethrowFromSystemServer();
6163 }
6164 }
6165
6166 /**
6167 * Like {@link #unsafeCheckOpNoThrow(String, int, String)} but returns the <em>raw</em>
6168 * mode associated with the op. Does not throw a security exception, does not translate
6169 * {@link #MODE_FOREGROUND}.
6170 */
6171 public int unsafeCheckOpRawNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006172 try {
Svet Ganov9d528a12018-12-19 17:23:11 -08006173 return mService.checkOperationRaw(strOpToOp(op), uid, packageName);
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006174 } catch (RemoteException e) {
6175 throw e.rethrowFromSystemServer();
6176 }
6177 }
6178
6179 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006180 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006181 */
6182 @Deprecated
6183 public int noteOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006184 return noteOp(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006185 }
6186
6187 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006188 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006189 *
6190 * @hide
6191 */
6192 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006193 + "#noteOp(java.lang.String, int, java.lang.String, java.lang.String, "
6194 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006195 @Deprecated
6196 public int noteOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006197 return noteOp(op, Process.myUid(), mContext.getOpPackageName(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006198 }
6199
6200 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006201 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006202 *
6203 * @hide
6204 */
6205 @Deprecated
6206 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006207 + "#noteOp(java.lang.String, int, java.lang.String, java.lang.String, "
6208 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006209 public int noteOp(int op, int uid, @Nullable String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006210 return noteOp(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006211 }
6212
6213 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006214 * Make note of an application performing an operation. Note that you must pass
6215 * in both the uid and name of the application to be checked; this function will verify
6216 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
6217 * succeeds, the last execution time of the operation for this app will be updated to
6218 * the current time.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006219 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006220 * @param op The operation to note. One of the OPSTR_* constants.
6221 * @param uid The user id of the application attempting to perform the operation.
6222 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006223 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006224 * @param message A message describing the reason the op was noted
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08006225 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006226 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6227 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6228 * causing the app to crash).
6229 *
6230 * @throws SecurityException If the app has been configured to crash on this op.
Svet Ganov99b60432015-06-27 13:15:22 -07006231 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006232 public int noteOp(@NonNull String op, int uid, @Nullable String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006233 @Nullable String featureId, @Nullable String message) {
6234 return noteOp(strOpToOp(op), uid, packageName, featureId, message);
Svet Ganov99b60432015-06-27 13:15:22 -07006235 }
6236
6237 /**
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006238 * Make note of an application performing an operation. Note that you must pass
6239 * in both the uid and name of the application to be checked; this function will verify
6240 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
6241 * succeeds, the last execution time of the operation for this app will be updated to
6242 * the current time.
6243 *
6244 * @param op The operation to note. One of the OP_* constants.
6245 * @param uid The user id of the application attempting to perform the operation.
6246 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006247 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006248 * @param message A message describing the reason the op was noted
6249 *
6250 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6251 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6252 * causing the app to crash).
6253 *
6254 * @throws SecurityException If the app has been configured to crash on this op.
6255 *
6256 * @hide
6257 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006258 public int noteOp(int op, int uid, @Nullable String packageName, @Nullable String featureId,
6259 @Nullable String message) {
6260 final int mode = noteOpNoThrow(op, uid, packageName, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006261 if (mode == MODE_ERRORED) {
6262 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
6263 }
6264 return mode;
6265 }
6266
6267 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006268 * @deprecated Use {@link #noteOpNoThrow(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006269 */
6270 @Deprecated
6271 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006272 return noteOpNoThrow(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006273 }
6274
6275 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006276 * @deprecated Use {@link #noteOpNoThrow(int, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006277 *
6278 * @hide
6279 */
6280 @Deprecated
6281 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006282 + "#noteOpNoThrow(java.lang.String, int, java.lang.String, java.lang.String, "
6283 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006284 public int noteOpNoThrow(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006285 return noteOpNoThrow(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006286 }
6287
6288 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006289 * Like {@link #noteOp(String, int, String, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006290 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
6291 *
6292 * @param op The operation to note. One of the OPSTR_* constants.
6293 * @param uid The user id of the application attempting to perform the operation.
6294 * @param packageName The name of the application attempting to perform the operation.
6295 * @param message A message describing the reason the op was noted
6296 *
6297 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6298 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6299 * causing the app to crash).
6300 */
6301 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006302 @Nullable String feature, @Nullable String message) {
6303 return noteOpNoThrow(strOpToOp(op), uid, packageName, feature, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006304 }
6305
6306 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006307 * Like {@link #noteOp(String, int, String, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006308 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
6309 *
6310 * @param op The operation to note. One of the OP_* constants.
6311 * @param uid The user id of the application attempting to perform the operation.
6312 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006313 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006314 * @param message A message describing the reason the op was noted
6315 *
6316 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6317 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6318 * causing the app to crash).
6319 *
6320 * @hide
6321 */
6322 public int noteOpNoThrow(int op, int uid, @Nullable String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006323 @Nullable String featureId, @Nullable String message) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006324 try {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08006325 int collectionMode = getNotedOpCollectionMode(uid, packageName, op);
6326 if (collectionMode == COLLECT_ASYNC) {
6327 if (message == null) {
6328 // Set stack trace as default message
6329 message = getFormattedStackTrace();
6330 }
6331 }
6332
6333 int mode = mService.noteOperation(op, uid, packageName, featureId,
6334 collectionMode == COLLECT_ASYNC, message);
6335
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006336 if (mode == MODE_ALLOWED) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08006337 if (collectionMode == COLLECT_SELF) {
6338 collectNotedOpForSelf(op, featureId);
6339 } else if (collectionMode == COLLECT_SYNC) {
6340 collectNotedOpSync(op, featureId);
6341 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006342 }
6343
6344 return mode;
6345 } catch (RemoteException e) {
6346 throw e.rethrowFromSystemServer();
6347 }
6348 }
6349
6350 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006351 * @deprecated Use {@link #noteProxyOp(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006352 */
6353 @Deprecated
6354 public int noteProxyOp(@NonNull String op, @NonNull String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006355 return noteProxyOp(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006356 }
6357
6358 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006359 * @deprecated Use {@link #noteProxyOp(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006360 *
6361 * @hide
6362 */
6363 @Deprecated
6364 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006365 + "#noteProxyOp(java.lang.String, java.lang.String, int, java.lang.String, "
6366 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006367 public int noteProxyOp(int op, @Nullable String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006368 return noteProxyOp(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006369 }
6370
6371 /**
6372 * Make note of an application performing an operation on behalf of another application when
6373 * handling an IPC. This function will verify that the calling uid and proxied package name
6374 * match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution
6375 * time of the operation for the proxied app and your app will be updated to the current time.
6376 *
6377 * @param op The operation to note. One of the OP_* constants.
6378 * @param proxiedPackageName The name of the application calling into the proxy application.
6379 * @param proxiedUid The uid of the proxied application
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006380 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
6381 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006382 * @param message A message describing the reason the op was noted
6383 *
6384 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED}
6385 * if it is not allowed and should be silently ignored (without causing the app to crash).
6386 *
6387 * @throws SecurityException If the proxy or proxied app has been configured to crash on this
6388 * op.
6389 *
6390 * @hide
6391 */
6392 public int noteProxyOp(int op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006393 @Nullable String proxiedFeatureId, @Nullable String message) {
6394 int mode = noteProxyOpNoThrow(op, proxiedPackageName, proxiedUid, proxiedFeatureId,
6395 message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006396 if (mode == MODE_ERRORED) {
6397 throw new SecurityException("Proxy package " + mContext.getOpPackageName()
6398 + " from uid " + Process.myUid() + " or calling package " + proxiedPackageName
6399 + " from uid " + proxiedUid + " not allowed to perform " + sOpNames[op]);
6400 }
6401 return mode;
6402 }
6403
6404 /**
6405 * Make note of an application performing an operation on behalf of another application when
6406 * handling an IPC. This function will verify that the calling uid and proxied package name
6407 * match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution
6408 * time of the operation for the proxied app and your app will be updated to the current time.
6409 *
6410 * @param op The operation to note. One of the OPSTR_* constants.
6411 * @param proxiedPackageName The name of the application calling into the proxy application.
6412 * @param proxiedUid The uid of the proxied application
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006413 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
6414 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006415 * @param message A message describing the reason the op was noted
6416 *
6417 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED}
6418 * if it is not allowed and should be silently ignored (without causing the app to crash).
6419 *
6420 * @throws SecurityException If the proxy or proxied app has been configured to crash on this
6421 * op.
6422 */
6423 public int noteProxyOp(@NonNull String op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006424 @Nullable String proxiedFeatureId, @Nullable String message) {
6425 return noteProxyOp(strOpToOp(op), proxiedPackageName, proxiedUid, proxiedFeatureId,
6426 message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006427 }
6428
6429 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006430 * @deprecated Use {@link #noteProxyOpNoThrow(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006431 */
6432 @Deprecated
6433 public int noteProxyOpNoThrow(@NonNull String op, @NonNull String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006434 return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006435 }
6436
6437 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006438 * @deprecated Use {@link #noteProxyOpNoThrow(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006439 */
6440 @Deprecated
6441 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
6442 int proxiedUid) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006443 return noteProxyOpNoThrow(op, proxiedPackageName, proxiedUid, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006444 }
6445
6446 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006447 * Like {@link #noteProxyOp(String, String, int, String, String)} but instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006448 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08006449 *
6450 * <p>This API requires package with the {@code proxiedPackageName} to belong to
6451 * {@code proxiedUid}.
6452 *
6453 * @param op The op to note
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006454 * @param proxiedPackageName The package to note the op for
6455 * @param proxiedUid The uid the package belongs to
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006456 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
6457 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006458 * @param message A message describing the reason the op was noted
6459 */
6460 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006461 int proxiedUid, @Nullable String proxiedFeatureId, @Nullable String message) {
6462 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid,
6463 proxiedFeatureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006464 }
6465
6466 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006467 * Like {@link #noteProxyOp(int, String, int, String, String)} but instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006468 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
6469 *
6470 * @param op The op to note
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08006471 * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
6472 * noted for the "android" package
6473 * @param proxiedUid The uid the package belongs to
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006474 * @param proxiedFeatureId The feature in the proxied app or {@code null} for default
6475 * feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006476 * @param message A message describing the reason the op was noted
6477 *
6478 * @hide
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08006479 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006480 public int noteProxyOpNoThrow(int op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006481 @Nullable String proxiedFeatureId, @Nullable String message) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006482 int myUid = Process.myUid();
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08006483
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006484 try {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08006485 int collectionMode = getNotedOpCollectionMode(proxiedUid, proxiedPackageName, op);
6486 if (collectionMode == COLLECT_ASYNC) {
6487 if (message == null) {
6488 // Set stack trace as default message
6489 message = getFormattedStackTrace();
6490 }
6491 }
6492
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006493 int mode = mService.noteProxyOperation(op, proxiedUid, proxiedPackageName,
6494 proxiedFeatureId, myUid, mContext.getOpPackageName(),
Philip P. Moltmannda554e42019-12-20 11:21:02 -08006495 mContext.getFeatureId(), collectionMode == COLLECT_ASYNC, message);
6496
6497 if (mode == MODE_ALLOWED) {
6498 if (collectionMode == COLLECT_SELF) {
6499 collectNotedOpForSelf(op, proxiedFeatureId);
6500 } else if (collectionMode == COLLECT_SYNC
6501 // Only collect app-ops when the proxy is trusted
6502 && mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1,
6503 myUid) == PackageManager.PERMISSION_GRANTED) {
6504 collectNotedOpSync(op, proxiedFeatureId);
6505 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006506 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006507
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006508 return mode;
6509 } catch (RemoteException e) {
6510 throw e.rethrowFromSystemServer();
6511 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006512 }
6513
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006514 /**
6515 * Do a quick check for whether an application might be able to perform an operation.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006516 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006517 * String, String)} or {@link #startOp(int, int, String, boolean, String, String)} for your
6518 * actual security checks, which also ensure that the given uid and package name are consistent.
6519 * This function can just be used for a quick check to see if an operation has been disabled for
6520 * the application, as an early reject of some work. This does not modify the time stamp or
6521 * other data about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07006522 *
6523 * <p>Important things this will not do (which you need to ultimate use
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006524 * {@link #noteOp(String, int, String, String, String)} or
6525 * {@link #startOp(int, int, String, boolean, String, String)} to cover):</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -07006526 * <ul>
6527 * <li>Verifying the uid and package are consistent, so callers can't spoof
6528 * their identity.</li>
6529 * <li>Taking into account the current foreground/background state of the
6530 * app; apps whose mode varies by this state will always be reported
6531 * as {@link #MODE_ALLOWED}.</li>
6532 * </ul>
6533 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006534 * @param op The operation to check. One of the OP_* constants.
6535 * @param uid The user id of the application attempting to perform the operation.
6536 * @param packageName The name of the application attempting to perform the operation.
6537 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6538 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6539 * causing the app to crash).
6540 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006541 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006542 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01006543 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08006544 public int checkOp(int op, int uid, String packageName) {
6545 try {
6546 int mode = mService.checkOperation(op, uid, packageName);
6547 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07006548 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08006549 }
6550 return mode;
6551 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006552 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08006553 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08006554 }
6555
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006556 /**
6557 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
6558 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006559 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006560 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01006561 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08006562 public int checkOpNoThrow(int op, int uid, String packageName) {
6563 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006564 int mode = mService.checkOperation(op, uid, packageName);
6565 return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08006566 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006567 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08006568 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08006569 }
6570
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006571 /**
Jeff Sharkey911d7f42013-09-05 18:11:45 -07006572 * Do a quick check to validate if a package name belongs to a UID.
6573 *
6574 * @throws SecurityException if the package name doesn't belong to the given
6575 * UID, or if ownership cannot be verified.
6576 */
Dianne Hackborn62878492019-03-11 15:57:07 -07006577 public void checkPackage(int uid, @NonNull String packageName) {
Jeff Sharkey911d7f42013-09-05 18:11:45 -07006578 try {
6579 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
6580 throw new SecurityException(
6581 "Package " + packageName + " does not belong to " + uid);
6582 }
6583 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006584 throw e.rethrowFromSystemServer();
Jeff Sharkey911d7f42013-09-05 18:11:45 -07006585 }
6586 }
6587
6588 /**
John Spurlock1af30c72014-03-10 08:33:35 -04006589 * Like {@link #checkOp} but at a stream-level for audio operations.
6590 * @hide
6591 */
6592 public int checkAudioOp(int op, int stream, int uid, String packageName) {
6593 try {
6594 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
6595 if (mode == MODE_ERRORED) {
6596 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
6597 }
6598 return mode;
6599 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006600 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04006601 }
John Spurlock1af30c72014-03-10 08:33:35 -04006602 }
6603
6604 /**
6605 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
6606 * returns {@link #MODE_ERRORED}.
6607 * @hide
6608 */
6609 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
6610 try {
6611 return mService.checkAudioOperation(op, stream, uid, packageName);
6612 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006613 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04006614 }
John Spurlock1af30c72014-03-10 08:33:35 -04006615 }
6616
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -08006617 /**
6618 * @deprecated Use own local {@link android.os.Binder#Binder()}
6619 *
6620 * @hide
6621 */
6622 @Deprecated
6623 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Create own "
6624 + "local {@link android.os.Binder}")
Dianne Hackborne98f5db2013-07-17 17:23:25 -07006625 public static IBinder getToken(IAppOpsService service) {
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -08006626 return getClientId();
Dianne Hackborne98f5db2013-07-17 17:23:25 -07006627 }
6628
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -08006629 /** @hide */
6630 public static IBinder getClientId() {
6631 synchronized (AppOpsManager.class) {
6632 if (sClientId == null) {
6633 sClientId = new Binder();
6634 }
6635
6636 return sClientId;
6637 }
6638 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006639
6640 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006641 * @deprecated use {@link #startOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006642 */
6643 @Deprecated
6644 public int startOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006645 return startOp(op, uid, packageName, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08006646 }
6647
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006648 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006649 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Svet Ganovf7b47252018-02-26 11:11:27 -08006650 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006651 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006652 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006653 @Deprecated
6654 public int startOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006655 return startOp(op, Process.myUid(), mContext.getOpPackageName(), false, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08006656 }
6657
6658 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006659 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006660 *
6661 * @hide
6662 */
6663 @Deprecated
6664 public int startOp(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006665 return startOp(op, uid, packageName, false, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006666 }
6667
6668 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006669 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006670 *
6671 * @hide
6672 */
6673 @Deprecated
6674 public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006675 return startOp(op, uid, packageName, startIfModeDefault, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006676 }
6677
6678 /**
6679 * Report that an application has started executing a long-running operation.
6680 *
6681 * @param op The operation to start. One of the OPSTR_* constants.
6682 * @param uid The user id of the application attempting to perform the operation.
6683 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006684 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006685 * @param message Description why op was started
6686 *
6687 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6688 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6689 * causing the app to crash).
6690 *
6691 * @throws SecurityException If the app has been configured to crash on this op or
6692 * the package is not in the passed in UID.
6693 */
6694 public int startOp(@NonNull String op, int uid, @Nullable String packageName,
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -08006695 @Nullable String featureId, @Nullable String message) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006696 return startOp(strOpToOp(op), uid, packageName, false, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006697 }
6698
6699 /**
6700 * Report that an application has started executing a long-running operation.
Svet Ganovf7b47252018-02-26 11:11:27 -08006701 *
6702 * @param op The operation to start. One of the OP_* constants.
6703 * @param uid The user id of the application attempting to perform the operation.
6704 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006705 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006706 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
6707 * @param message Description why op was started
6708 *
Svet Ganovf7b47252018-02-26 11:11:27 -08006709 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6710 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6711 * causing the app to crash).
Svet Ganovf7b47252018-02-26 11:11:27 -08006712 *
6713 * @throws SecurityException If the app has been configured to crash on this op or
6714 * the package is not in the passed in UID.
6715 *
6716 * @hide
6717 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006718 public int startOp(int op, int uid, @Nullable String packageName, boolean startIfModeDefault,
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -08006719 @Nullable String featureId, @Nullable String message) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006720 final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault, featureId,
6721 message);
Svet Ganovf7b47252018-02-26 11:11:27 -08006722 if (mode == MODE_ERRORED) {
6723 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006724 }
Svet Ganovf7b47252018-02-26 11:11:27 -08006725 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006726 }
6727
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006728 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006729 * @deprecated use {@link #startOpNoThrow(String, int, String, String, String)} instead
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006730 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006731 @Deprecated
6732 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006733 return startOpNoThrow(op, uid, packageName, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08006734 }
6735
6736 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006737 * @deprecated Use {@link #startOpNoThrow(int, int, String, boolean, String, String} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006738 *
6739 * @hide
6740 */
6741 @Deprecated
6742 public int startOpNoThrow(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006743 return startOpNoThrow(op, uid, packageName, false, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006744 }
6745
6746 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006747 * @deprecated Use {@link #startOpNoThrow(int, int, String, boolean, String, String} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006748 *
6749 * @hide
6750 */
6751 @Deprecated
6752 public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006753 return startOpNoThrow(op, uid, packageName, startIfModeDefault, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006754 }
6755
6756 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006757 * Like {@link #startOp(String, int, String, String, String)} but instead of throwing a
Svet Ganovf7b47252018-02-26 11:11:27 -08006758 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
6759 *
6760 * @param op The operation to start. One of the OP_* constants.
6761 * @param uid The user id of the application attempting to perform the operation.
6762 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006763 * @param featureId The feature in the app or {@code null} for default feature
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006764 * @param message Description why op was started
6765 *
Svet Ganovf7b47252018-02-26 11:11:27 -08006766 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6767 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6768 * causing the app to crash).
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006769 */
6770 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006771 @NonNull String featureId, @Nullable String message) {
6772 return startOpNoThrow(strOpToOp(op), uid, packageName, false, featureId, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006773 }
6774
6775 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006776 * Like {@link #startOp(int, int, String, boolean, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006777 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
6778 *
6779 * @param op The operation to start. One of the OP_* constants.
6780 * @param uid The user id of the application attempting to perform the operation.
6781 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006782 * @param featureId The feature in the app or {@code null} for default feature
Svet Ganovf7b47252018-02-26 11:11:27 -08006783 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006784 * @param message Description why op was started
6785 *
6786 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
6787 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
6788 * causing the app to crash).
Svet Ganovf7b47252018-02-26 11:11:27 -08006789 *
6790 * @hide
6791 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006792 public int startOpNoThrow(int op, int uid, @NonNull String packageName,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006793 boolean startIfModeDefault, @Nullable String featureId, @Nullable String message) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006794 try {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08006795 int collectionMode = getNotedOpCollectionMode(uid, packageName, op);
6796 if (collectionMode == COLLECT_ASYNC) {
6797 if (message == null) {
6798 // Set stack trace as default message
6799 message = getFormattedStackTrace();
6800 }
6801 }
6802
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -08006803 int mode = mService.startOperation(getClientId(), op, uid, packageName,
Philip P. Moltmannda554e42019-12-20 11:21:02 -08006804 featureId, startIfModeDefault, collectionMode == COLLECT_ASYNC, message);
6805
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006806 if (mode == MODE_ALLOWED) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08006807 if (collectionMode == COLLECT_SELF) {
6808 collectNotedOpForSelf(op, featureId);
6809 } else if (collectionMode == COLLECT_SYNC) {
6810 collectNotedOpSync(op, featureId);
6811 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006812 }
6813
6814 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006815 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006816 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006817 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006818 }
6819
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006820 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006821 * @deprecated Use {@link #finishOp(String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006822 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006823 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006824 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006825 @Deprecated
6826 public void finishOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006827 finishOp(op, Process.myUid(), mContext.getOpPackageName(), null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006828 }
6829
6830 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006831 * @deprecated Use {@link #finishOp(String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006832 */
6833 public void finishOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006834 finishOp(strOpToOp(op), uid, packageName, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006835 }
6836
6837 /**
6838 * Report that an application is no longer performing an operation that had previously
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006839 * been started with {@link #startOp(String, int, String, String, String)}. There is no
6840 * validation of input or result; the parameters supplied here must be the exact same ones
6841 * previously passed in when starting the operation.
6842 */
6843 public void finishOp(@NonNull String op, int uid, @NonNull String packageName,
6844 @Nullable String featureId) {
6845 finishOp(strOpToOp(op), uid, packageName, featureId);
6846 }
6847
6848 /**
6849 * @deprecated Use {@link #finishOp(int, int, String, String)} instead
6850 *
6851 * @hide
6852 */
6853 public void finishOp(int op, int uid, @NonNull String packageName) {
6854 finishOp(op, uid, packageName, null);
6855 }
6856
6857 /**
6858 * Report that an application is no longer performing an operation that had previously
6859 * been started with {@link #startOp(int, int, String, boolean, String, String)}. There is no
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006860 * validation of input or result; the parameters supplied here must be the exact same ones
6861 * previously passed in when starting the operation.
6862 *
6863 * @hide
6864 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006865 public void finishOp(int op, int uid, @NonNull String packageName,
6866 @Nullable String featureId) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006867 try {
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -08006868 mService.finishOperation(getClientId(), op, uid, packageName, featureId);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006869 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006870 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006871 }
6872 }
6873
Svet Ganovf7b47252018-02-26 11:11:27 -08006874 /**
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006875 * Checks whether the given op for a package is active.
6876 * <p>
6877 * If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS}
6878 * permission you can query only for your UID.
6879 *
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006880 * @see #finishOp(String, int, String, String)
6881 * @see #startOp(String, int, String, String, String)
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006882 */
6883 public boolean isOpActive(@NonNull String op, int uid, @NonNull String packageName) {
6884 return isOperationActive(strOpToOp(op), uid, packageName);
6885 }
6886
6887 /**
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006888 * Start collection of noted appops on this thread.
6889 *
6890 * <p>Called at the beginning of a two way binder transaction.
6891 *
6892 * @see #finishNotedAppOpsCollection()
6893 *
6894 * @hide
6895 */
6896 public static void startNotedAppOpsCollection(int callingUid) {
6897 sBinderThreadCallingUid.set(callingUid);
6898 }
6899
6900 /**
6901 * State of a temporarily paused noted app-ops collection.
6902 *
6903 * @see #pauseNotedAppOpsCollection()
6904 *
6905 * @hide
6906 */
6907 public static class PausedNotedAppOpsCollection {
6908 final int mUid;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006909 final @Nullable ArrayMap<String, long[]> mCollectedNotedAppOps;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006910
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006911 PausedNotedAppOpsCollection(int uid, @Nullable ArrayMap<String,
6912 long[]> collectedNotedAppOps) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006913 mUid = uid;
6914 mCollectedNotedAppOps = collectedNotedAppOps;
6915 }
6916 }
6917
6918 /**
6919 * Temporarily suspend collection of noted app-ops when binder-thread calls into the other
6920 * process. During such a call there might be call-backs coming back on the same thread which
6921 * should not be accounted to the current collection.
6922 *
6923 * @return a state needed to resume the collection
6924 *
6925 * @hide
6926 */
6927 public static @Nullable PausedNotedAppOpsCollection pauseNotedAppOpsCollection() {
6928 Integer previousUid = sBinderThreadCallingUid.get();
6929 if (previousUid != null) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006930 ArrayMap<String, long[]> previousCollectedNotedAppOps =
6931 sAppOpsNotedInThisBinderTransaction.get();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006932
6933 sBinderThreadCallingUid.remove();
6934 sAppOpsNotedInThisBinderTransaction.remove();
6935
6936 return new PausedNotedAppOpsCollection(previousUid, previousCollectedNotedAppOps);
6937 }
6938
6939 return null;
6940 }
6941
6942 /**
6943 * Resume a collection paused via {@link #pauseNotedAppOpsCollection}.
6944 *
6945 * @param prevCollection The state of the previous collection
6946 *
6947 * @hide
6948 */
6949 public static void resumeNotedAppOpsCollection(
6950 @Nullable PausedNotedAppOpsCollection prevCollection) {
6951 if (prevCollection != null) {
6952 sBinderThreadCallingUid.set(prevCollection.mUid);
6953
6954 if (prevCollection.mCollectedNotedAppOps != null) {
6955 sAppOpsNotedInThisBinderTransaction.set(prevCollection.mCollectedNotedAppOps);
6956 }
6957 }
6958 }
6959
6960 /**
6961 * Finish collection of noted appops on this thread.
6962 *
6963 * <p>Called at the end of a two way binder transaction.
6964 *
6965 * @see #startNotedAppOpsCollection(int)
6966 *
6967 * @hide
6968 */
6969 public static void finishNotedAppOpsCollection() {
6970 sBinderThreadCallingUid.remove();
6971 sAppOpsNotedInThisBinderTransaction.remove();
6972 }
6973
6974 /**
Philip P. Moltmannda554e42019-12-20 11:21:02 -08006975 * Collect a noted op for the current process.
6976 *
6977 * @param op The noted op
6978 * @param featureId The feature the op is noted for
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006979 */
Philip P. Moltmannda554e42019-12-20 11:21:02 -08006980 private void collectNotedOpForSelf(int op, @Nullable String featureId) {
6981 synchronized (sLock) {
6982 if (sNotedAppOpsCollector != null) {
6983 sNotedAppOpsCollector.onSelfNoted(new SyncNotedAppOp(op, featureId));
6984 }
6985 }
6986 }
6987
6988 /**
6989 * Collect a noted op when inside of a two-way binder call.
6990 *
6991 * <p> Delivered to caller via {@link #prefixParcelWithAppOpsIfNeeded}
6992 *
6993 * @param op The noted op
6994 * @param featureId The feature the op is noted for
6995 */
6996 private void collectNotedOpSync(int op, @Nullable String featureId) {
6997 // If this is inside of a two-way binder call:
6998 // We are inside of a two-way binder call. Delivered to caller via
6999 // {@link #prefixParcelWithAppOpsIfNeeded}
7000 ArrayMap<String, long[]> appOpsNoted = sAppOpsNotedInThisBinderTransaction.get();
7001 if (appOpsNoted == null) {
7002 appOpsNoted = new ArrayMap<>(1);
7003 sAppOpsNotedInThisBinderTransaction.set(appOpsNoted);
7004 }
7005
7006 long[] appOpsNotedForFeature = appOpsNoted.get(featureId);
7007 if (appOpsNotedForFeature == null) {
7008 appOpsNotedForFeature = new long[2];
7009 appOpsNoted.put(featureId, appOpsNotedForFeature);
7010 }
7011
7012 if (op < 64) {
7013 appOpsNotedForFeature[0] |= 1L << op;
7014 } else {
7015 appOpsNotedForFeature[1] |= 1L << (op - 64);
7016 }
7017 }
7018
7019 /** @hide */
7020 @Retention(RetentionPolicy.SOURCE)
7021 @IntDef(value = {
7022 DONT_COLLECT,
7023 COLLECT_SELF,
7024 COLLECT_SYNC,
7025 COLLECT_ASYNC
7026 })
7027 private @interface NotedOpCollectionMode {}
7028 private static final int DONT_COLLECT = 0;
7029 private static final int COLLECT_SELF = 1;
7030 private static final int COLLECT_SYNC = 2;
7031 private static final int COLLECT_ASYNC = 3;
7032
7033 /**
7034 * Mark an app-op as noted.
7035 */
7036 private @NotedOpCollectionMode int getNotedOpCollectionMode(int uid,
7037 @Nullable String packageName, int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007038 if (packageName == null) {
7039 packageName = "android";
7040 }
7041
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007042 // check it the appops needs to be collected and cache result
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007043 if (sAppOpsToNote[op] == SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007044 boolean shouldCollectNotes;
7045 try {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007046 shouldCollectNotes = mService.shouldCollectNotes(op);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007047 } catch (RemoteException e) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007048 return DONT_COLLECT;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007049 }
7050
7051 if (shouldCollectNotes) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007052 sAppOpsToNote[op] = SHOULD_COLLECT_NOTE_OP;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007053 } else {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007054 sAppOpsToNote[op] = SHOULD_NOT_COLLECT_NOTE_OP;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007055 }
7056 }
7057
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007058 if (sAppOpsToNote[op] != SHOULD_COLLECT_NOTE_OP) {
7059 return DONT_COLLECT;
7060 }
7061
7062 synchronized (sLock) {
7063 if (uid == Process.myUid()
7064 && packageName.equals(ActivityThread.currentOpPackageName())) {
7065 return COLLECT_SELF;
7066 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007067 }
7068
7069 Integer binderUid = sBinderThreadCallingUid.get();
7070
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07007071 if (binderUid != null && binderUid == uid) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007072 return COLLECT_SYNC;
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07007073 } else {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007074 return COLLECT_ASYNC;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007075 }
7076 }
7077
7078 /**
7079 * Append app-ops noted in the current two-way binder transaction to parcel.
7080 *
7081 * <p>This is called on the callee side of a two way binder transaction just before the
7082 * transaction returns.
7083 *
7084 * @param p the parcel to append the noted app-ops to
7085 *
7086 * @hide
7087 */
7088 public static void prefixParcelWithAppOpsIfNeeded(@NonNull Parcel p) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007089 ArrayMap<String, long[]> notedAppOps = sAppOpsNotedInThisBinderTransaction.get();
7090 if (notedAppOps == null) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007091 return;
7092 }
7093
7094 p.writeInt(Parcel.EX_HAS_NOTED_APPOPS_REPLY_HEADER);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007095
7096 int numFeatureWithNotesAppOps = notedAppOps.size();
7097 p.writeInt(numFeatureWithNotesAppOps);
7098
7099 for (int i = 0; i < numFeatureWithNotesAppOps; i++) {
7100 p.writeString(notedAppOps.keyAt(i));
7101 p.writeLong(notedAppOps.valueAt(i)[0]);
7102 p.writeLong(notedAppOps.valueAt(i)[1]);
7103 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007104 }
7105
7106 /**
7107 * Read app-ops noted during a two-way binder transaction from parcel.
7108 *
7109 * <p>This is called on the calling side of a two way binder transaction just after the
7110 * transaction returns.
7111 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007112 * @param p The parcel to read from
7113 *
7114 * @hide
7115 */
7116 public static void readAndLogNotedAppops(@NonNull Parcel p) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007117 int numFeaturesWithNotedAppOps = p.readInt();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007118
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007119 for (int i = 0; i < numFeaturesWithNotedAppOps; i++) {
7120 String featureId = p.readString();
7121 long[] rawNotedAppOps = new long[2];
7122 rawNotedAppOps[0] = p.readLong();
7123 rawNotedAppOps[1] = p.readLong();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007124
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007125 if (rawNotedAppOps[0] != 0 || rawNotedAppOps[1] != 0) {
7126 BitSet notedAppOps = BitSet.valueOf(rawNotedAppOps);
7127
7128 synchronized (sLock) {
7129 for (int code = notedAppOps.nextSetBit(0); code != -1;
7130 code = notedAppOps.nextSetBit(code + 1)) {
7131 if (sNotedAppOpsCollector != null) {
7132 sNotedAppOpsCollector.onNoted(new SyncNotedAppOp(code, featureId));
7133 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007134 }
7135 }
7136 }
7137 }
7138 }
7139
7140 /**
7141 * Register a new {@link AppOpsCollector}.
7142 *
7143 * <p>There can only ever be one collector per process. If there currently is a collector
7144 * registered, it will be unregistered.
7145 *
7146 * <p><b>Only appops related to dangerous permissions are collected.</b>
7147 *
7148 * @param collector The collector to set or {@code null} to unregister.
7149 */
7150 public void setNotedAppOpsCollector(@Nullable AppOpsCollector collector) {
7151 synchronized (sLock) {
7152 if (sNotedAppOpsCollector != null) {
7153 try {
7154 mService.stopWatchingAsyncNoted(mContext.getPackageName(),
7155 sNotedAppOpsCollector.mAsyncCb);
7156 } catch (RemoteException e) {
7157 e.rethrowFromSystemServer();
7158 }
7159 }
7160
7161 sNotedAppOpsCollector = collector;
7162
7163 if (sNotedAppOpsCollector != null) {
7164 List<AsyncNotedAppOp> missedAsyncOps = null;
7165 try {
7166 mService.startWatchingAsyncNoted(mContext.getPackageName(),
7167 sNotedAppOpsCollector.mAsyncCb);
7168 missedAsyncOps = mService.extractAsyncOps(mContext.getPackageName());
7169 } catch (RemoteException e) {
7170 e.rethrowFromSystemServer();
7171 }
7172
7173 if (missedAsyncOps != null) {
7174 int numMissedAsyncOps = missedAsyncOps.size();
7175 for (int i = 0; i < numMissedAsyncOps; i++) {
7176 final AsyncNotedAppOp asyncNotedAppOp = missedAsyncOps.get(i);
7177 if (sNotedAppOpsCollector != null) {
7178 sNotedAppOpsCollector.getAsyncNotedExecutor().execute(
7179 () -> sNotedAppOpsCollector.onAsyncNoted(
7180 asyncNotedAppOp));
7181 }
7182 }
7183 }
7184 }
7185 }
7186 }
7187
7188 /**
7189 * @return {@code true} iff the process currently is currently collecting noted appops.
7190 *
7191 * @see #setNotedAppOpsCollector(AppOpsCollector)
7192 *
7193 * @hide
7194 */
7195 public static boolean isCollectingNotedAppOps() {
7196 synchronized (sLock) {
7197 return sNotedAppOpsCollector != null;
7198 }
7199 }
7200
7201 /**
7202 * Callback an app can choose to {@link #setNotedAppOpsCollector register} to monitor it's noted
7203 * appops.
7204 *
7205 * <p><b>Only appops related to dangerous permissions are collected.</b>
7206 */
7207 public abstract static class AppOpsCollector {
7208 /** Callback registered with the system. This will receive the async notes ops */
7209 private final IAppOpsAsyncNotedCallback mAsyncCb = new IAppOpsAsyncNotedCallback.Stub() {
7210 @Override
7211 public void opNoted(AsyncNotedAppOp op) {
Daulet Zhanguzin0af97d62019-12-30 15:41:28 +00007212 Objects.requireNonNull(op);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007213
7214 getAsyncNotedExecutor().execute(() -> onAsyncNoted(op));
7215 }
7216 };
7217
7218 /**
7219 * @return The executor for the system to use when calling {@link #onAsyncNoted}.
7220 */
7221 public @NonNull Executor getAsyncNotedExecutor() {
7222 return new HandlerExecutor(Handler.getMain());
7223 }
7224
7225 /**
7226 * Called when an app-op was noted for this package inside of a two-way binder-call.
7227 *
7228 * <p>Called on the calling thread just after executing the binder-call. This allows
7229 * the app to e.g. collect stack traces to figure out where the access came from.
7230 *
7231 * @param op The op noted
7232 */
7233 public abstract void onNoted(@NonNull SyncNotedAppOp op);
7234
7235 /**
7236 * Called when this app noted an app-op for its own package.
7237 *
7238 * <p>Called on the thread the noted the op. This allows the app to e.g. collect stack
7239 * traces to figure out where the access came from.
7240 *
7241 * @param op The op noted
7242 */
7243 public abstract void onSelfNoted(@NonNull SyncNotedAppOp op);
7244
7245 /**
7246 * Called when an app-op was noted for this package which cannot be delivered via the other
7247 * two mechanisms.
7248 *
7249 * <p>Called as soon as possible after the app-op was noted, but the delivery delay is not
7250 * guaranteed. Due to how async calls work in Android this might even be delivered slightly
7251 * before the private data is delivered to the app.
7252 *
7253 * <p>If the app is not running or no {@link AppOpsCollector} is registered a small amount
7254 * of noted app-ops are buffered and then delivered as soon as a collector is registered.
7255 *
7256 * @param asyncOp The op noted
7257 */
7258 public abstract void onAsyncNoted(@NonNull AsyncNotedAppOp asyncOp);
7259 }
7260
7261 /**
7262 * Generate a stack trace used for noted app-ops logging.
7263 *
7264 * <p>This strips away the first few and last few stack trace elements as they are not
7265 * interesting to apps.
7266 */
7267 private static String getFormattedStackTrace() {
7268 StackTraceElement[] trace = new Exception().getStackTrace();
7269
7270 int firstInteresting = 0;
7271 for (int i = 0; i < trace.length; i++) {
7272 if (trace[i].getClassName().startsWith(AppOpsManager.class.getName())
7273 || trace[i].getClassName().startsWith(Parcel.class.getName())
7274 || trace[i].getClassName().contains("$Stub$Proxy")
7275 || trace[i].getClassName().startsWith(DatabaseUtils.class.getName())
7276 || trace[i].getClassName().startsWith("android.content.ContentProviderProxy")
7277 || trace[i].getClassName().startsWith(ContentResolver.class.getName())) {
7278 firstInteresting = i;
7279 } else {
7280 break;
7281 }
7282 }
7283
7284 int lastInteresting = trace.length - 1;
7285 for (int i = trace.length - 1; i >= 0; i--) {
7286 if (trace[i].getClassName().startsWith(HandlerThread.class.getName())
7287 || trace[i].getClassName().startsWith(Handler.class.getName())
7288 || trace[i].getClassName().startsWith(Looper.class.getName())
7289 || trace[i].getClassName().startsWith(Binder.class.getName())
7290 || trace[i].getClassName().startsWith(RuntimeInit.class.getName())
7291 || trace[i].getClassName().startsWith(ZygoteInit.class.getName())
7292 || trace[i].getClassName().startsWith(ActivityThread.class.getName())
7293 || trace[i].getClassName().startsWith(Method.class.getName())
7294 || trace[i].getClassName().startsWith("com.android.server.SystemServer")) {
7295 lastInteresting = i;
7296 } else {
7297 break;
7298 }
7299 }
7300
7301 StringBuilder sb = new StringBuilder();
7302 for (int i = firstInteresting; i <= lastInteresting; i++) {
7303 sb.append(trace[i]);
7304 if (i != lastInteresting) {
7305 sb.append('\n');
7306 }
7307 }
7308
7309 return sb.toString();
7310 }
7311
7312 /**
Svet Ganovf7b47252018-02-26 11:11:27 -08007313 * Checks whether the given op for a UID and package is active.
7314 *
7315 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
7316 * you can query only for your UID.
7317 *
7318 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
7319 * @see #stopWatchingMode(OnOpChangedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007320 * @see #finishOp(int, int, String, String)
7321 * @see #startOp(int, int, String, boolean, String, String)
Svet Ganovf7b47252018-02-26 11:11:27 -08007322 *
7323 * @hide */
7324 @TestApi
7325 // TODO: Uncomment below annotation once b/73559440 is fixed
7326 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey35e46d22017-06-09 10:01:20 -06007327 public boolean isOperationActive(int code, int uid, String packageName) {
7328 try {
7329 return mService.isOperationActive(code, uid, packageName);
7330 } catch (RemoteException e) {
7331 throw e.rethrowFromSystemServer();
7332 }
7333 }
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00007334
7335 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08007336 * Configures the app ops persistence for testing.
7337 *
7338 * @param mode The mode in which the historical registry operates.
7339 * @param baseSnapshotInterval The base interval on which we would be persisting a snapshot of
7340 * the historical data. The history is recursive where every subsequent step encompasses
7341 * {@code compressionStep} longer interval with {@code compressionStep} distance between
7342 * snapshots.
7343 * @param compressionStep The compression step in every iteration.
7344 *
7345 * @see #HISTORICAL_MODE_DISABLED
7346 * @see #HISTORICAL_MODE_ENABLED_ACTIVE
7347 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
7348 *
7349 * @hide
7350 */
7351 @TestApi
7352 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
7353 public void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval,
7354 int compressionStep) {
7355 try {
7356 mService.setHistoryParameters(mode, baseSnapshotInterval, compressionStep);
7357 } catch (RemoteException e) {
7358 throw e.rethrowFromSystemServer();
7359 }
7360 }
7361
7362 /**
7363 * Offsets the history by the given duration.
7364 *
7365 * @param offsetMillis The offset duration.
7366 *
7367 * @hide
7368 */
7369 @TestApi
7370 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
7371 public void offsetHistory(long offsetMillis) {
7372 try {
7373 mService.offsetHistory(offsetMillis);
7374 } catch (RemoteException e) {
7375 throw e.rethrowFromSystemServer();
7376 }
7377 }
7378
7379 /**
7380 * Adds ops to the history directly. This could be useful for testing especially
7381 * when the historical registry operates in {@link #HISTORICAL_MODE_ENABLED_PASSIVE}
7382 * mode.
7383 *
7384 * @param ops The ops to add to the history.
7385 *
7386 * @see #setHistoryParameters(int, long, int)
7387 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
7388 *
7389 * @hide
7390 */
7391 @TestApi
7392 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
7393 public void addHistoricalOps(@NonNull HistoricalOps ops) {
7394 try {
7395 mService.addHistoricalOps(ops);
7396 } catch (RemoteException e) {
7397 throw e.rethrowFromSystemServer();
7398 }
7399 }
7400
7401 /**
7402 * Resets the app ops persistence for testing.
7403 *
7404 * @see #setHistoryParameters(int, long, int)
7405 *
7406 * @hide
7407 */
7408 @TestApi
7409 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
7410 public void resetHistoryParameters() {
7411 try {
7412 mService.resetHistoryParameters();
7413 } catch (RemoteException e) {
7414 throw e.rethrowFromSystemServer();
7415 }
7416 }
7417
7418 /**
7419 * Clears all app ops history.
7420 *
7421 * @hide
7422 */
7423 @TestApi
7424 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
7425 public void clearHistory() {
7426 try {
7427 mService.clearHistory();
7428 } catch (RemoteException e) {
7429 throw e.rethrowFromSystemServer();
7430 }
7431 }
7432
7433 /**
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00007434 * Returns all supported operation names.
7435 * @hide
7436 */
7437 @SystemApi
7438 @TestApi
7439 public static String[] getOpStrs() {
7440 return Arrays.copyOf(sOpToString, sOpToString.length);
7441 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07007442
Philip P. Moltmann24576812018-05-07 10:42:05 -07007443
7444 /**
7445 * @return number of App ops
7446 * @hide
7447 */
7448 @TestApi
7449 public static int getNumOps() {
7450 return _NUM_OP;
7451 }
7452
Dianne Hackbornc216a262018-04-26 13:46:22 -07007453 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08007454 * Gets the last of the event.
Svet Ganovaf189e32019-02-15 18:45:29 -08007455 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08007456 * @param events The events
7457 * @param flags The UID flags
7458 * @param beginUidState The maximum UID state (inclusive)
7459 * @param endUidState The minimum UID state (inclusive)
7460 *
7461 * @return The last event of {@code null}
Dianne Hackbornc216a262018-04-26 13:46:22 -07007462 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08007463 private static @Nullable NoteOpEvent getLastEvent(
7464 @Nullable LongSparseArray<NoteOpEvent> events, @UidState int beginUidState,
7465 @UidState int endUidState, @OpFlags int flags) {
7466 if (events == null) {
7467 return null;
Svet Ganovaf189e32019-02-15 18:45:29 -08007468 }
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08007469
7470 NoteOpEvent lastEvent = null;
Svet Ganovaf189e32019-02-15 18:45:29 -08007471 while (flags != 0) {
7472 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
7473 flags &= ~flag;
7474 for (int uidState : UID_STATES) {
7475 if (uidState < beginUidState || uidState > endUidState) {
7476 continue;
7477 }
7478 final long key = makeKey(uidState, flag);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08007479
7480 NoteOpEvent event = events.get(key);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08007481 if (lastEvent == null
7482 || event != null && event.getNoteTime() > lastEvent.getNoteTime()) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08007483 lastEvent = event;
7484 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07007485 }
7486 }
Svet Ganovaf189e32019-02-15 18:45:29 -08007487
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08007488 return lastEvent;
7489 }
Svet Ganovaf189e32019-02-15 18:45:29 -08007490
7491 private static void writeLongSparseLongArrayToParcel(
7492 @Nullable LongSparseLongArray array, @NonNull Parcel parcel) {
7493 if (array != null) {
7494 final int size = array.size();
7495 parcel.writeInt(size);
7496 for (int i = 0; i < size; i++) {
7497 parcel.writeLong(array.keyAt(i));
7498 parcel.writeLong(array.valueAt(i));
7499 }
7500 } else {
7501 parcel.writeInt(-1);
7502 }
7503 }
7504
7505 private static @Nullable LongSparseLongArray readLongSparseLongArrayFromParcel(
7506 @NonNull Parcel parcel) {
7507 final int size = parcel.readInt();
7508 if (size < 0) {
7509 return null;
7510 }
7511 final LongSparseLongArray array = new LongSparseLongArray(size);
7512 for (int i = 0; i < size; i++) {
7513 array.append(parcel.readLong(), parcel.readLong());
7514 }
7515 return array;
7516 }
7517
Svet Ganovaf189e32019-02-15 18:45:29 -08007518 /**
7519 * Collects the keys from an array to the result creating the result if needed.
7520 *
7521 * @param array The array whose keys to collect.
7522 * @param result The optional result store collected keys.
7523 * @return The result collected keys array.
7524 */
7525 private static LongSparseArray<Object> collectKeys(@Nullable LongSparseLongArray array,
7526 @Nullable LongSparseArray<Object> result) {
7527 if (array != null) {
7528 if (result == null) {
7529 result = new LongSparseArray<>();
7530 }
7531 final int accessSize = array.size();
7532 for (int i = 0; i < accessSize; i++) {
7533 result.put(array.keyAt(i), null);
7534 }
7535 }
7536 return result;
Dianne Hackbornc216a262018-04-26 13:46:22 -07007537 }
Svet Ganov8455ba22019-01-02 13:05:56 -08007538
7539 /** @hide */
7540 public static String uidStateToString(@UidState int uidState) {
7541 switch (uidState) {
7542 case UID_STATE_PERSISTENT: {
7543 return "UID_STATE_PERSISTENT";
7544 }
7545 case UID_STATE_TOP: {
7546 return "UID_STATE_TOP";
7547 }
Amith Yamasania0a30a12019-01-22 11:38:06 -08007548 case UID_STATE_FOREGROUND_SERVICE_LOCATION: {
7549 return "UID_STATE_FOREGROUND_SERVICE_LOCATION";
7550 }
Svet Ganov8455ba22019-01-02 13:05:56 -08007551 case UID_STATE_FOREGROUND_SERVICE: {
7552 return "UID_STATE_FOREGROUND_SERVICE";
7553 }
7554 case UID_STATE_FOREGROUND: {
7555 return "UID_STATE_FOREGROUND";
7556 }
7557 case UID_STATE_BACKGROUND: {
7558 return "UID_STATE_BACKGROUND";
7559 }
7560 case UID_STATE_CACHED: {
7561 return "UID_STATE_CACHED";
7562 }
7563 default: {
7564 return "UNKNOWN";
7565 }
7566 }
7567 }
7568
7569 /** @hide */
7570 public static int parseHistoricalMode(@NonNull String mode) {
7571 switch (mode) {
7572 case "HISTORICAL_MODE_ENABLED_ACTIVE": {
7573 return HISTORICAL_MODE_ENABLED_ACTIVE;
7574 }
7575 case "HISTORICAL_MODE_ENABLED_PASSIVE": {
7576 return HISTORICAL_MODE_ENABLED_PASSIVE;
7577 }
7578 default: {
7579 return HISTORICAL_MODE_DISABLED;
7580 }
7581 }
7582 }
7583
7584 /** @hide */
7585 public static String historicalModeToString(@HistoricalMode int mode) {
7586 switch (mode) {
7587 case HISTORICAL_MODE_DISABLED: {
7588 return "HISTORICAL_MODE_DISABLED";
7589 }
7590 case HISTORICAL_MODE_ENABLED_ACTIVE: {
7591 return "HISTORICAL_MODE_ENABLED_ACTIVE";
7592 }
7593 case HISTORICAL_MODE_ENABLED_PASSIVE: {
7594 return "HISTORICAL_MODE_ENABLED_PASSIVE";
7595 }
7596 default: {
7597 return "UNKNOWN";
7598 }
7599 }
7600 }
Ng Zhi An65a99b62018-10-01 11:57:53 -07007601
7602 private static int getSystemAlertWindowDefault() {
7603 final Context context = ActivityThread.currentApplication();
7604 if (context == null) {
7605 return AppOpsManager.MODE_DEFAULT;
7606 }
7607
7608 // system alert window is disable on low ram phones starting from Q
7609 final PackageManager pm = context.getPackageManager();
7610 // TVs are constantly plugged in and has less concern for memory/power
7611 if (ActivityManager.isLowRamDeviceStatic()
7612 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) {
7613 return AppOpsManager.MODE_IGNORED;
7614 }
7615
7616 return AppOpsManager.MODE_DEFAULT;
7617 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007618}