blob: 3347e045886af4db088256fd1c31bb8152b696a4 [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;
Philip P. Moltmann7641cd02020-03-11 14:42:43 -070030import android.compat.Compatibility;
Philip P. Moltmannb2bc6512020-01-24 15:34:34 -080031import android.compat.annotation.ChangeId;
32import android.compat.annotation.EnabledAfter;
Artur Satayevc895b1b2019-12-10 17:47:51 +000033import android.compat.annotation.UnsupportedAppUsage;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070034import android.content.ContentResolver;
Jeff Davidson05542602014-08-11 14:07:27 -070035import android.content.Context;
Ng Zhi An65a99b62018-10-01 11:57:53 -070036import android.content.pm.PackageManager;
Svet Ganovad0a49b2018-10-29 10:07:08 -070037import android.content.pm.ParceledListSlice;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070038import android.database.DatabaseUtils;
John Spurlock7b414672014-07-18 13:02:39 -040039import android.media.AudioAttributes.AttributeUsage;
Dianne Hackborne98f5db2013-07-17 17:23:25 -070040import android.os.Binder;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070041import android.os.Build;
42import android.os.Handler;
43import android.os.HandlerExecutor;
44import android.os.HandlerThread;
Dianne Hackborne98f5db2013-07-17 17:23:25 -070045import android.os.IBinder;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070046import android.os.Looper;
Dianne Hackborn35654b62013-01-14 17:38:02 -080047import android.os.Parcel;
48import android.os.Parcelable;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080049import android.os.Process;
Svet Ganov8455ba22019-01-02 13:05:56 -080050import android.os.RemoteCallback;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080051import android.os.RemoteException;
Stanislav Zholnin90516b92020-01-20 14:03:06 +000052import android.os.ServiceManager;
53import android.os.SystemClock;
Jeff Davidson05542602014-08-11 14:07:27 -070054import android.os.UserManager;
55import android.util.ArrayMap;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -080056import android.util.ArraySet;
Svet Ganovaf189e32019-02-15 18:45:29 -080057import android.util.LongSparseArray;
58import android.util.LongSparseLongArray;
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -080059import android.util.Pools;
Ng Zhi An65a99b62018-10-01 11:57:53 -070060import android.util.SparseArray;
Jeff Davidson05542602014-08-11 14:07:27 -070061
Svet Ganovb3d2ae22018-12-17 22:06:15 -080062import com.android.internal.annotations.GuardedBy;
Svet Ganov23c88db2019-01-22 20:38:11 -080063import com.android.internal.annotations.Immutable;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080064import com.android.internal.app.IAppOpsActiveCallback;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070065import com.android.internal.app.IAppOpsAsyncNotedCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070066import com.android.internal.app.IAppOpsCallback;
Svet Ganovb3d2ae22018-12-17 22:06:15 -080067import com.android.internal.app.IAppOpsNotedCallback;
Jeff Davidson05542602014-08-11 14:07:27 -070068import com.android.internal.app.IAppOpsService;
Adam Bookatz182862e2020-04-27 21:58:22 -070069import com.android.internal.app.IAppOpsStartedCallback;
Stanislav Zholnin90516b92020-01-20 14:03:06 +000070import com.android.internal.app.MessageSamplingConfig;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070071import com.android.internal.os.RuntimeInit;
72import com.android.internal.os.ZygoteInit;
Svet Ganov8455ba22019-01-02 13:05:56 -080073import com.android.internal.util.ArrayUtils;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -080074import com.android.internal.util.DataClass;
Muhammad Qureshi317061a2020-03-02 13:15:51 -080075import com.android.internal.util.FrameworkStatsLog;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -080076import com.android.internal.util.Parcelling;
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -080077import com.android.internal.util.Preconditions;
Jeff Davidson05542602014-08-11 14:07:27 -070078
Svet Ganovaf189e32019-02-15 18:45:29 -080079import java.lang.annotation.ElementType;
Svet Ganovad0a49b2018-10-29 10:07:08 -070080import java.lang.annotation.Retention;
81import java.lang.annotation.RetentionPolicy;
Svet Ganovaf189e32019-02-15 18:45:29 -080082import java.lang.annotation.Target;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070083import java.lang.reflect.Method;
Svet Ganov8455ba22019-01-02 13:05:56 -080084import java.math.BigDecimal;
85import java.math.RoundingMode;
Jeff Davidson05542602014-08-11 14:07:27 -070086import java.util.ArrayList;
Peter Visontay5a2a1ef2017-12-18 20:34:03 +000087import java.util.Arrays;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -070088import java.util.BitSet;
Svet Ganovad0a49b2018-10-29 10:07:08 -070089import java.util.Collections;
Jeff Davidson05542602014-08-11 14:07:27 -070090import java.util.HashMap;
91import java.util.List;
Philip P. Moltmann59076d82019-08-19 15:00:40 -070092import java.util.Map;
Svet Ganovaf189e32019-02-15 18:45:29 -080093import java.util.Objects;
Svet Ganov8455ba22019-01-02 13:05:56 -080094import java.util.concurrent.Executor;
95import java.util.function.Consumer;
Svet Ganovaf189e32019-02-15 18:45:29 -080096import java.util.function.Supplier;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080097
Dianne Hackbornd7d28e62013-02-12 14:59:53 -080098/**
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -080099 * App-ops are used for two purposes: Access control and tracking.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800100 *
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -0800101 * <p>App-ops cover a wide variety of functionality from helping with runtime permissions access
102 * control and tracking to battery consumption tracking.
Philip P. Moltmann9e367002020-02-03 17:01:05 -0800103 *
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -0800104 * <h2>Access control</h2>
105 *
106 * <p>App-ops can either be controlled for each uid or for each package. Which one is used depends
107 * on the API provider maintaining this app-op. For any security or privacy related app-op the
108 * provider needs to control the app-op for per uid as all security and privacy is based on uid in
109 * Android.
110 *
111 * <p>To control access the app-op can be set to a mode to:
112 * <dl>
113 * <dt>{@link #MODE_DEFAULT}
114 * <dd>Default behavior, might differ from app-op or app-op
115 * <dt>{@link #MODE_ALLOWED}
116 * <dd>Allow the access
117 * <dt>{@link #MODE_IGNORED}
118 * <dd>Don't allow the access, i.e. don't perform the requested action or return no or dummy
119 * data
120 * <dt>{@link #MODE_ERRORED}
121 * <dd>Throw a {@link SecurityException} on access. This can be suppressed by using a
122 * {@code ...noThrow} method to check the mode
123 * </dl>
124 *
125 * <p>API providers need to check the mode returned by {@link #noteOp} if they are are allowing
126 * access to operations gated by the app-op. {@link #unsafeCheckOp} should be used to check the
127 * mode if no access is granted. E.g. this can be used for displaying app-op state in the UI or
128 * when checking the state before later calling {@link #noteOp} anyway.
129 *
130 * <p>If an operation refers to a time span (e.g. a audio-recording session) the API provider
131 * should use {@link #startOp} and {@link #finishOp} instead of {@link #noteOp}.
132 *
133 * <h3>Runtime permissions and app-ops</h3>
134 *
135 * <p>Each platform defined runtime permission (beside background modifiers) has an associated app
136 * op which is used for tracking but also to allow for silent failures. I.e. if the runtime
137 * permission is denied the caller gets a {@link SecurityException}, but if the permission is
138 * granted and the app-op is {@link #MODE_IGNORED} then the callers gets dummy behavior, e.g.
139 * location callbacks would not happen.
140 *
141 * <h3>App-op permissions</h3>
142 *
143 * <p>App-ops permissions are platform defined permissions that can be overridden. The security
144 * check for app-op permissions should by {@link #MODE_DEFAULT default} check the permission grant
145 * state. If the app-op state is set to {@link #MODE_ALLOWED} or {@link #MODE_IGNORED} the app-op
146 * state should be checked instead of the permission grant state.
147 *
148 * <p>This functionality allows to grant access by default to apps fulfilling the requirements for
149 * a certain permission level. Still the behavior can be overridden when needed.
150 *
151 * <h2>Tracking</h2>
152 *
153 * <p>App-ops track many important events, including all accesses to runtime permission protected
154 * APIs. This is done by tracking when an app-op was {@link #noteOp noted} or
155 * {@link #startOp started}. The tracked data can only be read by system components.
156 *
157 * <p><b>Only {@link #noteOp}/{@link #startOp} are tracked; {@link #unsafeCheckOp} is not tracked.
158 * Hence it is important to eventually call {@link #noteOp} or {@link #startOp} when providing
159 * access to protected operations or data.</b>
160 *
161 * <p>Some apps are forwarding access to other apps. E.g. an app might get the location from the
162 * system's location provider and then send the location further to a 3rd app. In this case the
163 * app passing on the data needs to call {@link #noteProxyOp} to signal the access proxying. This
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -0800164 * might also make sense inside of a single app if the access is forwarded between two parts of
165 * the tagged with different attribution tags.
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -0800166 *
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -0800167 * <p>An app can register an {@link OnOpNotedCallback} to get informed about what accesses the
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -0800168 * system is tracking for it. As each runtime permission has an associated app-op this API is
169 * particularly useful for an app that want to find unexpected private data accesses.
Dianne Hackbornd7d28e62013-02-12 14:59:53 -0800170 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -0600171@SystemService(Context.APP_OPS_SERVICE)
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800172public class AppOpsManager {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700173 /**
Philip P. Moltmannb2bc6512020-01-24 15:34:34 -0800174 * This is a subtle behavior change to {@link #startWatchingMode}.
175 *
176 * Before this change the system called back for the switched op. After the change the system
177 * will call back for the actually requested op or all switched ops if no op is specified.
178 *
179 * @hide
180 */
181 @ChangeId
182 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
183 public static final long CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE = 148180766L;
184
Stanislav Zholnine44f1342020-06-02 20:26:20 +0100185 private static final int MAX_UNFORWARDED_OPS = 10;
186
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800187 final Context mContext;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800188
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100189 @UnsupportedAppUsage
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800190 final IAppOpsService mService;
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800191
Stanislav Zholnin90516b92020-01-20 14:03:06 +0000192 /**
193 * Service for the application context, to be used by static methods via
194 * {@link #getService()}
195 */
196 @GuardedBy("sLock")
197 static IAppOpsService sService;
198
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800199 @GuardedBy("mModeWatchers")
200 private final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers =
201 new ArrayMap<>();
202
203 @GuardedBy("mActiveWatchers")
204 private final ArrayMap<OnOpActiveChangedListener, IAppOpsActiveCallback> mActiveWatchers =
205 new ArrayMap<>();
206
Adam Bookatz182862e2020-04-27 21:58:22 -0700207 @GuardedBy("mStartedWatchers")
208 private final ArrayMap<OnOpStartedListener, IAppOpsStartedCallback> mStartedWatchers =
209 new ArrayMap<>();
210
Svet Ganovb3d2ae22018-12-17 22:06:15 -0800211 @GuardedBy("mNotedWatchers")
212 private final ArrayMap<OnOpNotedListener, IAppOpsNotedCallback> mNotedWatchers =
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -0800213 new ArrayMap<>();
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800214
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -0700215 private static final Object sLock = new Object();
216
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -0800217 /** Current {@link OnOpNotedCallback}. Change via {@link #setOnOpNotedCallback} */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -0700218 @GuardedBy("sLock")
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -0800219 private static @Nullable OnOpNotedCallback sOnOpNotedCallback;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -0700220
Stanislav Zholnin90516b92020-01-20 14:03:06 +0000221 /**
Stanislav Zholnine44f1342020-06-02 20:26:20 +0100222 * Sync note-ops collected from {@link #readAndLogNotedAppops(Parcel)} that have not been
223 * delivered to a callback yet.
224 *
225 * Similar to {@link com.android.server.appop.AppOpsService#mUnforwardedAsyncNotedOps} for
226 * {@link COLLECT_ASYNC}. Used in situation when AppOpsManager asks to collect stacktrace with
227 * {@link #sMessageCollector}, which forces {@link COLLECT_SYNC} mode.
228 */
229 @GuardedBy("sLock")
Stanislav Zholnin456b4962020-06-18 16:52:50 +0100230 private static ArrayList<AsyncNotedAppOp> sUnforwardedOps = new ArrayList<>();
Stanislav Zholnine44f1342020-06-02 20:26:20 +0100231
232 /**
Stanislav Zholnin90516b92020-01-20 14:03:06 +0000233 * Additional collector that collect accesses and forwards a few of them them via
234 * {@link IAppOpsService#reportRuntimeAppOpAccessMessageAndGetConfig}.
235 */
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -0800236 private static OnOpNotedCallback sMessageCollector =
237 new OnOpNotedCallback() {
Stanislav Zholnin90516b92020-01-20 14:03:06 +0000238 @Override
239 public void onNoted(@NonNull SyncNotedAppOp op) {
240 reportStackTraceIfNeeded(op);
241 }
242
243 @Override
244 public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncOp) {
245 // collected directly in AppOpsService
246 }
247
248 @Override
249 public void onSelfNoted(@NonNull SyncNotedAppOp op) {
250 reportStackTraceIfNeeded(op);
251 }
252
253 private void reportStackTraceIfNeeded(@NonNull SyncNotedAppOp op) {
Stanislav Zholnind4968a02020-04-18 21:01:13 +0100254 if (!isCollectingStackTraces()) {
Stanislav Zholnin90516b92020-01-20 14:03:06 +0000255 return;
256 }
Stanislav Zholnin90516b92020-01-20 14:03:06 +0000257 MessageSamplingConfig config = sConfig;
258 if (leftCircularDistance(strOpToOp(op.getOp()), config.getSampledOpCode(),
259 _NUM_OP) <= config.getAcceptableLeftDistance()
260 || config.getExpirationTimeSinceBootMillis()
261 < SystemClock.elapsedRealtime()) {
262 String stackTrace = getFormattedStackTrace();
263 try {
Stanislav Zholnin9edce642020-06-15 17:28:33 +0100264 String packageName = ActivityThread.currentOpPackageName();
Stanislav Zholnin90516b92020-01-20 14:03:06 +0000265 sConfig = getService().reportRuntimeAppOpAccessMessageAndGetConfig(
Stanislav Zholnin9edce642020-06-15 17:28:33 +0100266 packageName == null ? "" : packageName, op, stackTrace);
Stanislav Zholnin90516b92020-01-20 14:03:06 +0000267 } catch (RemoteException e) {
268 e.rethrowFromSystemServer();
269 }
270 }
271 }
272 };
273
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -0800274 static IBinder sClientId;
Dianne Hackborne98f5db2013-07-17 17:23:25 -0700275
Philip P. Moltmanne565c7b2020-01-28 13:15:52 -0800276 /**
277 * How many seconds we want for a drop in uid state from top to settle before applying it.
278 *
279 * <>Set a parameter to {@link android.provider.Settings.Global#APP_OPS_CONSTANTS}
280 *
281 * @hide
282 */
283 @TestApi
284 public static final String KEY_TOP_STATE_SETTLE_TIME = "top_state_settle_time";
285
286 /**
287 * How many second we want for a drop in uid state from foreground to settle before applying it.
288 *
289 * <>Set a parameter to {@link android.provider.Settings.Global#APP_OPS_CONSTANTS}
290 *
291 * @hide
292 */
293 @TestApi
294 public static final String KEY_FG_SERVICE_STATE_SETTLE_TIME =
295 "fg_service_state_settle_time";
296
297 /**
298 * How many seconds we want for a drop in uid state from background to settle before applying
299 * it.
300 *
301 * <>Set a parameter to {@link android.provider.Settings.Global#APP_OPS_CONSTANTS}
302 *
303 * @hide
304 */
305 @TestApi
306 public static final String KEY_BG_STATE_SETTLE_TIME = "bg_state_settle_time";
307
Svet Ganov8455ba22019-01-02 13:05:56 -0800308 /** @hide */
309 @Retention(RetentionPolicy.SOURCE)
310 @IntDef(flag = true, prefix = { "HISTORICAL_MODE_" }, value = {
311 HISTORICAL_MODE_DISABLED,
312 HISTORICAL_MODE_ENABLED_ACTIVE,
313 HISTORICAL_MODE_ENABLED_PASSIVE
314 })
315 public @interface HistoricalMode {}
316
317 /**
318 * Mode in which app op history is completely disabled.
319 * @hide
320 */
321 @TestApi
322 public static final int HISTORICAL_MODE_DISABLED = 0;
323
324 /**
325 * Mode in which app op history is enabled and app ops performed by apps would
326 * be tracked. This is the mode in which the feature is completely enabled.
327 * @hide
328 */
329 @TestApi
330 public static final int HISTORICAL_MODE_ENABLED_ACTIVE = 1;
331
332 /**
333 * Mode in which app op history is enabled but app ops performed by apps would
334 * not be tracked and the only way to add ops to the history is via explicit calls
335 * to dedicated APIs. This mode is useful for testing to allow full control of
336 * the historical content.
337 * @hide
338 */
339 @TestApi
340 public static final int HISTORICAL_MODE_ENABLED_PASSIVE = 2;
341
342 /** @hide */
343 @Retention(RetentionPolicy.SOURCE)
344 @IntDef(flag = true, prefix = { "MODE_" }, value = {
345 MODE_ALLOWED,
346 MODE_IGNORED,
347 MODE_ERRORED,
348 MODE_DEFAULT,
349 MODE_FOREGROUND
350 })
351 public @interface Mode {}
352
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700353 /**
354 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
355 * allowed to perform the given operation.
356 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800357 public static final int MODE_ALLOWED = 0;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700358
359 /**
360 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is
361 * not allowed to perform the given operation, and this attempt should
362 * <em>silently fail</em> (it should not cause the app to crash).
363 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800364 public static final int MODE_IGNORED = 1;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700365
366 /**
367 * Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the
368 * given caller is not allowed to perform the given operation, and this attempt should
369 * cause it to have a fatal error, typically a {@link SecurityException}.
370 */
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800371 public static final int MODE_ERRORED = 2;
372
Dianne Hackborn33f5ddd2014-07-21 15:35:45 -0700373 /**
374 * Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should
375 * use its default security check. This mode is not normally used; it should only be used
376 * with appop permissions, and callers must explicitly check for it and deal with it.
377 */
378 public static final int MODE_DEFAULT = 3;
379
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700380 /**
Dianne Hackbornc216a262018-04-26 13:46:22 -0700381 * Special mode that means "allow only when app is in foreground." This is <b>not</b>
Dianne Hackbornf8709f52019-02-04 16:31:24 -0800382 * returned from {@link #unsafeCheckOp}, {@link #noteOp}, {@link #startOp}. Rather,
383 * {@link #unsafeCheckOp} will always return {@link #MODE_ALLOWED} (because it is always
384 * possible for it to be ultimately allowed, depending on the app's background state),
385 * and {@link #noteOp} and {@link #startOp} will return {@link #MODE_ALLOWED} when the app
386 * being checked is currently in the foreground, otherwise {@link #MODE_IGNORED}.
387 *
388 * <p>The only place you will this normally see this value is through
389 * {@link #unsafeCheckOpRaw}, which returns the actual raw mode of the op. Note that because
390 * you can't know the current state of the app being checked (and it can change at any
391 * point), you can only treat the result here as an indication that it will vary between
392 * {@link #MODE_ALLOWED} and {@link #MODE_IGNORED} depending on changes in the background
393 * state of the app. You thus must always use {@link #noteOp} or {@link #startOp} to do
394 * the actual check for access to the op.</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -0700395 */
396 public static final int MODE_FOREGROUND = 4;
397
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700398 /**
399 * Flag for {@link #startWatchingMode(String, String, int, OnOpChangedListener)}:
400 * Also get reports if the foreground state of an op's uid changes. This only works
401 * when watching a particular op, not when watching a package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -0700402 */
403 public static final int WATCH_FOREGROUND_CHANGES = 1 << 0;
Dianne Hackbornc216a262018-04-26 13:46:22 -0700404
Philip P. Moltmann7641cd02020-03-11 14:42:43 -0700405 /**
406 * Flag for {@link #startWatchingMode} that causes the callback to happen on the switch-op
407 * instead the op the callback was registered. (This simulates pre-R behavior).
408 *
409 * @hide
410 */
411 public static final int CALL_BACK_ON_SWITCHED_OP = 1 << 1;
David Cheung2ead9662020-02-19 16:11:06 -0800412
413 /**
414 * Flag to determine whether we should log noteOp/startOp calls to make sure they
415 * are correctly used
416 *
417 * @hide
418 */
419 public static final boolean NOTE_OP_COLLECTION_ENABLED = false;
420
Dianne Hackbornc216a262018-04-26 13:46:22 -0700421 /**
422 * @hide
423 */
424 public static final String[] MODE_NAMES = new String[] {
425 "allow", // MODE_ALLOWED
426 "ignore", // MODE_IGNORED
427 "deny", // MODE_ERRORED
428 "default", // MODE_DEFAULT
429 "foreground", // MODE_FOREGROUND
430 };
431
Svet Ganovad0a49b2018-10-29 10:07:08 -0700432 /** @hide */
433 @Retention(RetentionPolicy.SOURCE)
Svet Ganovaf189e32019-02-15 18:45:29 -0800434 @IntDef(prefix = { "UID_STATE_" }, value = {
Svet Ganovad0a49b2018-10-29 10:07:08 -0700435 UID_STATE_PERSISTENT,
436 UID_STATE_TOP,
Amith Yamasania0a30a12019-01-22 11:38:06 -0800437 UID_STATE_FOREGROUND_SERVICE_LOCATION,
Svet Ganovad0a49b2018-10-29 10:07:08 -0700438 UID_STATE_FOREGROUND_SERVICE,
439 UID_STATE_FOREGROUND,
440 UID_STATE_BACKGROUND,
441 UID_STATE_CACHED
442 })
443 public @interface UidState {}
444
Dianne Hackbornc216a262018-04-26 13:46:22 -0700445 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700446 * Uid state: The UID is a foreground persistent app. The lower the UID
447 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700448 * @hide
449 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800450 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700451 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800452 public static final int UID_STATE_PERSISTENT = 100;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700453
454 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700455 * Uid state: The UID is top foreground app. The lower the UID
456 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700457 * @hide
458 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800459 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700460 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800461 public static final int UID_STATE_TOP = 200;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700462
463 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800464 * Uid state: The UID is running a foreground service of location type.
Svet Ganov05fcd222019-07-08 16:30:45 -0700465 * The lower the UID state the more important the UID is for the user.
Hui Yu26969322019-08-21 14:56:35 -0700466 * This uid state is a counterpart to PROCESS_STATE_FOREGROUND_SERVICE_LOCATION which has been
467 * deprecated.
Amith Yamasania0a30a12019-01-22 11:38:06 -0800468 * @hide
Hui Yu26969322019-08-21 14:56:35 -0700469 * @deprecated
Amith Yamasania0a30a12019-01-22 11:38:06 -0800470 */
471 @TestApi
472 @SystemApi
Hui Yu26969322019-08-21 14:56:35 -0700473 @Deprecated
Svet Ganovaf189e32019-02-15 18:45:29 -0800474 public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300;
Amith Yamasania0a30a12019-01-22 11:38:06 -0800475
476 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700477 * Uid state: The UID is running a foreground service. The lower the UID
478 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700479 * @hide
480 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800481 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700482 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800483 public static final int UID_STATE_FOREGROUND_SERVICE = 400;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700484
485 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700486 * Uid state: The UID is a foreground app. The lower the UID
487 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700488 * @hide
489 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800490 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700491 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800492 public static final int UID_STATE_FOREGROUND = 500;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700493
494 /**
Hui Yu26969322019-08-21 14:56:35 -0700495 * The max, which is min priority, UID state for which any app op
496 * would be considered as performed in the foreground.
497 * @hide
498 */
499 public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND;
500
501 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700502 * Uid state: The UID is a background app. The lower the UID
503 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700504 * @hide
505 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800506 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700507 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800508 public static final int UID_STATE_BACKGROUND = 600;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700509
510 /**
Svet Ganov05fcd222019-07-08 16:30:45 -0700511 * Uid state: The UID is a cached app. The lower the UID
512 * state the more important the UID is for the user.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700513 * @hide
514 */
Svet Ganov8455ba22019-01-02 13:05:56 -0800515 @TestApi
Svet Ganovad0a49b2018-10-29 10:07:08 -0700516 @SystemApi
Svet Ganovaf189e32019-02-15 18:45:29 -0800517 public static final int UID_STATE_CACHED = 700;
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700518
519 /**
Svet Ganovaf189e32019-02-15 18:45:29 -0800520 * Uid state: The UID state with the highest priority.
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700521 * @hide
522 */
Svet Ganovaf189e32019-02-15 18:45:29 -0800523 public static final int MAX_PRIORITY_UID_STATE = UID_STATE_PERSISTENT;
524
525 /**
526 * Uid state: The UID state with the lowest priority.
527 * @hide
528 */
529 public static final int MIN_PRIORITY_UID_STATE = UID_STATE_CACHED;
530
531 /**
Hui Yu26969322019-08-21 14:56:35 -0700532 * Resolves the first unrestricted state given an app op.
Svet Ganovaf189e32019-02-15 18:45:29 -0800533 * @param op The op to resolve.
534 * @return The last restricted UID state.
535 *
536 * @hide
537 */
538 public static int resolveFirstUnrestrictedUidState(int op) {
Hui Yu26969322019-08-21 14:56:35 -0700539 return UID_STATE_FOREGROUND;
Svet Ganovaf189e32019-02-15 18:45:29 -0800540 }
541
542 /**
Hui Yu26969322019-08-21 14:56:35 -0700543 * Resolves the last restricted state given an app op.
Svet Ganovaf189e32019-02-15 18:45:29 -0800544 * @param op The op to resolve.
545 * @return The last restricted UID state.
546 *
547 * @hide
548 */
549 public static int resolveLastRestrictedUidState(int op) {
Hui Yu26969322019-08-21 14:56:35 -0700550 return UID_STATE_BACKGROUND;
Svet Ganovaf189e32019-02-15 18:45:29 -0800551 }
552
553 /** @hide Note: Keep these sorted */
554 public static final int[] UID_STATES = {
555 UID_STATE_PERSISTENT,
556 UID_STATE_TOP,
557 UID_STATE_FOREGROUND_SERVICE_LOCATION,
558 UID_STATE_FOREGROUND_SERVICE,
559 UID_STATE_FOREGROUND,
560 UID_STATE_BACKGROUND,
561 UID_STATE_CACHED
562 };
563
564 /** @hide */
565 public static String getUidStateName(@UidState int uidState) {
566 switch (uidState) {
567 case UID_STATE_PERSISTENT:
568 return "pers";
569 case UID_STATE_TOP:
570 return "top";
571 case UID_STATE_FOREGROUND_SERVICE_LOCATION:
572 return "fgsvcl";
573 case UID_STATE_FOREGROUND_SERVICE:
574 return "fgsvc";
575 case UID_STATE_FOREGROUND:
576 return "fg";
577 case UID_STATE_BACKGROUND:
578 return "bg";
579 case UID_STATE_CACHED:
580 return "cch";
581 default:
582 return "unknown";
583 }
584 }
585
586 /**
587 * Flag: non proxy operations. These are operations
588 * performed on behalf of the app itself and not on behalf of
589 * another one.
590 *
591 * @hide
592 */
593 @TestApi
594 @SystemApi
595 public static final int OP_FLAG_SELF = 0x1;
596
597 /**
598 * Flag: trusted proxy operations. These are operations
599 * performed on behalf of another app by a trusted app.
600 * Which is work a trusted app blames on another app.
601 *
602 * @hide
603 */
604 @TestApi
605 @SystemApi
606 public static final int OP_FLAG_TRUSTED_PROXY = 0x2;
607
608 /**
609 * Flag: untrusted proxy operations. These are operations
610 * performed on behalf of another app by an untrusted app.
611 * Which is work an untrusted app blames on another app.
612 *
613 * @hide
614 */
615 @TestApi
616 @SystemApi
617 public static final int OP_FLAG_UNTRUSTED_PROXY = 0x4;
618
619 /**
620 * Flag: trusted proxied operations. These are operations
621 * performed by a trusted other app on behalf of an app.
622 * Which is work an app was blamed for by a trusted app.
623 *
624 * @hide
625 */
626 @TestApi
627 @SystemApi
628 public static final int OP_FLAG_TRUSTED_PROXIED = 0x8;
629
630 /**
631 * Flag: untrusted proxied operations. These are operations
632 * performed by an untrusted other app on behalf of an app.
633 * Which is work an app was blamed for by an untrusted app.
634 *
635 * @hide
636 */
637 @TestApi
638 @SystemApi
639 public static final int OP_FLAG_UNTRUSTED_PROXIED = 0x10;
640
641 /**
642 * Flags: all operations. These include operations matched
643 * by {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXIED},
644 * {@link #OP_FLAG_UNTRUSTED_PROXIED}, {@link #OP_FLAG_TRUSTED_PROXIED},
645 * {@link #OP_FLAG_UNTRUSTED_PROXIED}.
646 *
647 * @hide
648 */
649 @TestApi
650 @SystemApi
651 public static final int OP_FLAGS_ALL =
652 OP_FLAG_SELF
653 | OP_FLAG_TRUSTED_PROXY
654 | OP_FLAG_UNTRUSTED_PROXY
655 | OP_FLAG_TRUSTED_PROXIED
656 | OP_FLAG_UNTRUSTED_PROXIED;
657
658 /**
659 * Flags: all trusted operations which is ones either the app did {@link #OP_FLAG_SELF},
660 * or it was blamed for by a trusted app {@link #OP_FLAG_TRUSTED_PROXIED}, or ones the
661 * app if untrusted blamed on other apps {@link #OP_FLAG_UNTRUSTED_PROXY}.
662 *
663 * @hide
664 */
665 @SystemApi
666 public static final int OP_FLAGS_ALL_TRUSTED = AppOpsManager.OP_FLAG_SELF
667 | AppOpsManager.OP_FLAG_UNTRUSTED_PROXY
668 | AppOpsManager.OP_FLAG_TRUSTED_PROXIED;
669
670 /** @hide */
671 @Retention(RetentionPolicy.SOURCE)
672 @IntDef(flag = true, prefix = { "FLAG_" }, value = {
673 OP_FLAG_SELF,
674 OP_FLAG_TRUSTED_PROXY,
675 OP_FLAG_UNTRUSTED_PROXY,
676 OP_FLAG_TRUSTED_PROXIED,
677 OP_FLAG_UNTRUSTED_PROXIED
678 })
679 public @interface OpFlags {}
680
Svet Ganovaf189e32019-02-15 18:45:29 -0800681 /** @hide */
682 public static final String getFlagName(@OpFlags int flag) {
683 switch (flag) {
684 case OP_FLAG_SELF:
685 return "s";
686 case OP_FLAG_TRUSTED_PROXY:
687 return "tp";
688 case OP_FLAG_UNTRUSTED_PROXY:
689 return "up";
690 case OP_FLAG_TRUSTED_PROXIED:
691 return "tpd";
692 case OP_FLAG_UNTRUSTED_PROXIED:
693 return "upd";
694 default:
695 return "unknown";
696 }
697 }
698
Muhammad Qureshi317061a2020-03-02 13:15:51 -0800699 // These constants are redefined here to work around a metalava limitation/bug where
700 // @IntDef is not able to see @hide symbols when they are hidden via package hiding:
701 // frameworks/base/core/java/com/android/internal/package.html
702
703 /** @hide */
704 public static final int SAMPLING_STRATEGY_DEFAULT =
705 FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__DEFAULT;
706
707 /** @hide */
708 public static final int SAMPLING_STRATEGY_UNIFORM =
709 FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__UNIFORM;
710
711 /** @hide */
712 public static final int SAMPLING_STRATEGY_RARELY_USED =
713 FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__RARELY_USED;
714
Stanislav Zholnin4c323852020-03-04 18:03:24 +0000715 /** @hide */
716 public static final int SAMPLING_STRATEGY_BOOT_TIME_SAMPLING =
717 FrameworkStatsLog.RUNTIME_APP_OP_ACCESS__SAMPLING_STRATEGY__BOOT_TIME_SAMPLING;
718
Stanislav Zholnin90516b92020-01-20 14:03:06 +0000719 /**
720 * Strategies used for message sampling
721 * @hide
722 */
723 @Retention(RetentionPolicy.SOURCE)
Muhammad Qureshi317061a2020-03-02 13:15:51 -0800724 @IntDef(prefix = {"SAMPLING_STRATEGY_"}, value = {
725 SAMPLING_STRATEGY_DEFAULT,
726 SAMPLING_STRATEGY_UNIFORM,
Stanislav Zholnin4c323852020-03-04 18:03:24 +0000727 SAMPLING_STRATEGY_RARELY_USED,
728 SAMPLING_STRATEGY_BOOT_TIME_SAMPLING
Stanislav Zholnin90516b92020-01-20 14:03:06 +0000729 })
730 public @interface SamplingStrategy {}
731
Svet Ganovaf189e32019-02-15 18:45:29 -0800732 private static final int UID_STATE_OFFSET = 31;
733 private static final int FLAGS_MASK = 0xFFFFFFFF;
734
735 /**
736 * Key for a data bucket storing app op state. The bucket
737 * is composed of the uid state and state flags. This way
738 * we can query data for given uid state and a set of flags where
739 * the flags control which type of data to get. For example,
740 * one can get the ops an app did on behalf of other apps
741 * while in the background.
742 *
743 * @hide
744 */
745 @Retention(RetentionPolicy.SOURCE)
746 @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
747 public @interface DataBucketKey {
748 }
749
750 /** @hide */
751 public static String keyToString(@DataBucketKey long key) {
752 final int uidState = extractUidStateFromKey(key);
753 final int flags = extractFlagsFromKey(key);
754 return "[" + getUidStateName(uidState) + "-" + flagsToString(flags) + "]";
755 }
756
757 /** @hide */
758 public static @DataBucketKey long makeKey(@UidState int uidState, @OpFlags int flags) {
759 return ((long) uidState << UID_STATE_OFFSET) | flags;
760 }
761
762 /** @hide */
763 public static int extractUidStateFromKey(@DataBucketKey long key) {
764 return (int) (key >> UID_STATE_OFFSET);
765 }
766
767 /** @hide */
768 public static int extractFlagsFromKey(@DataBucketKey long key) {
769 return (int) (key & FLAGS_MASK);
770 }
771
772 /** @hide */
773 public static String flagsToString(@OpFlags int flags) {
774 final StringBuilder flagsBuilder = new StringBuilder();
775 while (flags != 0) {
776 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
777 flags &= ~flag;
778 if (flagsBuilder.length() > 0) {
779 flagsBuilder.append('|');
780 }
781 flagsBuilder.append(getFlagName(flag));
782 }
783 return flagsBuilder.toString();
784 }
Dianne Hackborncd1f30b2018-04-23 17:38:09 -0700785
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500786 // when adding one of these:
787 // - increment _NUM_OP
Peter Visontay5a2a1ef2017-12-18 20:34:03 +0000788 // - define an OPSTR_* constant (marked as @SystemApi)
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -0700789 // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault
Daniel Sandlerfde19b12013-01-17 00:21:05 -0500790 // - add descriptive strings to Settings/res/values/arrays.xml
David Christie0b837452013-07-29 16:02:13 -0700791 // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app)
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700792
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700793 /** @hide No operation specified. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100794 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000795 public static final int OP_NONE = AppProtoEnums.APP_OP_NONE;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700796 /** @hide Access to coarse location information. */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000797 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -0800798 @TestApi
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000799 public static final int OP_COARSE_LOCATION = AppProtoEnums.APP_OP_COARSE_LOCATION;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700800 /** @hide Access to fine location information. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100801 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000802 public static final int OP_FINE_LOCATION = AppProtoEnums.APP_OP_FINE_LOCATION;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700803 /** @hide Causing GPS to run. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100804 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000805 public static final int OP_GPS = AppProtoEnums.APP_OP_GPS;
Dianne Hackbornf265ea92013-01-31 15:00:51 -0800806 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100807 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000808 public static final int OP_VIBRATE = AppProtoEnums.APP_OP_VIBRATE;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700809 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100810 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000811 public static final int OP_READ_CONTACTS = AppProtoEnums.APP_OP_READ_CONTACTS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700812 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100813 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000814 public static final int OP_WRITE_CONTACTS = AppProtoEnums.APP_OP_WRITE_CONTACTS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700815 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100816 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000817 public static final int OP_READ_CALL_LOG = AppProtoEnums.APP_OP_READ_CALL_LOG;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700818 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100819 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000820 public static final int OP_WRITE_CALL_LOG = AppProtoEnums.APP_OP_WRITE_CALL_LOG;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700821 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100822 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000823 public static final int OP_READ_CALENDAR = AppProtoEnums.APP_OP_READ_CALENDAR;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700824 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100825 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000826 public static final int OP_WRITE_CALENDAR = AppProtoEnums.APP_OP_WRITE_CALENDAR;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700827 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100828 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000829 public static final int OP_WIFI_SCAN = AppProtoEnums.APP_OP_WIFI_SCAN;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700830 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100831 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000832 public static final int OP_POST_NOTIFICATION = AppProtoEnums.APP_OP_POST_NOTIFICATION;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700833 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100834 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000835 public static final int OP_NEIGHBORING_CELLS = AppProtoEnums.APP_OP_NEIGHBORING_CELLS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700836 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100837 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000838 public static final int OP_CALL_PHONE = AppProtoEnums.APP_OP_CALL_PHONE;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700839 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100840 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000841 public static final int OP_READ_SMS = AppProtoEnums.APP_OP_READ_SMS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700842 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100843 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000844 public static final int OP_WRITE_SMS = AppProtoEnums.APP_OP_WRITE_SMS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700845 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100846 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000847 public static final int OP_RECEIVE_SMS = AppProtoEnums.APP_OP_RECEIVE_SMS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700848 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100849 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000850 public static final int OP_RECEIVE_EMERGECY_SMS =
851 AppProtoEnums.APP_OP_RECEIVE_EMERGENCY_SMS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700852 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100853 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000854 public static final int OP_RECEIVE_MMS = AppProtoEnums.APP_OP_RECEIVE_MMS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700855 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100856 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000857 public static final int OP_RECEIVE_WAP_PUSH = AppProtoEnums.APP_OP_RECEIVE_WAP_PUSH;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700858 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100859 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000860 public static final int OP_SEND_SMS = AppProtoEnums.APP_OP_SEND_SMS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700861 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100862 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000863 public static final int OP_READ_ICC_SMS = AppProtoEnums.APP_OP_READ_ICC_SMS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700864 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100865 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000866 public static final int OP_WRITE_ICC_SMS = AppProtoEnums.APP_OP_WRITE_ICC_SMS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700867 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100868 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000869 public static final int OP_WRITE_SETTINGS = AppProtoEnums.APP_OP_WRITE_SETTINGS;
Peter Visontay96449f62017-12-11 18:50:03 +0000870 /** @hide Required to draw on top of other apps. */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000871 @UnsupportedAppUsage
Svet Ganovf7b47252018-02-26 11:11:27 -0800872 @TestApi
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000873 public static final int OP_SYSTEM_ALERT_WINDOW = AppProtoEnums.APP_OP_SYSTEM_ALERT_WINDOW;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700874 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100875 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000876 public static final int OP_ACCESS_NOTIFICATIONS =
877 AppProtoEnums.APP_OP_ACCESS_NOTIFICATIONS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700878 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100879 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000880 public static final int OP_CAMERA = AppProtoEnums.APP_OP_CAMERA;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700881 /** @hide */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +0000882 @UnsupportedAppUsage
Svet Ganova7a0db62018-02-27 20:08:01 -0800883 @TestApi
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000884 public static final int OP_RECORD_AUDIO = AppProtoEnums.APP_OP_RECORD_AUDIO;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700885 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100886 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000887 public static final int OP_PLAY_AUDIO = AppProtoEnums.APP_OP_PLAY_AUDIO;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700888 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100889 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000890 public static final int OP_READ_CLIPBOARD = AppProtoEnums.APP_OP_READ_CLIPBOARD;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700891 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100892 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000893 public static final int OP_WRITE_CLIPBOARD = AppProtoEnums.APP_OP_WRITE_CLIPBOARD;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700894 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100895 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000896 public static final int OP_TAKE_MEDIA_BUTTONS = AppProtoEnums.APP_OP_TAKE_MEDIA_BUTTONS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700897 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100898 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000899 public static final int OP_TAKE_AUDIO_FOCUS = AppProtoEnums.APP_OP_TAKE_AUDIO_FOCUS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700900 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100901 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000902 public static final int OP_AUDIO_MASTER_VOLUME = AppProtoEnums.APP_OP_AUDIO_MASTER_VOLUME;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700903 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100904 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000905 public static final int OP_AUDIO_VOICE_VOLUME = AppProtoEnums.APP_OP_AUDIO_VOICE_VOLUME;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700906 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100907 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000908 public static final int OP_AUDIO_RING_VOLUME = AppProtoEnums.APP_OP_AUDIO_RING_VOLUME;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700909 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100910 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000911 public static final int OP_AUDIO_MEDIA_VOLUME = AppProtoEnums.APP_OP_AUDIO_MEDIA_VOLUME;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700912 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100913 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000914 public static final int OP_AUDIO_ALARM_VOLUME = AppProtoEnums.APP_OP_AUDIO_ALARM_VOLUME;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700915 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100916 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000917 public static final int OP_AUDIO_NOTIFICATION_VOLUME =
918 AppProtoEnums.APP_OP_AUDIO_NOTIFICATION_VOLUME;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700919 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100920 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000921 public static final int OP_AUDIO_BLUETOOTH_VOLUME =
922 AppProtoEnums.APP_OP_AUDIO_BLUETOOTH_VOLUME;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700923 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100924 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000925 public static final int OP_WAKE_LOCK = AppProtoEnums.APP_OP_WAKE_LOCK;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700926 /** @hide Continually monitoring location data. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100927 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000928 public static final int OP_MONITOR_LOCATION =
929 AppProtoEnums.APP_OP_MONITOR_LOCATION;
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -0700930 /** @hide Continually monitoring location data with a relatively high power request. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100931 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000932 public static final int OP_MONITOR_HIGH_POWER_LOCATION =
933 AppProtoEnums.APP_OP_MONITOR_HIGH_POWER_LOCATION;
Dianne Hackborne22b3b12014-05-07 18:06:44 -0700934 /** @hide Retrieve current usage stats via {@link UsageStatsManager}. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100935 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000936 public static final int OP_GET_USAGE_STATS = AppProtoEnums.APP_OP_GET_USAGE_STATS;
Dianne Hackborn1304f4a2013-07-09 18:17:27 -0700937 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100938 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000939 public static final int OP_MUTE_MICROPHONE = AppProtoEnums.APP_OP_MUTE_MICROPHONE;
Emily Bernier22c921a2014-05-28 11:01:32 -0400940 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100941 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000942 public static final int OP_TOAST_WINDOW = AppProtoEnums.APP_OP_TOAST_WINDOW;
Michael Wrightc39d47a2014-07-08 18:07:36 -0700943 /** @hide Capture the device's display contents and/or audio */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100944 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000945 public static final int OP_PROJECT_MEDIA = AppProtoEnums.APP_OP_PROJECT_MEDIA;
Benedict Wong3eb95202019-11-05 12:50:59 -0800946 /**
947 * Start (without additional user intervention) a VPN connection, as used by {@link
948 * android.net.VpnService} along with as Platform VPN connections, as used by {@link
949 * android.net.VpnManager}
950 *
951 * <p>This appop is granted to apps that have already been given user consent to start
952 * VpnService based VPN connections. As this is a superset of OP_ACTIVATE_PLATFORM_VPN, this
953 * appop also allows the starting of Platform VPNs.
954 *
955 * @hide
956 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100957 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000958 public static final int OP_ACTIVATE_VPN = AppProtoEnums.APP_OP_ACTIVATE_VPN;
Benjamin Franzf3ece362015-02-11 10:51:10 +0000959 /** @hide Access the WallpaperManagerAPI to write wallpapers. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100960 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000961 public static final int OP_WRITE_WALLPAPER = AppProtoEnums.APP_OP_WRITE_WALLPAPER;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700962 /** @hide Received the assist structure from an app. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100963 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000964 public static final int OP_ASSIST_STRUCTURE = AppProtoEnums.APP_OP_ASSIST_STRUCTURE;
Dianne Hackbornd59a5d52015-04-04 14:52:14 -0700965 /** @hide Received a screenshot from assist. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100966 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000967 public static final int OP_ASSIST_SCREENSHOT = AppProtoEnums.APP_OP_ASSIST_SCREENSHOT;
Svet Ganov16a16892015-04-16 10:32:04 -0700968 /** @hide Read the phone state. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100969 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000970 public static final int OP_READ_PHONE_STATE = AppProtoEnums.APP_OP_READ_PHONE_STATE;
Svet Ganovc3300092015-04-17 09:07:22 -0700971 /** @hide Add voicemail messages to the voicemail content provider. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100972 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000973 public static final int OP_ADD_VOICEMAIL = AppProtoEnums.APP_OP_ADD_VOICEMAIL;
Svetoslav5335b672015-04-29 12:00:51 -0700974 /** @hide Access APIs for SIP calling over VOIP or WiFi. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100975 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000976 public static final int OP_USE_SIP = AppProtoEnums.APP_OP_USE_SIP;
Svetoslavc656e6f2015-04-29 14:08:16 -0700977 /** @hide Intercept outgoing calls. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100978 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000979 public static final int OP_PROCESS_OUTGOING_CALLS =
980 AppProtoEnums.APP_OP_PROCESS_OUTGOING_CALLS;
Svetoslav4af76a52015-04-29 15:29:46 -0700981 /** @hide User the fingerprint API. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100982 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000983 public static final int OP_USE_FINGERPRINT = AppProtoEnums.APP_OP_USE_FINGERPRINT;
Svet Ganovb9d71a62015-04-30 10:38:13 -0700984 /** @hide Access to body sensors such as heart rate, etc. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100985 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000986 public static final int OP_BODY_SENSORS = AppProtoEnums.APP_OP_BODY_SENSORS;
Svet Ganovede43162015-05-02 17:42:44 -0700987 /** @hide Read previously received cell broadcast messages. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100988 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000989 public static final int OP_READ_CELL_BROADCASTS = AppProtoEnums.APP_OP_READ_CELL_BROADCASTS;
Svet Ganovf7e9cf42015-05-13 10:40:31 -0700990 /** @hide Inject mock location into the system. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100991 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000992 public static final int OP_MOCK_LOCATION = AppProtoEnums.APP_OP_MOCK_LOCATION;
Svet Ganov921c7df2015-06-29 21:51:41 -0700993 /** @hide Read external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100994 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000995 public static final int OP_READ_EXTERNAL_STORAGE = AppProtoEnums.APP_OP_READ_EXTERNAL_STORAGE;
Svet Ganov921c7df2015-06-29 21:51:41 -0700996 /** @hide Write external storage. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +0100997 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +0000998 public static final int OP_WRITE_EXTERNAL_STORAGE =
999 AppProtoEnums.APP_OP_WRITE_EXTERNAL_STORAGE;
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001000 /** @hide Turned on the screen. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001001 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001002 public static final int OP_TURN_SCREEN_ON = AppProtoEnums.APP_OP_TURN_SCREEN_ON;
Svetoslavf3f02ac2015-09-08 14:36:35 -07001003 /** @hide Get device accounts. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001004 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001005 public static final int OP_GET_ACCOUNTS = AppProtoEnums.APP_OP_GET_ACCOUNTS;
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001006 /** @hide Control whether an application is allowed to run in the background. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001007 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001008 public static final int OP_RUN_IN_BACKGROUND =
Stanislav Zholnin5c88c732020-03-29 21:46:35 +01001009 AppProtoEnums.APP_OP_RUN_IN_BACKGROUND;
Jason Monk1c7c3192014-06-26 12:52:18 -04001010 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001011 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001012 public static final int OP_AUDIO_ACCESSIBILITY_VOLUME =
1013 AppProtoEnums.APP_OP_AUDIO_ACCESSIBILITY_VOLUME;
Chad Brubaker73ec8f92016-11-10 11:24:40 -08001014 /** @hide Read the phone number. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001015 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001016 public static final int OP_READ_PHONE_NUMBERS = AppProtoEnums.APP_OP_READ_PHONE_NUMBERS;
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001017 /** @hide Request package installs through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001018 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001019 public static final int OP_REQUEST_INSTALL_PACKAGES =
1020 AppProtoEnums.APP_OP_REQUEST_INSTALL_PACKAGES;
Winson Chungf4ac0632017-03-17 12:34:12 -07001021 /** @hide Enter picture-in-picture. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001022 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001023 public static final int OP_PICTURE_IN_PICTURE = AppProtoEnums.APP_OP_PICTURE_IN_PICTURE;
Chad Brubaker97b383f2017-02-02 15:04:35 -08001024 /** @hide Instant app start foreground service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001025 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001026 public static final int OP_INSTANT_APP_START_FOREGROUND =
1027 AppProtoEnums.APP_OP_INSTANT_APP_START_FOREGROUND;
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001028 /** @hide Answer incoming phone calls */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001029 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001030 public static final int OP_ANSWER_PHONE_CALLS = AppProtoEnums.APP_OP_ANSWER_PHONE_CALLS;
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001031 /** @hide Run jobs when in background */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001032 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001033 public static final int OP_RUN_ANY_IN_BACKGROUND = AppProtoEnums.APP_OP_RUN_ANY_IN_BACKGROUND;
Peter Visontay1246d9e2017-10-17 17:02:45 +01001034 /** @hide Change Wi-Fi connectivity state */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001035 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001036 public static final int OP_CHANGE_WIFI_STATE = AppProtoEnums.APP_OP_CHANGE_WIFI_STATE;
Peter Visontayf2e38362017-11-27 15:27:16 +00001037 /** @hide Request package deletion through package installer */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001038 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001039 public static final int OP_REQUEST_DELETE_PACKAGES =
1040 AppProtoEnums.APP_OP_REQUEST_DELETE_PACKAGES;
Peter Visontay11950832017-11-14 19:34:59 +00001041 /** @hide Bind an accessibility service. */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001042 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001043 public static final int OP_BIND_ACCESSIBILITY_SERVICE =
1044 AppProtoEnums.APP_OP_BIND_ACCESSIBILITY_SERVICE;
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001045 /** @hide Continue handover of a call from another app */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001046 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001047 public static final int OP_ACCEPT_HANDOVER = AppProtoEnums.APP_OP_ACCEPT_HANDOVER;
Nathan Harold1bb420672018-03-14 17:08:53 -07001048 /** @hide Create and Manage IPsec Tunnels */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001049 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001050 public static final int OP_MANAGE_IPSEC_TUNNELS = AppProtoEnums.APP_OP_MANAGE_IPSEC_TUNNELS;
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001051 /** @hide Any app start foreground service. */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00001052 @UnsupportedAppUsage
Svet Ganovaf189e32019-02-15 18:45:29 -08001053 @TestApi
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001054 public static final int OP_START_FOREGROUND = AppProtoEnums.APP_OP_START_FOREGROUND;
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001055 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001056 @UnsupportedAppUsage
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001057 public static final int OP_BLUETOOTH_SCAN = AppProtoEnums.APP_OP_BLUETOOTH_SCAN;
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001058 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001059 public static final int OP_USE_BIOMETRIC = AppProtoEnums.APP_OP_USE_BIOMETRIC;
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001060 /** @hide Physical activity recognition. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001061 public static final int OP_ACTIVITY_RECOGNITION = AppProtoEnums.APP_OP_ACTIVITY_RECOGNITION;
Hongming Jin228cd012018-11-09 14:47:50 -08001062 /** @hide Financial app sms read. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001063 public static final int OP_SMS_FINANCIAL_TRANSACTIONS =
1064 AppProtoEnums.APP_OP_SMS_FINANCIAL_TRANSACTIONS;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001065 /** @hide Read media of audio type. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001066 public static final int OP_READ_MEDIA_AUDIO = AppProtoEnums.APP_OP_READ_MEDIA_AUDIO;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001067 /** @hide Write media of audio type. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001068 public static final int OP_WRITE_MEDIA_AUDIO = AppProtoEnums.APP_OP_WRITE_MEDIA_AUDIO;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001069 /** @hide Read media of video type. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001070 public static final int OP_READ_MEDIA_VIDEO = AppProtoEnums.APP_OP_READ_MEDIA_VIDEO;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001071 /** @hide Write media of video type. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001072 public static final int OP_WRITE_MEDIA_VIDEO = AppProtoEnums.APP_OP_WRITE_MEDIA_VIDEO;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001073 /** @hide Read media of image type. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001074 public static final int OP_READ_MEDIA_IMAGES = AppProtoEnums.APP_OP_READ_MEDIA_IMAGES;
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001075 /** @hide Write media of image type. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001076 public static final int OP_WRITE_MEDIA_IMAGES = AppProtoEnums.APP_OP_WRITE_MEDIA_IMAGES;
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001077 /** @hide Has a legacy (non-isolated) view of storage. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001078 public static final int OP_LEGACY_STORAGE = AppProtoEnums.APP_OP_LEGACY_STORAGE;
Jackal Guo8dc791e2019-01-14 10:26:42 +08001079 /** @hide Accessing accessibility features */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001080 public static final int OP_ACCESS_ACCESSIBILITY = AppProtoEnums.APP_OP_ACCESS_ACCESSIBILITY;
Michael Groover656ef912019-04-09 17:09:57 -07001081 /** @hide Read the device identifiers (IMEI / MEID, IMSI, SIM / Build serial) */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001082 public static final int OP_READ_DEVICE_IDENTIFIERS =
1083 AppProtoEnums.APP_OP_READ_DEVICE_IDENTIFIERS;
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001084 /** @hide Read location metadata from media */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001085 public static final int OP_ACCESS_MEDIA_LOCATION = AppProtoEnums.APP_OP_ACCESS_MEDIA_LOCATION;
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001086 /** @hide Query all apps on device, regardless of declarations in the calling app manifest */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001087 public static final int OP_QUERY_ALL_PACKAGES = AppProtoEnums.APP_OP_QUERY_ALL_PACKAGES;
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001088 /** @hide Access all external storage */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001089 public static final int OP_MANAGE_EXTERNAL_STORAGE =
1090 AppProtoEnums.APP_OP_MANAGE_EXTERNAL_STORAGE;
kholoud mohamed20ded1f2019-12-03 17:52:38 +00001091 /** @hide Communicate cross-profile within the same profile group. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001092 public static final int OP_INTERACT_ACROSS_PROFILES =
1093 AppProtoEnums.APP_OP_INTERACT_ACROSS_PROFILES;
Benedict Wong3eb95202019-11-05 12:50:59 -08001094 /**
1095 * Start (without additional user intervention) a Platform VPN connection, as used by {@link
1096 * android.net.VpnManager}
1097 *
1098 * <p>This appop is granted to apps that have already been given user consent to start Platform
1099 * VPN connections. This appop is insufficient to start VpnService based VPNs; OP_ACTIVATE_VPN
1100 * is needed for that.
1101 *
1102 * @hide
1103 */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001104 public static final int OP_ACTIVATE_PLATFORM_VPN = AppProtoEnums.APP_OP_ACTIVATE_PLATFORM_VPN;
Todd Kennedy0f006752020-04-29 09:37:10 -07001105 /** @hide Controls whether or not read logs are available for incremental installations. */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001106 public static final int OP_LOADER_USAGE_STATS = AppProtoEnums.APP_OP_LOADER_USAGE_STATS;
Ricardo Correaacdc8272020-03-24 11:02:54 -07001107
1108 // App op deprecated/removed.
1109 private static final int OP_DEPRECATED_1 = AppProtoEnums.APP_OP_DEPRECATED_1;
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001110
Eugene Susla5fc2d762020-03-04 13:53:10 -08001111 /** @hide Auto-revoke app permissions if app is unused for an extended period */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001112 public static final int OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED =
1113 AppProtoEnums.APP_OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED;
Eugene Susla5fc2d762020-03-04 13:53:10 -08001114
Eugene Susla922cd082020-03-11 12:38:17 -07001115 /**
1116 * Whether {@link #OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED} is allowed to be changed by
1117 * the installer
1118 *
1119 * @hide
1120 */
Stanislav Zholnind5378e92020-03-15 18:37:12 +00001121 public static final int OP_AUTO_REVOKE_MANAGED_BY_INSTALLER =
1122 AppProtoEnums.APP_OP_AUTO_REVOKE_MANAGED_BY_INSTALLER;
Eugene Susla922cd082020-03-11 12:38:17 -07001123
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001124 /** @hide */
Nikita Ioffeac095e52020-06-08 22:24:06 +01001125 public static final int OP_NO_ISOLATED_STORAGE = AppProtoEnums.APP_OP_NO_ISOLATED_STORAGE;
1126
1127 /** @hide */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001128 @UnsupportedAppUsage
Nikita Ioffeac095e52020-06-08 22:24:06 +01001129 public static final int _NUM_OP = 100;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001130
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001131 /** Access to coarse location information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001132 public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001133 /** Access to fine location information. */
1134 public static final String OPSTR_FINE_LOCATION =
1135 "android:fine_location";
1136 /** Continually monitoring location data. */
1137 public static final String OPSTR_MONITOR_LOCATION
1138 = "android:monitor_location";
1139 /** Continually monitoring location data with a relatively high power request. */
1140 public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
1141 = "android:monitor_location_high_power";
Dianne Hackborn5064e7c2014-09-02 10:57:16 -07001142 /** Access to {@link android.app.usage.UsageStatsManager}. */
1143 public static final String OPSTR_GET_USAGE_STATS
1144 = "android:get_usage_stats";
Jeff Davidson05542602014-08-11 14:07:27 -07001145 /** Activate a VPN connection without user intervention. @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001146 @SystemApi @TestApi
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001147 public static final String OPSTR_ACTIVATE_VPN
1148 = "android:activate_vpn";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001149 /** Allows an application to read the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001150 public static final String OPSTR_READ_CONTACTS
1151 = "android:read_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001152 /** Allows an application to write to the user's contacts data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001153 public static final String OPSTR_WRITE_CONTACTS
1154 = "android:write_contacts";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001155 /** Allows an application to read the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001156 public static final String OPSTR_READ_CALL_LOG
1157 = "android:read_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001158 /** Allows an application to write to the user's call log. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001159 public static final String OPSTR_WRITE_CALL_LOG
1160 = "android:write_call_log";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001161 /** Allows an application to read the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001162 public static final String OPSTR_READ_CALENDAR
1163 = "android:read_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001164 /** Allows an application to write to the user's calendar data. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001165 public static final String OPSTR_WRITE_CALENDAR
1166 = "android:write_calendar";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001167 /** Allows an application to initiate a phone call. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001168 public static final String OPSTR_CALL_PHONE
1169 = "android:call_phone";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001170 /** Allows an application to read SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001171 public static final String OPSTR_READ_SMS
1172 = "android:read_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001173 /** Allows an application to receive SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001174 public static final String OPSTR_RECEIVE_SMS
1175 = "android:receive_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001176 /** Allows an application to receive MMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001177 public static final String OPSTR_RECEIVE_MMS
1178 = "android:receive_mms";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001179 /** Allows an application to receive WAP push messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001180 public static final String OPSTR_RECEIVE_WAP_PUSH
1181 = "android:receive_wap_push";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001182 /** Allows an application to send SMS messages. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001183 public static final String OPSTR_SEND_SMS
1184 = "android:send_sms";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001185 /** Required to be able to access the camera device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001186 public static final String OPSTR_CAMERA
1187 = "android:camera";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001188 /** Required to be able to access the microphone device. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001189 public static final String OPSTR_RECORD_AUDIO
1190 = "android:record_audio";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001191 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001192 public static final String OPSTR_READ_PHONE_STATE
1193 = "android:read_phone_state";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001194 /** Required to access phone state related information. */
Svet Ganov6e8f67c2015-04-29 17:35:19 -07001195 public static final String OPSTR_ADD_VOICEMAIL
1196 = "android:add_voicemail";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001197 /** Access APIs for SIP calling over VOIP or WiFi */
Svet Ganovb9d71a62015-04-30 10:38:13 -07001198 public static final String OPSTR_USE_SIP
1199 = "android:use_sip";
Svet Ganove8e89422016-09-22 19:56:50 -07001200 /** Access APIs for diverting outgoing calls */
Svet Ganov824ad6e2016-09-22 19:36:53 -07001201 public static final String OPSTR_PROCESS_OUTGOING_CALLS
1202 = "android:process_outgoing_calls";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001203 /** Use the fingerprint API. */
Svet Ganovb9d71a62015-04-30 10:38:13 -07001204 public static final String OPSTR_USE_FINGERPRINT
1205 = "android:use_fingerprint";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001206 /** Access to body sensors such as heart rate, etc. */
Svet Ganovb9d71a62015-04-30 10:38:13 -07001207 public static final String OPSTR_BODY_SENSORS
1208 = "android:body_sensors";
Svet Ganov715cf2a2015-06-13 17:31:29 -07001209 /** Read previously received cell broadcast messages. */
Svet Ganovede43162015-05-02 17:42:44 -07001210 public static final String OPSTR_READ_CELL_BROADCASTS
1211 = "android:read_cell_broadcasts";
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001212 /** Inject mock location into the system. */
1213 public static final String OPSTR_MOCK_LOCATION
1214 = "android:mock_location";
Svet Ganov921c7df2015-06-29 21:51:41 -07001215 /** Read external storage. */
1216 public static final String OPSTR_READ_EXTERNAL_STORAGE
1217 = "android:read_external_storage";
1218 /** Write external storage. */
1219 public static final String OPSTR_WRITE_EXTERNAL_STORAGE
1220 = "android:write_external_storage";
Billy Lau24b9c832015-07-20 17:34:09 +01001221 /** Required to draw on top of other apps. */
1222 public static final String OPSTR_SYSTEM_ALERT_WINDOW
1223 = "android:system_alert_window";
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08001224 /** Required to write/modify/update system settings. */
Billy Lau24b9c832015-07-20 17:34:09 +01001225 public static final String OPSTR_WRITE_SETTINGS
1226 = "android:write_settings";
Svetoslavf3f02ac2015-09-08 14:36:35 -07001227 /** @hide Get device accounts. */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001228 @SystemApi @TestApi
Svetoslavf3f02ac2015-09-08 14:36:35 -07001229 public static final String OPSTR_GET_ACCOUNTS
1230 = "android:get_accounts";
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001231 public static final String OPSTR_READ_PHONE_NUMBERS
1232 = "android:read_phone_numbers";
Winson Chungf4ac0632017-03-17 12:34:12 -07001233 /** Access to picture-in-picture. */
1234 public static final String OPSTR_PICTURE_IN_PICTURE
1235 = "android:picture_in_picture";
Chad Brubaker97b383f2017-02-02 15:04:35 -08001236 /** @hide */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001237 @SystemApi @TestApi
Chad Brubaker97b383f2017-02-02 15:04:35 -08001238 public static final String OPSTR_INSTANT_APP_START_FOREGROUND
1239 = "android:instant_app_start_foreground";
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001240 /** Answer incoming phone calls */
1241 public static final String OPSTR_ANSWER_PHONE_CALLS
1242 = "android:answer_phone_calls";
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001243 /**
1244 * Accept call handover
1245 * @hide
1246 */
1247 @SystemApi @TestApi
1248 public static final String OPSTR_ACCEPT_HANDOVER
1249 = "android:accept_handover";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001250 /** @hide */
1251 @SystemApi @TestApi
1252 public static final String OPSTR_GPS = "android:gps";
1253 /** @hide */
1254 @SystemApi @TestApi
1255 public static final String OPSTR_VIBRATE = "android:vibrate";
1256 /** @hide */
1257 @SystemApi @TestApi
1258 public static final String OPSTR_WIFI_SCAN = "android:wifi_scan";
1259 /** @hide */
1260 @SystemApi @TestApi
1261 public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
1262 /** @hide */
1263 @SystemApi @TestApi
1264 public static final String OPSTR_NEIGHBORING_CELLS = "android:neighboring_cells";
1265 /** @hide */
1266 @SystemApi @TestApi
1267 public static final String OPSTR_WRITE_SMS = "android:write_sms";
1268 /** @hide */
1269 @SystemApi @TestApi
1270 public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST =
1271 "android:receive_emergency_broadcast";
1272 /** @hide */
1273 @SystemApi @TestApi
1274 public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
1275 /** @hide */
1276 @SystemApi @TestApi
1277 public static final String OPSTR_WRITE_ICC_SMS = "android:write_icc_sms";
1278 /** @hide */
1279 @SystemApi @TestApi
1280 public static final String OPSTR_ACCESS_NOTIFICATIONS = "android:access_notifications";
1281 /** @hide */
1282 @SystemApi @TestApi
1283 public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
1284 /** @hide */
1285 @SystemApi @TestApi
1286 public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
1287 /** @hide */
1288 @SystemApi @TestApi
1289 public static final String OPSTR_WRITE_CLIPBOARD = "android:write_clipboard";
1290 /** @hide */
1291 @SystemApi @TestApi
1292 public static final String OPSTR_TAKE_MEDIA_BUTTONS = "android:take_media_buttons";
1293 /** @hide */
1294 @SystemApi @TestApi
1295 public static final String OPSTR_TAKE_AUDIO_FOCUS = "android:take_audio_focus";
1296 /** @hide */
1297 @SystemApi @TestApi
1298 public static final String OPSTR_AUDIO_MASTER_VOLUME = "android:audio_master_volume";
1299 /** @hide */
1300 @SystemApi @TestApi
1301 public static final String OPSTR_AUDIO_VOICE_VOLUME = "android:audio_voice_volume";
1302 /** @hide */
1303 @SystemApi @TestApi
1304 public static final String OPSTR_AUDIO_RING_VOLUME = "android:audio_ring_volume";
1305 /** @hide */
1306 @SystemApi @TestApi
1307 public static final String OPSTR_AUDIO_MEDIA_VOLUME = "android:audio_media_volume";
1308 /** @hide */
1309 @SystemApi @TestApi
1310 public static final String OPSTR_AUDIO_ALARM_VOLUME = "android:audio_alarm_volume";
1311 /** @hide */
1312 @SystemApi @TestApi
1313 public static final String OPSTR_AUDIO_NOTIFICATION_VOLUME =
1314 "android:audio_notification_volume";
1315 /** @hide */
1316 @SystemApi @TestApi
1317 public static final String OPSTR_AUDIO_BLUETOOTH_VOLUME = "android:audio_bluetooth_volume";
1318 /** @hide */
1319 @SystemApi @TestApi
1320 public static final String OPSTR_WAKE_LOCK = "android:wake_lock";
1321 /** @hide */
1322 @SystemApi @TestApi
1323 public static final String OPSTR_MUTE_MICROPHONE = "android:mute_microphone";
1324 /** @hide */
1325 @SystemApi @TestApi
1326 public static final String OPSTR_TOAST_WINDOW = "android:toast_window";
1327 /** @hide */
1328 @SystemApi @TestApi
1329 public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
1330 /** @hide */
1331 @SystemApi @TestApi
1332 public static final String OPSTR_WRITE_WALLPAPER = "android:write_wallpaper";
1333 /** @hide */
1334 @SystemApi @TestApi
1335 public static final String OPSTR_ASSIST_STRUCTURE = "android:assist_structure";
1336 /** @hide */
1337 @SystemApi @TestApi
1338 public static final String OPSTR_ASSIST_SCREENSHOT = "android:assist_screenshot";
1339 /** @hide */
1340 @SystemApi @TestApi
1341 public static final String OPSTR_TURN_SCREEN_ON = "android:turn_screen_on";
1342 /** @hide */
1343 @SystemApi @TestApi
1344 public static final String OPSTR_RUN_IN_BACKGROUND = "android:run_in_background";
1345 /** @hide */
1346 @SystemApi @TestApi
1347 public static final String OPSTR_AUDIO_ACCESSIBILITY_VOLUME =
1348 "android:audio_accessibility_volume";
1349 /** @hide */
1350 @SystemApi @TestApi
1351 public static final String OPSTR_REQUEST_INSTALL_PACKAGES = "android:request_install_packages";
1352 /** @hide */
1353 @SystemApi @TestApi
1354 public static final String OPSTR_RUN_ANY_IN_BACKGROUND = "android:run_any_in_background";
1355 /** @hide */
1356 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001357 public static final String OPSTR_CHANGE_WIFI_STATE = "android:change_wifi_state";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001358 /** @hide */
1359 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001360 public static final String OPSTR_REQUEST_DELETE_PACKAGES = "android:request_delete_packages";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001361 /** @hide */
1362 @SystemApi @TestApi
Peter Visontaya382a8e2018-03-16 16:06:57 +00001363 public static final String OPSTR_BIND_ACCESSIBILITY_SERVICE =
1364 "android:bind_accessibility_service";
Nathan Harold1bb420672018-03-14 17:08:53 -07001365 /** @hide */
1366 @SystemApi @TestApi
1367 public static final String OPSTR_MANAGE_IPSEC_TUNNELS = "android:manage_ipsec_tunnels";
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001368 /** @hide */
1369 @SystemApi @TestApi
1370 public static final String OPSTR_START_FOREGROUND = "android:start_foreground";
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001371 /** @hide */
1372 public static final String OPSTR_BLUETOOTH_SCAN = "android:bluetooth_scan";
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001373
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001374 /** @hide Use the BiometricPrompt/BiometricManager APIs. */
1375 public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001376
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001377 /** @hide Recognize physical activity. */
1378 public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition";
1379
Hongming Jin228cd012018-11-09 14:47:50 -08001380 /** @hide Financial app read sms. */
1381 public static final String OPSTR_SMS_FINANCIAL_TRANSACTIONS =
1382 "android:sms_financial_transactions";
1383
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001384 /** @hide Read media of audio type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001385 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001386 public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
1387 /** @hide Write media of audio type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001388 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001389 public static final String OPSTR_WRITE_MEDIA_AUDIO = "android:write_media_audio";
1390 /** @hide Read media of video type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001391 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001392 public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
1393 /** @hide Write media of video type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001394 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001395 public static final String OPSTR_WRITE_MEDIA_VIDEO = "android:write_media_video";
1396 /** @hide Read media of image type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001397 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001398 public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
1399 /** @hide Write media of image type. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001400 @SystemApi @TestApi
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001401 public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001402 /** @hide Has a legacy (non-isolated) view of storage. */
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001403 @SystemApi @TestApi
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001404 public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001405 /** @hide Read location metadata from media */
1406 public static final String OPSTR_ACCESS_MEDIA_LOCATION = "android:access_media_location";
Jeff Sharkey5997cc82019-08-21 11:14:40 -06001407
Jackal Guo8dc791e2019-01-14 10:26:42 +08001408 /** @hide Interact with accessibility. */
Joel Galensonff4fe202019-02-06 14:43:58 -08001409 @SystemApi
Jackal Guo8dc791e2019-01-14 10:26:42 +08001410 public static final String OPSTR_ACCESS_ACCESSIBILITY = "android:access_accessibility";
Michael Groover656ef912019-04-09 17:09:57 -07001411 /** @hide Read device identifiers */
1412 public static final String OPSTR_READ_DEVICE_IDENTIFIERS = "android:read_device_identifiers";
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001413 /** @hide Query all packages on device */
1414 public static final String OPSTR_QUERY_ALL_PACKAGES = "android:query_all_packages";
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001415 /** @hide Access all external storage */
1416 @SystemApi
shafik2a207902020-04-08 17:49:47 +01001417 @TestApi
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001418 public static final String OPSTR_MANAGE_EXTERNAL_STORAGE =
1419 "android:manage_external_storage";
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001420
Eugene Susla5fc2d762020-03-04 13:53:10 -08001421 /** @hide Auto-revoke app permissions if app is unused for an extended period */
1422 @SystemApi
1423 public static final String OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED =
1424 "android:auto_revoke_permissions_if_unused";
1425
Eugene Susla1d7a7912020-03-14 09:16:29 -07001426 /** @hide Auto-revoke app permissions if app is unused for an extended period */
Eugene Suslaf3ce46a2020-03-14 10:28:09 -07001427 @SystemApi
Eugene Susla1d7a7912020-03-14 09:16:29 -07001428 public static final String OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER =
1429 "android:auto_revoke_managed_by_installer";
1430
kholoud mohamed20ded1f2019-12-03 17:52:38 +00001431 /** @hide Communicate cross-profile within the same profile group. */
1432 @SystemApi
1433 public static final String OPSTR_INTERACT_ACROSS_PROFILES = "android:interact_across_profiles";
Benedict Wong3eb95202019-11-05 12:50:59 -08001434 /** @hide Start Platform VPN without user intervention */
1435 public static final String OPSTR_ACTIVATE_PLATFORM_VPN = "android:activate_platform_vpn";
Todd Kennedyb0948d42020-01-27 15:20:07 -08001436 /** @hide */
1437 @SystemApi
1438 public static final String OPSTR_LOADER_USAGE_STATS = "android:loader_usage_stats";
kholoud mohamed20ded1f2019-12-03 17:52:38 +00001439
Nikita Ioffeac095e52020-06-08 22:24:06 +01001440 /**
1441 * AppOp granted to apps that we are started via {@code am instrument -e --no-isolated-storage}
1442 *
1443 * @hide
1444 */
1445 public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07001446
1447 /** {@link #sAppOpsToNote} not initialized yet for this op */
1448 private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
1449 /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
1450 private static final byte SHOULD_NOT_COLLECT_NOTE_OP = 1;
1451 /** Should collect noting of this app-op in {@link #sAppOpsToNote} */
1452 private static final byte SHOULD_COLLECT_NOTE_OP = 2;
1453
1454 @Retention(RetentionPolicy.SOURCE)
1455 @IntDef(flag = true, prefix = { "SHOULD_" }, value = {
1456 SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED,
1457 SHOULD_NOT_COLLECT_NOTE_OP,
1458 SHOULD_COLLECT_NOTE_OP
1459 })
1460 private @interface ShouldCollectNoteOp {}
1461
Svet Ganovda0acdf2017-02-15 10:28:51 -08001462 private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
1463 // RUNTIME PERMISSIONS
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001464 // Contacts
1465 OP_READ_CONTACTS,
1466 OP_WRITE_CONTACTS,
1467 OP_GET_ACCOUNTS,
1468 // Calendar
1469 OP_READ_CALENDAR,
1470 OP_WRITE_CALENDAR,
1471 // SMS
1472 OP_SEND_SMS,
1473 OP_RECEIVE_SMS,
1474 OP_READ_SMS,
1475 OP_RECEIVE_WAP_PUSH,
1476 OP_RECEIVE_MMS,
1477 OP_READ_CELL_BROADCASTS,
1478 // Storage
1479 OP_READ_EXTERNAL_STORAGE,
1480 OP_WRITE_EXTERNAL_STORAGE,
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001481 OP_ACCESS_MEDIA_LOCATION,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001482 // Location
1483 OP_COARSE_LOCATION,
1484 OP_FINE_LOCATION,
1485 // Phone
1486 OP_READ_PHONE_STATE,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001487 OP_READ_PHONE_NUMBERS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001488 OP_CALL_PHONE,
1489 OP_READ_CALL_LOG,
1490 OP_WRITE_CALL_LOG,
1491 OP_ADD_VOICEMAIL,
1492 OP_USE_SIP,
1493 OP_PROCESS_OUTGOING_CALLS,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001494 OP_ANSWER_PHONE_CALLS,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001495 OP_ACCEPT_HANDOVER,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001496 // Microphone
1497 OP_RECORD_AUDIO,
1498 // Camera
1499 OP_CAMERA,
1500 // Body sensors
Svet Ganovda0acdf2017-02-15 10:28:51 -08001501 OP_BODY_SENSORS,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001502 // Activity recognition
1503 OP_ACTIVITY_RECOGNITION,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001504 // Aural
1505 OP_READ_MEDIA_AUDIO,
1506 OP_WRITE_MEDIA_AUDIO,
1507 // Visual
1508 OP_READ_MEDIA_VIDEO,
1509 OP_WRITE_MEDIA_VIDEO,
1510 OP_READ_MEDIA_IMAGES,
1511 OP_WRITE_MEDIA_IMAGES,
Svet Ganovda0acdf2017-02-15 10:28:51 -08001512
1513 // APPOP PERMISSIONS
1514 OP_ACCESS_NOTIFICATIONS,
1515 OP_SYSTEM_ALERT_WINDOW,
1516 OP_WRITE_SETTINGS,
1517 OP_REQUEST_INSTALL_PACKAGES,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001518 OP_START_FOREGROUND,
Hongming Jin228cd012018-11-09 14:47:50 -08001519 OP_SMS_FINANCIAL_TRANSACTIONS,
Philip P. Moltmann4b38fbe2019-09-13 21:33:07 -07001520 OP_MANAGE_IPSEC_TUNNELS,
shafik77cabc72020-01-03 16:22:50 +00001521 OP_INSTANT_APP_START_FOREGROUND,
1522 OP_MANAGE_EXTERNAL_STORAGE,
Todd Kennedyb0948d42020-01-27 15:20:07 -08001523 OP_INTERACT_ACROSS_PROFILES,
1524 OP_LOADER_USAGE_STATS,
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07001525 };
1526
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001527 /**
1528 * This maps each operation to the operation that serves as the
1529 * switch to determine whether it is allowed. Generally this is
1530 * a 1:1 mapping, but for some things (like location) that have
1531 * multiple low-level operations being tracked that should be
David Christie0b837452013-07-29 16:02:13 -07001532 * presented to the user as one switch then this can be used to
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001533 * make them all controlled by the same single operation.
1534 */
1535 private static int[] sOpToSwitch = new int[] {
Dianne Hackbornc216a262018-04-26 13:46:22 -07001536 OP_COARSE_LOCATION, // COARSE_LOCATION
1537 OP_COARSE_LOCATION, // FINE_LOCATION
1538 OP_COARSE_LOCATION, // GPS
1539 OP_VIBRATE, // VIBRATE
1540 OP_READ_CONTACTS, // READ_CONTACTS
1541 OP_WRITE_CONTACTS, // WRITE_CONTACTS
1542 OP_READ_CALL_LOG, // READ_CALL_LOG
1543 OP_WRITE_CALL_LOG, // WRITE_CALL_LOG
1544 OP_READ_CALENDAR, // READ_CALENDAR
1545 OP_WRITE_CALENDAR, // WRITE_CALENDAR
1546 OP_COARSE_LOCATION, // WIFI_SCAN
1547 OP_POST_NOTIFICATION, // POST_NOTIFICATION
1548 OP_COARSE_LOCATION, // NEIGHBORING_CELLS
1549 OP_CALL_PHONE, // CALL_PHONE
1550 OP_READ_SMS, // READ_SMS
1551 OP_WRITE_SMS, // WRITE_SMS
1552 OP_RECEIVE_SMS, // RECEIVE_SMS
1553 OP_RECEIVE_SMS, // RECEIVE_EMERGECY_SMS
1554 OP_RECEIVE_MMS, // RECEIVE_MMS
1555 OP_RECEIVE_WAP_PUSH, // RECEIVE_WAP_PUSH
1556 OP_SEND_SMS, // SEND_SMS
1557 OP_READ_SMS, // READ_ICC_SMS
1558 OP_WRITE_SMS, // WRITE_ICC_SMS
1559 OP_WRITE_SETTINGS, // WRITE_SETTINGS
1560 OP_SYSTEM_ALERT_WINDOW, // SYSTEM_ALERT_WINDOW
1561 OP_ACCESS_NOTIFICATIONS, // ACCESS_NOTIFICATIONS
1562 OP_CAMERA, // CAMERA
1563 OP_RECORD_AUDIO, // RECORD_AUDIO
1564 OP_PLAY_AUDIO, // PLAY_AUDIO
1565 OP_READ_CLIPBOARD, // READ_CLIPBOARD
1566 OP_WRITE_CLIPBOARD, // WRITE_CLIPBOARD
1567 OP_TAKE_MEDIA_BUTTONS, // TAKE_MEDIA_BUTTONS
1568 OP_TAKE_AUDIO_FOCUS, // TAKE_AUDIO_FOCUS
1569 OP_AUDIO_MASTER_VOLUME, // AUDIO_MASTER_VOLUME
1570 OP_AUDIO_VOICE_VOLUME, // AUDIO_VOICE_VOLUME
1571 OP_AUDIO_RING_VOLUME, // AUDIO_RING_VOLUME
1572 OP_AUDIO_MEDIA_VOLUME, // AUDIO_MEDIA_VOLUME
1573 OP_AUDIO_ALARM_VOLUME, // AUDIO_ALARM_VOLUME
1574 OP_AUDIO_NOTIFICATION_VOLUME, // AUDIO_NOTIFICATION_VOLUME
1575 OP_AUDIO_BLUETOOTH_VOLUME, // AUDIO_BLUETOOTH_VOLUME
1576 OP_WAKE_LOCK, // WAKE_LOCK
1577 OP_COARSE_LOCATION, // MONITOR_LOCATION
1578 OP_COARSE_LOCATION, // MONITOR_HIGH_POWER_LOCATION
1579 OP_GET_USAGE_STATS, // GET_USAGE_STATS
1580 OP_MUTE_MICROPHONE, // MUTE_MICROPHONE
1581 OP_TOAST_WINDOW, // TOAST_WINDOW
1582 OP_PROJECT_MEDIA, // PROJECT_MEDIA
1583 OP_ACTIVATE_VPN, // ACTIVATE_VPN
1584 OP_WRITE_WALLPAPER, // WRITE_WALLPAPER
1585 OP_ASSIST_STRUCTURE, // ASSIST_STRUCTURE
1586 OP_ASSIST_SCREENSHOT, // ASSIST_SCREENSHOT
1587 OP_READ_PHONE_STATE, // READ_PHONE_STATE
1588 OP_ADD_VOICEMAIL, // ADD_VOICEMAIL
1589 OP_USE_SIP, // USE_SIP
1590 OP_PROCESS_OUTGOING_CALLS, // PROCESS_OUTGOING_CALLS
1591 OP_USE_FINGERPRINT, // USE_FINGERPRINT
1592 OP_BODY_SENSORS, // BODY_SENSORS
1593 OP_READ_CELL_BROADCASTS, // READ_CELL_BROADCASTS
1594 OP_MOCK_LOCATION, // MOCK_LOCATION
1595 OP_READ_EXTERNAL_STORAGE, // READ_EXTERNAL_STORAGE
1596 OP_WRITE_EXTERNAL_STORAGE, // WRITE_EXTERNAL_STORAGE
1597 OP_TURN_SCREEN_ON, // TURN_SCREEN_ON
1598 OP_GET_ACCOUNTS, // GET_ACCOUNTS
1599 OP_RUN_IN_BACKGROUND, // RUN_IN_BACKGROUND
1600 OP_AUDIO_ACCESSIBILITY_VOLUME, // AUDIO_ACCESSIBILITY_VOLUME
1601 OP_READ_PHONE_NUMBERS, // READ_PHONE_NUMBERS
1602 OP_REQUEST_INSTALL_PACKAGES, // REQUEST_INSTALL_PACKAGES
1603 OP_PICTURE_IN_PICTURE, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
1604 OP_INSTANT_APP_START_FOREGROUND, // INSTANT_APP_START_FOREGROUND
1605 OP_ANSWER_PHONE_CALLS, // ANSWER_PHONE_CALLS
1606 OP_RUN_ANY_IN_BACKGROUND, // OP_RUN_ANY_IN_BACKGROUND
1607 OP_CHANGE_WIFI_STATE, // OP_CHANGE_WIFI_STATE
1608 OP_REQUEST_DELETE_PACKAGES, // OP_REQUEST_DELETE_PACKAGES
1609 OP_BIND_ACCESSIBILITY_SERVICE, // OP_BIND_ACCESSIBILITY_SERVICE
1610 OP_ACCEPT_HANDOVER, // ACCEPT_HANDOVER
1611 OP_MANAGE_IPSEC_TUNNELS, // MANAGE_IPSEC_HANDOVERS
1612 OP_START_FOREGROUND, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001613 OP_COARSE_LOCATION, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001614 OP_USE_BIOMETRIC, // BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001615 OP_ACTIVITY_RECOGNITION, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08001616 OP_SMS_FINANCIAL_TRANSACTIONS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001617 OP_READ_MEDIA_AUDIO, // READ_MEDIA_AUDIO
1618 OP_WRITE_MEDIA_AUDIO, // WRITE_MEDIA_AUDIO
1619 OP_READ_MEDIA_VIDEO, // READ_MEDIA_VIDEO
1620 OP_WRITE_MEDIA_VIDEO, // WRITE_MEDIA_VIDEO
1621 OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES
1622 OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001623 OP_LEGACY_STORAGE, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001624 OP_ACCESS_ACCESSIBILITY, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001625 OP_READ_DEVICE_IDENTIFIERS, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001626 OP_ACCESS_MEDIA_LOCATION, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001627 OP_QUERY_ALL_PACKAGES, // QUERY_ALL_PACKAGES
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001628 OP_MANAGE_EXTERNAL_STORAGE, // MANAGE_EXTERNAL_STORAGE
kholoud mohamed20ded1f2019-12-03 17:52:38 +00001629 OP_INTERACT_ACROSS_PROFILES, //INTERACT_ACROSS_PROFILES
Benedict Wong3eb95202019-11-05 12:50:59 -08001630 OP_ACTIVATE_PLATFORM_VPN, // ACTIVATE_PLATFORM_VPN
Todd Kennedyb0948d42020-01-27 15:20:07 -08001631 OP_LOADER_USAGE_STATS, // LOADER_USAGE_STATS
Ricardo Correaacdc8272020-03-24 11:02:54 -07001632 OP_DEPRECATED_1, // deprecated
Eugene Susla5fc2d762020-03-04 13:53:10 -08001633 OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, //AUTO_REVOKE_PERMISSIONS_IF_UNUSED
Eugene Susla922cd082020-03-11 12:38:17 -07001634 OP_AUTO_REVOKE_MANAGED_BY_INSTALLER, //OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
Nikita Ioffeac095e52020-06-08 22:24:06 +01001635 OP_NO_ISOLATED_STORAGE, // NO_ISOLATED_STORAGE
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001636 };
1637
1638 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001639 * This maps each operation to the public string constant for it.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001640 */
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001641 private static String[] sOpToString = new String[]{
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001642 OPSTR_COARSE_LOCATION,
1643 OPSTR_FINE_LOCATION,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001644 OPSTR_GPS,
1645 OPSTR_VIBRATE,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001646 OPSTR_READ_CONTACTS,
1647 OPSTR_WRITE_CONTACTS,
1648 OPSTR_READ_CALL_LOG,
1649 OPSTR_WRITE_CALL_LOG,
1650 OPSTR_READ_CALENDAR,
1651 OPSTR_WRITE_CALENDAR,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001652 OPSTR_WIFI_SCAN,
1653 OPSTR_POST_NOTIFICATION,
1654 OPSTR_NEIGHBORING_CELLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001655 OPSTR_CALL_PHONE,
1656 OPSTR_READ_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001657 OPSTR_WRITE_SMS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001658 OPSTR_RECEIVE_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001659 OPSTR_RECEIVE_EMERGENCY_BROADCAST,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001660 OPSTR_RECEIVE_MMS,
1661 OPSTR_RECEIVE_WAP_PUSH,
1662 OPSTR_SEND_SMS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001663 OPSTR_READ_ICC_SMS,
1664 OPSTR_WRITE_ICC_SMS,
Billy Lau24b9c832015-07-20 17:34:09 +01001665 OPSTR_WRITE_SETTINGS,
1666 OPSTR_SYSTEM_ALERT_WINDOW,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001667 OPSTR_ACCESS_NOTIFICATIONS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001668 OPSTR_CAMERA,
1669 OPSTR_RECORD_AUDIO,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001670 OPSTR_PLAY_AUDIO,
1671 OPSTR_READ_CLIPBOARD,
1672 OPSTR_WRITE_CLIPBOARD,
1673 OPSTR_TAKE_MEDIA_BUTTONS,
1674 OPSTR_TAKE_AUDIO_FOCUS,
1675 OPSTR_AUDIO_MASTER_VOLUME,
1676 OPSTR_AUDIO_VOICE_VOLUME,
1677 OPSTR_AUDIO_RING_VOLUME,
1678 OPSTR_AUDIO_MEDIA_VOLUME,
1679 OPSTR_AUDIO_ALARM_VOLUME,
1680 OPSTR_AUDIO_NOTIFICATION_VOLUME,
1681 OPSTR_AUDIO_BLUETOOTH_VOLUME,
1682 OPSTR_WAKE_LOCK,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001683 OPSTR_MONITOR_LOCATION,
1684 OPSTR_MONITOR_HIGH_POWER_LOCATION,
Dianne Hackborn5064e7c2014-09-02 10:57:16 -07001685 OPSTR_GET_USAGE_STATS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001686 OPSTR_MUTE_MICROPHONE,
1687 OPSTR_TOAST_WINDOW,
1688 OPSTR_PROJECT_MEDIA,
Jeff Davidson05542602014-08-11 14:07:27 -07001689 OPSTR_ACTIVATE_VPN,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001690 OPSTR_WRITE_WALLPAPER,
1691 OPSTR_ASSIST_STRUCTURE,
1692 OPSTR_ASSIST_SCREENSHOT,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001693 OPSTR_READ_PHONE_STATE,
1694 OPSTR_ADD_VOICEMAIL,
1695 OPSTR_USE_SIP,
Svet Ganov824ad6e2016-09-22 19:36:53 -07001696 OPSTR_PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001697 OPSTR_USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001698 OPSTR_BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001699 OPSTR_READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001700 OPSTR_MOCK_LOCATION,
1701 OPSTR_READ_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001702 OPSTR_WRITE_EXTERNAL_STORAGE,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001703 OPSTR_TURN_SCREEN_ON,
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001704 OPSTR_GET_ACCOUNTS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001705 OPSTR_RUN_IN_BACKGROUND,
1706 OPSTR_AUDIO_ACCESSIBILITY_VOLUME,
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001707 OPSTR_READ_PHONE_NUMBERS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001708 OPSTR_REQUEST_INSTALL_PACKAGES,
Winson Chungf4ac0632017-03-17 12:34:12 -07001709 OPSTR_PICTURE_IN_PICTURE,
Chad Brubaker97b383f2017-02-02 15:04:35 -08001710 OPSTR_INSTANT_APP_START_FOREGROUND,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001711 OPSTR_ANSWER_PHONE_CALLS,
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00001712 OPSTR_RUN_ANY_IN_BACKGROUND,
1713 OPSTR_CHANGE_WIFI_STATE,
1714 OPSTR_REQUEST_DELETE_PACKAGES,
1715 OPSTR_BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001716 OPSTR_ACCEPT_HANDOVER,
Nathan Harold1bb420672018-03-14 17:08:53 -07001717 OPSTR_MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001718 OPSTR_START_FOREGROUND,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001719 OPSTR_BLUETOOTH_SCAN,
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001720 OPSTR_USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001721 OPSTR_ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001722 OPSTR_SMS_FINANCIAL_TRANSACTIONS,
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001723 OPSTR_READ_MEDIA_AUDIO,
1724 OPSTR_WRITE_MEDIA_AUDIO,
1725 OPSTR_READ_MEDIA_VIDEO,
1726 OPSTR_WRITE_MEDIA_VIDEO,
1727 OPSTR_READ_MEDIA_IMAGES,
1728 OPSTR_WRITE_MEDIA_IMAGES,
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001729 OPSTR_LEGACY_STORAGE,
Jackal Guo8dc791e2019-01-14 10:26:42 +08001730 OPSTR_ACCESS_ACCESSIBILITY,
Michael Groover656ef912019-04-09 17:09:57 -07001731 OPSTR_READ_DEVICE_IDENTIFIERS,
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001732 OPSTR_ACCESS_MEDIA_LOCATION,
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001733 OPSTR_QUERY_ALL_PACKAGES,
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08001734 OPSTR_MANAGE_EXTERNAL_STORAGE,
kholoud mohamed20ded1f2019-12-03 17:52:38 +00001735 OPSTR_INTERACT_ACROSS_PROFILES,
Benedict Wong3eb95202019-11-05 12:50:59 -08001736 OPSTR_ACTIVATE_PLATFORM_VPN,
Todd Kennedyb0948d42020-01-27 15:20:07 -08001737 OPSTR_LOADER_USAGE_STATS,
Ricardo Correaacdc8272020-03-24 11:02:54 -07001738 "", // deprecated
Eugene Susla5fc2d762020-03-04 13:53:10 -08001739 OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
Eugene Susla1d7a7912020-03-14 09:16:29 -07001740 OPSTR_AUTO_REVOKE_MANAGED_BY_INSTALLER,
Nikita Ioffeac095e52020-06-08 22:24:06 +01001741 OPSTR_NO_ISOLATED_STORAGE,
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07001742 };
1743
1744 /**
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001745 * This provides a simple name for each operation to be used
1746 * in debug output.
1747 */
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001748 private static String[] sOpNames = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001749 "COARSE_LOCATION",
1750 "FINE_LOCATION",
1751 "GPS",
1752 "VIBRATE",
1753 "READ_CONTACTS",
1754 "WRITE_CONTACTS",
1755 "READ_CALL_LOG",
1756 "WRITE_CALL_LOG",
1757 "READ_CALENDAR",
1758 "WRITE_CALENDAR",
1759 "WIFI_SCAN",
1760 "POST_NOTIFICATION",
1761 "NEIGHBORING_CELLS",
1762 "CALL_PHONE",
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001763 "READ_SMS",
1764 "WRITE_SMS",
1765 "RECEIVE_SMS",
1766 "RECEIVE_EMERGECY_SMS",
1767 "RECEIVE_MMS",
1768 "RECEIVE_WAP_PUSH",
1769 "SEND_SMS",
1770 "READ_ICC_SMS",
1771 "WRITE_ICC_SMS",
Dianne Hackborn961321f2013-02-05 17:22:41 -08001772 "WRITE_SETTINGS",
Dianne Hackbornc2293022013-02-06 23:14:49 -08001773 "SYSTEM_ALERT_WINDOW",
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001774 "ACCESS_NOTIFICATIONS",
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001775 "CAMERA",
1776 "RECORD_AUDIO",
1777 "PLAY_AUDIO",
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001778 "READ_CLIPBOARD",
1779 "WRITE_CLIPBOARD",
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001780 "TAKE_MEDIA_BUTTONS",
1781 "TAKE_AUDIO_FOCUS",
1782 "AUDIO_MASTER_VOLUME",
1783 "AUDIO_VOICE_VOLUME",
1784 "AUDIO_RING_VOLUME",
1785 "AUDIO_MEDIA_VOLUME",
1786 "AUDIO_ALARM_VOLUME",
1787 "AUDIO_NOTIFICATION_VOLUME",
1788 "AUDIO_BLUETOOTH_VOLUME",
Dianne Hackborn713df152013-05-17 11:27:57 -07001789 "WAKE_LOCK",
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001790 "MONITOR_LOCATION",
David Christie0b837452013-07-29 16:02:13 -07001791 "MONITOR_HIGH_POWER_LOCATION",
Emily Bernier22c921a2014-05-28 11:01:32 -04001792 "GET_USAGE_STATS",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001793 "MUTE_MICROPHONE",
Jason Monk1c7c3192014-06-26 12:52:18 -04001794 "TOAST_WINDOW",
Michael Wrightc39d47a2014-07-08 18:07:36 -07001795 "PROJECT_MEDIA",
Jeff Davidson05542602014-08-11 14:07:27 -07001796 "ACTIVATE_VPN",
Benjamin Franzf3ece362015-02-11 10:51:10 +00001797 "WRITE_WALLPAPER",
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001798 "ASSIST_STRUCTURE",
Svet Ganov16a16892015-04-16 10:32:04 -07001799 "ASSIST_SCREENSHOT",
Eugene Suslae4ee2c22018-11-05 12:23:30 -08001800 "READ_PHONE_STATE",
Svetoslav5335b672015-04-29 12:00:51 -07001801 "ADD_VOICEMAIL",
Svetoslavc656e6f2015-04-29 14:08:16 -07001802 "USE_SIP",
Svetoslav4af76a52015-04-29 15:29:46 -07001803 "PROCESS_OUTGOING_CALLS",
Svet Ganovb9d71a62015-04-30 10:38:13 -07001804 "USE_FINGERPRINT",
Svet Ganovede43162015-05-02 17:42:44 -07001805 "BODY_SENSORS",
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001806 "READ_CELL_BROADCASTS",
Svet Ganov921c7df2015-06-29 21:51:41 -07001807 "MOCK_LOCATION",
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001808 "READ_EXTERNAL_STORAGE",
1809 "WRITE_EXTERNAL_STORAGE",
1810 "TURN_ON_SCREEN",
Svetoslavf3f02ac2015-09-08 14:36:35 -07001811 "GET_ACCOUNTS",
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001812 "RUN_IN_BACKGROUND",
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001813 "AUDIO_ACCESSIBILITY_VOLUME",
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001814 "READ_PHONE_NUMBERS",
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001815 "REQUEST_INSTALL_PACKAGES",
Winson Chungf4ac0632017-03-17 12:34:12 -07001816 "PICTURE_IN_PICTURE",
Chad Brubaker97b383f2017-02-02 15:04:35 -08001817 "INSTANT_APP_START_FOREGROUND",
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001818 "ANSWER_PHONE_CALLS",
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001819 "RUN_ANY_IN_BACKGROUND",
Peter Visontay1246d9e2017-10-17 17:02:45 +01001820 "CHANGE_WIFI_STATE",
Peter Visontayf2e38362017-11-27 15:27:16 +00001821 "REQUEST_DELETE_PACKAGES",
Peter Visontay11950832017-11-14 19:34:59 +00001822 "BIND_ACCESSIBILITY_SERVICE",
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001823 "ACCEPT_HANDOVER",
Nathan Harold1bb420672018-03-14 17:08:53 -07001824 "MANAGE_IPSEC_TUNNELS",
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001825 "START_FOREGROUND",
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001826 "BLUETOOTH_SCAN",
Kevin Chynb3c05aa2018-09-21 16:50:32 -07001827 "USE_BIOMETRIC",
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001828 "ACTIVITY_RECOGNITION",
Hongming Jin228cd012018-11-09 14:47:50 -08001829 "SMS_FINANCIAL_TRANSACTIONS",
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07001830 "READ_MEDIA_AUDIO",
1831 "WRITE_MEDIA_AUDIO",
1832 "READ_MEDIA_VIDEO",
1833 "WRITE_MEDIA_VIDEO",
1834 "READ_MEDIA_IMAGES",
1835 "WRITE_MEDIA_IMAGES",
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001836 "LEGACY_STORAGE",
Jackal Guo8dc791e2019-01-14 10:26:42 +08001837 "ACCESS_ACCESSIBILITY",
Michael Groover656ef912019-04-09 17:09:57 -07001838 "READ_DEVICE_IDENTIFIERS",
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001839 "ACCESS_MEDIA_LOCATION",
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001840 "QUERY_ALL_PACKAGES",
kholoud mohamed20ded1f2019-12-03 17:52:38 +00001841 "MANAGE_EXTERNAL_STORAGE",
Benedict Wong3eb95202019-11-05 12:50:59 -08001842 "INTERACT_ACROSS_PROFILES",
1843 "ACTIVATE_PLATFORM_VPN",
Todd Kennedyb0948d42020-01-27 15:20:07 -08001844 "LOADER_USAGE_STATS",
Ricardo Correaacdc8272020-03-24 11:02:54 -07001845 "deprecated",
Eugene Susla5fc2d762020-03-04 13:53:10 -08001846 "AUTO_REVOKE_PERMISSIONS_IF_UNUSED",
Eugene Susla1d7a7912020-03-14 09:16:29 -07001847 "AUTO_REVOKE_MANAGED_BY_INSTALLER",
Nikita Ioffeac095e52020-06-08 22:24:06 +01001848 "NO_ISOLATED_STORAGE",
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001849 };
1850
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001851 /**
1852 * This optionally maps a permission to an operation. If there
1853 * is no permission associated with an operation, it is null.
1854 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01001855 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001856 private static String[] sOpPerms = new String[] {
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001857 android.Manifest.permission.ACCESS_COARSE_LOCATION,
1858 android.Manifest.permission.ACCESS_FINE_LOCATION,
1859 null,
1860 android.Manifest.permission.VIBRATE,
1861 android.Manifest.permission.READ_CONTACTS,
1862 android.Manifest.permission.WRITE_CONTACTS,
1863 android.Manifest.permission.READ_CALL_LOG,
1864 android.Manifest.permission.WRITE_CALL_LOG,
1865 android.Manifest.permission.READ_CALENDAR,
1866 android.Manifest.permission.WRITE_CALENDAR,
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001867 android.Manifest.permission.ACCESS_WIFI_STATE,
Robert Craigf97616c2013-10-07 12:32:02 -04001868 null, // no permission required for notifications
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001869 null, // neighboring cells shares the coarse location perm
1870 android.Manifest.permission.CALL_PHONE,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001871 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001872 null, // no permission required for writing sms
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001873 android.Manifest.permission.RECEIVE_SMS,
1874 android.Manifest.permission.RECEIVE_EMERGENCY_BROADCAST,
1875 android.Manifest.permission.RECEIVE_MMS,
1876 android.Manifest.permission.RECEIVE_WAP_PUSH,
1877 android.Manifest.permission.SEND_SMS,
1878 android.Manifest.permission.READ_SMS,
Svetoslav6c589572015-04-16 16:19:24 -07001879 null, // no permission required for writing icc sms
Dianne Hackborn961321f2013-02-05 17:22:41 -08001880 android.Manifest.permission.WRITE_SETTINGS,
Dianne Hackbornc2293022013-02-06 23:14:49 -08001881 android.Manifest.permission.SYSTEM_ALERT_WINDOW,
Daniel Sandlerfde19b12013-01-17 00:21:05 -05001882 android.Manifest.permission.ACCESS_NOTIFICATIONS,
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001883 android.Manifest.permission.CAMERA,
1884 android.Manifest.permission.RECORD_AUDIO,
1885 null, // no permission for playing audio
Dianne Hackbornefcc1a22013-02-25 18:02:35 -08001886 null, // no permission for reading clipboard
1887 null, // no permission for writing clipboard
Dianne Hackbornba50b97c2013-04-30 15:04:46 -07001888 null, // no permission for taking media buttons
1889 null, // no permission for taking audio focus
1890 null, // no permission for changing master volume
1891 null, // no permission for changing voice volume
1892 null, // no permission for changing ring volume
1893 null, // no permission for changing media volume
1894 null, // no permission for changing alarm volume
1895 null, // no permission for changing notification volume
1896 null, // no permission for changing bluetooth volume
Dianne Hackborn713df152013-05-17 11:27:57 -07001897 android.Manifest.permission.WAKE_LOCK,
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07001898 null, // no permission for generic location monitoring
David Christie0b837452013-07-29 16:02:13 -07001899 null, // no permission for high power location monitoring
Dianne Hackborne22b3b12014-05-07 18:06:44 -07001900 android.Manifest.permission.PACKAGE_USAGE_STATS,
Emily Bernier22c921a2014-05-28 11:01:32 -04001901 null, // no permission for muting/unmuting microphone
Jason Monk1c7c3192014-06-26 12:52:18 -04001902 null, // no permission for displaying toasts
Michael Wrightc39d47a2014-07-08 18:07:36 -07001903 null, // no permission for projecting media
Jeff Davidson05542602014-08-11 14:07:27 -07001904 null, // no permission for activating vpn
Benjamin Franzf3ece362015-02-11 10:51:10 +00001905 null, // no permission for supporting wallpaper
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07001906 null, // no permission for receiving assist structure
1907 null, // no permission for receiving assist screenshot
Svet Ganovc3300092015-04-17 09:07:22 -07001908 Manifest.permission.READ_PHONE_STATE,
Svetoslav5335b672015-04-29 12:00:51 -07001909 Manifest.permission.ADD_VOICEMAIL,
Svetoslavc656e6f2015-04-29 14:08:16 -07001910 Manifest.permission.USE_SIP,
Svetoslav4af76a52015-04-29 15:29:46 -07001911 Manifest.permission.PROCESS_OUTGOING_CALLS,
Svet Ganovb9d71a62015-04-30 10:38:13 -07001912 Manifest.permission.USE_FINGERPRINT,
Svet Ganovede43162015-05-02 17:42:44 -07001913 Manifest.permission.BODY_SENSORS,
Svet Ganovf7e9cf42015-05-13 10:40:31 -07001914 Manifest.permission.READ_CELL_BROADCASTS,
Svet Ganov921c7df2015-06-29 21:51:41 -07001915 null,
1916 Manifest.permission.READ_EXTERNAL_STORAGE,
1917 Manifest.permission.WRITE_EXTERNAL_STORAGE,
Dianne Hackborn280a64e2015-07-13 14:48:08 -07001918 null, // no permission for turning the screen on
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07001919 Manifest.permission.GET_ACCOUNTS,
1920 null, // no permission for running in background
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08001921 null, // no permission for changing accessibility volume
Chad Brubaker0c1651f2017-03-30 16:29:10 -07001922 Manifest.permission.READ_PHONE_NUMBERS,
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08001923 Manifest.permission.REQUEST_INSTALL_PACKAGES,
Winson Chung59fda9e2017-01-20 16:14:51 -08001924 null, // no permission for entering picture-in-picture on hide
Chad Brubaker97b383f2017-02-02 15:04:35 -08001925 Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
Eugene Suslacae3d3e2017-01-31 11:08:11 -08001926 Manifest.permission.ANSWER_PHONE_CALLS,
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07001927 null, // no permission for OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01001928 Manifest.permission.CHANGE_WIFI_STATE,
Peter Visontayf2e38362017-11-27 15:27:16 +00001929 Manifest.permission.REQUEST_DELETE_PACKAGES,
Peter Visontay11950832017-11-14 19:34:59 +00001930 Manifest.permission.BIND_ACCESSIBILITY_SERVICE,
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08001931 Manifest.permission.ACCEPT_HANDOVER,
Philip P. Moltmann4b38fbe2019-09-13 21:33:07 -07001932 Manifest.permission.MANAGE_IPSEC_TUNNELS,
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07001933 Manifest.permission.FOREGROUND_SERVICE,
Dianne Hackborne04f13d2018-05-02 12:51:52 -07001934 null, // no permission for OP_BLUETOOTH_SCAN
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001935 Manifest.permission.USE_BIOMETRIC,
Zimuzo6cbf9cc2018-10-05 12:05:58 +01001936 Manifest.permission.ACTIVITY_RECOGNITION,
Hongming Jin228cd012018-11-09 14:47:50 -08001937 Manifest.permission.SMS_FINANCIAL_TRANSACTIONS,
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001938 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001939 null, // no permission for OP_WRITE_MEDIA_AUDIO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001940 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001941 null, // no permission for OP_WRITE_MEDIA_VIDEO
Philip P. Moltmann129a0b02019-03-27 12:24:45 -07001942 null,
Jeff Sharkey9787a9452018-11-18 17:53:02 -07001943 null, // no permission for OP_WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07001944 null, // no permission for OP_LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08001945 null, // no permission for OP_ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07001946 null, // no direct permission for OP_READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07001947 Manifest.permission.ACCESS_MEDIA_LOCATION,
Patrick Baumann6c1c8092019-06-27 14:55:44 -07001948 null, // no permission for OP_QUERY_ALL_PACKAGES
shafik77cabc72020-01-03 16:22:50 +00001949 Manifest.permission.MANAGE_EXTERNAL_STORAGE,
kholoud mohamed20ded1f2019-12-03 17:52:38 +00001950 android.Manifest.permission.INTERACT_ACROSS_PROFILES,
Benedict Wong3eb95202019-11-05 12:50:59 -08001951 null, // no permission for OP_ACTIVATE_PLATFORM_VPN
Todd Kennedyb0948d42020-01-27 15:20:07 -08001952 android.Manifest.permission.LOADER_USAGE_STATS,
Ricardo Correaacdc8272020-03-24 11:02:54 -07001953 null, // deprecated operation
Eugene Susla5fc2d762020-03-04 13:53:10 -08001954 null, // no permission for OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
Eugene Susla922cd082020-03-11 12:38:17 -07001955 null, // no permission for OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
Nikita Ioffeac095e52020-06-08 22:24:06 +01001956 null, // no permission for OP_NO_ISOLATED_STORAGE
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08001957 };
1958
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08001959 /**
Jason Monk62062992014-05-06 09:55:28 -04001960 * Specifies whether an Op should be restricted by a user restriction.
1961 * Each Op should be filled with a restriction string from UserManager or
1962 * null to specify it is not affected by any user restriction.
1963 */
1964 private static String[] sOpRestrictions = new String[] {
Julia Reynolds9854d572014-07-02 14:46:02 -04001965 UserManager.DISALLOW_SHARE_LOCATION, //COARSE_LOCATION
1966 UserManager.DISALLOW_SHARE_LOCATION, //FINE_LOCATION
1967 UserManager.DISALLOW_SHARE_LOCATION, //GPS
Jason Monk62062992014-05-06 09:55:28 -04001968 null, //VIBRATE
1969 null, //READ_CONTACTS
1970 null, //WRITE_CONTACTS
Yorke Lee15f83c62014-08-13 14:14:29 -07001971 UserManager.DISALLOW_OUTGOING_CALLS, //READ_CALL_LOG
1972 UserManager.DISALLOW_OUTGOING_CALLS, //WRITE_CALL_LOG
Jason Monk62062992014-05-06 09:55:28 -04001973 null, //READ_CALENDAR
1974 null, //WRITE_CALENDAR
Julia Reynolds9854d572014-07-02 14:46:02 -04001975 UserManager.DISALLOW_SHARE_LOCATION, //WIFI_SCAN
Jason Monk62062992014-05-06 09:55:28 -04001976 null, //POST_NOTIFICATION
1977 null, //NEIGHBORING_CELLS
1978 null, //CALL_PHONE
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001979 UserManager.DISALLOW_SMS, //READ_SMS
1980 UserManager.DISALLOW_SMS, //WRITE_SMS
1981 UserManager.DISALLOW_SMS, //RECEIVE_SMS
1982 null, //RECEIVE_EMERGENCY_SMS
1983 UserManager.DISALLOW_SMS, //RECEIVE_MMS
Jason Monk62062992014-05-06 09:55:28 -04001984 null, //RECEIVE_WAP_PUSH
Amith Yamasani41c1ded2014-08-05 11:15:05 -07001985 UserManager.DISALLOW_SMS, //SEND_SMS
1986 UserManager.DISALLOW_SMS, //READ_ICC_SMS
1987 UserManager.DISALLOW_SMS, //WRITE_ICC_SMS
Jason Monk62062992014-05-06 09:55:28 -04001988 null, //WRITE_SETTINGS
Jason Monk1c7c3192014-06-26 12:52:18 -04001989 UserManager.DISALLOW_CREATE_WINDOWS, //SYSTEM_ALERT_WINDOW
Jason Monk62062992014-05-06 09:55:28 -04001990 null, //ACCESS_NOTIFICATIONS
Makoto Onuki759a7632015-10-28 16:43:10 -07001991 UserManager.DISALLOW_CAMERA, //CAMERA
Fyodor Kupolovb5013302015-04-17 17:59:14 -07001992 UserManager.DISALLOW_RECORD_AUDIO, //RECORD_AUDIO
Jason Monk62062992014-05-06 09:55:28 -04001993 null, //PLAY_AUDIO
1994 null, //READ_CLIPBOARD
1995 null, //WRITE_CLIPBOARD
1996 null, //TAKE_MEDIA_BUTTONS
1997 null, //TAKE_AUDIO_FOCUS
Emily Bernier45775c42014-05-16 15:12:04 -04001998 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MASTER_VOLUME
1999 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_VOICE_VOLUME
2000 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_RING_VOLUME
2001 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_MEDIA_VOLUME
2002 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ALARM_VOLUME
2003 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_NOTIFICATION_VOLUME
2004 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_BLUETOOTH_VOLUME
Jason Monk62062992014-05-06 09:55:28 -04002005 null, //WAKE_LOCK
Julia Reynolds9854d572014-07-02 14:46:02 -04002006 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_LOCATION
2007 UserManager.DISALLOW_SHARE_LOCATION, //MONITOR_HIGH_POWER_LOCATION
Jason Monk62062992014-05-06 09:55:28 -04002008 null, //GET_USAGE_STATS
Emily Bernier22c921a2014-05-28 11:01:32 -04002009 UserManager.DISALLOW_UNMUTE_MICROPHONE, // MUTE_MICROPHONE
Jason Monk1c7c3192014-06-26 12:52:18 -04002010 UserManager.DISALLOW_CREATE_WINDOWS, // TOAST_WINDOW
Michael Wrightc39d47a2014-07-08 18:07:36 -07002011 null, //PROJECT_MEDIA
Tony Mak33d03a92016-06-02 15:01:16 +01002012 null, // ACTIVATE_VPN
Benjamin Franzf3ece362015-02-11 10:51:10 +00002013 UserManager.DISALLOW_WALLPAPER, // WRITE_WALLPAPER
Dianne Hackbornd59a5d52015-04-04 14:52:14 -07002014 null, // ASSIST_STRUCTURE
2015 null, // ASSIST_SCREENSHOT
Svet Ganovc3300092015-04-17 09:07:22 -07002016 null, // READ_PHONE_STATE
Svetoslav5335b672015-04-29 12:00:51 -07002017 null, // ADD_VOICEMAIL
Svetoslavc656e6f2015-04-29 14:08:16 -07002018 null, // USE_SIP
Svetoslav4af76a52015-04-29 15:29:46 -07002019 null, // PROCESS_OUTGOING_CALLS
Svet Ganovb9d71a62015-04-30 10:38:13 -07002020 null, // USE_FINGERPRINT
Svet Ganovede43162015-05-02 17:42:44 -07002021 null, // BODY_SENSORS
Svet Ganovf7e9cf42015-05-13 10:40:31 -07002022 null, // READ_CELL_BROADCASTS
Svet Ganov921c7df2015-06-29 21:51:41 -07002023 null, // MOCK_LOCATION
2024 null, // READ_EXTERNAL_STORAGE
Dianne Hackborn280a64e2015-07-13 14:48:08 -07002025 null, // WRITE_EXTERNAL_STORAGE
2026 null, // TURN_ON_SCREEN
Svetoslavf3f02ac2015-09-08 14:36:35 -07002027 null, // GET_ACCOUNTS
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07002028 null, // RUN_IN_BACKGROUND
Jean-Michel Trivi3f0945a2016-11-11 10:05:18 -08002029 UserManager.DISALLOW_ADJUST_VOLUME, //AUDIO_ACCESSIBILITY_VOLUME
Chad Brubaker0c1651f2017-03-30 16:29:10 -07002030 null, // READ_PHONE_NUMBERS
Suprabh Shukla2f34b1a2016-12-16 14:47:25 -08002031 null, // REQUEST_INSTALL_PACKAGES
Winson Chung59fda9e2017-01-20 16:14:51 -08002032 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
Chad Brubaker97b383f2017-02-02 15:04:35 -08002033 null, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08002034 null, // ANSWER_PHONE_CALLS
Suprabh Shukla3ac1daa2017-07-14 12:15:27 -07002035 null, // OP_RUN_ANY_IN_BACKGROUND
Peter Visontay1246d9e2017-10-17 17:02:45 +01002036 null, // OP_CHANGE_WIFI_STATE
Peter Visontayf2e38362017-11-27 15:27:16 +00002037 null, // REQUEST_DELETE_PACKAGES
Peter Visontay11950832017-11-14 19:34:59 +00002038 null, // OP_BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002039 null, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07002040 null, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07002041 null, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07002042 null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07002043 null, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01002044 null, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08002045 UserManager.DISALLOW_SMS, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07002046 null, // READ_MEDIA_AUDIO
2047 null, // WRITE_MEDIA_AUDIO
2048 null, // READ_MEDIA_VIDEO
2049 null, // WRITE_MEDIA_VIDEO
2050 null, // READ_MEDIA_IMAGES
2051 null, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07002052 null, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08002053 null, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07002054 null, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07002055 null, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07002056 null, // QUERY_ALL_PACKAGES
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08002057 null, // MANAGE_EXTERNAL_STORAGE
kholoud mohamed20ded1f2019-12-03 17:52:38 +00002058 null, // INTERACT_ACROSS_PROFILES
Benedict Wong3eb95202019-11-05 12:50:59 -08002059 null, // ACTIVATE_PLATFORM_VPN
Todd Kennedyb0948d42020-01-27 15:20:07 -08002060 null, // LOADER_USAGE_STATS
Ricardo Correaacdc8272020-03-24 11:02:54 -07002061 null, // deprecated operation
Eugene Susla5fc2d762020-03-04 13:53:10 -08002062 null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
Eugene Susla1d7a7912020-03-14 09:16:29 -07002063 null, // AUTO_REVOKE_MANAGED_BY_INSTALLER
Nikita Ioffeac095e52020-06-08 22:24:06 +01002064 null, // NO_ISOLATED_STORAGE
Jason Monk1c7c3192014-06-26 12:52:18 -04002065 };
2066
2067 /**
Philip P. Moltmannad787aa2020-03-10 09:49:22 -07002068 * In which cases should an app be allowed to bypass the {@link #setUserRestriction user
2069 * restriction} for a certain app-op.
Jason Monk1c7c3192014-06-26 12:52:18 -04002070 */
Philip P. Moltmannad787aa2020-03-10 09:49:22 -07002071 private static RestrictionBypass[] sOpAllowSystemRestrictionBypass = new RestrictionBypass[] {
2072 new RestrictionBypass(true, false), //COARSE_LOCATION
2073 new RestrictionBypass(true, false), //FINE_LOCATION
2074 null, //GPS
2075 null, //VIBRATE
2076 null, //READ_CONTACTS
2077 null, //WRITE_CONTACTS
2078 null, //READ_CALL_LOG
2079 null, //WRITE_CALL_LOG
2080 null, //READ_CALENDAR
2081 null, //WRITE_CALENDAR
2082 new RestrictionBypass(true, false), //WIFI_SCAN
2083 null, //POST_NOTIFICATION
2084 null, //NEIGHBORING_CELLS
2085 null, //CALL_PHONE
2086 null, //READ_SMS
2087 null, //WRITE_SMS
2088 null, //RECEIVE_SMS
2089 null, //RECEIVE_EMERGECY_SMS
2090 null, //RECEIVE_MMS
2091 null, //RECEIVE_WAP_PUSH
2092 null, //SEND_SMS
2093 null, //READ_ICC_SMS
2094 null, //WRITE_ICC_SMS
2095 null, //WRITE_SETTINGS
2096 new RestrictionBypass(true, false), //SYSTEM_ALERT_WINDOW
2097 null, //ACCESS_NOTIFICATIONS
2098 null, //CAMERA
2099 new RestrictionBypass(false, true), //RECORD_AUDIO
2100 null, //PLAY_AUDIO
2101 null, //READ_CLIPBOARD
2102 null, //WRITE_CLIPBOARD
2103 null, //TAKE_MEDIA_BUTTONS
2104 null, //TAKE_AUDIO_FOCUS
2105 null, //AUDIO_MASTER_VOLUME
2106 null, //AUDIO_VOICE_VOLUME
2107 null, //AUDIO_RING_VOLUME
2108 null, //AUDIO_MEDIA_VOLUME
2109 null, //AUDIO_ALARM_VOLUME
2110 null, //AUDIO_NOTIFICATION_VOLUME
2111 null, //AUDIO_BLUETOOTH_VOLUME
2112 null, //WAKE_LOCK
2113 null, //MONITOR_LOCATION
2114 null, //MONITOR_HIGH_POWER_LOCATION
2115 null, //GET_USAGE_STATS
2116 null, //MUTE_MICROPHONE
2117 new RestrictionBypass(true, false), //TOAST_WINDOW
2118 null, //PROJECT_MEDIA
2119 null, //ACTIVATE_VPN
2120 null, //WALLPAPER
2121 null, //ASSIST_STRUCTURE
2122 null, //ASSIST_SCREENSHOT
2123 null, //READ_PHONE_STATE
2124 null, //ADD_VOICEMAIL
2125 null, // USE_SIP
2126 null, // PROCESS_OUTGOING_CALLS
2127 null, // USE_FINGERPRINT
2128 null, // BODY_SENSORS
2129 null, // READ_CELL_BROADCASTS
2130 null, // MOCK_LOCATION
2131 null, // READ_EXTERNAL_STORAGE
2132 null, // WRITE_EXTERNAL_STORAGE
2133 null, // TURN_ON_SCREEN
2134 null, // GET_ACCOUNTS
2135 null, // RUN_IN_BACKGROUND
2136 null, // AUDIO_ACCESSIBILITY_VOLUME
2137 null, // READ_PHONE_NUMBERS
2138 null, // REQUEST_INSTALL_PACKAGES
2139 null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
2140 null, // INSTANT_APP_START_FOREGROUND
2141 null, // ANSWER_PHONE_CALLS
2142 null, // OP_RUN_ANY_IN_BACKGROUND
2143 null, // OP_CHANGE_WIFI_STATE
2144 null, // OP_REQUEST_DELETE_PACKAGES
2145 null, // OP_BIND_ACCESSIBILITY_SERVICE
2146 null, // ACCEPT_HANDOVER
2147 null, // MANAGE_IPSEC_HANDOVERS
2148 null, // START_FOREGROUND
2149 new RestrictionBypass(true, false), // BLUETOOTH_SCAN
2150 null, // USE_BIOMETRIC
2151 null, // ACTIVITY_RECOGNITION
2152 null, // SMS_FINANCIAL_TRANSACTIONS
2153 null, // READ_MEDIA_AUDIO
2154 null, // WRITE_MEDIA_AUDIO
2155 null, // READ_MEDIA_VIDEO
2156 null, // WRITE_MEDIA_VIDEO
2157 null, // READ_MEDIA_IMAGES
2158 null, // WRITE_MEDIA_IMAGES
2159 null, // LEGACY_STORAGE
2160 null, // ACCESS_ACCESSIBILITY
2161 null, // READ_DEVICE_IDENTIFIERS
2162 null, // ACCESS_MEDIA_LOCATION
2163 null, // QUERY_ALL_PACKAGES
2164 null, // MANAGE_EXTERNAL_STORAGE
2165 null, // INTERACT_ACROSS_PROFILES
2166 null, // ACTIVATE_PLATFORM_VPN
2167 null, // LOADER_USAGE_STATS
Ricardo Correaacdc8272020-03-24 11:02:54 -07002168 null, // deprecated operation
Philip P. Moltmannad787aa2020-03-10 09:49:22 -07002169 null, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
Eugene Susla1d7a7912020-03-14 09:16:29 -07002170 null, // AUTO_REVOKE_MANAGED_BY_INSTALLER
Nikita Ioffeac095e52020-06-08 22:24:06 +01002171 null, // NO_ISOLATED_STORAGE
Jason Monk62062992014-05-06 09:55:28 -04002172 };
2173
2174 /**
David Braunf5d83192013-09-16 13:43:51 -07002175 * This specifies the default mode for each operation.
2176 */
2177 private static int[] sOpDefaultMode = new int[] {
Eugene Susla93519852018-06-13 16:44:31 -07002178 AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION
2179 AppOpsManager.MODE_ALLOWED, // FINE_LOCATION
2180 AppOpsManager.MODE_ALLOWED, // GPS
2181 AppOpsManager.MODE_ALLOWED, // VIBRATE
2182 AppOpsManager.MODE_ALLOWED, // READ_CONTACTS
2183 AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS
Svet Ganovd563e932019-04-14 13:07:41 -07002184 AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG
2185 AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG
Eugene Susla93519852018-06-13 16:44:31 -07002186 AppOpsManager.MODE_ALLOWED, // READ_CALENDAR
2187 AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR
2188 AppOpsManager.MODE_ALLOWED, // WIFI_SCAN
2189 AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION
2190 AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS
2191 AppOpsManager.MODE_ALLOWED, // CALL_PHONE
Svet Ganovd563e932019-04-14 13:07:41 -07002192 AppOpsManager.MODE_ALLOWED, // READ_SMS
Eugene Suslaaaff0072018-10-30 13:35:03 -07002193 AppOpsManager.MODE_IGNORED, // WRITE_SMS
Svet Ganovd563e932019-04-14 13:07:41 -07002194 AppOpsManager.MODE_ALLOWED, // RECEIVE_SMS
Eugene Susla93519852018-06-13 16:44:31 -07002195 AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST
Svet Ganovd563e932019-04-14 13:07:41 -07002196 AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS
2197 AppOpsManager.MODE_ALLOWED, // RECEIVE_WAP_PUSH
2198 AppOpsManager.MODE_ALLOWED, // SEND_SMS
Eugene Susla93519852018-06-13 16:44:31 -07002199 AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS
2200 AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS
2201 AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS
Ng Zhi An65a99b62018-10-01 11:57:53 -07002202 getSystemAlertWindowDefault(), // SYSTEM_ALERT_WINDOW
Eugene Susla93519852018-06-13 16:44:31 -07002203 AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS
2204 AppOpsManager.MODE_ALLOWED, // CAMERA
2205 AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO
2206 AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO
2207 AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD
2208 AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD
2209 AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS
2210 AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS
2211 AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME
2212 AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME
2213 AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME
2214 AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME
2215 AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME
2216 AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME
2217 AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME
2218 AppOpsManager.MODE_ALLOWED, // WAKE_LOCK
2219 AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION
2220 AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION
2221 AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS
2222 AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE
2223 AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW
2224 AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA
2225 AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN
2226 AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER
2227 AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE
2228 AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT
2229 AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE
2230 AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL
2231 AppOpsManager.MODE_ALLOWED, // USE_SIP
Svet Ganovd563e932019-04-14 13:07:41 -07002232 AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07002233 AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT
2234 AppOpsManager.MODE_ALLOWED, // BODY_SENSORS
Svet Ganovd563e932019-04-14 13:07:41 -07002235 AppOpsManager.MODE_ALLOWED, // READ_CELL_BROADCASTS
Eugene Susla93519852018-06-13 16:44:31 -07002236 AppOpsManager.MODE_ERRORED, // MOCK_LOCATION
2237 AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE
2238 AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE
2239 AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON
2240 AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS
2241 AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND
2242 AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME
2243 AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS
2244 AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES
2245 AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE
2246 AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND
2247 AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
2248 AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND
2249 AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE
2250 AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES
2251 AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE
2252 AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER
2253 AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS
2254 AppOpsManager.MODE_ALLOWED, // START_FOREGROUND
2255 AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN
2256 AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01002257 AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08002258 AppOpsManager.MODE_DEFAULT, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07002259 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_AUDIO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07002260 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_AUDIO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07002261 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_VIDEO
Jeff Sharkey9787a9452018-11-18 17:53:02 -07002262 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07002263 AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES
Jeff Sharkey9787a9452018-11-18 17:53:02 -07002264 AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES
Jeff Sharkeye82cbb12018-12-06 15:53:11 -07002265 AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08002266 AppOpsManager.MODE_ALLOWED, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07002267 AppOpsManager.MODE_ERRORED, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07002268 AppOpsManager.MODE_ALLOWED, // ALLOW_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07002269 AppOpsManager.MODE_DEFAULT, // QUERY_ALL_PACKAGES
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08002270 AppOpsManager.MODE_DEFAULT, // MANAGE_EXTERNAL_STORAGE
kholoud mohamed20ded1f2019-12-03 17:52:38 +00002271 AppOpsManager.MODE_DEFAULT, // INTERACT_ACROSS_PROFILES
Benedict Wong3eb95202019-11-05 12:50:59 -08002272 AppOpsManager.MODE_IGNORED, // ACTIVATE_PLATFORM_VPN
Todd Kennedyb0948d42020-01-27 15:20:07 -08002273 AppOpsManager.MODE_DEFAULT, // LOADER_USAGE_STATS
Ricardo Correaacdc8272020-03-24 11:02:54 -07002274 AppOpsManager.MODE_IGNORED, // deprecated operation
Eugene Susla5fc2d762020-03-04 13:53:10 -08002275 AppOpsManager.MODE_DEFAULT, // OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED
Eugene Susla922cd082020-03-11 12:38:17 -07002276 AppOpsManager.MODE_ALLOWED, // OP_AUTO_REVOKE_MANAGED_BY_INSTALLER
Nikita Ioffeac095e52020-06-08 22:24:06 +01002277 AppOpsManager.MODE_ERRORED, // OP_NO_ISOLATED_STORAGE
David Braunf5d83192013-09-16 13:43:51 -07002278 };
2279
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002280 /**
2281 * This specifies whether each option is allowed to be reset
2282 * when resetting all app preferences. Disable reset for
2283 * app ops that are under strong control of some part of the
2284 * system (such as OP_WRITE_SMS, which should be allowed only
2285 * for whichever app is selected as the current SMS app).
2286 */
2287 private static boolean[] sOpDisableReset = new boolean[] {
Eugene Susla93519852018-06-13 16:44:31 -07002288 false, // COARSE_LOCATION
2289 false, // FINE_LOCATION
2290 false, // GPS
2291 false, // VIBRATE
2292 false, // READ_CONTACTS
2293 false, // WRITE_CONTACTS
2294 false, // READ_CALL_LOG
2295 false, // WRITE_CALL_LOG
2296 false, // READ_CALENDAR
2297 false, // WRITE_CALENDAR
2298 false, // WIFI_SCAN
2299 false, // POST_NOTIFICATION
2300 false, // NEIGHBORING_CELLS
2301 false, // CALL_PHONE
2302 true, // READ_SMS
2303 true, // WRITE_SMS
2304 true, // RECEIVE_SMS
2305 false, // RECEIVE_EMERGENCY_BROADCAST
2306 false, // RECEIVE_MMS
2307 true, // RECEIVE_WAP_PUSH
2308 true, // SEND_SMS
2309 false, // READ_ICC_SMS
2310 false, // WRITE_ICC_SMS
2311 false, // WRITE_SETTINGS
2312 false, // SYSTEM_ALERT_WINDOW
2313 false, // ACCESS_NOTIFICATIONS
2314 false, // CAMERA
2315 false, // RECORD_AUDIO
2316 false, // PLAY_AUDIO
2317 false, // READ_CLIPBOARD
2318 false, // WRITE_CLIPBOARD
2319 false, // TAKE_MEDIA_BUTTONS
2320 false, // TAKE_AUDIO_FOCUS
2321 false, // AUDIO_MASTER_VOLUME
2322 false, // AUDIO_VOICE_VOLUME
2323 false, // AUDIO_RING_VOLUME
2324 false, // AUDIO_MEDIA_VOLUME
2325 false, // AUDIO_ALARM_VOLUME
2326 false, // AUDIO_NOTIFICATION_VOLUME
2327 false, // AUDIO_BLUETOOTH_VOLUME
2328 false, // WAKE_LOCK
2329 false, // MONITOR_LOCATION
2330 false, // MONITOR_HIGH_POWER_LOCATION
2331 false, // GET_USAGE_STATS
2332 false, // MUTE_MICROPHONE
2333 false, // TOAST_WINDOW
2334 false, // PROJECT_MEDIA
2335 false, // ACTIVATE_VPN
2336 false, // WRITE_WALLPAPER
2337 false, // ASSIST_STRUCTURE
2338 false, // ASSIST_SCREENSHOT
2339 false, // READ_PHONE_STATE
2340 false, // ADD_VOICEMAIL
2341 false, // USE_SIP
2342 false, // PROCESS_OUTGOING_CALLS
2343 false, // USE_FINGERPRINT
2344 false, // BODY_SENSORS
2345 true, // READ_CELL_BROADCASTS
2346 false, // MOCK_LOCATION
2347 false, // READ_EXTERNAL_STORAGE
2348 false, // WRITE_EXTERNAL_STORAGE
2349 false, // TURN_SCREEN_ON
2350 false, // GET_ACCOUNTS
2351 false, // RUN_IN_BACKGROUND
2352 false, // AUDIO_ACCESSIBILITY_VOLUME
2353 false, // READ_PHONE_NUMBERS
2354 false, // REQUEST_INSTALL_PACKAGES
2355 false, // PICTURE_IN_PICTURE
2356 false, // INSTANT_APP_START_FOREGROUND
Eugene Suslacae3d3e2017-01-31 11:08:11 -08002357 false, // ANSWER_PHONE_CALLS
Eugene Susla93519852018-06-13 16:44:31 -07002358 false, // RUN_ANY_IN_BACKGROUND
2359 false, // CHANGE_WIFI_STATE
2360 false, // REQUEST_DELETE_PACKAGES
2361 false, // BIND_ACCESSIBILITY_SERVICE
Tyler Gunn79bc1ec2018-01-22 15:17:54 -08002362 false, // ACCEPT_HANDOVER
Nathan Harold1bb420672018-03-14 17:08:53 -07002363 false, // MANAGE_IPSEC_TUNNELS
Dianne Hackborne9d9b4b2018-03-28 13:51:46 -07002364 false, // START_FOREGROUND
Dianne Hackborne04f13d2018-05-02 12:51:52 -07002365 false, // BLUETOOTH_SCAN
Kevin Chynb3c05aa2018-09-21 16:50:32 -07002366 false, // USE_BIOMETRIC
Zimuzo6cbf9cc2018-10-05 12:05:58 +01002367 false, // ACTIVITY_RECOGNITION
Hongming Jin228cd012018-11-09 14:47:50 -08002368 false, // SMS_FINANCIAL_TRANSACTIONS
Jeff Sharkeyd2a1f0d2018-11-19 10:32:52 -07002369 false, // READ_MEDIA_AUDIO
2370 false, // WRITE_MEDIA_AUDIO
2371 false, // READ_MEDIA_VIDEO
2372 false, // WRITE_MEDIA_VIDEO
2373 false, // READ_MEDIA_IMAGES
2374 false, // WRITE_MEDIA_IMAGES
Zimc72c9d12019-11-27 15:49:33 +00002375 true, // LEGACY_STORAGE
Jackal Guo8dc791e2019-01-14 10:26:42 +08002376 false, // ACCESS_ACCESSIBILITY
Michael Groover656ef912019-04-09 17:09:57 -07002377 false, // READ_DEVICE_IDENTIFIERS
Philip P. Moltmann89b044f2019-09-13 15:12:34 -07002378 false, // ACCESS_MEDIA_LOCATION
Patrick Baumann6c1c8092019-06-27 14:55:44 -07002379 false, // QUERY_ALL_PACKAGES
Philip P. Moltmannb43dfe32019-11-11 14:14:49 -08002380 false, // MANAGE_EXTERNAL_STORAGE
kholoud mohamed20ded1f2019-12-03 17:52:38 +00002381 false, // INTERACT_ACROSS_PROFILES
Benedict Wong3eb95202019-11-05 12:50:59 -08002382 false, // ACTIVATE_PLATFORM_VPN
Todd Kennedyb0948d42020-01-27 15:20:07 -08002383 false, // LOADER_USAGE_STATS
Ricardo Correaacdc8272020-03-24 11:02:54 -07002384 false, // deprecated operation
Eugene Susla5fc2d762020-03-04 13:53:10 -08002385 false, // AUTO_REVOKE_PERMISSIONS_IF_UNUSED
Eugene Susla1d7a7912020-03-14 09:16:29 -07002386 false, // AUTO_REVOKE_MANAGED_BY_INSTALLER
Nikita Ioffeac095e52020-06-08 22:24:06 +01002387 true, // NO_ISOLATED_STORAGE
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002388 };
2389
Svet Ganovfbf01f72015-04-28 18:39:06 -07002390 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07002391 * Mapping from an app op name to the app op code.
Svet Ganovfbf01f72015-04-28 18:39:06 -07002392 */
Svet Ganovb9d71a62015-04-30 10:38:13 -07002393 private static HashMap<String, Integer> sOpStrToOp = new HashMap<>();
Svet Ganovfbf01f72015-04-28 18:39:06 -07002394
Svet Ganovb9d71a62015-04-30 10:38:13 -07002395 /**
2396 * Mapping from a permission to the corresponding app op.
2397 */
Svet Ganovda0acdf2017-02-15 10:28:51 -08002398 private static HashMap<String, Integer> sPermToOp = new HashMap<>();
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002399
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002400 /**
2401 * Set to the uid of the caller if this thread is currently executing a two-way binder
2402 * transaction. Not set if this thread is currently not executing a two way binder transaction.
2403 *
2404 * @see #startNotedAppOpsCollection
Philip P. Moltmannda554e42019-12-20 11:21:02 -08002405 * @see #getNotedOpCollectionMode
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002406 */
2407 private static final ThreadLocal<Integer> sBinderThreadCallingUid = new ThreadLocal<>();
2408
2409 /**
2410 * If a thread is currently executing a two-way binder transaction, this stores the op-codes of
2411 * the app-ops that were noted during this transaction.
2412 *
Philip P. Moltmannda554e42019-12-20 11:21:02 -08002413 * @see #getNotedOpCollectionMode
2414 * @see #collectNotedOpSync
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002415 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07002416 private static final ThreadLocal<ArrayMap<String, long[]>> sAppOpsNotedInThisBinderTransaction =
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002417 new ThreadLocal<>();
2418
2419 /** Whether noting for an appop should be collected */
2420 private static final @ShouldCollectNoteOp byte[] sAppOpsToNote = new byte[_NUM_OP];
2421
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002422 static {
2423 if (sOpToSwitch.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002424 throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002425 + " should be " + _NUM_OP);
2426 }
2427 if (sOpToString.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002428 throw new IllegalStateException("sOpToString length " + sOpToString.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002429 + " should be " + _NUM_OP);
2430 }
2431 if (sOpNames.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002432 throw new IllegalStateException("sOpNames length " + sOpNames.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002433 + " should be " + _NUM_OP);
2434 }
2435 if (sOpPerms.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002436 throw new IllegalStateException("sOpPerms length " + sOpPerms.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002437 + " should be " + _NUM_OP);
2438 }
2439 if (sOpDefaultMode.length != _NUM_OP) {
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002440 throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
2441 + " should be " + _NUM_OP);
2442 }
2443 if (sOpDisableReset.length != _NUM_OP) {
2444 throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002445 + " should be " + _NUM_OP);
2446 }
Jason Monk62062992014-05-06 09:55:28 -04002447 if (sOpRestrictions.length != _NUM_OP) {
2448 throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
2449 + " should be " + _NUM_OP);
2450 }
Jason Monk1c7c3192014-06-26 12:52:18 -04002451 if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
2452 throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
2453 + sOpRestrictions.length + " should be " + _NUM_OP);
2454 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002455 for (int i=0; i<_NUM_OP; i++) {
2456 if (sOpToString[i] != null) {
2457 sOpStrToOp.put(sOpToString[i], i);
2458 }
2459 }
Svet Ganovda0acdf2017-02-15 10:28:51 -08002460 for (int op : RUNTIME_AND_APPOP_PERMISSIONS_OPS) {
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07002461 if (sOpPerms[op] != null) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002462 sPermToOp.put(sOpPerms[op], op);
Svet Ganovb9d71a62015-04-30 10:38:13 -07002463 }
2464 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07002465
2466 if ((_NUM_OP + Long.SIZE - 1) / Long.SIZE != 2) {
2467 // The code currently assumes that the length of sAppOpsNotedInThisBinderTransaction is
2468 // two longs
2469 throw new IllegalStateException("notedAppOps collection code assumes < 128 appops");
2470 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002471 }
2472
Stanislav Zholnin90516b92020-01-20 14:03:06 +00002473 /** Config used to control app ops access messages sampling */
2474 private static MessageSamplingConfig sConfig =
2475 new MessageSamplingConfig(OP_NONE, 0, 0);
2476
Svet Ganov8455ba22019-01-02 13:05:56 -08002477 /** @hide */
2478 public static final String KEY_HISTORICAL_OPS = "historical_ops";
2479
Chad Brubaker7c6dba62019-01-23 15:51:43 -08002480 /** System properties for debug logging of noteOp call sites */
2481 private static final String DEBUG_LOGGING_ENABLE_PROP = "appops.logging_enabled";
2482 private static final String DEBUG_LOGGING_PACKAGES_PROP = "appops.logging_packages";
2483 private static final String DEBUG_LOGGING_OPS_PROP = "appops.logging_ops";
2484 private static final String DEBUG_LOGGING_TAG = "AppOpsManager";
2485
David Braunf5d83192013-09-16 13:43:51 -07002486 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002487 * Retrieve the op switch that controls the given operation.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002488 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002489 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002490 @UnsupportedAppUsage
Dianne Hackbornf265ea92013-01-31 15:00:51 -08002491 public static int opToSwitch(int op) {
2492 return sOpToSwitch[op];
2493 }
2494
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002495 /**
2496 * Retrieve a non-localized name for the operation, for debugging output.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07002497 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002498 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002499 @UnsupportedAppUsage
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002500 public static String opToName(int op) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08002501 if (op == OP_NONE) return "NONE";
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002502 return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
2503 }
2504
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002505 /**
Svet Ganov65f1b9e2019-01-17 19:19:40 -08002506 * Retrieve a non-localized public name for the operation.
2507 *
2508 * @hide
2509 */
2510 public static @NonNull String opToPublicName(int op) {
2511 return sOpToString[op];
2512 }
2513
2514 /**
Dianne Hackborn7b7c58b2014-12-02 18:32:20 -08002515 * @hide
2516 */
2517 public static int strDebugOpToOp(String op) {
2518 for (int i=0; i<sOpNames.length; i++) {
2519 if (sOpNames[i].equals(op)) {
2520 return i;
2521 }
2522 }
2523 throw new IllegalArgumentException("Unknown operation string: " + op);
2524 }
2525
2526 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002527 * Retrieve the permission associated with an operation, or null if there is not one.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002528 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002529 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00002530 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07002531 @TestApi
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08002532 public static String opToPermission(int op) {
2533 return sOpPerms[op];
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002534 }
2535
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002536 /**
Hai Zhangb7776682018-09-25 15:10:57 -07002537 * Retrieve the permission associated with an operation, or null if there is not one.
2538 *
2539 * @param op The operation name.
2540 *
2541 * @hide
2542 */
2543 @Nullable
2544 @SystemApi
2545 public static String opToPermission(@NonNull String op) {
2546 return opToPermission(strOpToOp(op));
2547 }
2548
2549 /**
Jason Monk62062992014-05-06 09:55:28 -04002550 * Retrieve the user restriction associated with an operation, or null if there is not one.
2551 * @hide
2552 */
2553 public static String opToRestriction(int op) {
2554 return sOpRestrictions[op];
2555 }
2556
2557 /**
Svet Ganovb9d71a62015-04-30 10:38:13 -07002558 * Retrieve the app op code for a permission, or null if there is not one.
Svet Ganovda0acdf2017-02-15 10:28:51 -08002559 * This API is intended to be used for mapping runtime or appop permissions
2560 * to the corresponding app op.
Svet Ganovb9d71a62015-04-30 10:38:13 -07002561 * @hide
2562 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00002563 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07002564 @TestApi
Svet Ganovb9d71a62015-04-30 10:38:13 -07002565 public static int permissionToOpCode(String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08002566 Integer boxedOpCode = sPermToOp.get(permission);
Svet Ganov019d2302015-05-04 11:07:38 -07002567 return boxedOpCode != null ? boxedOpCode : OP_NONE;
Svet Ganovb9d71a62015-04-30 10:38:13 -07002568 }
2569
2570 /**
Philip P. Moltmannad787aa2020-03-10 09:49:22 -07002571 * Retrieve whether the op allows to bypass the user restriction.
2572 *
Jason Monk1c7c3192014-06-26 12:52:18 -04002573 * @hide
2574 */
Philip P. Moltmannad787aa2020-03-10 09:49:22 -07002575 public static RestrictionBypass opAllowSystemBypassRestriction(int op) {
Jason Monk1c7c3192014-06-26 12:52:18 -04002576 return sOpAllowSystemRestrictionBypass[op];
2577 }
2578
2579 /**
David Braunf5d83192013-09-16 13:43:51 -07002580 * Retrieve the default mode for the operation.
2581 * @hide
2582 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002583 public static @Mode int opToDefaultMode(int op) {
David Braunf5d83192013-09-16 13:43:51 -07002584 return sOpDefaultMode[op];
2585 }
2586
2587 /**
Hai Zhangc595f112018-11-06 14:20:38 -08002588 * Retrieve the default mode for the app op.
2589 *
2590 * @param appOp The app op name
2591 *
2592 * @return the default mode for the app op
2593 *
2594 * @hide
2595 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07002596 @TestApi
Hai Zhangc595f112018-11-06 14:20:38 -08002597 @SystemApi
2598 public static int opToDefaultMode(@NonNull String appOp) {
2599 return opToDefaultMode(strOpToOp(appOp));
2600 }
2601
2602 /**
Svet Ganov82f09bc2018-01-12 22:08:40 -08002603 * Retrieve the human readable mode.
2604 * @hide
2605 */
Svet Ganov8455ba22019-01-02 13:05:56 -08002606 public static String modeToName(@Mode int mode) {
Dianne Hackbornc216a262018-04-26 13:46:22 -07002607 if (mode >= 0 && mode < MODE_NAMES.length) {
2608 return MODE_NAMES[mode];
Svet Ganov82f09bc2018-01-12 22:08:40 -08002609 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07002610 return "mode=" + mode;
Svet Ganov82f09bc2018-01-12 22:08:40 -08002611 }
2612
2613 /**
Dianne Hackborn8828d3a2013-09-25 16:47:10 -07002614 * Retrieve whether the op allows itself to be reset.
2615 * @hide
2616 */
2617 public static boolean opAllowsReset(int op) {
2618 return !sOpDisableReset[op];
2619 }
2620
2621 /**
Soonil Nagarkar4523f962020-04-14 19:04:41 -07002622 * Returns a listenerId suitable for use with {@link #noteOp(int, int, String, String, String)}.
2623 *
2624 * This is intended for use client side, when the receiver id must be created before the
2625 * associated call is made to the system server. If using {@link PendingIntent} as the receiver,
2626 * avoid using this method as it will include a pointless additional x-process call. Instead to
2627 * prefer passing the PendingIntent to the system server, and then invoking
2628 * {@link #toReceiverId(PendingIntent)} instead.
2629 *
2630 * @param obj the receiver in use
2631 * @return a string representation of the receiver suitable for app ops use
2632 * @hide
2633 */
2634 // TODO: this should probably be @SystemApi as well
2635 public static @NonNull String toReceiverId(@NonNull Object obj) {
2636 if (obj instanceof PendingIntent) {
2637 return toReceiverId((PendingIntent) obj);
2638 } else {
2639 return obj.getClass().getName() + "@" + System.identityHashCode(obj);
2640 }
2641 }
2642
2643 /**
2644 * Returns a listenerId suitable for use with {@link #noteOp(int, int, String, String, String)}.
2645 *
2646 * This is intended for use server side, where ActivityManagerService can be referenced without
2647 * an additional x-process call.
2648 *
2649 * @param pendingIntent the pendingIntent in use
2650 * @return a string representation of the pending intent suitable for app ops use
2651 * @see #toReceiverId(Object)
2652 * @hide
2653 */
2654 // TODO: this should probably be @SystemApi as well
2655 public static @NonNull String toReceiverId(@NonNull PendingIntent pendingIntent) {
2656 return pendingIntent.getTag("");
2657 }
2658
2659 /**
Philip P. Moltmannad787aa2020-03-10 09:49:22 -07002660 * When to not enforce {@link #setUserRestriction restrictions}.
2661 *
2662 * @hide
2663 */
2664 public static class RestrictionBypass {
2665 /** Does the app need to be privileged to bypass the restriction */
2666 public boolean isPrivileged;
2667
2668 /**
2669 * Does the app need to have the EXEMPT_FROM_AUDIO_RESTRICTIONS permission to bypass the
2670 * restriction
2671 */
2672 public boolean isRecordAudioRestrictionExcept;
2673
2674 public RestrictionBypass(boolean isPrivileged, boolean isRecordAudioRestrictionExcept) {
2675 this.isPrivileged = isPrivileged;
2676 this.isRecordAudioRestrictionExcept = isRecordAudioRestrictionExcept;
2677 }
2678
2679 public static RestrictionBypass UNRESTRICTED = new RestrictionBypass(true, true);
2680 }
2681
2682 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002683 * Class holding all of the operation information associated with an app.
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07002684 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002685 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002686 @TestApi
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002687 @SystemApi
2688 public static final class PackageOps implements Parcelable {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002689 private final String mPackageName;
2690 private final int mUid;
2691 private final List<OpEntry> mEntries;
2692
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07002693 /**
2694 * @hide
2695 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01002696 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08002697 public PackageOps(String packageName, int uid, List<OpEntry> entries) {
2698 mPackageName = packageName;
2699 mUid = uid;
2700 mEntries = entries;
2701 }
2702
Svet Ganovaf189e32019-02-15 18:45:29 -08002703 /**
2704 * @return The name of the package.
2705 */
2706 public @NonNull String getPackageName() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002707 return mPackageName;
2708 }
2709
Svet Ganovaf189e32019-02-15 18:45:29 -08002710 /**
2711 * @return The uid of the package.
2712 */
Dianne Hackborn35654b62013-01-14 17:38:02 -08002713 public int getUid() {
2714 return mUid;
2715 }
2716
Svet Ganovaf189e32019-02-15 18:45:29 -08002717 /**
2718 * @return The ops of the package.
2719 */
Dianne Hackborn62878492019-03-11 15:57:07 -07002720 public @NonNull List<OpEntry> getOps() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002721 return mEntries;
2722 }
2723
2724 @Override
2725 public int describeContents() {
2726 return 0;
2727 }
2728
2729 @Override
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002730 public void writeToParcel(@NonNull Parcel dest, int flags) {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002731 dest.writeString(mPackageName);
2732 dest.writeInt(mUid);
2733 dest.writeInt(mEntries.size());
2734 for (int i=0; i<mEntries.size(); i++) {
2735 mEntries.get(i).writeToParcel(dest, flags);
2736 }
2737 }
2738
2739 PackageOps(Parcel source) {
2740 mPackageName = source.readString();
2741 mUid = source.readInt();
2742 mEntries = new ArrayList<OpEntry>();
2743 final int N = source.readInt();
2744 for (int i=0; i<N; i++) {
2745 mEntries.add(OpEntry.CREATOR.createFromParcel(source));
2746 }
2747 }
2748
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07002749 public static final @android.annotation.NonNull Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
Dianne Hackborn35654b62013-01-14 17:38:02 -08002750 @Override public PackageOps createFromParcel(Parcel source) {
2751 return new PackageOps(source);
2752 }
2753
2754 @Override public PackageOps[] newArray(int size) {
2755 return new PackageOps[size];
2756 }
2757 };
2758 }
2759
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08002760 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002761 * Proxy information for a {@link #noteOp} event
2762 *
2763 * @hide
2764 */
2765 @TestApi
2766 @SystemApi
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002767 // @DataClass(genHiddenConstructor = true, genHiddenCopyConstructor = true)
2768 // genHiddenCopyConstructor does not work for @hide @SystemApi classes
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002769 public static final class OpEventProxyInfo implements Parcelable {
2770 /** UID of the proxy app that noted the op */
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002771 private @IntRange(from = 0) int mUid;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002772 /** Package of the proxy that noted the op */
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002773 private @Nullable String mPackageName;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002774 /** Attribution tag of the proxy that noted the op */
2775 private @Nullable String mAttributionTag;
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002776
2777 /**
2778 * Reinit existing object with new state.
2779 *
2780 * @param uid UID of the proxy app that noted the op
2781 * @param packageName Package of the proxy that noted the op
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002782 * @param attributionTag attribution tag of the proxy that noted the op
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002783 *
2784 * @hide
2785 */
2786 public void reinit(@IntRange(from = 0) int uid, @Nullable String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002787 @Nullable String attributionTag) {
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002788 mUid = Preconditions.checkArgumentNonnegative(uid);
2789 mPackageName = packageName;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002790 mAttributionTag = attributionTag;
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002791 }
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002792
2793
2794
2795 // Code below generated by codegen v1.0.14.
2796 //
2797 // DO NOT MODIFY!
2798 // CHECKSTYLE:OFF Generated code
2799 //
2800 // To regenerate run:
2801 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
2802 //
2803 // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
2804 // Settings > Editor > Code Style > Formatter Control
2805 //@formatter:off
2806
2807
2808 /**
2809 * Creates a new OpEventProxyInfo.
2810 *
2811 * @param uid
2812 * UID of the proxy app that noted the op
2813 * @param packageName
2814 * Package of the proxy that noted the op
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002815 * @param attributionTag
2816 * Attribution tag of the proxy that noted the op
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002817 * @hide
2818 */
2819 @DataClass.Generated.Member
2820 public OpEventProxyInfo(
2821 @IntRange(from = 0) int uid,
2822 @Nullable String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002823 @Nullable String attributionTag) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002824 this.mUid = uid;
2825 com.android.internal.util.AnnotationValidations.validate(
2826 IntRange.class, null, mUid,
2827 "from", 0);
2828 this.mPackageName = packageName;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002829 this.mAttributionTag = attributionTag;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002830
2831 // onConstructed(); // You can define this method to get a callback
2832 }
2833
2834 /**
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002835 * Copy constructor
2836 *
2837 * @hide
2838 */
2839 @DataClass.Generated.Member
2840 public OpEventProxyInfo(@NonNull OpEventProxyInfo orig) {
2841 mUid = orig.mUid;
2842 mPackageName = orig.mPackageName;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002843 mAttributionTag = orig.mAttributionTag;
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002844 }
2845
2846 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002847 * UID of the proxy app that noted the op
2848 */
2849 @DataClass.Generated.Member
2850 public @IntRange(from = 0) int getUid() {
2851 return mUid;
2852 }
2853
2854 /**
2855 * Package of the proxy that noted the op
2856 */
2857 @DataClass.Generated.Member
2858 public @Nullable String getPackageName() {
2859 return mPackageName;
2860 }
2861
2862 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002863 * Attribution tag of the proxy that noted the op
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002864 */
2865 @DataClass.Generated.Member
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002866 public @Nullable String getAttributionTag() {
2867 return mAttributionTag;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002868 }
2869
2870 @Override
2871 @DataClass.Generated.Member
2872 public void writeToParcel(@NonNull Parcel dest, int flags) {
2873 // You can override field parcelling by defining methods like:
2874 // void parcelFieldName(Parcel dest, int flags) { ... }
2875
2876 byte flg = 0;
2877 if (mPackageName != null) flg |= 0x2;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002878 if (mAttributionTag != null) flg |= 0x4;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002879 dest.writeByte(flg);
2880 dest.writeInt(mUid);
2881 if (mPackageName != null) dest.writeString(mPackageName);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002882 if (mAttributionTag != null) dest.writeString(mAttributionTag);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002883 }
2884
2885 @Override
2886 @DataClass.Generated.Member
2887 public int describeContents() { return 0; }
2888
2889 /** @hide */
2890 @SuppressWarnings({"unchecked", "RedundantCast"})
2891 @DataClass.Generated.Member
2892 /* package-private */ OpEventProxyInfo(@NonNull Parcel in) {
2893 // You can override field unparcelling by defining methods like:
2894 // static FieldType unparcelFieldName(Parcel in) { ... }
2895
2896 byte flg = in.readByte();
2897 int uid = in.readInt();
2898 String packageName = (flg & 0x2) == 0 ? null : in.readString();
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002899 String attributionTag = (flg & 0x4) == 0 ? null : in.readString();
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002900
2901 this.mUid = uid;
2902 com.android.internal.util.AnnotationValidations.validate(
2903 IntRange.class, null, mUid,
2904 "from", 0);
2905 this.mPackageName = packageName;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002906 this.mAttributionTag = attributionTag;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002907
2908 // onConstructed(); // You can define this method to get a callback
2909 }
2910
2911 @DataClass.Generated.Member
2912 public static final @NonNull Parcelable.Creator<OpEventProxyInfo> CREATOR
2913 = new Parcelable.Creator<OpEventProxyInfo>() {
2914 @Override
2915 public OpEventProxyInfo[] newArray(int size) {
2916 return new OpEventProxyInfo[size];
2917 }
2918
2919 @Override
2920 public OpEventProxyInfo createFromParcel(@NonNull Parcel in) {
2921 return new OpEventProxyInfo(in);
2922 }
2923 };
2924
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002925 /*
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002926 @DataClass.Generated(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002927 time = 1576814974615L,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002928 codegenVersion = "1.0.14",
2929 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08002930 inputSignatures = "private @android.annotation.IntRange(from=0L) int mUid\nprivate @android.annotation.Nullable java.lang.String mPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\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 -08002931 @Deprecated
2932 private void __metadata() {}
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002933 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002934
2935 //@formatter:on
2936 // End of generated code
2937
2938 }
2939
2940 /**
2941 * Description of a {@link #noteOp} or {@link #startOp} event
2942 *
2943 * @hide
2944 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002945 //@DataClass codegen verifier is broken
2946 public static final class NoteOpEvent implements Parcelable {
2947 /** Time of noteOp event */
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002948 private @IntRange(from = 0) long mNoteTime;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002949 /** The duration of this event (in case this is a startOp event, -1 otherwise). */
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002950 private @IntRange(from = -1) long mDuration;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002951 /** Proxy information of the noteOp event */
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08002952 private @Nullable OpEventProxyInfo mProxy;
2953
2954 /**
2955 * Reinit existing object with new state.
2956 *
2957 * @param noteTime Time of noteOp event
2958 * @param duration The duration of this event (in case this is a startOp event,
2959 * -1 otherwise).
2960 * @param proxy Proxy information of the noteOp event
2961 * @param proxyPool The pool to release previous {@link OpEventProxyInfo} to
2962 */
2963 public void reinit(@IntRange(from = 0) long noteTime,
2964 @IntRange(from = -1) long duration,
2965 @Nullable OpEventProxyInfo proxy,
2966 @NonNull Pools.Pool<OpEventProxyInfo> proxyPool) {
2967 mNoteTime = Preconditions.checkArgumentNonnegative(noteTime);
2968 mDuration = Preconditions.checkArgumentInRange(duration, -1L, Long.MAX_VALUE,
2969 "duration");
2970
2971 if (mProxy != null) {
2972 proxyPool.release(mProxy);
2973 }
2974 mProxy = proxy;
2975 }
2976
2977 /**
2978 * Copy constructor
2979 *
2980 * @hide
2981 */
2982 public NoteOpEvent(@NonNull NoteOpEvent original) {
2983 this(original.mNoteTime, original.mDuration,
2984 original.mProxy != null ? new OpEventProxyInfo(original.mProxy) : null);
2985 }
2986
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08002987
2988
2989 // Code below generated by codegen v1.0.14.
2990 //
2991 // DO NOT MODIFY!
2992 // CHECKSTYLE:OFF Generated code
2993 //
2994 // To regenerate run:
2995 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
2996 //
2997 // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
2998 // Settings > Editor > Code Style > Formatter Control
2999 //@formatter:off
3000
3001
3002 /**
3003 * Creates a new NoteOpEvent.
3004 *
3005 * @param noteTime
3006 * Time of noteOp event
3007 * @param duration
3008 * The duration of this event (in case this is a startOp event, -1 otherwise).
3009 * @param proxy
3010 * Proxy information of the noteOp event
3011 */
3012 @DataClass.Generated.Member
3013 public NoteOpEvent(
3014 @IntRange(from = 0) long noteTime,
3015 @IntRange(from = -1) long duration,
3016 @Nullable OpEventProxyInfo proxy) {
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003017 this.mNoteTime = noteTime;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003018 com.android.internal.util.AnnotationValidations.validate(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003019 IntRange.class, null, mNoteTime,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003020 "from", 0);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003021 this.mDuration = duration;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003022 com.android.internal.util.AnnotationValidations.validate(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003023 IntRange.class, null, mDuration,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003024 "from", -1);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003025 this.mProxy = proxy;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003026
3027 // onConstructed(); // You can define this method to get a callback
3028 }
3029
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003030 /**
3031 * Time of noteOp event
3032 */
3033 @DataClass.Generated.Member
3034 public @IntRange(from = 0) long getNoteTime() {
3035 return mNoteTime;
3036 }
3037
3038 /**
3039 * The duration of this event (in case this is a startOp event, -1 otherwise).
3040 */
3041 @DataClass.Generated.Member
3042 public @IntRange(from = -1) long getDuration() {
3043 return mDuration;
3044 }
3045
3046 /**
3047 * Proxy information of the noteOp event
3048 */
3049 @DataClass.Generated.Member
3050 public @Nullable OpEventProxyInfo getProxy() {
3051 return mProxy;
3052 }
3053
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003054 @Override
3055 @DataClass.Generated.Member
3056 public void writeToParcel(@NonNull Parcel dest, int flags) {
3057 // You can override field parcelling by defining methods like:
3058 // void parcelFieldName(Parcel dest, int flags) { ... }
3059
3060 byte flg = 0;
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003061 if (mProxy != null) flg |= 0x4;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003062 dest.writeByte(flg);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003063 dest.writeLong(mNoteTime);
3064 dest.writeLong(mDuration);
3065 if (mProxy != null) dest.writeTypedObject(mProxy, flags);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003066 }
3067
3068 @Override
3069 @DataClass.Generated.Member
3070 public int describeContents() { return 0; }
3071
3072 /** @hide */
3073 @SuppressWarnings({"unchecked", "RedundantCast"})
3074 @DataClass.Generated.Member
3075 /* package-private */ NoteOpEvent(@NonNull Parcel in) {
3076 // You can override field unparcelling by defining methods like:
3077 // static FieldType unparcelFieldName(Parcel in) { ... }
3078
3079 byte flg = in.readByte();
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003080 long noteTime = in.readLong();
3081 long duration = in.readLong();
3082 OpEventProxyInfo proxy = (flg & 0x4) == 0 ? null : (OpEventProxyInfo) in.readTypedObject(OpEventProxyInfo.CREATOR);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003083
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003084 this.mNoteTime = noteTime;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003085 com.android.internal.util.AnnotationValidations.validate(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003086 IntRange.class, null, mNoteTime,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003087 "from", 0);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003088 this.mDuration = duration;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003089 com.android.internal.util.AnnotationValidations.validate(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003090 IntRange.class, null, mDuration,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003091 "from", -1);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003092 this.mProxy = proxy;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003093
3094 // onConstructed(); // You can define this method to get a callback
3095 }
3096
3097 @DataClass.Generated.Member
3098 public static final @NonNull Parcelable.Creator<NoteOpEvent> CREATOR
3099 = new Parcelable.Creator<NoteOpEvent>() {
3100 @Override
3101 public NoteOpEvent[] newArray(int size) {
3102 return new NoteOpEvent[size];
3103 }
3104
3105 @Override
3106 public NoteOpEvent createFromParcel(@NonNull Parcel in) {
3107 return new NoteOpEvent(in);
3108 }
3109 };
3110
3111 /*
3112 @DataClass.Generated(
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003113 time = 1576811792274L,
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003114 codegenVersion = "1.0.14",
3115 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003116 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 -08003117 @Deprecated
3118 private void __metadata() {}
3119 */
3120
3121
3122 //@formatter:on
3123 // End of generated code
3124
3125 }
3126
3127 /**
3128 * Last {@link #noteOp} and {@link #startOp} events performed for a single op and a specific
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003129 * {@link Context#createAttributionContext(String) attribution} for all uidModes and opFlags.
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003130 *
3131 * @hide
3132 */
3133 @TestApi
3134 @SystemApi
3135 @Immutable
3136 // @DataClass(genHiddenConstructor = true) codegen verifier is broken
3137 @DataClass.Suppress({"getAccessEvents", "getRejectEvents", "getOp"})
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003138 public static final class AttributedOpEntry implements Parcelable {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003139 /** The code of the op */
3140 private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp;
3141 /** Whether the op is running */
3142 private final boolean mRunning;
3143 /** The access events */
3144 @DataClass.ParcelWith(LongSparseArrayParceling.class)
3145 private final @Nullable LongSparseArray<NoteOpEvent> mAccessEvents;
3146 /** The rejection events */
3147 @DataClass.ParcelWith(LongSparseArrayParceling.class)
3148 private final @Nullable LongSparseArray<NoteOpEvent> mRejectEvents;
3149
3150 /**
3151 * Returns all keys for which we have events.
3152 *
3153 * @hide
3154 */
3155 public @NonNull ArraySet<Long> collectKeys() {
3156 ArraySet<Long> keys = new ArraySet<>();
3157
3158 if (mAccessEvents != null) {
3159 int numEvents = mAccessEvents.size();
3160 for (int i = 0; i < numEvents; i++) {
3161 keys.add(mAccessEvents.keyAt(i));
3162 }
3163 }
3164
3165 if (mRejectEvents != null) {
3166 int numEvents = mRejectEvents.size();
3167 for (int i = 0; i < numEvents; i++) {
3168 keys.add(mRejectEvents.keyAt(i));
3169 }
3170 }
3171
3172 return keys;
3173 }
3174
3175 /**
3176 * Return the last access time.
3177 *
3178 * @param flags The op flags
3179 *
3180 * @return the last access time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003181 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003182 *
3183 * @see #getLastAccessForegroundTime(int)
3184 * @see #getLastAccessBackgroundTime(int)
3185 * @see #getLastAccessTime(int, int, int)
3186 * @see OpEntry#getLastAccessTime(int)
3187 */
3188 public long getLastAccessTime(@OpFlags int flags) {
3189 return getLastAccessTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
3190 }
3191
3192 /**
3193 * Return the last foreground access time.
3194 *
3195 * @param flags The op flags
3196 *
3197 * @return the last access time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003198 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no foreground access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003199 *
3200 * @see #getLastAccessTime(int)
3201 * @see #getLastAccessBackgroundTime(int)
3202 * @see #getLastAccessTime(int, int, int)
3203 * @see OpEntry#getLastAccessForegroundTime(int)
3204 */
3205 public long getLastAccessForegroundTime(@OpFlags int flags) {
3206 return getLastAccessTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
3207 flags);
3208 }
3209
3210 /**
3211 * Return the last background access time.
3212 *
3213 * @param flags The op flags
3214 *
3215 * @return the last access time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003216 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no background access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003217 *
3218 * @see #getLastAccessTime(int)
3219 * @see #getLastAccessForegroundTime(int)
3220 * @see #getLastAccessTime(int, int, int)
3221 * @see OpEntry#getLastAccessBackgroundTime(int)
3222 */
3223 public long getLastAccessBackgroundTime(@OpFlags int flags) {
3224 return getLastAccessTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
3225 flags);
3226 }
3227
3228 /**
3229 * Return the last access event.
3230 *
3231 * @param flags The op flags
3232 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003233 * @return the last access event of {@code null} if there was no access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003234 */
3235 private @Nullable NoteOpEvent getLastAccessEvent(@UidState int fromUidState,
3236 @UidState int toUidState, @OpFlags int flags) {
3237 return getLastEvent(mAccessEvents, fromUidState, toUidState, flags);
3238 }
3239
3240 /**
3241 * Return the last access time.
3242 *
3243 * @param fromUidState The lowest UID state for which to query
3244 * @param toUidState The highest UID state for which to query (inclusive)
3245 * @param flags The op flags
3246 *
3247 * @return the last access time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003248 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003249 *
3250 * @see #getLastAccessTime(int)
3251 * @see #getLastAccessForegroundTime(int)
3252 * @see #getLastAccessBackgroundTime(int)
3253 * @see OpEntry#getLastAccessTime(int, int, int)
3254 */
3255 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
3256 @OpFlags int flags) {
3257 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
3258 if (lastEvent == null) {
3259 return -1;
3260 }
3261
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003262 return lastEvent.getNoteTime();
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003263 }
3264
3265 /**
3266 * Return the last rejection time.
3267 *
3268 * @param flags The op flags
3269 *
3270 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003271 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003272 *
3273 * @see #getLastRejectForegroundTime(int)
3274 * @see #getLastRejectBackgroundTime(int)
3275 * @see #getLastRejectTime(int, int, int)
3276 * @see OpEntry#getLastRejectTime(int)
3277 */
3278 public long getLastRejectTime(@OpFlags int flags) {
3279 return getLastRejectTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
3280 }
3281
3282 /**
3283 * Return the last foreground rejection time.
3284 *
3285 * @param flags The op flags
3286 *
3287 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003288 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no foreground rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003289 *
3290 * @see #getLastRejectTime(int)
3291 * @see #getLastRejectBackgroundTime(int)
3292 * @see #getLastRejectTime(int, int, int)
3293 * @see OpEntry#getLastRejectForegroundTime(int)
3294 */
3295 public long getLastRejectForegroundTime(@OpFlags int flags) {
3296 return getLastRejectTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
3297 flags);
3298 }
3299
3300 /**
3301 * Return the last background rejection time.
3302 *
3303 * @param flags The op flags
3304 *
3305 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003306 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no background rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003307 *
3308 * @see #getLastRejectTime(int)
3309 * @see #getLastRejectForegroundTime(int)
3310 * @see #getLastRejectTime(int, int, int)
3311 * @see OpEntry#getLastRejectBackgroundTime(int)
3312 */
3313 public long getLastRejectBackgroundTime(@OpFlags int flags) {
3314 return getLastRejectTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
3315 flags);
3316 }
3317
3318 /**
3319 * Return the last background rejection event.
3320 *
3321 * @param flags The op flags
3322 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003323 * @return the last rejection event of {@code null} if there was no rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003324 *
3325 * @see #getLastRejectTime(int)
3326 * @see #getLastRejectForegroundTime(int)
3327 * @see #getLastRejectBackgroundTime(int)
3328 * @see OpEntry#getLastRejectTime(int, int, int)
3329 */
3330 private @Nullable NoteOpEvent getLastRejectEvent(@UidState int fromUidState,
3331 @UidState int toUidState, @OpFlags int flags) {
3332 return getLastEvent(mRejectEvents, fromUidState, toUidState, flags);
3333 }
3334
3335 /**
3336 * Return the last rejection time.
3337 *
3338 * @param fromUidState The lowest UID state for which to query
3339 * @param toUidState The highest UID state for which to query (inclusive)
3340 * @param flags The op flags
3341 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003342 * @return the last access time (in milliseconds since epoch) or {@code -1} if there was no
3343 * rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003344 *
3345 * @see #getLastRejectTime(int)
3346 * @see #getLastRejectForegroundTime(int)
3347 * @see #getLastRejectForegroundTime(int)
3348 * @see #getLastRejectTime(int, int, int)
3349 * @see OpEntry#getLastRejectTime(int, int, int)
3350 */
3351 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
3352 @OpFlags int flags) {
3353 NoteOpEvent lastEvent = getLastRejectEvent(fromUidState, toUidState, flags);
3354 if (lastEvent == null) {
3355 return -1;
3356 }
3357
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003358 return lastEvent.getNoteTime();
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003359 }
3360
3361 /**
3362 * Return the duration in milliseconds of the last the access.
3363 *
3364 * @param flags The op flags
3365 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003366 * @return the duration in milliseconds or {@code -1} if there was no rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003367 *
3368 * @see #getLastForegroundDuration(int)
3369 * @see #getLastBackgroundDuration(int)
3370 * @see #getLastDuration(int, int, int)
3371 * @see OpEntry#getLastDuration(int)
3372 */
3373 public long getLastDuration(@OpFlags int flags) {
3374 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
3375 }
3376
3377 /**
3378 * Return the duration in milliseconds of the last foreground access.
3379 *
3380 * @param flags The op flags
3381 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003382 * @return the duration in milliseconds or {@code -1} if there was no foreground rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003383 *
3384 * @see #getLastDuration(int)
3385 * @see #getLastBackgroundDuration(int)
3386 * @see #getLastDuration(int, int, int)
3387 * @see OpEntry#getLastForegroundDuration(int)
3388 */
3389 public long getLastForegroundDuration(@OpFlags int flags) {
3390 return getLastDuration(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
3391 flags);
3392 }
3393
3394 /**
3395 * Return the duration in milliseconds of the last background access.
3396 *
3397 * @param flags The op flags
3398 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003399 * @return the duration in milliseconds or {@code -1} if there was no background rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003400 *
3401 * @see #getLastDuration(int)
3402 * @see #getLastForegroundDuration(int)
3403 * @see #getLastDuration(int, int, int)
3404 * @see OpEntry#getLastBackgroundDuration(int)
3405 */
3406 public long getLastBackgroundDuration(@OpFlags int flags) {
3407 return getLastDuration(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
3408 flags);
3409 }
3410
3411 /**
3412 * Return the duration in milliseconds of the last access.
3413 *
3414 * @param fromUidState The lowest UID state for which to query
3415 * @param toUidState The highest UID state for which to query (inclusive)
3416 * @param flags The op flags
3417 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003418 * @return the duration in milliseconds or {@code -1} if there was no rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003419 *
3420 * @see #getLastDuration(int)
3421 * @see #getLastForegroundDuration(int)
3422 * @see #getLastBackgroundDuration(int)
3423 * @see #getLastDuration(int, int, int)
3424 * @see OpEntry#getLastDuration(int, int, int)
3425 */
3426 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
3427 @OpFlags int flags) {
3428 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);;
3429 if (lastEvent == null) {
3430 return -1;
3431 }
3432
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003433 return lastEvent.getDuration();
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003434 }
3435
3436 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003437 * Gets the proxy info of the app that performed the last access on behalf of this
3438 * attribution and as a result blamed the op on this attribution.
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003439 *
3440 * @param flags The op flags
3441 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003442 * @return The proxy info or {@code null} if there was no proxy access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003443 *
3444 * @see #getLastForegroundProxyInfo(int)
3445 * @see #getLastBackgroundProxyInfo(int)
3446 * @see #getLastProxyInfo(int, int, int)
3447 * @see OpEntry#getLastProxyInfo(int)
3448 */
3449 public @Nullable OpEventProxyInfo getLastProxyInfo(@OpFlags int flags) {
3450 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
3451 }
3452
3453 /**
3454 * Gets the proxy info of the app that performed the last foreground access on behalf of
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003455 * this attribution and as a result blamed the op on this attribution.
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003456 *
3457 * @param flags The op flags
3458 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003459 * @return The proxy info or {@code null} if there was no proxy access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003460 *
3461 * @see #getLastProxyInfo(int)
3462 * @see #getLastBackgroundProxyInfo(int)
3463 * @see #getLastProxyInfo(int, int, int)
3464 * @see OpEntry#getLastForegroundProxyInfo(int)
3465 */
3466 public @Nullable OpEventProxyInfo getLastForegroundProxyInfo(@OpFlags int flags) {
3467 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
3468 flags);
3469 }
3470
3471 /**
3472 * Gets the proxy info of the app that performed the last background access on behalf of
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003473 * this attribution and as a result blamed the op on this attribution.
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003474 *
3475 * @param flags The op flags
3476 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003477 * @return The proxy info or {@code null} if there was no proxy background access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003478 *
3479 * @see #getLastProxyInfo(int)
3480 * @see #getLastForegroundProxyInfo(int)
3481 * @see #getLastProxyInfo(int, int, int)
3482 * @see OpEntry#getLastBackgroundProxyInfo(int)
3483 */
3484 public @Nullable OpEventProxyInfo getLastBackgroundProxyInfo(@OpFlags int flags) {
3485 return getLastProxyInfo(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
3486 flags);
3487 }
3488
3489 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003490 * Gets the proxy info of the app that performed the last access on behalf of this
3491 * attribution and as a result blamed the op on this attribution.
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003492 *
3493 * @param fromUidState The lowest UID state for which to query
3494 * @param toUidState The highest UID state for which to query (inclusive)
3495 * @param flags The op flags
3496 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003497 * @return The proxy info or {@code null} if there was no proxy foreground access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003498 *
3499 * @see #getLastProxyInfo(int)
3500 * @see #getLastForegroundProxyInfo(int)
3501 * @see #getLastBackgroundProxyInfo(int)
3502 * @see OpEntry#getLastProxyInfo(int, int, int)
3503 */
3504 public @Nullable OpEventProxyInfo getLastProxyInfo(@UidState int fromUidState,
3505 @UidState int toUidState, @OpFlags int flags) {
3506 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
3507 if (lastEvent == null) {
3508 return null;
3509 }
3510
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003511 return lastEvent.getProxy();
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003512 }
3513
3514 private static class LongSparseArrayParceling implements
3515 Parcelling<LongSparseArray<NoteOpEvent>> {
3516 @Override
3517 public void parcel(@Nullable LongSparseArray<NoteOpEvent> array, @NonNull Parcel dest,
3518 int parcelFlags) {
3519 if (array == null) {
3520 dest.writeInt(-1);
3521 return;
3522 }
3523
3524 int numEntries = array.size();
3525 dest.writeInt(numEntries);
3526
3527 for (int i = 0; i < numEntries; i++) {
3528 dest.writeLong(array.keyAt(i));
3529 dest.writeParcelable(array.valueAt(i), parcelFlags);
3530 }
3531 }
3532
3533 @Override
3534 public @Nullable LongSparseArray<NoteOpEvent> unparcel(@NonNull Parcel source) {
3535 int numEntries = source.readInt();
3536 if (numEntries == -1) {
3537 return null;
3538 }
3539
3540 LongSparseArray<NoteOpEvent> array = new LongSparseArray<>(numEntries);
3541
3542 for (int i = 0; i < numEntries; i++) {
3543 array.put(source.readLong(), source.readParcelable(null));
3544 }
3545
3546 return array;
3547 }
3548 }
3549
3550
3551
3552 // Code below generated by codegen v1.0.14.
3553 //
3554 // DO NOT MODIFY!
3555 // CHECKSTYLE:OFF Generated code
3556 //
3557 // To regenerate run:
3558 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
3559 //
3560 // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
3561 // Settings > Editor > Code Style > Formatter Control
3562 //@formatter:off
3563
3564
3565 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003566 * Creates a new OpAttributionEntry.
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003567 *
3568 * @param op
3569 * The code of the op
3570 * @param running
3571 * Whether the op is running
3572 * @param accessEvents
3573 * The access events
3574 * @param rejectEvents
3575 * The rejection events
3576 * @hide
3577 */
3578 @DataClass.Generated.Member
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003579 public AttributedOpEntry(
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003580 @IntRange(from = 0, to = _NUM_OP - 1) int op,
3581 boolean running,
3582 @Nullable LongSparseArray<NoteOpEvent> accessEvents,
3583 @Nullable LongSparseArray<NoteOpEvent> rejectEvents) {
3584 this.mOp = op;
3585 com.android.internal.util.AnnotationValidations.validate(
3586 IntRange.class, null, mOp,
3587 "from", 0,
3588 "to", _NUM_OP - 1);
3589 this.mRunning = running;
3590 this.mAccessEvents = accessEvents;
3591 this.mRejectEvents = rejectEvents;
3592
3593 // onConstructed(); // You can define this method to get a callback
3594 }
3595
3596 /**
3597 * Whether the op is running
3598 */
3599 @DataClass.Generated.Member
3600 public boolean isRunning() {
3601 return mRunning;
3602 }
3603
3604 @DataClass.Generated.Member
3605 static Parcelling<LongSparseArray<NoteOpEvent>> sParcellingForAccessEvents =
3606 Parcelling.Cache.get(
3607 LongSparseArrayParceling.class);
3608 static {
3609 if (sParcellingForAccessEvents == null) {
3610 sParcellingForAccessEvents = Parcelling.Cache.put(
3611 new LongSparseArrayParceling());
3612 }
3613 }
3614
3615 @DataClass.Generated.Member
3616 static Parcelling<LongSparseArray<NoteOpEvent>> sParcellingForRejectEvents =
3617 Parcelling.Cache.get(
3618 LongSparseArrayParceling.class);
3619 static {
3620 if (sParcellingForRejectEvents == null) {
3621 sParcellingForRejectEvents = Parcelling.Cache.put(
3622 new LongSparseArrayParceling());
3623 }
3624 }
3625
3626 @Override
3627 @DataClass.Generated.Member
3628 public void writeToParcel(@NonNull Parcel dest, int flags) {
3629 // You can override field parcelling by defining methods like:
3630 // void parcelFieldName(Parcel dest, int flags) { ... }
3631
3632 byte flg = 0;
3633 if (mRunning) flg |= 0x2;
3634 if (mAccessEvents != null) flg |= 0x4;
3635 if (mRejectEvents != null) flg |= 0x8;
3636 dest.writeByte(flg);
3637 dest.writeInt(mOp);
3638 sParcellingForAccessEvents.parcel(mAccessEvents, dest, flags);
3639 sParcellingForRejectEvents.parcel(mRejectEvents, dest, flags);
3640 }
3641
3642 @Override
3643 @DataClass.Generated.Member
3644 public int describeContents() { return 0; }
3645
3646 /** @hide */
3647 @SuppressWarnings({"unchecked", "RedundantCast"})
3648 @DataClass.Generated.Member
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003649 /* package-private */ AttributedOpEntry(@NonNull Parcel in) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003650 // You can override field unparcelling by defining methods like:
3651 // static FieldType unparcelFieldName(Parcel in) { ... }
3652
3653 byte flg = in.readByte();
3654 boolean running = (flg & 0x2) != 0;
3655 int op = in.readInt();
3656 LongSparseArray<NoteOpEvent> accessEvents = sParcellingForAccessEvents.unparcel(in);
3657 LongSparseArray<NoteOpEvent> rejectEvents = sParcellingForRejectEvents.unparcel(in);
3658
3659 this.mOp = op;
3660 com.android.internal.util.AnnotationValidations.validate(
3661 IntRange.class, null, mOp,
3662 "from", 0,
3663 "to", _NUM_OP - 1);
3664 this.mRunning = running;
3665 this.mAccessEvents = accessEvents;
3666 this.mRejectEvents = rejectEvents;
3667
3668 // onConstructed(); // You can define this method to get a callback
3669 }
3670
3671 @DataClass.Generated.Member
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003672 public static final @NonNull Parcelable.Creator<AttributedOpEntry> CREATOR
3673 = new Parcelable.Creator<AttributedOpEntry>() {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003674 @Override
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003675 public AttributedOpEntry[] newArray(int size) {
3676 return new AttributedOpEntry[size];
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003677 }
3678
3679 @Override
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003680 public AttributedOpEntry createFromParcel(@NonNull Parcel in) {
3681 return new AttributedOpEntry(in);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003682 }
3683 };
3684
3685 /*
3686 @DataClass.Generated(
3687 time = 1574809856239L,
3688 codegenVersion = "1.0.14",
3689 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003690 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.OpAttributionEntry.LongSparseArrayParceling.class) @android.annotation.Nullable android.util.LongSparseArray<android.app.NoteOpEvent> mAccessEvents\nprivate final @com.android.internal.util.DataClass.ParcelWith(android.app.OpAttributionEntry.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 getProxyAttributionTag(int,int)\nclass OpAttributionEntry extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003691 @Deprecated
3692 private void __metadata() {}
3693 */
3694
3695
3696 //@formatter:on
3697 // End of generated code
3698
3699 }
3700
3701 /**
3702 * Last {@link #noteOp} and {@link #startOp} events performed for a single op for all uidModes
3703 * and opFlags.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003704 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07003705 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08003706 */
Svet Ganovaf189e32019-02-15 18:45:29 -08003707 @TestApi
3708 @Immutable
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07003709 @SystemApi
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003710 // @DataClass(genHiddenConstructor = true) codegen verifier is broken
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003711 public static final class OpEntry implements Parcelable {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003712 /** The code of the op */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003713 private final @IntRange(from = 0, to = _NUM_OP - 1) int mOp;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003714 /** The mode of the op */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003715 private final @Mode int mMode;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003716 /** The attributed entries by attribution tag */
3717 private final @NonNull Map<String, AttributedOpEntry> mAttributedOpEntries;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003718
3719 /**
3720 * @hide
3721 */
Philip P. Moltmannac443502020-05-11 13:15:12 -07003722 @UnsupportedAppUsage(/*maxTargetSdk = Build.VERSION_CODES.R,*/ publicAlternatives = "{@code "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003723 + "#getOpStr()}")
3724 public int getOp() {
3725 return mOp;
3726 }
3727
3728 /**
3729 * @return This entry's op string name, such as {@link #OPSTR_COARSE_LOCATION}.
3730 */
3731 public @NonNull String getOpStr() {
3732 return sOpToString[mOp];
3733 }
3734
3735 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003736 * @hide
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003737 *
3738 * @deprecated Use {@link #getLastAccessTime(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003739 */
3740 @Deprecated
Philip P. Moltmannac443502020-05-11 13:15:12 -07003741 @UnsupportedAppUsage(/*maxTargetSdk = Build.VERSION_CODES.R,*/ publicAlternatives = "{@code "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003742 + "#getLastAccessTime(int)}")
3743 public long getTime() {
3744 return getLastAccessTime(OP_FLAGS_ALL);
3745 }
3746
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003747 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003748 * Return the last access time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003749 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003750 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003751 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003752 * @return the last access time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003753 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no access
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003754 *
3755 * @see #getLastAccessForegroundTime(int)
3756 * @see #getLastAccessBackgroundTime(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003757 * @see #getLastAccessTime(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003758 * @see AttributedOpEntry#getLastAccessTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003759 */
3760 public long getLastAccessTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003761 return getLastAccessTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003762 }
3763
3764 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003765 * Return the last foreground access time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003766 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003767 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003768 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003769 * @return the last access time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003770 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no foreground access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003771 *
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003772 * @see #getLastAccessTime(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003773 * @see #getLastAccessBackgroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003774 * @see #getLastAccessTime(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003775 * @see AttributedOpEntry#getLastAccessForegroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003776 */
3777 public long getLastAccessForegroundTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003778 return getLastAccessTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
3779 flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003780 }
3781
3782 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003783 * Return the last background access time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003784 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003785 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003786 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003787 * @return the last access time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003788 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no background access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003789 *
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003790 * @see #getLastAccessTime(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003791 * @see #getLastAccessForegroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003792 * @see #getLastAccessTime(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003793 * @see AttributedOpEntry#getLastAccessBackgroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003794 */
3795 public long getLastAccessBackgroundTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003796 return getLastAccessTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
3797 flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003798 }
3799
3800 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003801 * Return the last access event.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003802 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003803 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003804 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003805 * @return the last access event of {@code null} if there was no access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003806 */
3807 private @Nullable NoteOpEvent getLastAccessEvent(@UidState int fromUidState,
3808 @UidState int toUidState, @OpFlags int flags) {
3809 NoteOpEvent lastAccessEvent = null;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003810 for (AttributedOpEntry attributionEntry : mAttributedOpEntries.values()) {
3811 NoteOpEvent lastAttributionAccessEvent = attributionEntry.getLastAccessEvent(
3812 fromUidState, toUidState, flags);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003813
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003814 if (lastAccessEvent == null || (lastAttributionAccessEvent != null
3815 && lastAttributionAccessEvent.getNoteTime()
3816 > lastAccessEvent.getNoteTime())) {
3817 lastAccessEvent = lastAttributionAccessEvent;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003818 }
3819 }
3820
3821 return lastAccessEvent;
3822 }
3823
3824 /**
3825 * Return the last access time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003826 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003827 * @param fromUidState the lowest uid state to query
3828 * @param toUidState the highest uid state to query (inclusive)
3829 * @param flags The op flags
3830 *
3831 * @return the last access time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003832 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003833 *
3834 * @see #getLastAccessTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003835 * @see #getLastAccessForegroundTime(int)
3836 * @see #getLastAccessBackgroundTime(int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003837 * @see AttributedOpEntry#getLastAccessTime(int, int, int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003838 */
3839 public long getLastAccessTime(@UidState int fromUidState, @UidState int toUidState,
3840 @OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003841 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);;
3842
3843 if (lastEvent == null) {
3844 return -1;
3845 }
3846
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003847 return lastEvent.getNoteTime();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003848 }
3849
3850 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003851 * @hide
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003852 *
3853 * @deprecated Use {@link #getLastRejectTime(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003854 */
3855 @Deprecated
Philip P. Moltmannac443502020-05-11 13:15:12 -07003856 @UnsupportedAppUsage(/*maxTargetSdk = Build.VERSION_CODES.R,*/ publicAlternatives = "{@code "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003857 + "#getLastRejectTime(int)}")
3858 public long getRejectTime() {
3859 return getLastRejectTime(OP_FLAGS_ALL);
3860 }
3861
3862 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003863 * Return the last rejection time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003864 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003865 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003866 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003867 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003868 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003869 *
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003870 * @see #getLastRejectForegroundTime(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003871 * @see #getLastRejectBackgroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003872 * @see #getLastRejectTime(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003873 * @see AttributedOpEntry#getLastRejectTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003874 */
3875 public long getLastRejectTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003876 return getLastRejectTime(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003877 }
3878
3879 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003880 * Return the last foreground rejection time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003881 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003882 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003883 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003884 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003885 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no foreground rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003886 *
3887 * @see #getLastRejectTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003888 * @see #getLastRejectBackgroundTime(int)
3889 * @see #getLastRejectTime(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003890 * @see AttributedOpEntry#getLastRejectForegroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003891 */
3892 public long getLastRejectForegroundTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003893 return getLastRejectTime(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
3894 flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003895 }
3896
3897 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003898 * Return the last background rejection time.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003899 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003900 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003901 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003902 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003903 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no background rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003904 *
3905 * @see #getLastRejectTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003906 * @see #getLastRejectForegroundTime(int)
3907 * @see #getLastRejectTime(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003908 * @see AttributedOpEntry#getLastRejectBackgroundTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003909 */
3910 public long getLastRejectBackgroundTime(@OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003911 return getLastRejectTime(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
3912 flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003913 }
3914
3915 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003916 * Return the last rejection event.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003917 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003918 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003919 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003920 * @return the last reject event of {@code null} if there was no rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003921 */
3922 private @Nullable NoteOpEvent getLastRejectEvent(@UidState int fromUidState,
3923 @UidState int toUidState, @OpFlags int flags) {
3924 NoteOpEvent lastAccessEvent = null;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003925 for (AttributedOpEntry attributionEntry : mAttributedOpEntries.values()) {
3926 NoteOpEvent lastAttributionAccessEvent = attributionEntry.getLastRejectEvent(
3927 fromUidState, toUidState, flags);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003928
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003929 if (lastAccessEvent == null || (lastAttributionAccessEvent != null
3930 && lastAttributionAccessEvent.getNoteTime()
3931 > lastAccessEvent.getNoteTime())) {
3932 lastAccessEvent = lastAttributionAccessEvent;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003933 }
3934 }
3935
3936 return lastAccessEvent;
3937 }
3938
3939 /**
3940 * Return the last rejection time.
3941 *
3942 * @param fromUidState the lowest uid state to query
3943 * @param toUidState the highest uid state to query (inclusive)
3944 * @param flags The op flags
3945 *
3946 * @return the last rejection time (in milliseconds since epoch start (January 1, 1970
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003947 * 00:00:00.000 GMT - Gregorian)) or {@code -1} if there was no rejection
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003948 *
3949 * @see #getLastRejectTime(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003950 * @see #getLastRejectForegroundTime(int)
3951 * @see #getLastRejectBackgroundTime(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003952 * @see #getLastRejectTime(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003953 * @see AttributedOpEntry#getLastRejectTime(int, int, int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003954 */
3955 public long getLastRejectTime(@UidState int fromUidState, @UidState int toUidState,
3956 @OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003957 NoteOpEvent lastEvent = getLastRejectEvent(fromUidState, toUidState, flags);
3958 if (lastEvent == null) {
3959 return -1;
3960 }
3961
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08003962 return lastEvent.getNoteTime();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003963 }
3964
3965 /**
3966 * @return Whether the operation is running.
3967 */
3968 public boolean isRunning() {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003969 for (AttributedOpEntry opAttributionEntry : mAttributedOpEntries.values()) {
3970 if (opAttributionEntry.isRunning()) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003971 return true;
3972 }
3973 }
3974
3975 return false;
3976 }
3977
3978 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003979 * @deprecated Use {@link #getLastDuration(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003980 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003981 @Deprecated
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003982 public long getDuration() {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003983 return getLastDuration(OP_FLAGS_ALL);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003984 }
3985
3986 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003987 * Return the duration in milliseconds of the last the access.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003988 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003989 * @param flags The op flags
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003990 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08003991 * @return the duration in milliseconds or {@code -1} if there was no access
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003992 *
3993 * @see #getLastForegroundDuration(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003994 * @see #getLastBackgroundDuration(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003995 * @see #getLastDuration(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08003996 * @see AttributedOpEntry#getLastDuration(int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07003997 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08003998 public long getLastDuration(@OpFlags int flags) {
3999 return getLastDuration(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004000 }
4001
4002 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004003 * Return the duration in milliseconds of the last foreground access.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004004 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004005 * @param flags The op flags
4006 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08004007 * @return the duration in milliseconds or {@code -1} if there was no foreground access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004008 *
4009 * @see #getLastDuration(int)
4010 * @see #getLastBackgroundDuration(int)
4011 * @see #getLastDuration(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004012 * @see AttributedOpEntry#getLastForegroundDuration(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004013 */
4014 public long getLastForegroundDuration(@OpFlags int flags) {
4015 return getLastDuration(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
4016 flags);
4017 }
4018
4019 /**
4020 * Return the duration in milliseconds of the last background access.
4021 *
4022 * @param flags The op flags
4023 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08004024 * @return the duration in milliseconds or {@code -1} if there was no background access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004025 *
4026 * @see #getLastDuration(int)
4027 * @see #getLastForegroundDuration(int)
4028 * @see #getLastDuration(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004029 * @see AttributedOpEntry#getLastBackgroundDuration(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004030 */
4031 public long getLastBackgroundDuration(@OpFlags int flags) {
4032 return getLastDuration(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
4033 flags);
4034 }
4035
4036 /**
4037 * Return the duration in milliseconds of the last access.
4038 *
4039 * @param fromUidState The lowest UID state for which to query
4040 * @param toUidState The highest UID state for which to query (inclusive)
4041 * @param flags The op flags
4042 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08004043 * @return the duration in milliseconds or {@code -1} if there was no access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004044 *
4045 * @see #getLastDuration(int)
4046 * @see #getLastForegroundDuration(int)
4047 * @see #getLastBackgroundDuration(int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004048 * @see AttributedOpEntry#getLastDuration(int, int, int)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004049 */
4050 public long getLastDuration(@UidState int fromUidState, @UidState int toUidState,
4051 @OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004052 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
4053 if (lastEvent == null) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004054 return -1;
4055 }
4056
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08004057 return lastEvent.getDuration();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004058 }
4059
4060 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004061 * @deprecated Use {@link #getLastProxyInfo(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004062 */
4063 @Deprecated
4064 public int getProxyUid() {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004065 OpEventProxyInfo proxy = getLastProxyInfo(OP_FLAGS_ALL);
4066 if (proxy == null) {
4067 return Process.INVALID_UID;
4068 }
4069
4070 return proxy.getUid();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004071 }
4072
4073 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004074 * @deprecated Use {@link #getLastProxyInfo(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004075 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004076 @Deprecated
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004077 public int getProxyUid(@UidState int uidState, @OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004078 OpEventProxyInfo proxy = getLastProxyInfo(uidState, uidState, flags);
4079 if (proxy == null) {
4080 return Process.INVALID_UID;
4081 }
4082
4083 return proxy.getUid();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004084 }
4085
4086 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004087 * @deprecated Use {@link #getLastProxyInfo(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004088 */
4089 @Deprecated
4090 public @Nullable String getProxyPackageName() {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004091 OpEventProxyInfo proxy = getLastProxyInfo(OP_FLAGS_ALL);
4092 if (proxy == null) {
4093 return null;
4094 }
4095
4096 return proxy.getPackageName();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004097 }
4098
4099 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004100 * @deprecated Use {@link #getLastProxyInfo(int)} instead
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004101 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004102 @Deprecated
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004103 public @Nullable String getProxyPackageName(@UidState int uidState, @OpFlags int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004104 OpEventProxyInfo proxy = getLastProxyInfo(uidState, uidState, flags);
4105 if (proxy == null) {
4106 return null;
4107 }
4108
4109 return proxy.getPackageName();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004110 }
4111
4112 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004113 * Gets the proxy info of the app that performed the last access on behalf of this app and
4114 * as a result blamed the op on this app.
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004115 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004116 * @param flags The op flags
4117 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08004118 * @return The proxy info or {@code null} if there was no proxy access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004119 *
4120 * @see #getLastForegroundProxyInfo(int)
4121 * @see #getLastBackgroundProxyInfo(int)
4122 * @see #getLastProxyInfo(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004123 * @see AttributedOpEntry#getLastProxyInfo(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004124 */
4125 public @Nullable OpEventProxyInfo getLastProxyInfo(@OpFlags int flags) {
4126 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, MIN_PRIORITY_UID_STATE, flags);
4127 }
4128
4129 /**
4130 * Gets the proxy info of the app that performed the last foreground access on behalf of
4131 * this app and as a result blamed the op on this app.
4132 *
4133 * @param flags The op flags
4134 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08004135 * @return The proxy info or {@code null} if there was no foreground proxy access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004136 *
4137 * @see #getLastProxyInfo(int)
4138 * @see #getLastBackgroundProxyInfo(int)
4139 * @see #getLastProxyInfo(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004140 * @see AttributedOpEntry#getLastForegroundProxyInfo(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004141 */
4142 public @Nullable OpEventProxyInfo getLastForegroundProxyInfo(@OpFlags int flags) {
4143 return getLastProxyInfo(MAX_PRIORITY_UID_STATE, resolveFirstUnrestrictedUidState(mOp),
4144 flags);
4145 }
4146
4147 /**
4148 * Gets the proxy info of the app that performed the last background access on behalf of
4149 * this app and as a result blamed the op on this app.
4150 *
4151 * @param flags The op flags
4152 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08004153 * @return The proxy info or {@code null} if there was no background proxy access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004154 *
4155 * @see #getLastProxyInfo(int)
4156 * @see #getLastForegroundProxyInfo(int)
4157 * @see #getLastProxyInfo(int, int, int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004158 * @see AttributedOpEntry#getLastBackgroundProxyInfo(int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004159 */
4160 public @Nullable OpEventProxyInfo getLastBackgroundProxyInfo(@OpFlags int flags) {
4161 return getLastProxyInfo(resolveLastRestrictedUidState(mOp), MIN_PRIORITY_UID_STATE,
4162 flags);
4163 }
4164
4165 /**
4166 * Gets the proxy info of the app that performed the last access on behalf of this app and
4167 * as a result blamed the op on this app.
4168 *
4169 * @param fromUidState The lowest UID state for which to query
4170 * @param toUidState The highest UID state for which to query (inclusive)
4171 * @param flags The op flags
4172 *
Philip P. Moltmann7c0524f2020-02-06 09:21:31 -08004173 * @return The proxy info or {@code null} if there was no proxy access
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004174 *
4175 * @see #getLastProxyInfo(int)
4176 * @see #getLastForegroundProxyInfo(int)
4177 * @see #getLastBackgroundProxyInfo(int)
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004178 * @see AttributedOpEntry#getLastProxyInfo(int, int, int)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004179 */
4180 public @Nullable OpEventProxyInfo getLastProxyInfo(@UidState int fromUidState,
4181 @UidState int toUidState, @OpFlags int flags) {
4182 NoteOpEvent lastEvent = getLastAccessEvent(fromUidState, toUidState, flags);
4183 if (lastEvent == null) {
4184 return null;
4185 }
4186
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08004187 return lastEvent.getProxy();
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004188 }
4189
4190
4191
4192 // Code below generated by codegen v1.0.14.
4193 //
4194 // DO NOT MODIFY!
4195 // CHECKSTYLE:OFF Generated code
4196 //
4197 // To regenerate run:
4198 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
4199 //
4200 // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
4201 // Settings > Editor > Code Style > Formatter Control
4202 //@formatter:off
4203
4204
4205 /**
4206 * Creates a new OpEntry.
4207 *
4208 * @param op
4209 * The code of the op
4210 * @param mode
4211 * The mode of the op
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004212 * @param attributedOpEntries
4213 * The attributions that have been used when noting the op
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004214 * @hide
4215 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004216 @DataClass.Generated.Member
4217 public OpEntry(
4218 @IntRange(from = 0, to = _NUM_OP - 1) int op,
4219 @Mode int mode,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004220 @NonNull Map<String, AttributedOpEntry> attributedOpEntries) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004221 this.mOp = op;
4222 com.android.internal.util.AnnotationValidations.validate(
4223 IntRange.class, null, mOp,
4224 "from", 0,
4225 "to", _NUM_OP - 1);
4226 this.mMode = mode;
4227 com.android.internal.util.AnnotationValidations.validate(
4228 Mode.class, null, mMode);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004229 this.mAttributedOpEntries = attributedOpEntries;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004230 com.android.internal.util.AnnotationValidations.validate(
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004231 NonNull.class, null, mAttributedOpEntries);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004232
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004233 // onConstructed(); // You can define this method to get a callback
4234 }
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004235
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004236 /**
4237 * The mode of the op
4238 */
4239 @DataClass.Generated.Member
4240 public @Mode int getMode() {
4241 return mMode;
4242 }
4243
4244 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004245 * The attributed entries keyed by attribution tag.
Philip P. Moltmann3f9ee362020-02-06 09:32:28 -08004246 *
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004247 * @see Context#createAttributionContext(String)
Philip P. Moltmann3f9ee362020-02-06 09:32:28 -08004248 * @see #noteOp(String, int, String, String, String)
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004249 */
4250 @DataClass.Generated.Member
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004251 public @NonNull Map<String, AttributedOpEntry> getAttributedOpEntries() {
4252 return mAttributedOpEntries;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004253 }
4254
Dianne Hackborn35654b62013-01-14 17:38:02 -08004255 @Override
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004256 @DataClass.Generated.Member
Dianne Hackborn35654b62013-01-14 17:38:02 -08004257 public void writeToParcel(Parcel dest, int flags) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004258 // You can override field parcelling by defining methods like:
4259 // void parcelFieldName(Parcel dest, int flags) { ... }
4260
Dianne Hackborn35654b62013-01-14 17:38:02 -08004261 dest.writeInt(mOp);
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08004262 dest.writeInt(mMode);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004263 dest.writeMap(mAttributedOpEntries);
Dianne Hackborn35654b62013-01-14 17:38:02 -08004264 }
4265
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004266 @Override
4267 @DataClass.Generated.Member
4268 public int describeContents() { return 0; }
4269
4270 /** @hide */
4271 @SuppressWarnings({"unchecked", "RedundantCast"})
4272 @DataClass.Generated.Member
4273 /* package-private */ OpEntry(@NonNull Parcel in) {
4274 // You can override field unparcelling by defining methods like:
4275 // static FieldType unparcelFieldName(Parcel in) { ... }
4276
4277 int op = in.readInt();
4278 int mode = in.readInt();
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004279 Map<String, AttributedOpEntry> attributions = new java.util.LinkedHashMap<>();
4280 in.readMap(attributions, AttributedOpEntry.class.getClassLoader());
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004281
4282 this.mOp = op;
4283 com.android.internal.util.AnnotationValidations.validate(
4284 IntRange.class, null, mOp,
4285 "from", 0,
4286 "to", _NUM_OP - 1);
4287 this.mMode = mode;
4288 com.android.internal.util.AnnotationValidations.validate(
4289 Mode.class, null, mMode);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004290 this.mAttributedOpEntries = attributions;
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004291 com.android.internal.util.AnnotationValidations.validate(
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004292 NonNull.class, null, mAttributedOpEntries);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004293
4294 // onConstructed(); // You can define this method to get a callback
4295 }
4296
4297 @DataClass.Generated.Member
4298 public static final @NonNull Parcelable.Creator<OpEntry> CREATOR
4299 = new Parcelable.Creator<OpEntry>() {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004300 @Override
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004301 public OpEntry[] newArray(int size) {
4302 return new OpEntry[size];
Dianne Hackborn35654b62013-01-14 17:38:02 -08004303 }
4304
Philip P. Moltmann59076d82019-08-19 15:00:40 -07004305 @Override
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004306 public OpEntry createFromParcel(@NonNull Parcel in) {
4307 return new OpEntry(in);
Dianne Hackborn35654b62013-01-14 17:38:02 -08004308 }
4309 };
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004310
4311 /*
4312 @DataClass.Generated(
4313 time = 1574809856259L,
4314 codegenVersion = "1.0.14",
4315 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004316 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.OpAttributionEntry> mAttributions\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 getLastAccessUidStateForFlagsInStatesOfAllAttributions(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 getLastRejectUidStateForFlagsInStatesOfAllAttributions(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)")
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08004317 @Deprecated
4318 private void __metadata() {}
4319 */
4320
4321
4322 //@formatter:on
4323 // End of generated code
4324
Dianne Hackborn35654b62013-01-14 17:38:02 -08004325 }
4326
Svet Ganov8455ba22019-01-02 13:05:56 -08004327 /** @hide */
4328 public interface HistoricalOpsVisitor {
4329 void visitHistoricalOps(@NonNull HistoricalOps ops);
4330 void visitHistoricalUidOps(@NonNull HistoricalUidOps ops);
4331 void visitHistoricalPackageOps(@NonNull HistoricalPackageOps ops);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004332 void visitHistoricalAttributionOps(@NonNull AttributedHistoricalOps ops);
Svet Ganov8455ba22019-01-02 13:05:56 -08004333 void visitHistoricalOp(@NonNull HistoricalOp ops);
4334 }
4335
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08004336 /**
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004337 * Specifies what parameters to filter historical appop requests for
4338 *
4339 * @hide
4340 */
4341 @Retention(RetentionPolicy.SOURCE)
4342 @IntDef(flag = true, prefix = { "FILTER_BY_" }, value = {
4343 FILTER_BY_UID,
4344 FILTER_BY_PACKAGE_NAME,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004345 FILTER_BY_ATTRIBUTION_TAG,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004346 FILTER_BY_OP_NAMES
4347 })
4348 public @interface HistoricalOpsRequestFilter {}
4349
4350 /**
4351 * Filter historical appop request by uid.
4352 *
4353 * @hide
4354 */
4355 public static final int FILTER_BY_UID = 1<<0;
4356
4357 /**
4358 * Filter historical appop request by package name.
4359 *
4360 * @hide
4361 */
4362 public static final int FILTER_BY_PACKAGE_NAME = 1<<1;
4363
4364 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004365 * Filter historical appop request by attribution tag.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004366 *
4367 * @hide
4368 */
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004369 public static final int FILTER_BY_ATTRIBUTION_TAG = 1<<2;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004370
4371 /**
4372 * Filter historical appop request by op names.
4373 *
4374 * @hide
4375 */
4376 public static final int FILTER_BY_OP_NAMES = 1<<3;
4377
4378 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08004379 * Request for getting historical app op usage. The request acts
4380 * as a filtering criteria when querying historical op usage.
4381 *
4382 * @hide
4383 */
4384 @Immutable
4385 @TestApi
4386 @SystemApi
4387 public static final class HistoricalOpsRequest {
4388 private final int mUid;
4389 private final @Nullable String mPackageName;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004390 private final @Nullable String mAttributionTag;
Svet Ganov23c88db2019-01-22 20:38:11 -08004391 private final @Nullable List<String> mOpNames;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004392 private final @HistoricalOpsRequestFilter int mFilter;
Svet Ganov23c88db2019-01-22 20:38:11 -08004393 private final long mBeginTimeMillis;
4394 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08004395 private final @OpFlags int mFlags;
Svet Ganov23c88db2019-01-22 20:38:11 -08004396
4397 private HistoricalOpsRequest(int uid, @Nullable String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004398 @Nullable String attributionTag, @Nullable List<String> opNames,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004399 @HistoricalOpsRequestFilter int filter, long beginTimeMillis,
4400 long endTimeMillis, @OpFlags int flags) {
Svet Ganov23c88db2019-01-22 20:38:11 -08004401 mUid = uid;
4402 mPackageName = packageName;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004403 mAttributionTag = attributionTag;
Svet Ganov23c88db2019-01-22 20:38:11 -08004404 mOpNames = opNames;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004405 mFilter = filter;
Svet Ganov23c88db2019-01-22 20:38:11 -08004406 mBeginTimeMillis = beginTimeMillis;
4407 mEndTimeMillis = endTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08004408 mFlags = flags;
Svet Ganov23c88db2019-01-22 20:38:11 -08004409 }
4410
4411 /**
4412 * Builder for creating a {@link HistoricalOpsRequest}.
4413 *
4414 * @hide
4415 */
4416 @TestApi
4417 @SystemApi
4418 public static final class Builder {
4419 private int mUid = Process.INVALID_UID;
4420 private @Nullable String mPackageName;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004421 private @Nullable String mAttributionTag;
Svet Ganov23c88db2019-01-22 20:38:11 -08004422 private @Nullable List<String> mOpNames;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004423 private @HistoricalOpsRequestFilter int mFilter;
Svet Ganov23c88db2019-01-22 20:38:11 -08004424 private final long mBeginTimeMillis;
4425 private final long mEndTimeMillis;
Svet Ganovaf189e32019-02-15 18:45:29 -08004426 private @OpFlags int mFlags = OP_FLAGS_ALL;
Svet Ganov23c88db2019-01-22 20:38:11 -08004427
4428 /**
4429 * Creates a new builder.
4430 *
4431 * @param beginTimeMillis The beginning of the interval in milliseconds since
4432 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be non
4433 * negative.
4434 * @param endTimeMillis The end of the interval in milliseconds since
4435 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian). Must be after
4436 * {@code beginTimeMillis}. Pass {@link Long#MAX_VALUE} to get the most recent
4437 * history including ops that happen while this call is in flight.
4438 */
4439 public Builder(long beginTimeMillis, long endTimeMillis) {
4440 Preconditions.checkArgument(beginTimeMillis >= 0 && beginTimeMillis < endTimeMillis,
4441 "beginTimeMillis must be non negative and lesser than endTimeMillis");
4442 mBeginTimeMillis = beginTimeMillis;
4443 mEndTimeMillis = endTimeMillis;
4444 }
4445
4446 /**
4447 * Sets the UID to query for.
4448 *
4449 * @param uid The uid. Pass {@link android.os.Process#INVALID_UID} for any uid.
4450 * @return This builder.
4451 */
4452 public @NonNull Builder setUid(int uid) {
4453 Preconditions.checkArgument(uid == Process.INVALID_UID || uid >= 0,
4454 "uid must be " + Process.INVALID_UID + " or non negative");
4455 mUid = uid;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004456
4457 if (uid == Process.INVALID_UID) {
4458 mFilter &= ~FILTER_BY_UID;
4459 } else {
4460 mFilter |= FILTER_BY_UID;
4461 }
4462
Svet Ganov23c88db2019-01-22 20:38:11 -08004463 return this;
4464 }
4465
4466 /**
4467 * Sets the package to query for.
4468 *
4469 * @param packageName The package name. <code>Null</code> for any package.
4470 * @return This builder.
4471 */
4472 public @NonNull Builder setPackageName(@Nullable String packageName) {
4473 mPackageName = packageName;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004474
4475 if (packageName == null) {
4476 mFilter &= ~FILTER_BY_PACKAGE_NAME;
4477 } else {
4478 mFilter |= FILTER_BY_PACKAGE_NAME;
4479 }
4480
4481 return this;
4482 }
4483
4484 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004485 * Sets the attribution tag to query for.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004486 *
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004487 * @param attributionTag attribution tag
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004488 * @return This builder.
4489 */
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004490 public @NonNull Builder setAttributionTag(@Nullable String attributionTag) {
4491 mAttributionTag = attributionTag;
4492 mFilter |= FILTER_BY_ATTRIBUTION_TAG;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004493
Svet Ganov23c88db2019-01-22 20:38:11 -08004494 return this;
4495 }
4496
4497 /**
4498 * Sets the op names to query for.
4499 *
4500 * @param opNames The op names. <code>Null</code> for any op.
4501 * @return This builder.
4502 */
4503 public @NonNull Builder setOpNames(@Nullable List<String> opNames) {
4504 if (opNames != null) {
4505 final int opCount = opNames.size();
4506 for (int i = 0; i < opCount; i++) {
4507 Preconditions.checkArgument(AppOpsManager.strOpToOp(
4508 opNames.get(i)) != AppOpsManager.OP_NONE);
4509 }
4510 }
4511 mOpNames = opNames;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004512
4513 if (mOpNames == null) {
4514 mFilter &= ~FILTER_BY_OP_NAMES;
4515 } else {
4516 mFilter |= FILTER_BY_OP_NAMES;
4517 }
4518
Svet Ganov23c88db2019-01-22 20:38:11 -08004519 return this;
4520 }
4521
4522 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08004523 * Sets the op flags to query for. The flags specify the type of
4524 * op data being queried.
4525 *
4526 * @param flags The flags which are any combination of
4527 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
4528 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
4529 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
4530 * for any flag.
4531 * @return This builder.
4532 */
4533 public @NonNull Builder setFlags(@OpFlags int flags) {
4534 Preconditions.checkFlagsArgument(flags, OP_FLAGS_ALL);
4535 mFlags = flags;
4536 return this;
4537 }
4538
4539 /**
Svet Ganov23c88db2019-01-22 20:38:11 -08004540 * @return a new {@link HistoricalOpsRequest}.
4541 */
4542 public @NonNull HistoricalOpsRequest build() {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004543 return new HistoricalOpsRequest(mUid, mPackageName, mAttributionTag, mOpNames,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004544 mFilter, mBeginTimeMillis, mEndTimeMillis, mFlags);
Svet Ganov23c88db2019-01-22 20:38:11 -08004545 }
4546 }
4547 }
4548
4549 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08004550 * This class represents historical app op state of all UIDs for a given time interval.
4551 *
4552 * @hide
4553 */
4554 @TestApi
4555 @SystemApi
4556 public static final class HistoricalOps implements Parcelable {
4557 private long mBeginTimeMillis;
4558 private long mEndTimeMillis;
4559 private @Nullable SparseArray<HistoricalUidOps> mHistoricalUidOps;
4560
4561 /** @hide */
4562 @TestApi
4563 public HistoricalOps(long beginTimeMillis, long endTimeMillis) {
4564 Preconditions.checkState(beginTimeMillis <= endTimeMillis);
4565 mBeginTimeMillis = beginTimeMillis;
4566 mEndTimeMillis = endTimeMillis;
4567 }
4568
4569 /** @hide */
4570 public HistoricalOps(@NonNull HistoricalOps other) {
4571 mBeginTimeMillis = other.mBeginTimeMillis;
4572 mEndTimeMillis = other.mEndTimeMillis;
4573 Preconditions.checkState(mBeginTimeMillis <= mEndTimeMillis);
4574 if (other.mHistoricalUidOps != null) {
4575 final int opCount = other.getUidCount();
4576 for (int i = 0; i < opCount; i++) {
4577 final HistoricalUidOps origOps = other.getUidOpsAt(i);
4578 final HistoricalUidOps clonedOps = new HistoricalUidOps(origOps);
4579 if (mHistoricalUidOps == null) {
4580 mHistoricalUidOps = new SparseArray<>(opCount);
4581 }
4582 mHistoricalUidOps.put(clonedOps.getUid(), clonedOps);
4583 }
4584 }
4585 }
4586
4587 private HistoricalOps(Parcel parcel) {
4588 mBeginTimeMillis = parcel.readLong();
4589 mEndTimeMillis = parcel.readLong();
4590 final int[] uids = parcel.createIntArray();
4591 if (!ArrayUtils.isEmpty(uids)) {
4592 final ParceledListSlice<HistoricalUidOps> listSlice = parcel.readParcelable(
4593 HistoricalOps.class.getClassLoader());
4594 final List<HistoricalUidOps> uidOps = (listSlice != null)
4595 ? listSlice.getList() : null;
4596 if (uidOps == null) {
4597 return;
4598 }
4599 for (int i = 0; i < uids.length; i++) {
4600 if (mHistoricalUidOps == null) {
4601 mHistoricalUidOps = new SparseArray<>();
4602 }
4603 mHistoricalUidOps.put(uids[i], uidOps.get(i));
4604 }
4605 }
4606 }
4607
4608 /**
4609 * Splice a piece from the beginning of these ops.
4610 *
4611 * @param splicePoint The fraction of the data to be spliced off.
4612 *
4613 * @hide
4614 */
4615 public @NonNull HistoricalOps spliceFromBeginning(double splicePoint) {
4616 return splice(splicePoint, true);
4617 }
4618
4619 /**
4620 * Splice a piece from the end of these ops.
4621 *
4622 * @param fractionToRemove The fraction of the data to be spliced off.
4623 *
4624 * @hide
4625 */
4626 public @NonNull HistoricalOps spliceFromEnd(double fractionToRemove) {
4627 return splice(fractionToRemove, false);
4628 }
4629
4630 /**
4631 * Splice a piece from the beginning or end of these ops.
4632 *
4633 * @param fractionToRemove The fraction of the data to be spliced off.
4634 * @param beginning Whether to splice off the beginning or the end.
4635 *
4636 * @return The spliced off part.
4637 *
4638 * @hide
4639 */
4640 private @Nullable HistoricalOps splice(double fractionToRemove, boolean beginning) {
4641 final long spliceBeginTimeMills;
4642 final long spliceEndTimeMills;
4643 if (beginning) {
4644 spliceBeginTimeMills = mBeginTimeMillis;
4645 spliceEndTimeMills = (long) (mBeginTimeMillis
4646 + getDurationMillis() * fractionToRemove);
4647 mBeginTimeMillis = spliceEndTimeMills;
4648 } else {
4649 spliceBeginTimeMills = (long) (mEndTimeMillis
4650 - getDurationMillis() * fractionToRemove);
4651 spliceEndTimeMills = mEndTimeMillis;
4652 mEndTimeMillis = spliceBeginTimeMills;
4653 }
4654
4655 HistoricalOps splice = null;
4656 final int uidCount = getUidCount();
4657 for (int i = 0; i < uidCount; i++) {
4658 final HistoricalUidOps origOps = getUidOpsAt(i);
4659 final HistoricalUidOps spliceOps = origOps.splice(fractionToRemove);
4660 if (spliceOps != null) {
4661 if (splice == null) {
4662 splice = new HistoricalOps(spliceBeginTimeMills, spliceEndTimeMills);
4663 }
4664 if (splice.mHistoricalUidOps == null) {
4665 splice.mHistoricalUidOps = new SparseArray<>();
4666 }
4667 splice.mHistoricalUidOps.put(spliceOps.getUid(), spliceOps);
4668 }
4669 }
4670 return splice;
4671 }
4672
4673 /**
4674 * Merge the passed ops into the current ones. The time interval is a
4675 * union of the current and passed in one and the passed in data is
4676 * folded into the data of this instance.
4677 *
4678 * @hide
4679 */
4680 public void merge(@NonNull HistoricalOps other) {
4681 mBeginTimeMillis = Math.min(mBeginTimeMillis, other.mBeginTimeMillis);
4682 mEndTimeMillis = Math.max(mEndTimeMillis, other.mEndTimeMillis);
4683 final int uidCount = other.getUidCount();
4684 for (int i = 0; i < uidCount; i++) {
4685 final HistoricalUidOps otherUidOps = other.getUidOpsAt(i);
4686 final HistoricalUidOps thisUidOps = getUidOps(otherUidOps.getUid());
4687 if (thisUidOps != null) {
4688 thisUidOps.merge(otherUidOps);
4689 } else {
4690 if (mHistoricalUidOps == null) {
4691 mHistoricalUidOps = new SparseArray<>();
4692 }
4693 mHistoricalUidOps.put(otherUidOps.getUid(), otherUidOps);
4694 }
4695 }
4696 }
4697
4698 /**
4699 * AppPermissionUsage the ops to leave only the data we filter for.
4700 *
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004701 * @param uid Uid to filter for.
4702 * @param packageName Package to filter for.
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004703 * @param attributionTag attribution tag to filter for
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004704 * @param opNames Ops to filter for.
4705 * @param filter Which parameters to filter on.
Svet Ganov8455ba22019-01-02 13:05:56 -08004706 * @param beginTimeMillis The begin time to filter for or {@link Long#MIN_VALUE} for all.
4707 * @param endTimeMillis The end time to filter for or {@link Long#MAX_VALUE} for all.
4708 *
4709 * @hide
4710 */
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004711 public void filter(int uid, @Nullable String packageName, @Nullable String attributionTag,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004712 @Nullable String[] opNames, @HistoricalOpsRequestFilter int filter,
Svet Ganov8455ba22019-01-02 13:05:56 -08004713 long beginTimeMillis, long endTimeMillis) {
4714 final long durationMillis = getDurationMillis();
4715 mBeginTimeMillis = Math.max(mBeginTimeMillis, beginTimeMillis);
4716 mEndTimeMillis = Math.min(mEndTimeMillis, endTimeMillis);
4717 final double scaleFactor = Math.min((double) (endTimeMillis - beginTimeMillis)
4718 / (double) durationMillis, 1);
4719 final int uidCount = getUidCount();
4720 for (int i = uidCount - 1; i >= 0; i--) {
4721 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004722 if ((filter & FILTER_BY_UID) != 0 && uid != uidOp.getUid()) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004723 mHistoricalUidOps.removeAt(i);
4724 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004725 uidOp.filter(packageName, attributionTag, opNames, filter, scaleFactor);
Stanislav Zholnin0d9499c2020-01-16 13:39:50 +00004726 if (uidOp.getPackageCount() == 0) {
4727 mHistoricalUidOps.removeAt(i);
4728 }
Svet Ganov8455ba22019-01-02 13:05:56 -08004729 }
4730 }
4731 }
4732
4733 /** @hide */
4734 public boolean isEmpty() {
4735 if (getBeginTimeMillis() >= getEndTimeMillis()) {
4736 return true;
4737 }
4738 final int uidCount = getUidCount();
4739 for (int i = uidCount - 1; i >= 0; i--) {
4740 final HistoricalUidOps uidOp = mHistoricalUidOps.valueAt(i);
4741 if (!uidOp.isEmpty()) {
4742 return false;
4743 }
4744 }
4745 return true;
4746 }
4747
4748 /** @hide */
4749 public long getDurationMillis() {
4750 return mEndTimeMillis - mBeginTimeMillis;
4751 }
4752
4753 /** @hide */
4754 @TestApi
4755 public void increaseAccessCount(int opCode, int uid, @NonNull String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004756 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004757 long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004758 getOrCreateHistoricalUidOps(uid).increaseAccessCount(opCode,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004759 packageName, attributionTag, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004760 }
4761
4762 /** @hide */
4763 @TestApi
4764 public void increaseRejectCount(int opCode, int uid, @NonNull String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004765 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004766 long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004767 getOrCreateHistoricalUidOps(uid).increaseRejectCount(opCode,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004768 packageName, attributionTag, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004769 }
4770
4771 /** @hide */
4772 @TestApi
4773 public void increaseAccessDuration(int opCode, int uid, @NonNull String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004774 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08004775 long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004776 getOrCreateHistoricalUidOps(uid).increaseAccessDuration(opCode,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08004777 packageName, attributionTag, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08004778 }
4779
4780 /** @hide */
4781 @TestApi
4782 public void offsetBeginAndEndTime(long offsetMillis) {
4783 mBeginTimeMillis += offsetMillis;
4784 mEndTimeMillis += offsetMillis;
4785 }
4786
4787 /** @hide */
4788 public void setBeginAndEndTime(long beginTimeMillis, long endTimeMillis) {
4789 mBeginTimeMillis = beginTimeMillis;
4790 mEndTimeMillis = endTimeMillis;
4791 }
4792
4793 /** @hide */
4794 public void setBeginTime(long beginTimeMillis) {
4795 mBeginTimeMillis = beginTimeMillis;
4796 }
4797
4798 /** @hide */
4799 public void setEndTime(long endTimeMillis) {
4800 mEndTimeMillis = endTimeMillis;
4801 }
4802
4803 /**
4804 * @return The beginning of the interval in milliseconds since
4805 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
4806 */
4807 public long getBeginTimeMillis() {
4808 return mBeginTimeMillis;
4809 }
4810
4811 /**
4812 * @return The end of the interval in milliseconds since
4813 * epoch start (January 1, 1970 00:00:00.000 GMT - Gregorian).
4814 */
4815 public long getEndTimeMillis() {
4816 return mEndTimeMillis;
4817 }
4818
4819 /**
4820 * Gets number of UIDs with historical ops.
4821 *
4822 * @return The number of UIDs with historical ops.
4823 *
4824 * @see #getUidOpsAt(int)
4825 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004826 public @IntRange(from = 0) int getUidCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004827 if (mHistoricalUidOps == null) {
4828 return 0;
4829 }
4830 return mHistoricalUidOps.size();
4831 }
4832
4833 /**
4834 * Gets the historical UID ops at a given index.
4835 *
4836 * @param index The index.
4837 *
4838 * @return The historical UID ops at the given index.
4839 *
4840 * @see #getUidCount()
4841 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07004842 public @NonNull HistoricalUidOps getUidOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004843 if (mHistoricalUidOps == null) {
4844 throw new IndexOutOfBoundsException();
4845 }
4846 return mHistoricalUidOps.valueAt(index);
4847 }
4848
4849 /**
4850 * Gets the historical UID ops for a given UID.
4851 *
4852 * @param uid The UID.
4853 *
4854 * @return The historical ops for the UID.
4855 */
4856 public @Nullable HistoricalUidOps getUidOps(int uid) {
4857 if (mHistoricalUidOps == null) {
4858 return null;
4859 }
4860 return mHistoricalUidOps.get(uid);
4861 }
4862
Winson4e3b4352019-05-07 16:29:59 -07004863 /** @hide */
4864 public void clearHistory(int uid, @NonNull String packageName) {
4865 HistoricalUidOps historicalUidOps = getOrCreateHistoricalUidOps(uid);
4866 historicalUidOps.clearHistory(packageName);
4867 if (historicalUidOps.isEmpty()) {
4868 mHistoricalUidOps.remove(uid);
4869 }
4870 }
4871
Svet Ganov8455ba22019-01-02 13:05:56 -08004872 @Override
4873 public int describeContents() {
4874 return 0;
4875 }
4876
4877 @Override
4878 public void writeToParcel(Parcel parcel, int flags) {
4879 parcel.writeLong(mBeginTimeMillis);
4880 parcel.writeLong(mEndTimeMillis);
4881 if (mHistoricalUidOps != null) {
4882 final int uidCount = mHistoricalUidOps.size();
4883 parcel.writeInt(uidCount);
4884 for (int i = 0; i < uidCount; i++) {
4885 parcel.writeInt(mHistoricalUidOps.keyAt(i));
4886 }
4887 final List<HistoricalUidOps> opsList = new ArrayList<>(uidCount);
4888 for (int i = 0; i < uidCount; i++) {
4889 opsList.add(mHistoricalUidOps.valueAt(i));
4890 }
4891 parcel.writeParcelable(new ParceledListSlice<>(opsList), flags);
4892 } else {
4893 parcel.writeInt(-1);
4894 }
4895 }
4896
4897 /**
4898 * Accepts a visitor to traverse the ops tree.
4899 *
4900 * @param visitor The visitor.
4901 *
4902 * @hide
4903 */
4904 public void accept(@NonNull HistoricalOpsVisitor visitor) {
4905 visitor.visitHistoricalOps(this);
4906 final int uidCount = getUidCount();
4907 for (int i = 0; i < uidCount; i++) {
4908 getUidOpsAt(i).accept(visitor);
4909 }
4910 }
4911
4912 private @NonNull HistoricalUidOps getOrCreateHistoricalUidOps(int uid) {
4913 if (mHistoricalUidOps == null) {
4914 mHistoricalUidOps = new SparseArray<>();
4915 }
4916 HistoricalUidOps historicalUidOp = mHistoricalUidOps.get(uid);
4917 if (historicalUidOp == null) {
4918 historicalUidOp = new HistoricalUidOps(uid);
4919 mHistoricalUidOps.put(uid, historicalUidOp);
4920 }
4921 return historicalUidOp;
4922 }
4923
4924 /**
4925 * @return Rounded value up at the 0.5 boundary.
4926 *
4927 * @hide
4928 */
4929 public static double round(double value) {
4930 final BigDecimal decimalScale = new BigDecimal(value);
4931 return decimalScale.setScale(0, RoundingMode.HALF_UP).doubleValue();
4932 }
4933
4934 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004935 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08004936 if (this == obj) {
4937 return true;
4938 }
4939 if (obj == null || getClass() != obj.getClass()) {
4940 return false;
4941 }
4942 final HistoricalOps other = (HistoricalOps) obj;
4943 if (mBeginTimeMillis != other.mBeginTimeMillis) {
4944 return false;
4945 }
4946 if (mEndTimeMillis != other.mEndTimeMillis) {
4947 return false;
4948 }
4949 if (mHistoricalUidOps == null) {
4950 if (other.mHistoricalUidOps != null) {
4951 return false;
4952 }
4953 } else if (!mHistoricalUidOps.equals(other.mHistoricalUidOps)) {
4954 return false;
4955 }
4956 return true;
4957 }
4958
4959 @Override
4960 public int hashCode() {
4961 int result = (int) (mBeginTimeMillis ^ (mBeginTimeMillis >>> 32));
4962 result = 31 * result + mHistoricalUidOps.hashCode();
4963 return result;
4964 }
4965
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07004966 @NonNull
Svet Ganov8455ba22019-01-02 13:05:56 -08004967 @Override
4968 public String toString() {
4969 return getClass().getSimpleName() + "[from:"
4970 + mBeginTimeMillis + " to:" + mEndTimeMillis + "]";
4971 }
4972
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07004973 public static final @android.annotation.NonNull Creator<HistoricalOps> CREATOR = new Creator<HistoricalOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08004974 @Override
4975 public @NonNull HistoricalOps createFromParcel(@NonNull Parcel parcel) {
4976 return new HistoricalOps(parcel);
4977 }
4978
4979 @Override
4980 public @NonNull HistoricalOps[] newArray(int size) {
4981 return new HistoricalOps[size];
4982 }
4983 };
4984 }
4985
4986 /**
4987 * This class represents historical app op state for a UID.
4988 *
4989 * @hide
4990 */
4991 @TestApi
4992 @SystemApi
4993 public static final class HistoricalUidOps implements Parcelable {
4994 private final int mUid;
4995 private @Nullable ArrayMap<String, HistoricalPackageOps> mHistoricalPackageOps;
4996
4997 /** @hide */
4998 public HistoricalUidOps(int uid) {
4999 mUid = uid;
5000 }
5001
5002 private HistoricalUidOps(@NonNull HistoricalUidOps other) {
5003 mUid = other.mUid;
5004 final int opCount = other.getPackageCount();
5005 for (int i = 0; i < opCount; i++) {
5006 final HistoricalPackageOps origOps = other.getPackageOpsAt(i);
5007 final HistoricalPackageOps cloneOps = new HistoricalPackageOps(origOps);
5008 if (mHistoricalPackageOps == null) {
5009 mHistoricalPackageOps = new ArrayMap<>(opCount);
5010 }
5011 mHistoricalPackageOps.put(cloneOps.getPackageName(), cloneOps);
5012 }
5013 }
5014
5015 private HistoricalUidOps(@NonNull Parcel parcel) {
5016 // No arg check since we always read from a trusted source.
5017 mUid = parcel.readInt();
5018 mHistoricalPackageOps = parcel.createTypedArrayMap(HistoricalPackageOps.CREATOR);
5019 }
5020
5021 private @Nullable HistoricalUidOps splice(double fractionToRemove) {
5022 HistoricalUidOps splice = null;
5023 final int packageCount = getPackageCount();
5024 for (int i = 0; i < packageCount; i++) {
5025 final HistoricalPackageOps origOps = getPackageOpsAt(i);
5026 final HistoricalPackageOps spliceOps = origOps.splice(fractionToRemove);
5027 if (spliceOps != null) {
5028 if (splice == null) {
5029 splice = new HistoricalUidOps(mUid);
5030 }
5031 if (splice.mHistoricalPackageOps == null) {
5032 splice.mHistoricalPackageOps = new ArrayMap<>();
5033 }
5034 splice.mHistoricalPackageOps.put(spliceOps.getPackageName(), spliceOps);
5035 }
5036 }
5037 return splice;
5038 }
5039
5040 private void merge(@NonNull HistoricalUidOps other) {
5041 final int packageCount = other.getPackageCount();
5042 for (int i = 0; i < packageCount; i++) {
5043 final HistoricalPackageOps otherPackageOps = other.getPackageOpsAt(i);
5044 final HistoricalPackageOps thisPackageOps = getPackageOps(
5045 otherPackageOps.getPackageName());
5046 if (thisPackageOps != null) {
5047 thisPackageOps.merge(otherPackageOps);
5048 } else {
5049 if (mHistoricalPackageOps == null) {
5050 mHistoricalPackageOps = new ArrayMap<>();
5051 }
5052 mHistoricalPackageOps.put(otherPackageOps.getPackageName(), otherPackageOps);
5053 }
5054 }
5055 }
5056
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005057 private void filter(@Nullable String packageName, @Nullable String attributionTag,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005058 @Nullable String[] opNames, @HistoricalOpsRequestFilter int filter,
Svet Ganov8455ba22019-01-02 13:05:56 -08005059 double fractionToRemove) {
5060 final int packageCount = getPackageCount();
5061 for (int i = packageCount - 1; i >= 0; i--) {
5062 final HistoricalPackageOps packageOps = getPackageOpsAt(i);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005063 if ((filter & FILTER_BY_PACKAGE_NAME) != 0 && !packageName.equals(
5064 packageOps.getPackageName())) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005065 mHistoricalPackageOps.removeAt(i);
5066 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005067 packageOps.filter(attributionTag, opNames, filter, fractionToRemove);
5068 if (packageOps.getAttributedOpsCount() == 0) {
Stanislav Zholnin0d9499c2020-01-16 13:39:50 +00005069 mHistoricalPackageOps.removeAt(i);
5070 }
Svet Ganov8455ba22019-01-02 13:05:56 -08005071 }
5072 }
5073 }
5074
5075 private boolean isEmpty() {
5076 final int packageCount = getPackageCount();
5077 for (int i = packageCount - 1; i >= 0; i--) {
5078 final HistoricalPackageOps packageOps = mHistoricalPackageOps.valueAt(i);
5079 if (!packageOps.isEmpty()) {
5080 return false;
5081 }
5082 }
5083 return true;
5084 }
5085
5086 private void increaseAccessCount(int opCode, @NonNull String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005087 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005088 long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005089 getOrCreateHistoricalPackageOps(packageName).increaseAccessCount(
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005090 opCode, attributionTag, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08005091 }
5092
5093 private void increaseRejectCount(int opCode, @NonNull String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005094 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005095 long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005096 getOrCreateHistoricalPackageOps(packageName).increaseRejectCount(
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005097 opCode, attributionTag, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08005098 }
5099
5100 private void increaseAccessDuration(int opCode, @NonNull String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005101 @Nullable String attributionTag, @UidState int uidState, @OpFlags int flags,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005102 long increment) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005103 getOrCreateHistoricalPackageOps(packageName).increaseAccessDuration(
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005104 opCode, attributionTag, uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08005105 }
5106
5107 /**
5108 * @return The UID for which the data is related.
5109 */
5110 public int getUid() {
5111 return mUid;
5112 }
5113
5114 /**
5115 * Gets number of packages with historical ops.
5116 *
5117 * @return The number of packages with historical ops.
5118 *
5119 * @see #getPackageOpsAt(int)
5120 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07005121 public @IntRange(from = 0) int getPackageCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08005122 if (mHistoricalPackageOps == null) {
5123 return 0;
5124 }
5125 return mHistoricalPackageOps.size();
5126 }
5127
5128 /**
5129 * Gets the historical package ops at a given index.
5130 *
5131 * @param index The index.
5132 *
5133 * @return The historical package ops at the given index.
5134 *
5135 * @see #getPackageCount()
5136 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07005137 public @NonNull HistoricalPackageOps getPackageOpsAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005138 if (mHistoricalPackageOps == null) {
5139 throw new IndexOutOfBoundsException();
5140 }
5141 return mHistoricalPackageOps.valueAt(index);
5142 }
5143
5144 /**
5145 * Gets the historical package ops for a given package.
5146 *
5147 * @param packageName The package.
5148 *
5149 * @return The historical ops for the package.
5150 */
5151 public @Nullable HistoricalPackageOps getPackageOps(@NonNull String packageName) {
5152 if (mHistoricalPackageOps == null) {
5153 return null;
5154 }
5155 return mHistoricalPackageOps.get(packageName);
5156 }
5157
Winson4e3b4352019-05-07 16:29:59 -07005158 private void clearHistory(@NonNull String packageName) {
5159 if (mHistoricalPackageOps != null) {
5160 mHistoricalPackageOps.remove(packageName);
5161 }
5162 }
5163
Svet Ganov8455ba22019-01-02 13:05:56 -08005164 @Override
5165 public int describeContents() {
5166 return 0;
5167 }
5168
5169 @Override
5170 public void writeToParcel(Parcel parcel, int flags) {
5171 parcel.writeInt(mUid);
5172 parcel.writeTypedArrayMap(mHistoricalPackageOps, flags);
5173 }
5174
5175 private void accept(@NonNull HistoricalOpsVisitor visitor) {
5176 visitor.visitHistoricalUidOps(this);
5177 final int packageCount = getPackageCount();
5178 for (int i = 0; i < packageCount; i++) {
5179 getPackageOpsAt(i).accept(visitor);
5180 }
5181 }
5182
5183 private @NonNull HistoricalPackageOps getOrCreateHistoricalPackageOps(
5184 @NonNull String packageName) {
5185 if (mHistoricalPackageOps == null) {
5186 mHistoricalPackageOps = new ArrayMap<>();
5187 }
5188 HistoricalPackageOps historicalPackageOp = mHistoricalPackageOps.get(packageName);
5189 if (historicalPackageOp == null) {
5190 historicalPackageOp = new HistoricalPackageOps(packageName);
5191 mHistoricalPackageOps.put(packageName, historicalPackageOp);
5192 }
5193 return historicalPackageOp;
5194 }
5195
5196
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -07005197 public static final @android.annotation.NonNull Creator<HistoricalUidOps> CREATOR = new Creator<HistoricalUidOps>() {
Svet Ganov8455ba22019-01-02 13:05:56 -08005198 @Override
5199 public @NonNull HistoricalUidOps createFromParcel(@NonNull Parcel parcel) {
5200 return new HistoricalUidOps(parcel);
5201 }
5202
5203 @Override
5204 public @NonNull HistoricalUidOps[] newArray(int size) {
5205 return new HistoricalUidOps[size];
5206 }
5207 };
5208
5209 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07005210 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005211 if (this == obj) {
5212 return true;
5213 }
5214 if (obj == null || getClass() != obj.getClass()) {
5215 return false;
5216 }
5217 final HistoricalUidOps other = (HistoricalUidOps) obj;
5218 if (mUid != other.mUid) {
5219 return false;
5220 }
5221 if (mHistoricalPackageOps == null) {
5222 if (other.mHistoricalPackageOps != null) {
5223 return false;
5224 }
5225 } else if (!mHistoricalPackageOps.equals(other.mHistoricalPackageOps)) {
5226 return false;
5227 }
5228 return true;
5229 }
5230
5231 @Override
5232 public int hashCode() {
5233 int result = mUid;
5234 result = 31 * result + (mHistoricalPackageOps != null
5235 ? mHistoricalPackageOps.hashCode() : 0);
5236 return result;
5237 }
5238 }
5239
5240 /**
5241 * This class represents historical app op information about a package.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005242 *
5243 * @hide
5244 */
5245 @TestApi
5246 @SystemApi
5247 public static final class HistoricalPackageOps implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07005248 private final @NonNull String mPackageName;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005249 private @Nullable ArrayMap<String, AttributedHistoricalOps> mAttributedHistoricalOps;
Svet Ganovad0a49b2018-10-29 10:07:08 -07005250
Svet Ganov8455ba22019-01-02 13:05:56 -08005251 /** @hide */
5252 public HistoricalPackageOps(@NonNull String packageName) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07005253 mPackageName = packageName;
Svet Ganovad0a49b2018-10-29 10:07:08 -07005254 }
5255
Svet Ganov8455ba22019-01-02 13:05:56 -08005256 private HistoricalPackageOps(@NonNull HistoricalPackageOps other) {
5257 mPackageName = other.mPackageName;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005258 final int opCount = other.getAttributedOpsCount();
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005259 for (int i = 0; i < opCount; i++) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005260 final AttributedHistoricalOps origOps = other.getAttributedOpsAt(i);
5261 final AttributedHistoricalOps cloneOps = new AttributedHistoricalOps(origOps);
5262 if (mAttributedHistoricalOps == null) {
5263 mAttributedHistoricalOps = new ArrayMap<>(opCount);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005264 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005265 mAttributedHistoricalOps.put(cloneOps.getTag(), cloneOps);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005266 }
5267 }
5268
5269 private HistoricalPackageOps(@NonNull Parcel parcel) {
5270 mPackageName = parcel.readString();
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005271 mAttributedHistoricalOps = parcel.createTypedArrayMap(AttributedHistoricalOps.CREATOR);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005272 }
5273
5274 private @Nullable HistoricalPackageOps splice(double fractionToRemove) {
5275 HistoricalPackageOps splice = null;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005276 final int attributionCount = getAttributedOpsCount();
5277 for (int i = 0; i < attributionCount; i++) {
5278 final AttributedHistoricalOps origOps = getAttributedOpsAt(i);
5279 final AttributedHistoricalOps spliceOps = origOps.splice(fractionToRemove);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005280 if (spliceOps != null) {
5281 if (splice == null) {
5282 splice = new HistoricalPackageOps(mPackageName);
5283 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005284 if (splice.mAttributedHistoricalOps == null) {
5285 splice.mAttributedHistoricalOps = new ArrayMap<>();
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005286 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005287 splice.mAttributedHistoricalOps.put(spliceOps.getTag(), spliceOps);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005288 }
5289 }
5290 return splice;
5291 }
5292
5293 private void merge(@NonNull HistoricalPackageOps other) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005294 final int attributionCount = other.getAttributedOpsCount();
5295 for (int i = 0; i < attributionCount; i++) {
5296 final AttributedHistoricalOps otherAttributionOps = other.getAttributedOpsAt(i);
5297 final AttributedHistoricalOps thisAttributionOps = getAttributedOps(
5298 otherAttributionOps.getTag());
5299 if (thisAttributionOps != null) {
5300 thisAttributionOps.merge(otherAttributionOps);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005301 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005302 if (mAttributedHistoricalOps == null) {
5303 mAttributedHistoricalOps = new ArrayMap<>();
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005304 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005305 mAttributedHistoricalOps.put(otherAttributionOps.getTag(),
5306 otherAttributionOps);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005307 }
5308 }
5309 }
5310
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005311 private void filter(@Nullable String attributionTag, @Nullable String[] opNames,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005312 @HistoricalOpsRequestFilter int filter, double fractionToRemove) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005313 final int attributionCount = getAttributedOpsCount();
5314 for (int i = attributionCount - 1; i >= 0; i--) {
5315 final AttributedHistoricalOps attributionOps = getAttributedOpsAt(i);
5316 if ((filter & FILTER_BY_ATTRIBUTION_TAG) != 0 && !Objects.equals(attributionTag,
5317 attributionOps.getTag())) {
5318 mAttributedHistoricalOps.removeAt(i);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005319 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005320 attributionOps.filter(opNames, filter, fractionToRemove);
5321 if (attributionOps.getOpCount() == 0) {
5322 mAttributedHistoricalOps.removeAt(i);
Stanislav Zholnin0d9499c2020-01-16 13:39:50 +00005323 }
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005324 }
5325 }
5326 }
5327
5328 private void accept(@NonNull HistoricalOpsVisitor visitor) {
5329 visitor.visitHistoricalPackageOps(this);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005330 final int attributionCount = getAttributedOpsCount();
5331 for (int i = 0; i < attributionCount; i++) {
5332 getAttributedOpsAt(i).accept(visitor);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005333 }
5334 }
5335
5336 private boolean isEmpty() {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005337 final int attributionCount = getAttributedOpsCount();
5338 for (int i = attributionCount - 1; i >= 0; i--) {
5339 final AttributedHistoricalOps attributionOps = mAttributedHistoricalOps.valueAt(i);
5340 if (!attributionOps.isEmpty()) {
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005341 return false;
5342 }
5343 }
5344 return true;
5345 }
5346
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005347 private void increaseAccessCount(int opCode, @Nullable String attributionTag,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005348 @UidState int uidState, @OpFlags int flags, long increment) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005349 getOrCreateAttributedHistoricalOps(attributionTag).increaseAccessCount(
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005350 opCode, uidState, flags, increment);
5351 }
5352
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005353 private void increaseRejectCount(int opCode, @Nullable String attributionTag,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005354 @UidState int uidState, @OpFlags int flags, long increment) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005355 getOrCreateAttributedHistoricalOps(attributionTag).increaseRejectCount(
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005356 opCode, uidState, flags, increment);
5357 }
5358
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005359 private void increaseAccessDuration(int opCode, @Nullable String attributionTag,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005360 @UidState int uidState, @OpFlags int flags, long increment) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005361 getOrCreateAttributedHistoricalOps(attributionTag).increaseAccessDuration(
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005362 opCode, uidState, flags, increment);
5363 }
5364
5365 /**
5366 * Gets the package name which the data represents.
5367 *
5368 * @return The package name which the data represents.
5369 */
5370 public @NonNull String getPackageName() {
5371 return mPackageName;
5372 }
5373
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005374 private @NonNull AttributedHistoricalOps getOrCreateAttributedHistoricalOps(
5375 @Nullable String attributionTag) {
5376 if (mAttributedHistoricalOps == null) {
5377 mAttributedHistoricalOps = new ArrayMap<>();
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005378 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005379 AttributedHistoricalOps historicalAttributionOp = mAttributedHistoricalOps.get(
5380 attributionTag);
5381 if (historicalAttributionOp == null) {
5382 historicalAttributionOp = new AttributedHistoricalOps(attributionTag);
5383 mAttributedHistoricalOps.put(attributionTag, historicalAttributionOp);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005384 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005385 return historicalAttributionOp;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005386 }
5387
5388 /**
5389 * Gets number historical app ops.
5390 *
5391 * @return The number historical app ops.
5392 * @see #getOpAt(int)
5393 */
5394 public @IntRange(from = 0) int getOpCount() {
5395 int numOps = 0;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005396 int numAttributions = getAttributedOpsCount();
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005397
5398 for (int code = 0; code < _NUM_OP; code++) {
5399 String opName = opToPublicName(code);
5400
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005401 for (int attributionNum = 0; attributionNum < numAttributions; attributionNum++) {
5402 if (getAttributedOpsAt(attributionNum).getOp(opName) != null) {
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005403 numOps++;
5404 break;
5405 }
5406 }
5407 }
5408
5409 return numOps;
5410 }
5411
5412 /**
5413 * Gets the historical op at a given index.
5414 *
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005415 * <p>This combines the counts from all attributions.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005416 *
5417 * @param index The index to lookup.
5418 * @return The op at the given index.
5419 * @see #getOpCount()
5420 */
5421 public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) {
5422 int numOpsFound = 0;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005423 int numAttributions = getAttributedOpsCount();
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005424
5425 for (int code = 0; code < _NUM_OP; code++) {
5426 String opName = opToPublicName(code);
5427
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005428 for (int attributionNum = 0; attributionNum < numAttributions; attributionNum++) {
5429 if (getAttributedOpsAt(attributionNum).getOp(opName) != null) {
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005430 if (numOpsFound == index) {
5431 return getOp(opName);
5432 } else {
5433 numOpsFound++;
5434 break;
5435 }
5436 }
5437 }
5438 }
5439
5440 throw new IndexOutOfBoundsException();
5441 }
5442
5443 /**
5444 * Gets the historical entry for a given op name.
5445 *
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005446 * <p>This combines the counts from all attributions.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005447 *
5448 * @param opName The op name.
5449 * @return The historical entry for that op name.
5450 */
5451 public @Nullable HistoricalOp getOp(@NonNull String opName) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005452 if (mAttributedHistoricalOps == null) {
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005453 return null;
5454 }
5455
5456 HistoricalOp combinedOp = null;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005457 int numAttributions = getAttributedOpsCount();
5458 for (int i = 0; i < numAttributions; i++) {
5459 HistoricalOp attributionOp = getAttributedOpsAt(i).getOp(opName);
5460 if (attributionOp != null) {
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005461 if (combinedOp == null) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005462 combinedOp = new HistoricalOp(attributionOp);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005463 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005464 combinedOp.merge(attributionOp);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005465 }
5466 }
5467 }
5468
5469 return combinedOp;
5470 }
5471
5472 @Override
5473 public int describeContents() {
5474 return 0;
5475 }
5476
5477 @Override
5478 public void writeToParcel(@NonNull Parcel parcel, int flags) {
5479 parcel.writeString(mPackageName);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005480 parcel.writeTypedArrayMap(mAttributedHistoricalOps, flags);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005481 }
5482
5483 public static final @android.annotation.NonNull Creator<HistoricalPackageOps> CREATOR =
5484 new Creator<HistoricalPackageOps>() {
5485 @Override
5486 public @NonNull HistoricalPackageOps createFromParcel(@NonNull Parcel parcel) {
5487 return new HistoricalPackageOps(parcel);
5488 }
5489
5490 @Override
5491 public @NonNull HistoricalPackageOps[] newArray(int size) {
5492 return new HistoricalPackageOps[size];
5493 }
5494 };
5495
5496 @Override
5497 public boolean equals(@Nullable Object obj) {
5498 if (this == obj) {
5499 return true;
5500 }
5501 if (obj == null || getClass() != obj.getClass()) {
5502 return false;
5503 }
5504 final HistoricalPackageOps other = (HistoricalPackageOps) obj;
5505 if (!mPackageName.equals(other.mPackageName)) {
5506 return false;
5507 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005508 if (mAttributedHistoricalOps == null) {
5509 if (other.mAttributedHistoricalOps != null) {
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005510 return false;
5511 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005512 } else if (!mAttributedHistoricalOps.equals(other.mAttributedHistoricalOps)) {
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005513 return false;
5514 }
5515 return true;
5516 }
5517
5518 @Override
5519 public int hashCode() {
5520 int result = mPackageName != null ? mPackageName.hashCode() : 0;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005521 result = 31 * result + (mAttributedHistoricalOps != null
5522 ? mAttributedHistoricalOps.hashCode() : 0);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005523 return result;
5524 }
5525
5526 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005527 * Gets number of attributed historical ops.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005528 *
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005529 * @return The number of attribution with historical ops.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005530 *
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005531 * @see #getAttributedOpsAt(int)
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005532 */
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005533 public @IntRange(from = 0) int getAttributedOpsCount() {
5534 if (mAttributedHistoricalOps == null) {
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005535 return 0;
5536 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005537 return mAttributedHistoricalOps.size();
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005538 }
5539
5540 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005541 * Gets the attributed historical ops at a given index.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005542 *
5543 * @param index The index.
5544 *
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005545 * @return The historical attribution ops at the given index.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005546 *
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005547 * @see #getAttributedOpsCount()
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005548 */
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005549 public @NonNull AttributedHistoricalOps getAttributedOpsAt(@IntRange(from = 0) int index) {
5550 if (mAttributedHistoricalOps == null) {
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005551 throw new IndexOutOfBoundsException();
5552 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005553 return mAttributedHistoricalOps.valueAt(index);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005554 }
5555
5556 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005557 * Gets the attributed historical ops for a given attribution tag.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005558 *
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005559 * @param attributionTag The attribution tag.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005560 *
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005561 * @return The historical ops for the attribution.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005562 */
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005563 public @Nullable AttributedHistoricalOps getAttributedOps(@NonNull String attributionTag) {
5564 if (mAttributedHistoricalOps == null) {
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005565 return null;
5566 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005567 return mAttributedHistoricalOps.get(attributionTag);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005568 }
5569 }
5570
5571 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005572 * This class represents historical app op information about a attribution in a package.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005573 *
5574 * @hide
5575 */
5576 @TestApi
5577 @SystemApi
5578 /* codegen verifier cannot deal with nested class parameters
5579 @DataClass(genHiddenConstructor = true,
5580 genEqualsHashCode = true, genHiddenCopyConstructor = true) */
5581 @DataClass.Suppress("getHistoricalOps")
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005582 public static final class AttributedHistoricalOps implements Parcelable {
5583 /** {@link Context#createAttributionContext attribution} tag */
5584 private final @Nullable String mTag;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005585
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005586 /** Ops for this attribution */
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005587 private @Nullable ArrayMap<String, HistoricalOp> mHistoricalOps;
5588
5589 /** @hide */
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005590 public AttributedHistoricalOps(@NonNull String tag) {
5591 mTag = tag;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005592 }
5593
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005594 private AttributedHistoricalOps(@NonNull AttributedHistoricalOps other) {
5595 mTag = other.mTag;
Svet Ganov8455ba22019-01-02 13:05:56 -08005596 final int opCount = other.getOpCount();
5597 for (int i = 0; i < opCount; i++) {
5598 final HistoricalOp origOp = other.getOpAt(i);
5599 final HistoricalOp cloneOp = new HistoricalOp(origOp);
5600 if (mHistoricalOps == null) {
5601 mHistoricalOps = new ArrayMap<>(opCount);
5602 }
5603 mHistoricalOps.put(cloneOp.getOpName(), cloneOp);
5604 }
5605 }
5606
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005607 private @Nullable AttributedHistoricalOps splice(double fractionToRemove) {
5608 AttributedHistoricalOps splice = null;
Svet Ganov8455ba22019-01-02 13:05:56 -08005609 final int opCount = getOpCount();
5610 for (int i = 0; i < opCount; i++) {
5611 final HistoricalOp origOps = getOpAt(i);
5612 final HistoricalOp spliceOps = origOps.splice(fractionToRemove);
5613 if (spliceOps != null) {
5614 if (splice == null) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005615 splice = new AttributedHistoricalOps(mTag, null);
Svet Ganov8455ba22019-01-02 13:05:56 -08005616 }
5617 if (splice.mHistoricalOps == null) {
5618 splice.mHistoricalOps = new ArrayMap<>();
5619 }
5620 splice.mHistoricalOps.put(spliceOps.getOpName(), spliceOps);
5621 }
5622 }
5623 return splice;
5624 }
5625
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005626 private void merge(@NonNull AttributedHistoricalOps other) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005627 final int opCount = other.getOpCount();
5628 for (int i = 0; i < opCount; i++) {
5629 final HistoricalOp otherOp = other.getOpAt(i);
5630 final HistoricalOp thisOp = getOp(otherOp.getOpName());
5631 if (thisOp != null) {
5632 thisOp.merge(otherOp);
5633 } else {
5634 if (mHistoricalOps == null) {
5635 mHistoricalOps = new ArrayMap<>();
5636 }
5637 mHistoricalOps.put(otherOp.getOpName(), otherOp);
5638 }
5639 }
5640 }
5641
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005642 private void filter(@Nullable String[] opNames, @HistoricalOpsRequestFilter int filter,
5643 double scaleFactor) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005644 final int opCount = getOpCount();
5645 for (int i = opCount - 1; i >= 0; i--) {
5646 final HistoricalOp op = mHistoricalOps.valueAt(i);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005647 if ((filter & FILTER_BY_OP_NAMES) != 0 && !ArrayUtils.contains(opNames,
5648 op.getOpName())) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005649 mHistoricalOps.removeAt(i);
5650 } else {
5651 op.filter(scaleFactor);
5652 }
5653 }
5654 }
5655
5656 private boolean isEmpty() {
5657 final int opCount = getOpCount();
5658 for (int i = opCount - 1; i >= 0; i--) {
5659 final HistoricalOp op = mHistoricalOps.valueAt(i);
5660 if (!op.isEmpty()) {
5661 return false;
5662 }
5663 }
5664 return true;
5665 }
5666
Svet Ganovaf189e32019-02-15 18:45:29 -08005667 private void increaseAccessCount(int opCode, @UidState int uidState,
5668 @OpFlags int flags, long increment) {
5669 getOrCreateHistoricalOp(opCode).increaseAccessCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08005670 }
5671
Svet Ganovaf189e32019-02-15 18:45:29 -08005672 private void increaseRejectCount(int opCode, @UidState int uidState,
5673 @OpFlags int flags, long increment) {
5674 getOrCreateHistoricalOp(opCode).increaseRejectCount(uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08005675 }
5676
Svet Ganovaf189e32019-02-15 18:45:29 -08005677 private void increaseAccessDuration(int opCode, @UidState int uidState,
5678 @OpFlags int flags, long increment) {
5679 getOrCreateHistoricalOp(opCode).increaseAccessDuration(uidState, flags, increment);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005680 }
5681
5682 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005683 * Gets number historical app ops.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005684 *
Svet Ganov8455ba22019-01-02 13:05:56 -08005685 * @return The number historical app ops.
Svet Ganov8455ba22019-01-02 13:05:56 -08005686 * @see #getOpAt(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07005687 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07005688 public @IntRange(from = 0) int getOpCount() {
Svet Ganov8455ba22019-01-02 13:05:56 -08005689 if (mHistoricalOps == null) {
5690 return 0;
5691 }
5692 return mHistoricalOps.size();
Svet Ganovad0a49b2018-10-29 10:07:08 -07005693 }
5694
5695 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005696 * Gets the historical op at a given index.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005697 *
5698 * @param index The index to lookup.
Svet Ganov8455ba22019-01-02 13:05:56 -08005699 * @return The op at the given index.
Svet Ganov8455ba22019-01-02 13:05:56 -08005700 * @see #getOpCount()
Svet Ganovad0a49b2018-10-29 10:07:08 -07005701 */
Svet Ganov00a46ef2019-03-29 21:13:03 -07005702 public @NonNull HistoricalOp getOpAt(@IntRange(from = 0) int index) {
Svet Ganov8455ba22019-01-02 13:05:56 -08005703 if (mHistoricalOps == null) {
5704 throw new IndexOutOfBoundsException();
5705 }
5706 return mHistoricalOps.valueAt(index);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005707 }
5708
5709 /**
5710 * Gets the historical entry for a given op name.
5711 *
5712 * @param opName The op name.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005713 * @return The historical entry for that op name.
5714 */
Svet Ganov8455ba22019-01-02 13:05:56 -08005715 public @Nullable HistoricalOp getOp(@NonNull String opName) {
5716 if (mHistoricalOps == null) {
5717 return null;
Svet Ganovad0a49b2018-10-29 10:07:08 -07005718 }
Svet Ganov8455ba22019-01-02 13:05:56 -08005719 return mHistoricalOps.get(opName);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005720 }
5721
Svet Ganov8455ba22019-01-02 13:05:56 -08005722 private void accept(@NonNull HistoricalOpsVisitor visitor) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005723 visitor.visitHistoricalAttributionOps(this);
Svet Ganov8455ba22019-01-02 13:05:56 -08005724 final int opCount = getOpCount();
5725 for (int i = 0; i < opCount; i++) {
5726 getOpAt(i).accept(visitor);
5727 }
5728 }
5729
5730 private @NonNull HistoricalOp getOrCreateHistoricalOp(int opCode) {
5731 if (mHistoricalOps == null) {
5732 mHistoricalOps = new ArrayMap<>();
5733 }
5734 final String opStr = sOpToString[opCode];
5735 HistoricalOp op = mHistoricalOps.get(opStr);
5736 if (op == null) {
5737 op = new HistoricalOp(opCode);
5738 mHistoricalOps.put(opStr, op);
5739 }
5740 return op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07005741 }
5742
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005743
5744
5745 // Code below generated by codegen v1.0.14.
5746 //
5747 // DO NOT MODIFY!
5748 // CHECKSTYLE:OFF Generated code
5749 //
5750 // To regenerate run:
5751 // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/app/AppOpsManager.java
5752 //
5753 // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
5754 // Settings > Editor > Code Style > Formatter Control
5755 //@formatter:off
5756
5757
5758 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005759 * Creates a new HistoricalAttributionOps.
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005760 *
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005761 * @param tag
5762 * {@link Context#createAttributionContext attribution} tag
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005763 * @param historicalOps
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005764 * Ops for this attribution
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005765 * @hide
5766 */
5767 @DataClass.Generated.Member
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005768 public AttributedHistoricalOps(
5769 @Nullable String tag,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005770 @Nullable ArrayMap<String,HistoricalOp> historicalOps) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005771 this.mTag = tag;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005772 this.mHistoricalOps = historicalOps;
5773
5774 // onConstructed(); // You can define this method to get a callback
5775 }
5776
5777 /**
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005778 * {@link Context#createAttributionContext attribution} tag
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005779 */
5780 @DataClass.Generated.Member
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005781 public @Nullable String getTag() {
5782 return mTag;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005783 }
5784
5785 @Override
5786 @DataClass.Generated.Member
5787 public boolean equals(@Nullable Object o) {
5788 // You can override field equality logic by defining either of the methods like:
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005789 // boolean fieldNameEquals(HistoricalAttributionOps other) { ... }
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005790 // boolean fieldNameEquals(FieldType otherValue) { ... }
5791
5792 if (this == o) return true;
5793 if (o == null || getClass() != o.getClass()) return false;
5794 @SuppressWarnings("unchecked")
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005795 AttributedHistoricalOps that = (AttributedHistoricalOps) o;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005796 //noinspection PointlessBooleanExpression
5797 return true
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005798 && Objects.equals(mTag, that.mTag)
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005799 && Objects.equals(mHistoricalOps, that.mHistoricalOps);
5800 }
5801
5802 @Override
5803 @DataClass.Generated.Member
5804 public int hashCode() {
5805 // You can override field hashCode logic by defining methods like:
5806 // int fieldNameHashCode() { ... }
5807
5808 int _hash = 1;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005809 _hash = 31 * _hash + Objects.hashCode(mTag);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005810 _hash = 31 * _hash + Objects.hashCode(mHistoricalOps);
5811 return _hash;
5812 }
5813
5814 @Override
5815 @DataClass.Generated.Member
5816 public void writeToParcel(@NonNull Parcel dest, int flags) {
5817 // You can override field parcelling by defining methods like:
5818 // void parcelFieldName(Parcel dest, int flags) { ... }
5819
5820 byte flg = 0;
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005821 if (mTag != null) flg |= 0x1;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005822 if (mHistoricalOps != null) flg |= 0x2;
5823 dest.writeByte(flg);
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005824 if (mTag != null) dest.writeString(mTag);
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005825 if (mHistoricalOps != null) dest.writeMap(mHistoricalOps);
5826 }
5827
5828 @Override
5829 @DataClass.Generated.Member
5830 public int describeContents() { return 0; }
5831
5832 /** @hide */
5833 @SuppressWarnings({"unchecked", "RedundantCast"})
5834 @DataClass.Generated.Member
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005835 /* package-private */ AttributedHistoricalOps(@NonNull Parcel in) {
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005836 // You can override field unparcelling by defining methods like:
5837 // static FieldType unparcelFieldName(Parcel in) { ... }
5838
5839 byte flg = in.readByte();
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005840 String attributionTag = (flg & 0x1) == 0 ? null : in.readString();
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005841 ArrayMap<String,HistoricalOp> historicalOps = null;
5842 if ((flg & 0x2) != 0) {
5843 historicalOps = new ArrayMap();
5844 in.readMap(historicalOps, HistoricalOp.class.getClassLoader());
5845 }
5846
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005847 this.mTag = attributionTag;
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005848 this.mHistoricalOps = historicalOps;
5849
5850 // onConstructed(); // You can define this method to get a callback
5851 }
5852
5853 @DataClass.Generated.Member
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005854 public static final @NonNull Parcelable.Creator<AttributedHistoricalOps> CREATOR
5855 = new Parcelable.Creator<AttributedHistoricalOps>() {
Svet Ganovad0a49b2018-10-29 10:07:08 -07005856 @Override
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005857 public AttributedHistoricalOps[] newArray(int size) {
5858 return new AttributedHistoricalOps[size];
Svet Ganovad0a49b2018-10-29 10:07:08 -07005859 }
5860
5861 @Override
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005862 public AttributedHistoricalOps createFromParcel(@NonNull Parcel in) {
5863 return new AttributedHistoricalOps(in);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005864 }
5865 };
Svet Ganov8455ba22019-01-02 13:05:56 -08005866
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005867 /*
5868 @DataClass.Generated(
5869 time = 1578113234821L,
5870 codegenVersion = "1.0.14",
5871 sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08005872 inputSignatures = "private final @android.annotation.Nullable java.lang.String mAttributionTag\nprivate @android.annotation.Nullable android.util.ArrayMap<java.lang.String,android.app.HistoricalOp> mHistoricalOps\nprivate @android.annotation.Nullable android.app.HistoricalAttributionOps splice(double)\nprivate void merge(android.app.HistoricalAttributionOps)\nprivate void filter(java.lang.String[],int,double)\nprivate boolean isEmpty()\nprivate void increaseAccessCount(int,int,int,long)\nprivate void increaseRejectCount(int,int,int,long)\nprivate void increaseAccessDuration(int,int,int,long)\npublic @android.annotation.IntRange(from=0L) int getOpCount()\npublic @android.annotation.NonNull android.app.HistoricalOp getOpAt(int)\npublic @android.annotation.Nullable android.app.HistoricalOp getOp(java.lang.String)\nprivate void accept(android.app.HistoricalOpsVisitor)\nprivate @android.annotation.NonNull android.app.HistoricalOp getOrCreateHistoricalOp(int)\nclass HistoricalAttributionOps extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genEqualsHashCode=true, genHiddenCopyConstructor=true)")
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005873 @Deprecated
5874 private void __metadata() {}
5875 */
Svet Ganov8455ba22019-01-02 13:05:56 -08005876
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08005877 //@formatter:on
5878 // End of generated code
5879
Svet Ganovad0a49b2018-10-29 10:07:08 -07005880 }
5881
5882 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08005883 * This class represents historical information about an app op.
Svet Ganovad0a49b2018-10-29 10:07:08 -07005884 *
5885 * @hide
5886 */
5887 @TestApi
5888 @SystemApi
Svet Ganov8455ba22019-01-02 13:05:56 -08005889 public static final class HistoricalOp implements Parcelable {
Svet Ganovad0a49b2018-10-29 10:07:08 -07005890 private final int mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08005891 private @Nullable LongSparseLongArray mAccessCount;
5892 private @Nullable LongSparseLongArray mRejectCount;
5893 private @Nullable LongSparseLongArray mAccessDuration;
Svet Ganovad0a49b2018-10-29 10:07:08 -07005894
Svet Ganov8455ba22019-01-02 13:05:56 -08005895 /** @hide */
5896 public HistoricalOp(int op) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07005897 mOp = op;
Svet Ganovad0a49b2018-10-29 10:07:08 -07005898 }
5899
Svet Ganov8455ba22019-01-02 13:05:56 -08005900 private HistoricalOp(@NonNull HistoricalOp other) {
5901 mOp = other.mOp;
5902 if (other.mAccessCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08005903 mAccessCount = other.mAccessCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08005904 }
5905 if (other.mRejectCount != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08005906 mRejectCount = other.mRejectCount.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08005907 }
5908 if (other.mAccessDuration != null) {
Svet Ganovaf189e32019-02-15 18:45:29 -08005909 mAccessDuration = other.mAccessDuration.clone();
Svet Ganov8455ba22019-01-02 13:05:56 -08005910 }
5911 }
5912
5913 private HistoricalOp(@NonNull Parcel parcel) {
Svet Ganovad0a49b2018-10-29 10:07:08 -07005914 mOp = parcel.readInt();
Svet Ganovaf189e32019-02-15 18:45:29 -08005915 mAccessCount = readLongSparseLongArrayFromParcel(parcel);
5916 mRejectCount = readLongSparseLongArrayFromParcel(parcel);
5917 mAccessDuration = readLongSparseLongArrayFromParcel(parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07005918 }
5919
Svet Ganov8455ba22019-01-02 13:05:56 -08005920 private void filter(double scaleFactor) {
5921 scale(mAccessCount, scaleFactor);
5922 scale(mRejectCount, scaleFactor);
5923 scale(mAccessDuration, scaleFactor);
5924 }
5925
5926 private boolean isEmpty() {
5927 return !hasData(mAccessCount)
5928 && !hasData(mRejectCount)
5929 && !hasData(mAccessDuration);
5930 }
5931
Svet Ganovaf189e32019-02-15 18:45:29 -08005932 private boolean hasData(@NonNull LongSparseLongArray array) {
5933 return (array != null && array.size() > 0);
Svet Ganov8455ba22019-01-02 13:05:56 -08005934 }
5935
5936 private @Nullable HistoricalOp splice(double fractionToRemove) {
Svet Ganovaf189e32019-02-15 18:45:29 -08005937 final HistoricalOp splice = new HistoricalOp(mOp);
5938 splice(mAccessCount, splice::getOrCreateAccessCount, fractionToRemove);
5939 splice(mRejectCount, splice::getOrCreateRejectCount, fractionToRemove);
5940 splice(mAccessDuration, splice::getOrCreateAccessDuration, fractionToRemove);
Svet Ganov8455ba22019-01-02 13:05:56 -08005941 return splice;
5942 }
5943
Svet Ganovaf189e32019-02-15 18:45:29 -08005944 private static void splice(@Nullable LongSparseLongArray sourceContainer,
5945 @NonNull Supplier<LongSparseLongArray> destContainerProvider,
5946 double fractionToRemove) {
5947 if (sourceContainer != null) {
5948 final int size = sourceContainer.size();
5949 for (int i = 0; i < size; i++) {
5950 final long key = sourceContainer.keyAt(i);
5951 final long value = sourceContainer.valueAt(i);
5952 final long removedFraction = Math.round(value * fractionToRemove);
5953 if (removedFraction > 0) {
5954 destContainerProvider.get().put(key, removedFraction);
5955 sourceContainer.put(key, value - removedFraction);
5956 }
5957 }
5958 }
5959 }
5960
Svet Ganov8455ba22019-01-02 13:05:56 -08005961 private void merge(@NonNull HistoricalOp other) {
Svet Ganovaf189e32019-02-15 18:45:29 -08005962 merge(this::getOrCreateAccessCount, other.mAccessCount);
5963 merge(this::getOrCreateRejectCount, other.mRejectCount);
5964 merge(this::getOrCreateAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08005965 }
5966
Svet Ganovaf189e32019-02-15 18:45:29 -08005967 private void increaseAccessCount(@UidState int uidState, @OpFlags int flags,
5968 long increment) {
5969 increaseCount(getOrCreateAccessCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08005970 }
5971
Svet Ganovaf189e32019-02-15 18:45:29 -08005972 private void increaseRejectCount(@UidState int uidState, @OpFlags int flags,
5973 long increment) {
5974 increaseCount(getOrCreateRejectCount(), uidState, flags, increment);
Svet Ganov8455ba22019-01-02 13:05:56 -08005975 }
5976
Svet Ganovaf189e32019-02-15 18:45:29 -08005977 private void increaseAccessDuration(@UidState int uidState, @OpFlags int flags,
5978 long increment) {
5979 increaseCount(getOrCreateAccessDuration(), uidState, flags, increment);
5980 }
5981
5982 private void increaseCount(@NonNull LongSparseLongArray counts,
5983 @UidState int uidState, @OpFlags int flags, long increment) {
5984 while (flags != 0) {
5985 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
5986 flags &= ~flag;
5987 final long key = makeKey(uidState, flag);
5988 counts.put(key, counts.get(key) + increment);
5989 }
Svet Ganovad0a49b2018-10-29 10:07:08 -07005990 }
5991
5992 /**
5993 * Gets the op name.
5994 *
5995 * @return The op name.
5996 */
Svet Ganov8455ba22019-01-02 13:05:56 -08005997 public @NonNull String getOpName() {
Svet Ganovad0a49b2018-10-29 10:07:08 -07005998 return sOpToString[mOp];
5999 }
6000
Svet Ganov8455ba22019-01-02 13:05:56 -08006001 /** @hide */
6002 public int getOpCode() {
6003 return mOp;
6004 }
6005
Svet Ganovad0a49b2018-10-29 10:07:08 -07006006 /**
6007 * Gets the number times the op was accessed (performed) in the foreground.
6008 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006009 * @param flags The flags which are any combination of
6010 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
6011 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
6012 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
6013 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006014 * @return The times the op was accessed in the foreground.
6015 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006016 * @see #getBackgroundAccessCount(int)
6017 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07006018 */
Svet Ganovaf189e32019-02-15 18:45:29 -08006019 public long getForegroundAccessCount(@OpFlags int flags) {
6020 return sumForFlagsInStates(mAccessCount, MAX_PRIORITY_UID_STATE,
6021 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07006022 }
6023
6024 /**
6025 * Gets the number times the op was accessed (performed) in the background.
6026 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006027 * @param flags The flags which are any combination of
6028 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
6029 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
6030 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
6031 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006032 * @return The times the op was accessed in the background.
6033 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006034 * @see #getForegroundAccessCount(int)
6035 * @see #getAccessCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07006036 */
Svet Ganovaf189e32019-02-15 18:45:29 -08006037 public long getBackgroundAccessCount(@OpFlags int flags) {
6038 return sumForFlagsInStates(mAccessCount, resolveLastRestrictedUidState(mOp),
6039 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07006040 }
6041
6042 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08006043 * Gets the number times the op was accessed (performed) for a
6044 * range of uid states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006045 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006046 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07006047 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
6048 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
6049 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08006050 * @param toUidState The UID state to which to query.
6051 * @param flags The flags which are any combination of
6052 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
6053 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
6054 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
6055 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006056 *
6057 * @return The times the op was accessed for the given UID state.
6058 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006059 * @see #getForegroundAccessCount(int)
6060 * @see #getBackgroundAccessCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07006061 */
Svet Ganovaf189e32019-02-15 18:45:29 -08006062 public long getAccessCount(@UidState int fromUidState, @UidState int toUidState,
6063 @OpFlags int flags) {
6064 return sumForFlagsInStates(mAccessCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07006065 }
6066
6067 /**
6068 * Gets the number times the op was rejected in the foreground.
6069 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006070 * @param flags The flags which are any combination of
6071 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
6072 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
6073 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
6074 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006075 * @return The times the op was rejected in the foreground.
6076 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006077 * @see #getBackgroundRejectCount(int)
6078 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07006079 */
Svet Ganovaf189e32019-02-15 18:45:29 -08006080 public long getForegroundRejectCount(@OpFlags int flags) {
6081 return sumForFlagsInStates(mRejectCount, MAX_PRIORITY_UID_STATE,
6082 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07006083 }
6084
6085 /**
6086 * Gets the number times the op was rejected in the background.
6087 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006088 * @param flags The flags which are any combination of
6089 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
6090 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
6091 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
6092 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006093 * @return The times the op was rejected in the background.
6094 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006095 * @see #getForegroundRejectCount(int)
6096 * @see #getRejectCount(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07006097 */
Svet Ganovaf189e32019-02-15 18:45:29 -08006098 public long getBackgroundRejectCount(@OpFlags int flags) {
6099 return sumForFlagsInStates(mRejectCount, resolveLastRestrictedUidState(mOp),
6100 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07006101 }
6102
6103 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08006104 * Gets the number times the op was rejected for a given range of UID states.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006105 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006106 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07006107 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
6108 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
6109 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08006110 * @param toUidState The UID state to which to query.
6111 * @param flags The flags which are any combination of
6112 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
6113 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
6114 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
6115 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006116 *
6117 * @return The times the op was rejected for the given UID state.
6118 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006119 * @see #getForegroundRejectCount(int)
6120 * @see #getBackgroundRejectCount(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07006121 */
Svet Ganovaf189e32019-02-15 18:45:29 -08006122 public long getRejectCount(@UidState int fromUidState, @UidState int toUidState,
6123 @OpFlags int flags) {
6124 return sumForFlagsInStates(mRejectCount, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07006125 }
6126
6127 /**
6128 * Gets the total duration the app op was accessed (performed) in the foreground.
Svet Ganov6f672a32019-07-08 16:40:42 -07006129 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006130 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006131 * @param flags The flags which are any combination of
6132 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
6133 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
6134 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
6135 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006136 * @return The total duration the app op was accessed in the foreground.
6137 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006138 * @see #getBackgroundAccessDuration(int)
6139 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07006140 */
Svet Ganovaf189e32019-02-15 18:45:29 -08006141 public long getForegroundAccessDuration(@OpFlags int flags) {
6142 return sumForFlagsInStates(mAccessDuration, MAX_PRIORITY_UID_STATE,
6143 resolveFirstUnrestrictedUidState(mOp), flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07006144 }
6145
6146 /**
6147 * Gets the total duration the app op was accessed (performed) in the background.
Svet Ganov6f672a32019-07-08 16:40:42 -07006148 * The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006149 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006150 * @param flags The flags which are any combination of
6151 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
6152 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
6153 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
6154 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006155 * @return The total duration the app op was accessed in the background.
6156 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006157 * @see #getForegroundAccessDuration(int)
6158 * @see #getAccessDuration(int, int, int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07006159 */
Svet Ganovaf189e32019-02-15 18:45:29 -08006160 public long getBackgroundAccessDuration(@OpFlags int flags) {
6161 return sumForFlagsInStates(mAccessDuration, resolveLastRestrictedUidState(mOp),
6162 MIN_PRIORITY_UID_STATE, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07006163 }
6164
6165 /**
Svet Ganovaf189e32019-02-15 18:45:29 -08006166 * Gets the total duration the app op was accessed (performed) for a given
Svet Ganov6f672a32019-07-08 16:40:42 -07006167 * range of UID states. The duration is in wall time.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006168 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006169 * @param fromUidState The UID state from which to query. Could be one of
Svet Ganovad0a49b2018-10-29 10:07:08 -07006170 * {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
6171 * {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
6172 * {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
Svet Ganovaf189e32019-02-15 18:45:29 -08006173 * @param toUidState The UID state from which to query.
6174 * @param flags The flags which are any combination of
6175 * {@link #OP_FLAG_SELF}, {@link #OP_FLAG_TRUSTED_PROXY},
6176 * {@link #OP_FLAG_UNTRUSTED_PROXY}, {@link #OP_FLAG_TRUSTED_PROXIED},
6177 * {@link #OP_FLAG_UNTRUSTED_PROXIED}. You can use {@link #OP_FLAGS_ALL}
6178 * for any flag.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006179 *
6180 * @return The total duration the app op was accessed for the given UID state.
6181 *
Svet Ganovaf189e32019-02-15 18:45:29 -08006182 * @see #getForegroundAccessDuration(int)
6183 * @see #getBackgroundAccessDuration(int)
Svet Ganovad0a49b2018-10-29 10:07:08 -07006184 */
Svet Ganovaf189e32019-02-15 18:45:29 -08006185 public long getAccessDuration(@UidState int fromUidState, @UidState int toUidState,
6186 @OpFlags int flags) {
6187 return sumForFlagsInStates(mAccessDuration, fromUidState, toUidState, flags);
Svet Ganovad0a49b2018-10-29 10:07:08 -07006188 }
6189
6190 @Override
6191 public int describeContents() {
6192 return 0;
6193 }
6194
6195 @Override
6196 public void writeToParcel(Parcel parcel, int flags) {
6197 parcel.writeInt(mOp);
Svet Ganovaf189e32019-02-15 18:45:29 -08006198 writeLongSparseLongArrayToParcel(mAccessCount, parcel);
6199 writeLongSparseLongArrayToParcel(mRejectCount, parcel);
6200 writeLongSparseLongArrayToParcel(mAccessDuration, parcel);
Svet Ganovad0a49b2018-10-29 10:07:08 -07006201 }
6202
Svet Ganov8455ba22019-01-02 13:05:56 -08006203 @Override
Aurimas Liutikas4d1699d2019-08-28 13:01:05 -07006204 public boolean equals(@Nullable Object obj) {
Svet Ganov8455ba22019-01-02 13:05:56 -08006205 if (this == obj) {
6206 return true;
6207 }
6208 if (obj == null || getClass() != obj.getClass()) {
6209 return false;
6210 }
6211 final HistoricalOp other = (HistoricalOp) obj;
6212 if (mOp != other.mOp) {
6213 return false;
6214 }
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08006215 if (!equalsLongSparseLongArray(mAccessCount, other.mAccessCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08006216 return false;
6217 }
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08006218 if (!equalsLongSparseLongArray(mRejectCount, other.mRejectCount)) {
Svet Ganov8455ba22019-01-02 13:05:56 -08006219 return false;
6220 }
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08006221 return equalsLongSparseLongArray(mAccessDuration, other.mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08006222 }
6223
6224 @Override
6225 public int hashCode() {
6226 int result = mOp;
Svet Ganovaf189e32019-02-15 18:45:29 -08006227 result = 31 * result + Objects.hashCode(mAccessCount);
6228 result = 31 * result + Objects.hashCode(mRejectCount);
6229 result = 31 * result + Objects.hashCode(mAccessDuration);
Svet Ganov8455ba22019-01-02 13:05:56 -08006230 return result;
6231 }
Svet Ganovaf189e32019-02-15 18:45:29 -08006232
6233 private void accept(@NonNull HistoricalOpsVisitor visitor) {
6234 visitor.visitHistoricalOp(this);
6235 }
6236
6237 private @NonNull LongSparseLongArray getOrCreateAccessCount() {
6238 if (mAccessCount == null) {
6239 mAccessCount = new LongSparseLongArray();
6240 }
6241 return mAccessCount;
6242 }
6243
6244 private @NonNull LongSparseLongArray getOrCreateRejectCount() {
6245 if (mRejectCount == null) {
6246 mRejectCount = new LongSparseLongArray();
6247 }
6248 return mRejectCount;
6249 }
6250
6251 private @NonNull LongSparseLongArray getOrCreateAccessDuration() {
6252 if (mAccessDuration == null) {
6253 mAccessDuration = new LongSparseLongArray();
6254 }
6255 return mAccessDuration;
6256 }
6257
6258 /**
6259 * Multiplies the entries in the array with the passed in scale factor and
6260 * rounds the result at up 0.5 boundary.
6261 *
6262 * @param data The data to scale.
6263 * @param scaleFactor The scale factor.
6264 */
6265 private static void scale(@NonNull LongSparseLongArray data, double scaleFactor) {
6266 if (data != null) {
6267 final int size = data.size();
6268 for (int i = 0; i < size; i++) {
6269 data.put(data.keyAt(i), (long) HistoricalOps.round(
6270 (double) data.valueAt(i) * scaleFactor));
6271 }
6272 }
6273 }
6274
6275 /**
6276 * Merges two arrays while lazily acquiring the destination.
6277 *
6278 * @param thisSupplier The destination supplier.
6279 * @param other The array to merge in.
6280 */
6281 private static void merge(@NonNull Supplier<LongSparseLongArray> thisSupplier,
6282 @Nullable LongSparseLongArray other) {
6283 if (other != null) {
6284 final int otherSize = other.size();
6285 for (int i = 0; i < otherSize; i++) {
6286 final LongSparseLongArray that = thisSupplier.get();
6287 final long otherKey = other.keyAt(i);
6288 final long otherValue = other.valueAt(i);
6289 that.put(otherKey, that.get(otherKey) + otherValue);
6290 }
6291 }
6292 }
6293
6294 /** @hide */
6295 public @Nullable LongSparseArray<Object> collectKeys() {
6296 LongSparseArray<Object> result = AppOpsManager.collectKeys(mAccessCount,
6297 null /*result*/);
6298 result = AppOpsManager.collectKeys(mRejectCount, result);
6299 result = AppOpsManager.collectKeys(mAccessDuration, result);
6300 return result;
6301 }
6302
6303 public static final @android.annotation.NonNull Creator<HistoricalOp> CREATOR =
6304 new Creator<HistoricalOp>() {
6305 @Override
6306 public @NonNull HistoricalOp createFromParcel(@NonNull Parcel source) {
6307 return new HistoricalOp(source);
6308 }
6309
6310 @Override
6311 public @NonNull HistoricalOp[] newArray(int size) {
6312 return new HistoricalOp[size];
6313 }
6314 };
6315 }
6316
6317 /**
6318 * Computes the sum of the counts for the given flags in between the begin and
6319 * end UID states.
6320 *
6321 * @param counts The data array.
Philip P. Moltmann4052d362019-09-19 14:52:38 -07006322 * @param beginUidState The beginning UID state (inclusive).
6323 * @param endUidState The end UID state (inclusive).
Svet Ganovaf189e32019-02-15 18:45:29 -08006324 * @param flags The UID flags.
6325 * @return The sum.
6326 */
6327 private static long sumForFlagsInStates(@Nullable LongSparseLongArray counts,
6328 @UidState int beginUidState, @UidState int endUidState, @OpFlags int flags) {
6329 if (counts == null) {
6330 return 0;
6331 }
6332 long sum = 0;
6333 while (flags != 0) {
6334 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
6335 flags &= ~flag;
6336 for (int uidState : UID_STATES) {
6337 if (uidState < beginUidState || uidState > endUidState) {
6338 continue;
6339 }
6340 final long key = makeKey(uidState, flag);
6341 sum += counts.get(key);
6342 }
6343 }
6344 return sum;
6345 }
6346
6347 /**
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08006348 * Callback for notification of changes to operation state.
6349 */
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006350 public interface OnOpChangedListener {
6351 public void onOpChanged(String op, String packageName);
6352 }
6353
6354 /**
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006355 * Callback for notification of changes to operation active state.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006356 */
6357 public interface OnOpActiveChangedListener {
6358 /**
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08006359 * Called when the active state of an app-op changes.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006360 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006361 * @param op The operation that changed.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006362 * @param packageName The package performing the operation.
6363 * @param active Whether the operation became active or inactive.
6364 */
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006365 void onOpActiveChanged(@NonNull String op, int uid, @NonNull String packageName,
6366 boolean active);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006367 }
6368
6369 /**
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006370 * Callback for notification of an op being noted.
6371 *
6372 * @hide
6373 */
6374 public interface OnOpNotedListener {
6375 /**
6376 * Called when an op was noted.
6377 *
6378 * @param code The op code.
6379 * @param uid The UID performing the operation.
6380 * @param packageName The package performing the operation.
6381 * @param result The result of the note.
6382 */
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05006383 void onOpNoted(int code, int uid, String packageName, int result);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006384 }
6385
6386 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006387 * Callback for notification of changes to operation state.
6388 * This allows you to see the raw op codes instead of strings.
6389 * @hide
6390 */
6391 public static class OnOpChangedInternalListener implements OnOpChangedListener {
6392 public void onOpChanged(String op, String packageName) { }
6393 public void onOpChanged(int op, String packageName) { }
Dianne Hackbornc2293022013-02-06 23:14:49 -08006394 }
6395
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006396 /**
6397 * Callback for notification of changes to operation state.
6398 * This allows you to see the raw op codes instead of strings.
6399 * @hide
6400 */
6401 public interface OnOpActiveChangedInternalListener extends OnOpActiveChangedListener {
6402 default void onOpActiveChanged(String op, int uid, String packageName, boolean active) { }
6403 default void onOpActiveChanged(int op, int uid, String packageName, boolean active) { }
6404 }
6405
Adam Bookatz182862e2020-04-27 21:58:22 -07006406 /**
6407 * Callback for notification of an op being started.
6408 *
6409 * @hide
6410 */
6411 public interface OnOpStartedListener {
6412 /**
6413 * Called when an op was started.
6414 *
6415 * Note: This is only for op starts. It is not called when an op is noted or stopped.
6416 *
6417 * @param op The op code.
6418 * @param uid The UID performing the operation.
6419 * @param packageName The package performing the operation.
6420 * @param result The result of the start.
6421 */
6422 void onOpStarted(int op, int uid, String packageName, int result);
6423 }
6424
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006425 AppOpsManager(Context context, IAppOpsService service) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006426 mContext = context;
6427 mService = service;
6428 }
6429
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08006430 /**
6431 * Retrieve current operation state for all applications.
6432 *
Winson6a864b52019-05-10 10:34:14 -07006433 * The mode of the ops returned are set for the package but may not reflect their effective
6434 * state due to UID policy or because it's controlled by a different master op.
6435 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006436 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006437 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07006438 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08006439 * @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 -07006440 * @hide
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08006441 */
Svet Ganov8455ba22019-01-02 13:05:56 -08006442 @SystemApi
6443 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
6444 public @NonNull List<AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[] ops) {
6445 final int opCount = ops.length;
6446 final int[] opCodes = new int[opCount];
6447 for (int i = 0; i < opCount; i++) {
6448 opCodes[i] = sOpStrToOp.get(ops[i]);
6449 }
6450 final List<AppOpsManager.PackageOps> result = getPackagesForOps(opCodes);
6451 return (result != null) ? result : Collections.emptyList();
6452 }
6453
6454 /**
6455 * Retrieve current operation state for all applications.
6456 *
Winson6a864b52019-05-10 10:34:14 -07006457 * The mode of the ops returned are set for the package but may not reflect their effective
6458 * state due to UID policy or because it's controlled by a different master op.
6459 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006460 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006461 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07006462 *
Svet Ganov8455ba22019-01-02 13:05:56 -08006463 * @param ops The set of operations you are interested in, or null if you want all of them.
6464 * @hide
6465 */
Dianne Hackbornc216a262018-04-26 13:46:22 -07006466 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01006467 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08006468 public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
6469 try {
6470 return mService.getPackagesForOps(ops);
6471 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006472 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08006473 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08006474 }
6475
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08006476 /**
6477 * Retrieve current operation state for one application.
6478 *
Winson6a864b52019-05-10 10:34:14 -07006479 * The mode of the ops returned are set for the package but may not reflect their effective
6480 * state due to UID policy or because it's controlled by a different master op.
6481 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006482 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006483 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07006484 *
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08006485 * @param uid The uid of the application of interest.
6486 * @param packageName The name of the application of interest.
6487 * @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 -08006488 *
6489 * @deprecated The int op codes are not stable and you should use the string based op
6490 * names which are stable and namespaced. Use
6491 * {@link #getOpsForPackage(int, String, String...)})}.
6492 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006493 * @hide
Suprabh Shukla169bed72019-05-13 13:54:58 -07006494 * @removed
Dianne Hackbornd7d28e62013-02-12 14:59:53 -08006495 */
Svet Ganov8455ba22019-01-02 13:05:56 -08006496 @Deprecated
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07006497 @SystemApi
Dianne Hackbornc216a262018-04-26 13:46:22 -07006498 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Dianne Hackborn62878492019-03-11 15:57:07 -07006499 public @NonNull List<PackageOps> getOpsForPackage(int uid, @NonNull String packageName,
6500 @Nullable int[] ops) {
Dianne Hackborn72e39832013-01-18 18:36:09 -08006501 try {
6502 return mService.getOpsForPackage(uid, packageName, ops);
6503 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006504 throw e.rethrowFromSystemServer();
Dianne Hackborn72e39832013-01-18 18:36:09 -08006505 }
Dianne Hackborn72e39832013-01-18 18:36:09 -08006506 }
6507
Svet Ganovae0e03a2016-02-25 18:22:10 -08006508 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08006509 * Retrieve current operation state for one application. The UID and the
6510 * package must match.
6511 *
Winson6a864b52019-05-10 10:34:14 -07006512 * The mode of the ops returned are set for the package but may not reflect their effective
6513 * state due to UID policy or because it's controlled by a different master op.
6514 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07006515 * Use {@link #unsafeCheckOp(String, int, String)}} or
Philip P. Moltmann59076d82019-08-19 15:00:40 -07006516 * {@link #noteOp(String, int, String, String, String)} if the effective mode is needed.
Winson6a864b52019-05-10 10:34:14 -07006517 *
Svet Ganov8455ba22019-01-02 13:05:56 -08006518 * @param uid The uid of the application of interest.
6519 * @param packageName The name of the application of interest.
6520 * @param ops The set of operations you are interested in, or null if you want all of them.
6521 *
6522 * @hide
6523 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08006524 @TestApi
Svet Ganov8455ba22019-01-02 13:05:56 -08006525 @SystemApi
6526 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
6527 public @NonNull List<AppOpsManager.PackageOps> getOpsForPackage(int uid,
6528 @NonNull String packageName, @Nullable String... ops) {
6529 int[] opCodes = null;
6530 if (ops != null) {
6531 opCodes = new int[ops.length];
6532 for (int i = 0; i < ops.length; i++) {
6533 opCodes[i] = strOpToOp(ops[i]);
6534 }
6535 }
6536 try {
6537 final List<PackageOps> result = mService.getOpsForPackage(uid, packageName, opCodes);
6538 if (result == null) {
6539 return Collections.emptyList();
6540 }
6541 return result;
6542 } catch (RemoteException e) {
6543 throw e.rethrowFromSystemServer();
6544 }
6545 }
6546
6547 /**
6548 * Retrieve historical app op stats for a period.
6549 *
Svet Ganov23c88db2019-01-22 20:38:11 -08006550 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08006551 * @param executor Executor on which to run the callback. If <code>null</code>
6552 * the callback is executed on the default executor running on the main thread.
6553 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006554 *
6555 * @throws IllegalArgumentException If any of the argument contracts is violated.
6556 *
6557 * @hide
6558 */
6559 @TestApi
6560 @SystemApi
6561 @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS)
Svet Ganov23c88db2019-01-22 20:38:11 -08006562 public void getHistoricalOps(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08006563 @NonNull Executor executor, @NonNull Consumer<HistoricalOps> callback) {
Daulet Zhanguzin0af97d62019-12-30 15:41:28 +00006564 Objects.requireNonNull(executor, "executor cannot be null");
6565 Objects.requireNonNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07006566 try {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08006567 mService.getHistoricalOps(request.mUid, request.mPackageName, request.mAttributionTag,
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08006568 request.mOpNames, request.mFilter, request.mBeginTimeMillis,
6569 request.mEndTimeMillis, request.mFlags, new RemoteCallback((result) -> {
Svet Ganov8455ba22019-01-02 13:05:56 -08006570 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
6571 final long identity = Binder.clearCallingIdentity();
6572 try {
6573 executor.execute(() -> callback.accept(ops));
6574 } finally {
6575 Binder.restoreCallingIdentity(identity);
6576 }
6577 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07006578 } catch (RemoteException e) {
6579 throw e.rethrowFromSystemServer();
6580 }
6581 }
6582
6583 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08006584 * Retrieve historical app op stats for a period.
Svet Ganov8455ba22019-01-02 13:05:56 -08006585 * <p>
6586 * This method queries only the on disk state and the returned ops are raw,
6587 * which is their times are relative to the history start as opposed to the
6588 * epoch start.
6589 *
Svet Ganov23c88db2019-01-22 20:38:11 -08006590 * @param request A request object describing the data being queried for.
Svet Ganov8455ba22019-01-02 13:05:56 -08006591 * @param executor Executor on which to run the callback. If <code>null</code>
6592 * the callback is executed on the default executor running on the main thread.
6593 * @param callback Callback on which to deliver the result.
Svet Ganovad0a49b2018-10-29 10:07:08 -07006594 *
6595 * @throws IllegalArgumentException If any of the argument contracts is violated.
6596 *
6597 * @hide
6598 */
6599 @TestApi
Svet Ganov8e5bf962019-03-19 23:59:03 -07006600 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
Svet Ganov23c88db2019-01-22 20:38:11 -08006601 public void getHistoricalOpsFromDiskRaw(@NonNull HistoricalOpsRequest request,
Svet Ganov8455ba22019-01-02 13:05:56 -08006602 @Nullable Executor executor, @NonNull Consumer<HistoricalOps> callback) {
Daulet Zhanguzin0af97d62019-12-30 15:41:28 +00006603 Objects.requireNonNull(executor, "executor cannot be null");
6604 Objects.requireNonNull(callback, "callback cannot be null");
Svet Ganovad0a49b2018-10-29 10:07:08 -07006605 try {
Svet Ganov23c88db2019-01-22 20:38:11 -08006606 mService.getHistoricalOpsFromDiskRaw(request.mUid, request.mPackageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08006607 request.mAttributionTag, request.mOpNames, request.mFilter,
6608 request.mBeginTimeMillis, request.mEndTimeMillis, request.mFlags,
6609 new RemoteCallback((result) -> {
Svet Ganov23c88db2019-01-22 20:38:11 -08006610 final HistoricalOps ops = result.getParcelable(KEY_HISTORICAL_OPS);
Svet Ganov8455ba22019-01-02 13:05:56 -08006611 final long identity = Binder.clearCallingIdentity();
6612 try {
6613 executor.execute(() -> callback.accept(ops));
6614 } finally {
6615 Binder.restoreCallingIdentity(identity);
6616 }
6617 }));
Svet Ganovad0a49b2018-10-29 10:07:08 -07006618 } catch (RemoteException e) {
6619 throw e.rethrowFromSystemServer();
6620 }
6621 }
6622
6623 /**
Svet Ganov8e5bf962019-03-19 23:59:03 -07006624 * Reloads the non historical state to allow testing the read/write path.
6625 *
6626 * @hide
6627 */
6628 @TestApi
6629 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
6630 public void reloadNonHistoricalState() {
6631 try {
6632 mService.reloadNonHistoricalState();
6633 } catch (RemoteException e) {
6634 throw e.rethrowFromSystemServer();
6635 }
6636 }
6637
6638 /**
Svet Ganovae0e03a2016-02-25 18:22:10 -08006639 * Sets given app op in the specified mode for app ops in the UID.
6640 * This applies to all apps currently in the UID or installed in
6641 * this UID in the future.
6642 *
6643 * @param code The app op.
6644 * @param uid The UID for which to set the app.
6645 * @param mode The app op mode to set.
6646 * @hide
6647 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08006648 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08006649 public void setUidMode(int code, int uid, @Mode int mode) {
Svet Ganov2af57082015-07-30 08:44:20 -07006650 try {
6651 mService.setUidMode(code, uid, mode);
6652 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006653 throw e.rethrowFromSystemServer();
Svet Ganov2af57082015-07-30 08:44:20 -07006654 }
6655 }
6656
Svet Ganovae0e03a2016-02-25 18:22:10 -08006657 /**
6658 * Sets given app op in the specified mode for app ops in the UID.
6659 * This applies to all apps currently in the UID or installed in
6660 * this UID in the future.
6661 *
6662 * @param appOp The app op.
6663 * @param uid The UID for which to set the app.
6664 * @param mode The app op mode to set.
6665 * @hide
6666 */
6667 @SystemApi
Eugene Susla93519852018-06-13 16:44:31 -07006668 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08006669 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08006670 public void setUidMode(@NonNull String appOp, int uid, @Mode int mode) {
Svet Ganovae0e03a2016-02-25 18:22:10 -08006671 try {
6672 mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode);
6673 } catch (RemoteException e) {
6674 throw e.rethrowFromSystemServer();
6675 }
6676 }
6677
Svet Ganov2af57082015-07-30 08:44:20 -07006678 /** @hide */
Svet Ganov9cea80cd2016-02-16 11:47:00 -08006679 public void setUserRestriction(int code, boolean restricted, IBinder token) {
Ruben Brunk29931bc2016-03-11 00:24:26 -08006680 setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
6681 }
6682
6683 /** @hide */
6684 public void setUserRestriction(int code, boolean restricted, IBinder token,
6685 String[] exceptionPackages) {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07006686 setUserRestrictionForUser(code, restricted, token, exceptionPackages, mContext.getUserId());
6687 }
6688
6689 /** @hide */
6690 public void setUserRestrictionForUser(int code, boolean restricted, IBinder token,
6691 String[] exceptionPackages, int userId) {
Svet Ganov9cea80cd2016-02-16 11:47:00 -08006692 try {
Svetoslav Ganove33f6132016-06-01 16:25:31 -07006693 mService.setUserRestriction(code, restricted, token, userId, exceptionPackages);
Svet Ganov9cea80cd2016-02-16 11:47:00 -08006694 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006695 throw e.rethrowFromSystemServer();
Svet Ganov9cea80cd2016-02-16 11:47:00 -08006696 }
6697 }
6698
6699 /** @hide */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00006700 @UnsupportedAppUsage
Peter Visontayb97fbc82017-12-21 16:23:55 +00006701 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08006702 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Svet Ganov8455ba22019-01-02 13:05:56 -08006703 public void setMode(int code, int uid, String packageName, @Mode int mode) {
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08006704 try {
6705 mService.setMode(code, uid, packageName, mode);
6706 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006707 throw e.rethrowFromSystemServer();
Dianne Hackborn5e45ee62013-01-24 19:13:44 -08006708 }
6709 }
6710
John Spurlock1af30c72014-03-10 08:33:35 -04006711 /**
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08006712 * Change the operating mode for the given op in the given app package. You must pass
6713 * in both the uid and name of the application whose mode is being modified; if these
6714 * do not match, the modification will not be applied.
6715 *
6716 * @param op The operation to modify. One of the OPSTR_* constants.
6717 * @param uid The user id of the application whose mode will be changed.
6718 * @param packageName The name of the application package name whose mode will
6719 * be changed.
6720 * @hide
6721 */
Svet Ganov8e5bf962019-03-19 23:59:03 -07006722 @TestApi
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08006723 @SystemApi
6724 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08006725 public void setMode(@NonNull String op, int uid, @Nullable String packageName,
6726 @Mode int mode) {
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08006727 try {
6728 mService.setMode(strOpToOp(op), uid, packageName, mode);
6729 } catch (RemoteException e) {
6730 throw e.rethrowFromSystemServer();
6731 }
6732 }
6733
6734 /**
John Spurlock1af30c72014-03-10 08:33:35 -04006735 * Set a non-persisted restriction on an audio operation at a stream-level.
6736 * Restrictions are temporary additional constraints imposed on top of the persisted rules
6737 * defined by {@link #setMode}.
6738 *
6739 * @param code The operation to restrict.
John Spurlock7b414672014-07-18 13:02:39 -04006740 * @param usage The {@link android.media.AudioAttributes} usage value.
John Spurlock1af30c72014-03-10 08:33:35 -04006741 * @param mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
6742 * @param exceptionPackages Optional list of packages to exclude from the restriction.
6743 * @hide
6744 */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08006745 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01006746 @UnsupportedAppUsage
Svet Ganov8455ba22019-01-02 13:05:56 -08006747 public void setRestriction(int code, @AttributeUsage int usage, @Mode int mode,
John Spurlock7b414672014-07-18 13:02:39 -04006748 String[] exceptionPackages) {
John Spurlock1af30c72014-03-10 08:33:35 -04006749 try {
6750 final int uid = Binder.getCallingUid();
John Spurlock7b414672014-07-18 13:02:39 -04006751 mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
John Spurlock1af30c72014-03-10 08:33:35 -04006752 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006753 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04006754 }
6755 }
6756
Dianne Hackborn607b4142013-08-02 18:10:10 -07006757 /** @hide */
Dianne Hackbornbf1b57d2018-03-07 12:42:47 -08006758 @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
Mathew Inwood61e8ae62018-08-14 14:17:44 +01006759 @UnsupportedAppUsage
Dianne Hackborn607b4142013-08-02 18:10:10 -07006760 public void resetAllModes() {
6761 try {
Jeff Sharkeyad357d12018-02-02 13:25:31 -07006762 mService.resetAllModes(mContext.getUserId(), null);
Dianne Hackborn607b4142013-08-02 18:10:10 -07006763 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006764 throw e.rethrowFromSystemServer();
Dianne Hackborn607b4142013-08-02 18:10:10 -07006765 }
6766 }
6767
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006768 /**
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08006769 * Gets the app-op name associated with a given permission.
6770 *
6771 * <p>The app-op name is one of the public constants defined
Svet Ganovfbf01f72015-04-28 18:39:06 -07006772 * in this class such as {@link #OPSTR_COARSE_LOCATION}.
Svetoslav Ganoveaca4c52016-05-05 18:08:00 -07006773 * This API is intended to be used for mapping runtime
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08006774 * permissions to the corresponding app-op.
Svet Ganovfbf01f72015-04-28 18:39:06 -07006775 *
6776 * @param permission The permission.
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08006777 * @return The app-op associated with the permission or {@code null}.
Svet Ganovfbf01f72015-04-28 18:39:06 -07006778 */
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08006779 public static @Nullable String permissionToOp(@NonNull String permission) {
Svet Ganovda0acdf2017-02-15 10:28:51 -08006780 final Integer opCode = sPermToOp.get(permission);
Svet Ganovb9d71a62015-04-30 10:38:13 -07006781 if (opCode == null) {
6782 return null;
6783 }
6784 return sOpToString[opCode];
Svet Ganovfbf01f72015-04-28 18:39:06 -07006785 }
6786
6787 /**
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006788 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006789 * You can watch op changes only for your UID.
6790 *
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07006791 * @param op The operation to monitor, one of OPSTR_*.
6792 * @param packageName The name of the application to monitor.
6793 * @param callback Where to report changes.
6794 */
Dianne Hackborn62878492019-03-11 15:57:07 -07006795 public void startWatchingMode(@NonNull String op, @Nullable String packageName,
6796 @NonNull final OnOpChangedListener callback) {
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07006797 startWatchingMode(strOpToOp(op), packageName, callback);
6798 }
6799
6800 /**
6801 * Monitor for changes to the operating mode for the given op in the given app package.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006802 * You can watch op changes only for your UID.
6803 *
6804 * @param op The operation to monitor, one of OPSTR_*.
6805 * @param packageName The name of the application to monitor.
6806 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
6807 * @param callback Where to report changes.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006808 */
Dianne Hackborn62878492019-03-11 15:57:07 -07006809 public void startWatchingMode(@NonNull String op, @Nullable String packageName, int flags,
6810 @NonNull final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006811 startWatchingMode(strOpToOp(op), packageName, flags, callback);
6812 }
6813
6814 /**
6815 * Monitor for changes to the operating mode for the given op in the given app package.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006816 *
6817 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08006818 * you can watch changes only for your UID.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006819 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006820 * @param op The operation to monitor, one of OP_*.
6821 * @param packageName The name of the application to monitor.
6822 * @param callback Where to report changes.
Dianne Hackborne4cb66f2013-10-02 10:34:02 -07006823 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006824 */
Jeff Sharkeybf6b2132018-02-27 11:16:37 -07006825 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006826 public void startWatchingMode(int op, String packageName, final OnOpChangedListener callback) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006827 startWatchingMode(op, packageName, 0, callback);
6828 }
6829
6830 /**
6831 * Monitor for changes to the operating mode for the given op in the given app package.
6832 *
6833 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
6834 * you can watch changes only for your UID.
6835 *
6836 * @param op The operation to monitor, one of OP_*.
6837 * @param packageName The name of the application to monitor.
6838 * @param flags Option flags: any combination of {@link #WATCH_FOREGROUND_CHANGES} or 0.
6839 * @param callback Where to report changes.
6840 * @hide
6841 */
6842 @RequiresPermission(value=android.Manifest.permission.WATCH_APPOPS, conditional=true)
6843 public void startWatchingMode(int op, String packageName, int flags,
6844 final OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08006845 synchronized (mModeWatchers) {
6846 IAppOpsCallback cb = mModeWatchers.get(callback);
6847 if (cb == null) {
6848 cb = new IAppOpsCallback.Stub() {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -07006849 public void opChanged(int op, int uid, String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07006850 if (callback instanceof OnOpChangedInternalListener) {
6851 ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
6852 }
6853 if (sOpToString[op] != null) {
6854 callback.onOpChanged(sOpToString[op], packageName);
6855 }
Dianne Hackbornc2293022013-02-06 23:14:49 -08006856 }
6857 };
6858 mModeWatchers.put(callback, cb);
6859 }
Philip P. Moltmann7641cd02020-03-11 14:42:43 -07006860
6861 // See CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE
6862 if (!Compatibility.isChangeEnabled(
6863 CALL_BACK_ON_CHANGED_LISTENER_WITH_SWITCHED_OP_CHANGE)) {
6864 flags |= CALL_BACK_ON_SWITCHED_OP;
6865 }
6866
Dianne Hackbornc2293022013-02-06 23:14:49 -08006867 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07006868 mService.startWatchingModeWithFlags(op, packageName, flags, cb);
Dianne Hackbornc2293022013-02-06 23:14:49 -08006869 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006870 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08006871 }
6872 }
6873 }
6874
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07006875 /**
6876 * Stop monitoring that was previously started with {@link #startWatchingMode}. All
6877 * monitoring associated with this callback will be removed.
6878 */
Dianne Hackborn62878492019-03-11 15:57:07 -07006879 public void stopWatchingMode(@NonNull OnOpChangedListener callback) {
Dianne Hackbornc2293022013-02-06 23:14:49 -08006880 synchronized (mModeWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006881 IAppOpsCallback cb = mModeWatchers.remove(callback);
Dianne Hackbornc2293022013-02-06 23:14:49 -08006882 if (cb != null) {
6883 try {
6884 mService.stopWatchingMode(cb);
6885 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07006886 throw e.rethrowFromSystemServer();
Dianne Hackbornc2293022013-02-06 23:14:49 -08006887 }
6888 }
6889 }
6890 }
6891
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006892 /** {@hide} */
6893 @Deprecated
6894 public void startWatchingActive(@NonNull int[] ops,
6895 @NonNull OnOpActiveChangedListener callback) {
6896 final String[] strOps = new String[ops.length];
6897 for (int i = 0; i < ops.length; i++) {
6898 strOps[i] = opToPublicName(ops[i]);
6899 }
6900 startWatchingActive(strOps, mContext.getMainExecutor(), callback);
6901 }
6902
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006903 /**
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08006904 * Start watching for changes to the active state of app-ops. An app-op may be
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006905 * long running and it has a clear start and stop delimiters. If an op is being
6906 * started or stopped by any package you will get a callback. To change the
6907 * watched ops for a registered callback you need to unregister and register it
6908 * again.
6909 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006910 * <p> If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS} permission
Svet Ganovf7b47252018-02-26 11:11:27 -08006911 * you can watch changes only for your UID.
6912 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006913 * @param ops The operations to watch.
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006914 * @param callback Where to report changes.
6915 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006916 * @see #stopWatchingActive
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006917 */
Svet Ganovf7b47252018-02-26 11:11:27 -08006918 // TODO: Uncomment below annotation once b/73559440 is fixed
6919 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006920 public void startWatchingActive(@NonNull String[] ops,
6921 @CallbackExecutor @NonNull Executor executor,
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006922 @NonNull OnOpActiveChangedListener callback) {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006923 Objects.requireNonNull(ops);
6924 Objects.requireNonNull(executor);
6925 Objects.requireNonNull(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006926 IAppOpsActiveCallback cb;
6927 synchronized (mActiveWatchers) {
6928 cb = mActiveWatchers.get(callback);
6929 if (cb != null) {
6930 return;
6931 }
6932 cb = new IAppOpsActiveCallback.Stub() {
6933 @Override
6934 public void opActiveChanged(int op, int uid, String packageName, boolean active) {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006935 executor.execute(() -> {
6936 if (callback instanceof OnOpActiveChangedInternalListener) {
6937 ((OnOpActiveChangedInternalListener) callback).onOpActiveChanged(op,
6938 uid, packageName, active);
6939 }
6940 if (sOpToString[op] != null) {
6941 callback.onOpActiveChanged(sOpToString[op], uid, packageName, active);
6942 }
6943 });
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006944 }
6945 };
6946 mActiveWatchers.put(callback, cb);
6947 }
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006948 final int[] rawOps = new int[ops.length];
6949 for (int i = 0; i < ops.length; i++) {
6950 rawOps[i] = strOpToOp(ops[i]);
6951 }
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006952 try {
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006953 mService.startWatchingActive(rawOps, cb);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006954 } catch (RemoteException e) {
6955 throw e.rethrowFromSystemServer();
6956 }
6957 }
6958
6959 /**
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08006960 * Stop watching for changes to the active state of an app-op. An app-op may be
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006961 * long running and it has a clear start and stop delimiters. Unregistering a
6962 * non-registered callback has no effect.
6963 *
Jeff Sharkey7095ab92019-08-20 16:50:28 -06006964 * @see #startWatchingActive
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006965 */
6966 public void stopWatchingActive(@NonNull OnOpActiveChangedListener callback) {
6967 synchronized (mActiveWatchers) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006968 final IAppOpsActiveCallback cb = mActiveWatchers.remove(callback);
Svetoslav Ganov2d20fb42018-02-08 15:52:10 -08006969 if (cb != null) {
6970 try {
6971 mService.stopWatchingActive(cb);
6972 } catch (RemoteException e) {
6973 throw e.rethrowFromSystemServer();
6974 }
6975 }
6976 }
6977 }
6978
Svet Ganovb3d2ae22018-12-17 22:06:15 -08006979 /**
Adam Bookatz182862e2020-04-27 21:58:22 -07006980 * Start watching for started app-ops.
6981 * An app-op may be long running and it has a clear start delimiter.
6982 * If an op start is attempted by any package, you will get a callback.
6983 * To change the watched ops for a registered callback you need to unregister and register it
6984 * again.
6985 *
6986 * <p> If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS} permission
6987 * you can watch changes only for your UID.
6988 *
6989 * @param ops The operations to watch.
6990 * @param callback Where to report changes.
6991 *
6992 * @see #stopWatchingStarted(OnOpStartedListener)
6993 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
6994 * @see #startWatchingNoted(int[], OnOpNotedListener)
6995 * @see #startOp(int, int, String, boolean, String, String)
6996 * @see #finishOp(int, int, String, String)
6997 *
6998 * @hide
6999 */
7000 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
7001 public void startWatchingStarted(@NonNull int[] ops, @NonNull OnOpStartedListener callback) {
7002 IAppOpsStartedCallback cb;
7003 synchronized (mStartedWatchers) {
7004 if (mStartedWatchers.containsKey(callback)) {
7005 return;
7006 }
7007 cb = new IAppOpsStartedCallback.Stub() {
7008 @Override
7009 public void opStarted(int op, int uid, String packageName, int mode) {
7010 callback.onOpStarted(op, uid, packageName, mode);
7011 }
7012 };
7013 mStartedWatchers.put(callback, cb);
7014 }
7015 try {
7016 mService.startWatchingStarted(ops, cb);
7017 } catch (RemoteException e) {
7018 throw e.rethrowFromSystemServer();
7019 }
7020 }
7021
7022 /**
7023 * Stop watching for started app-ops.
7024 * An app-op may be long running and it has a clear start delimiter.
7025 * Henceforth, if an op start is attempted by any package, you will not get a callback.
7026 * Unregistering a non-registered callback has no effect.
7027 *
7028 * @see #startWatchingStarted(int[], OnOpStartedListener)
7029 * @see #startOp(int, int, String, boolean, String, String)
7030 *
7031 * @hide
7032 */
7033 public void stopWatchingStarted(@NonNull OnOpStartedListener callback) {
7034 synchronized (mStartedWatchers) {
7035 final IAppOpsStartedCallback cb = mStartedWatchers.remove(callback);
7036 if (cb != null) {
7037 try {
7038 mService.stopWatchingStarted(cb);
7039 } catch (RemoteException e) {
7040 throw e.rethrowFromSystemServer();
7041 }
7042 }
7043 }
7044 }
7045
7046 /**
Svet Ganovb3d2ae22018-12-17 22:06:15 -08007047 * Start watching for noted app ops. An app op may be immediate or long running.
7048 * Immediate ops are noted while long running ones are started and stopped. This
7049 * method allows registering a listener to be notified when an app op is noted. If
7050 * an op is being noted by any package you will get a callback. To change the
7051 * watched ops for a registered callback you need to unregister and register it again.
7052 *
7053 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
7054 * you can watch changes only for your UID.
7055 *
7056 * @param ops The ops to watch.
7057 * @param callback Where to report changes.
7058 *
7059 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
Adam Bookatz182862e2020-04-27 21:58:22 -07007060 * @see #startWatchingStarted(int[], OnOpStartedListener)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08007061 * @see #stopWatchingNoted(OnOpNotedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007062 * @see #noteOp(String, int, String, String, String)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08007063 *
7064 * @hide
7065 */
7066 @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05007067 public void startWatchingNoted(@NonNull int[] ops, @NonNull OnOpNotedListener callback) {
Svet Ganovb3d2ae22018-12-17 22:06:15 -08007068 IAppOpsNotedCallback cb;
7069 synchronized (mNotedWatchers) {
7070 cb = mNotedWatchers.get(callback);
7071 if (cb != null) {
7072 return;
7073 }
7074 cb = new IAppOpsNotedCallback.Stub() {
7075 @Override
7076 public void opNoted(int op, int uid, String packageName, int mode) {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05007077 callback.onOpNoted(op, uid, packageName, mode);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08007078 }
7079 };
7080 mNotedWatchers.put(callback, cb);
7081 }
7082 try {
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05007083 mService.startWatchingNoted(ops, cb);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08007084 } catch (RemoteException e) {
7085 throw e.rethrowFromSystemServer();
7086 }
7087 }
7088
7089 /**
7090 * Stop watching for noted app ops. An app op may be immediate or long running.
7091 * Unregistering a non-registered callback has no effect.
7092 *
Fabian Kozynski0b4592c2018-12-20 12:58:45 -05007093 * @see #startWatchingNoted(int[], OnOpNotedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007094 * @see #noteOp(String, int, String, String, String)
Svet Ganovb3d2ae22018-12-17 22:06:15 -08007095 *
7096 * @hide
7097 */
7098 public void stopWatchingNoted(@NonNull OnOpNotedListener callback) {
7099 synchronized (mNotedWatchers) {
Adam Bookatz182862e2020-04-27 21:58:22 -07007100 final IAppOpsNotedCallback cb = mNotedWatchers.remove(callback);
Svet Ganovb3d2ae22018-12-17 22:06:15 -08007101 if (cb != null) {
7102 try {
7103 mService.stopWatchingNoted(cb);
7104 } catch (RemoteException e) {
7105 throw e.rethrowFromSystemServer();
7106 }
7107 }
7108 }
7109 }
7110
Dianne Hackborn95d78532013-09-11 09:51:14 -07007111 private String buildSecurityExceptionMsg(int op, int uid, String packageName) {
7112 return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
7113 }
7114
Adam Lesinskib5cf61b2014-08-18 16:10:28 -07007115 /**
7116 * {@hide}
7117 */
Artur Satayevf0b7d0b2019-11-04 11:16:45 +00007118 @UnsupportedAppUsage
Philip P. Moltmann33115152018-04-11 13:39:36 -07007119 @TestApi
Dianne Hackborn62878492019-03-11 15:57:07 -07007120 public static int strOpToOp(@NonNull String op) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007121 Integer val = sOpStrToOp.get(op);
7122 if (val == null) {
7123 throw new IllegalArgumentException("Unknown operation string: " + op);
7124 }
7125 return val;
7126 }
7127
7128 /**
7129 * Do a quick check for whether an application might be able to perform an operation.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007130 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007131 * String, String)} or {@link #startOp(String, int, String, String, String)} for your actual
7132 * security checks, which also ensure that the given uid and package name are consistent. This
7133 * function can just be used for a quick check to see if an operation has been disabled for the
7134 * application, as an early reject of some work. This does not modify the time stamp or other
7135 * data about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07007136 *
7137 * <p>Important things this will not do (which you need to ultimate use
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007138 * {@link #noteOp(String, int, String, String, String)} or
7139 * {@link #startOp(String, int, String, String, String)} to cover):</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -07007140 * <ul>
7141 * <li>Verifying the uid and package are consistent, so callers can't spoof
7142 * their identity.</li>
7143 * <li>Taking into account the current foreground/background state of the
7144 * app; apps whose mode varies by this state will always be reported
7145 * as {@link #MODE_ALLOWED}.</li>
7146 * </ul>
7147 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007148 * @param op The operation to check. One of the OPSTR_* constants.
7149 * @param uid The user id of the application attempting to perform the operation.
7150 * @param packageName The name of the application attempting to perform the operation.
7151 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
7152 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
7153 * causing the app to crash).
7154 * @throws SecurityException If the app has been configured to crash on this op.
7155 */
Dianne Hackborn62878492019-03-11 15:57:07 -07007156 public int unsafeCheckOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07007157 return checkOp(strOpToOp(op), uid, packageName);
7158 }
7159
7160 /**
7161 * @deprecated Renamed to {@link #unsafeCheckOp(String, int, String)}.
7162 */
7163 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07007164 public int checkOp(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007165 return checkOp(strOpToOp(op), uid, packageName);
7166 }
7167
7168 /**
John Spurlock925b85e2014-03-10 16:52:11 -04007169 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007170 * returns {@link #MODE_ERRORED}.
7171 */
Dianne Hackborn62878492019-03-11 15:57:07 -07007172 public int unsafeCheckOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackbornf0c322a2018-06-13 15:24:04 -07007173 return checkOpNoThrow(strOpToOp(op), uid, packageName);
7174 }
7175
7176 /**
7177 * @deprecated Renamed to {@link #unsafeCheckOpNoThrow(String, int, String)}.
7178 */
7179 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07007180 public int checkOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007181 return checkOpNoThrow(strOpToOp(op), uid, packageName);
7182 }
7183
7184 /**
Dianne Hackborn65a4f252018-05-08 17:30:48 -07007185 * Like {@link #checkOp} but returns the <em>raw</em> mode associated with the op.
7186 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
Dianne Hackborn65a4f252018-05-08 17:30:48 -07007187 */
Dianne Hackborn62878492019-03-11 15:57:07 -07007188 public int unsafeCheckOpRaw(@NonNull String op, int uid, @NonNull String packageName) {
Adam Bookatz38767932020-02-05 12:13:40 -08007189 return unsafeCheckOpRawNoThrow(op, uid, packageName);
Svet Ganovaf189e32019-02-15 18:45:29 -08007190 }
7191
7192 /**
7193 * Like {@link #unsafeCheckOpNoThrow(String, int, String)} but returns the <em>raw</em>
7194 * mode associated with the op. Does not throw a security exception, does not translate
7195 * {@link #MODE_FOREGROUND}.
7196 */
7197 public int unsafeCheckOpRawNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Adam Bookatz38767932020-02-05 12:13:40 -08007198 return unsafeCheckOpRawNoThrow(strOpToOp(op), uid, packageName);
7199 }
7200
7201 /**
7202 * Returns the <em>raw</em> mode associated with the op.
7203 * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
7204 * @hide
7205 */
7206 public int unsafeCheckOpRawNoThrow(int op, int uid, @NonNull String packageName) {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07007207 try {
Adam Bookatz38767932020-02-05 12:13:40 -08007208 return mService.checkOperationRaw(op, uid, packageName);
Dianne Hackborn65a4f252018-05-08 17:30:48 -07007209 } catch (RemoteException e) {
7210 throw e.rethrowFromSystemServer();
7211 }
7212 }
7213
7214 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007215 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007216 */
7217 @Deprecated
7218 public int noteOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007219 return noteOp(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007220 }
7221
7222 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007223 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007224 *
7225 * @hide
7226 */
7227 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007228 + "#noteOp(java.lang.String, int, java.lang.String, java.lang.String, "
7229 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007230 @Deprecated
7231 public int noteOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007232 return noteOp(op, Process.myUid(), mContext.getOpPackageName(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007233 }
7234
7235 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007236 * @deprecated Use {@link #noteOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007237 *
7238 * @hide
7239 */
7240 @Deprecated
7241 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007242 + "#noteOp(java.lang.String, int, java.lang.String, java.lang.String, "
7243 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007244 public int noteOp(int op, int uid, @Nullable String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007245 return noteOp(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007246 }
7247
7248 /**
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007249 * Make note of an application performing an operation. Note that you must pass
7250 * in both the uid and name of the application to be checked; this function will verify
7251 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
7252 * succeeds, the last execution time of the operation for this app will be updated to
7253 * the current time.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007254 *
Philip P. Moltmann9e367002020-02-03 17:01:05 -08007255 * <p>If this is a check that is not preceding the protected operation, use
7256 * {@link #unsafeCheckOp} instead.
7257 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007258 * @param op The operation to note. One of the OPSTR_* constants.
7259 * @param uid The user id of the application attempting to perform the operation.
7260 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007261 * @param attributionTag The {@link Context#createAttributionContext attribution tag} or {@code
7262 * null} for default attribution
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007263 * @param message A message describing the reason the op was noted
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08007264 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007265 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
7266 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
7267 * causing the app to crash).
7268 *
7269 * @throws SecurityException If the app has been configured to crash on this op.
Svet Ganov99b60432015-06-27 13:15:22 -07007270 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007271 public int noteOp(@NonNull String op, int uid, @Nullable String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007272 @Nullable String attributionTag, @Nullable String message) {
7273 return noteOp(strOpToOp(op), uid, packageName, attributionTag, message);
Svet Ganov99b60432015-06-27 13:15:22 -07007274 }
7275
7276 /**
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007277 * Make note of an application performing an operation. Note that you must pass
7278 * in both the uid and name of the application to be checked; this function will verify
7279 * that these two match, and if not, return {@link #MODE_IGNORED}. If this call
7280 * succeeds, the last execution time of the operation for this app will be updated to
7281 * the current time.
7282 *
Philip P. Moltmann9e367002020-02-03 17:01:05 -08007283 * <p>If this is a check that is not preceding the protected operation, use
7284 * {@link #unsafeCheckOp} instead.
7285 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007286 * @param op The operation to note. One of the OP_* constants.
7287 * @param uid The user id of the application attempting to perform the operation.
7288 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007289 * @param attributionTag The {@link Context#createAttributionContext attribution tag} or {@code
7290 * null} for default attribution
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007291 * @param message A message describing the reason the op was noted
7292 *
7293 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
7294 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
7295 * causing the app to crash).
7296 *
7297 * @throws SecurityException If the app has been configured to crash on this op.
7298 *
7299 * @hide
7300 */
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007301 public int noteOp(int op, int uid, @Nullable String packageName,
7302 @Nullable String attributionTag, @Nullable String message) {
7303 final int mode = noteOpNoThrow(op, uid, packageName, attributionTag, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007304 if (mode == MODE_ERRORED) {
7305 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
7306 }
7307 return mode;
7308 }
7309
7310 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007311 * @deprecated Use {@link #noteOpNoThrow(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007312 */
7313 @Deprecated
7314 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007315 return noteOpNoThrow(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007316 }
7317
7318 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007319 * @deprecated Use {@link #noteOpNoThrow(int, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007320 *
7321 * @hide
7322 */
7323 @Deprecated
7324 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007325 + "#noteOpNoThrow(java.lang.String, int, java.lang.String, java.lang.String, "
7326 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007327 public int noteOpNoThrow(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007328 return noteOpNoThrow(op, uid, packageName, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007329 }
7330
7331 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007332 * Like {@link #noteOp(String, int, String, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007333 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
7334 *
7335 * @param op The operation to note. One of the OPSTR_* constants.
7336 * @param uid The user id of the application attempting to perform the operation.
7337 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007338 * @param attributionTag The {@link Context#createAttributionContext attribution tag} or {@code
7339 * null} for default attribution
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007340 * @param message A message describing the reason the op was noted
7341 *
7342 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
7343 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
7344 * causing the app to crash).
7345 */
7346 public int noteOpNoThrow(@NonNull String op, int uid, @NonNull String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007347 @Nullable String attributionTag, @Nullable String message) {
7348 return noteOpNoThrow(strOpToOp(op), uid, packageName, attributionTag, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007349 }
7350
7351 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007352 * Like {@link #noteOp(String, int, String, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007353 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
7354 *
7355 * @param op The operation to note. One of the OP_* constants.
7356 * @param uid The user id of the application attempting to perform the operation.
7357 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007358 * @param attributionTag The {@link Context#createAttributionContext attribution tag} or {@code
7359 * null} for default attribution
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007360 * @param message A message describing the reason the op was noted
7361 *
7362 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
7363 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
7364 * causing the app to crash).
7365 *
7366 * @hide
7367 */
7368 public int noteOpNoThrow(int op, int uid, @Nullable String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007369 @Nullable String attributionTag, @Nullable String message) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007370 try {
David Cheung2ead9662020-02-19 16:11:06 -08007371 collectNoteOpCallsForValidation(op);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007372 int collectionMode = getNotedOpCollectionMode(uid, packageName, op);
7373 if (collectionMode == COLLECT_ASYNC) {
7374 if (message == null) {
7375 // Set stack trace as default message
7376 message = getFormattedStackTrace();
7377 }
7378 }
7379
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007380 int mode = mService.noteOperation(op, uid, packageName, attributionTag,
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007381 collectionMode == COLLECT_ASYNC, message);
7382
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007383 if (mode == MODE_ALLOWED) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007384 if (collectionMode == COLLECT_SELF) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007385 collectNotedOpForSelf(op, attributionTag);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007386 } else if (collectionMode == COLLECT_SYNC) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007387 collectNotedOpSync(op, attributionTag);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007388 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007389 }
7390
7391 return mode;
7392 } catch (RemoteException e) {
7393 throw e.rethrowFromSystemServer();
7394 }
7395 }
7396
7397 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007398 * @deprecated Use {@link #noteProxyOp(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007399 */
7400 @Deprecated
7401 public int noteProxyOp(@NonNull String op, @NonNull String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007402 return noteProxyOp(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007403 }
7404
7405 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007406 * @deprecated Use {@link #noteProxyOp(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007407 *
7408 * @hide
7409 */
7410 @Deprecated
7411 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Use {@link "
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007412 + "#noteProxyOp(java.lang.String, java.lang.String, int, java.lang.String, "
7413 + "java.lang.String)} instead")
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007414 public int noteProxyOp(int op, @Nullable String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007415 return noteProxyOp(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007416 }
7417
7418 /**
7419 * Make note of an application performing an operation on behalf of another application when
7420 * handling an IPC. This function will verify that the calling uid and proxied package name
7421 * match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution
7422 * time of the operation for the proxied app and your app will be updated to the current time.
7423 *
7424 * @param op The operation to note. One of the OP_* constants.
7425 * @param proxiedPackageName The name of the application calling into the proxy application.
7426 * @param proxiedUid The uid of the proxied application
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007427 * @param proxiedAttributionTag The proxied {@link Context#createAttributionContext
7428 * attribution tag} or {@code null} for default attribution
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007429 * @param message A message describing the reason the op was noted
7430 *
7431 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED}
7432 * if it is not allowed and should be silently ignored (without causing the app to crash).
7433 *
7434 * @throws SecurityException If the proxy or proxied app has been configured to crash on this
7435 * op.
7436 *
7437 * @hide
7438 */
7439 public int noteProxyOp(int op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007440 @Nullable String proxiedAttributionTag, @Nullable String message) {
7441 int mode = noteProxyOpNoThrow(op, proxiedPackageName, proxiedUid, proxiedAttributionTag,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007442 message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007443 if (mode == MODE_ERRORED) {
7444 throw new SecurityException("Proxy package " + mContext.getOpPackageName()
7445 + " from uid " + Process.myUid() + " or calling package " + proxiedPackageName
7446 + " from uid " + proxiedUid + " not allowed to perform " + sOpNames[op]);
7447 }
7448 return mode;
7449 }
7450
7451 /**
7452 * Make note of an application performing an operation on behalf of another application when
7453 * handling an IPC. This function will verify that the calling uid and proxied package name
7454 * match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution
7455 * time of the operation for the proxied app and your app will be updated to the current time.
7456 *
7457 * @param op The operation to note. One of the OPSTR_* constants.
7458 * @param proxiedPackageName The name of the application calling into the proxy application.
7459 * @param proxiedUid The uid of the proxied application
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007460 * @param proxiedAttributionTag The proxied {@link Context#createAttributionContext
7461 * attribution tag} or {@code null} for default attribution
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007462 * @param message A message describing the reason the op was noted
7463 *
7464 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED}
7465 * if it is not allowed and should be silently ignored (without causing the app to crash).
7466 *
7467 * @throws SecurityException If the proxy or proxied app has been configured to crash on this
7468 * op.
7469 */
7470 public int noteProxyOp(@NonNull String op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007471 @Nullable String proxiedAttributionTag, @Nullable String message) {
7472 return noteProxyOp(strOpToOp(op), proxiedPackageName, proxiedUid, proxiedAttributionTag,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007473 message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007474 }
7475
7476 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007477 * @deprecated Use {@link #noteProxyOpNoThrow(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007478 */
7479 @Deprecated
7480 public int noteProxyOpNoThrow(@NonNull String op, @NonNull String proxiedPackageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007481 return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid(), null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007482 }
7483
7484 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007485 * @deprecated Use {@link #noteProxyOpNoThrow(String, String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007486 */
7487 @Deprecated
7488 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
7489 int proxiedUid) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007490 return noteProxyOpNoThrow(op, proxiedPackageName, proxiedUid, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007491 }
7492
7493 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007494 * Like {@link #noteProxyOp(String, String, int, String, String)} but instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007495 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08007496 *
7497 * <p>This API requires package with the {@code proxiedPackageName} to belong to
7498 * {@code proxiedUid}.
7499 *
7500 * @param op The op to note
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007501 * @param proxiedPackageName The package to note the op for
7502 * @param proxiedUid The uid the package belongs to
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007503 * @param proxiedAttributionTag The proxied {@link Context#createAttributionContext
7504 * attribution tag} or {@code null} for default attribution
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007505 * @param message A message describing the reason the op was noted
7506 */
7507 public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007508 int proxiedUid, @Nullable String proxiedAttributionTag, @Nullable String message) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007509 return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007510 proxiedAttributionTag, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007511 }
7512
7513 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007514 * Like {@link #noteProxyOp(int, String, int, String, String)} but instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007515 * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
7516 *
7517 * @param op The op to note
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08007518 * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
7519 * noted for the "android" package
7520 * @param proxiedUid The uid the package belongs to
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007521 * @param proxiedAttributionTag The proxied {@link Context#createAttributionContext
7522 * attribution tag} or {@code null} for default attribution
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007523 * @param message A message describing the reason the op was noted
7524 *
7525 * @hide
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08007526 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007527 public int noteProxyOpNoThrow(int op, @Nullable String proxiedPackageName, int proxiedUid,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007528 @Nullable String proxiedAttributionTag, @Nullable String message) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007529 int myUid = Process.myUid();
Philip P. Moltmann0d05e482019-02-08 13:05:25 -08007530
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007531 try {
David Cheung2ead9662020-02-19 16:11:06 -08007532 collectNoteOpCallsForValidation(op);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007533 int collectionMode = getNotedOpCollectionMode(proxiedUid, proxiedPackageName, op);
7534 if (collectionMode == COLLECT_ASYNC) {
7535 if (message == null) {
7536 // Set stack trace as default message
7537 message = getFormattedStackTrace();
7538 }
7539 }
7540
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007541 int mode = mService.noteProxyOperation(op, proxiedUid, proxiedPackageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007542 proxiedAttributionTag, myUid, mContext.getOpPackageName(),
7543 mContext.getAttributionTag(), collectionMode == COLLECT_ASYNC, message);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007544
7545 if (mode == MODE_ALLOWED) {
7546 if (collectionMode == COLLECT_SELF) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007547 collectNotedOpForSelf(op, proxiedAttributionTag);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007548 } else if (collectionMode == COLLECT_SYNC
7549 // Only collect app-ops when the proxy is trusted
7550 && mContext.checkPermission(Manifest.permission.UPDATE_APP_OPS_STATS, -1,
7551 myUid) == PackageManager.PERMISSION_GRANTED) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007552 collectNotedOpSync(op, proxiedAttributionTag);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007553 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007554 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007555
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007556 return mode;
7557 } catch (RemoteException e) {
7558 throw e.rethrowFromSystemServer();
7559 }
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007560 }
7561
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007562 /**
7563 * Do a quick check for whether an application might be able to perform an operation.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007564 * This is <em>not</em> a security check; you must use {@link #noteOp(String, int, String,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007565 * String, String)} or {@link #startOp(int, int, String, boolean, String, String)} for your
7566 * actual security checks, which also ensure that the given uid and package name are consistent.
7567 * This function can just be used for a quick check to see if an operation has been disabled for
7568 * the application, as an early reject of some work. This does not modify the time stamp or
7569 * other data about the operation.
Dianne Hackbornc216a262018-04-26 13:46:22 -07007570 *
7571 * <p>Important things this will not do (which you need to ultimate use
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007572 * {@link #noteOp(String, int, String, String, String)} or
7573 * {@link #startOp(int, int, String, boolean, String, String)} to cover):</p>
Dianne Hackbornc216a262018-04-26 13:46:22 -07007574 * <ul>
7575 * <li>Verifying the uid and package are consistent, so callers can't spoof
7576 * their identity.</li>
7577 * <li>Taking into account the current foreground/background state of the
7578 * app; apps whose mode varies by this state will always be reported
7579 * as {@link #MODE_ALLOWED}.</li>
7580 * </ul>
7581 *
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007582 * @param op The operation to check. One of the OP_* constants.
7583 * @param uid The user id of the application attempting to perform the operation.
7584 * @param packageName The name of the application attempting to perform the operation.
7585 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
7586 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
7587 * causing the app to crash).
7588 * @throws SecurityException If the app has been configured to crash on this op.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007589 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007590 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01007591 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08007592 public int checkOp(int op, int uid, String packageName) {
7593 try {
7594 int mode = mService.checkOperation(op, uid, packageName);
7595 if (mode == MODE_ERRORED) {
Dianne Hackborn95d78532013-09-11 09:51:14 -07007596 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborn35654b62013-01-14 17:38:02 -08007597 }
7598 return mode;
7599 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07007600 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08007601 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08007602 }
7603
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007604 /**
7605 * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
7606 * returns {@link #MODE_ERRORED}.
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007607 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007608 */
Mathew Inwood61e8ae62018-08-14 14:17:44 +01007609 @UnsupportedAppUsage
Dianne Hackborn35654b62013-01-14 17:38:02 -08007610 public int checkOpNoThrow(int op, int uid, String packageName) {
7611 try {
Dianne Hackborn65a4f252018-05-08 17:30:48 -07007612 int mode = mService.checkOperation(op, uid, packageName);
7613 return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
Dianne Hackborn35654b62013-01-14 17:38:02 -08007614 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07007615 throw e.rethrowFromSystemServer();
Dianne Hackborn35654b62013-01-14 17:38:02 -08007616 }
Dianne Hackborn35654b62013-01-14 17:38:02 -08007617 }
7618
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007619 /**
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08007620 * @deprecated Use {@link PackageManager#getPackageUid} instead
Jeff Sharkey911d7f42013-09-05 18:11:45 -07007621 */
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08007622 @Deprecated
Dianne Hackborn62878492019-03-11 15:57:07 -07007623 public void checkPackage(int uid, @NonNull String packageName) {
Jeff Sharkey911d7f42013-09-05 18:11:45 -07007624 try {
7625 if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
7626 throw new SecurityException(
7627 "Package " + packageName + " does not belong to " + uid);
7628 }
7629 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07007630 throw e.rethrowFromSystemServer();
Jeff Sharkey911d7f42013-09-05 18:11:45 -07007631 }
7632 }
7633
7634 /**
John Spurlock1af30c72014-03-10 08:33:35 -04007635 * Like {@link #checkOp} but at a stream-level for audio operations.
7636 * @hide
7637 */
7638 public int checkAudioOp(int op, int stream, int uid, String packageName) {
7639 try {
7640 final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
7641 if (mode == MODE_ERRORED) {
7642 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
7643 }
7644 return mode;
7645 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07007646 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04007647 }
John Spurlock1af30c72014-03-10 08:33:35 -04007648 }
7649
7650 /**
7651 * Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it
7652 * returns {@link #MODE_ERRORED}.
7653 * @hide
7654 */
7655 public int checkAudioOpNoThrow(int op, int stream, int uid, String packageName) {
7656 try {
7657 return mService.checkAudioOperation(op, stream, uid, packageName);
7658 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07007659 throw e.rethrowFromSystemServer();
John Spurlock1af30c72014-03-10 08:33:35 -04007660 }
John Spurlock1af30c72014-03-10 08:33:35 -04007661 }
7662
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -08007663 /**
7664 * @deprecated Use own local {@link android.os.Binder#Binder()}
7665 *
7666 * @hide
7667 */
7668 @Deprecated
7669 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "Create own "
7670 + "local {@link android.os.Binder}")
Dianne Hackborne98f5db2013-07-17 17:23:25 -07007671 public static IBinder getToken(IAppOpsService service) {
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -08007672 return getClientId();
Dianne Hackborne98f5db2013-07-17 17:23:25 -07007673 }
7674
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -08007675 /** @hide */
7676 public static IBinder getClientId() {
7677 synchronized (AppOpsManager.class) {
7678 if (sClientId == null) {
7679 sClientId = new Binder();
7680 }
7681
7682 return sClientId;
7683 }
7684 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007685
Stanislav Zholnin90516b92020-01-20 14:03:06 +00007686 /** @hide */
7687 private static IAppOpsService getService() {
7688 synchronized (sLock) {
7689 if (sService == null) {
7690 sService = IAppOpsService.Stub.asInterface(
7691 ServiceManager.getService(Context.APP_OPS_SERVICE));
7692 }
7693 return sService;
7694 }
7695 }
7696
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007697 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007698 * @deprecated use {@link #startOp(String, int, String, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007699 */
7700 @Deprecated
7701 public int startOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007702 return startOp(op, uid, packageName, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08007703 }
7704
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007705 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007706 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Svet Ganovf7b47252018-02-26 11:11:27 -08007707 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007708 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007709 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007710 @Deprecated
7711 public int startOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007712 return startOp(op, Process.myUid(), mContext.getOpPackageName(), false, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08007713 }
7714
7715 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007716 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007717 *
7718 * @hide
7719 */
7720 @Deprecated
7721 public int startOp(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007722 return startOp(op, uid, packageName, false, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007723 }
7724
7725 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007726 * @deprecated Use {@link #startOp(int, int, String, boolean, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007727 *
7728 * @hide
7729 */
7730 @Deprecated
7731 public int startOp(int op, int uid, String packageName, boolean startIfModeDefault) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007732 return startOp(op, uid, packageName, startIfModeDefault, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007733 }
7734
7735 /**
7736 * Report that an application has started executing a long-running operation.
7737 *
7738 * @param op The operation to start. One of the OPSTR_* constants.
7739 * @param uid The user id of the application attempting to perform the operation.
7740 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007741 * @param attributionTag The {@link Context#createAttributionContext attribution tag} or
7742 * {@code null} for default attribution
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007743 * @param message Description why op was started
7744 *
7745 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
7746 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
7747 * causing the app to crash).
7748 *
7749 * @throws SecurityException If the app has been configured to crash on this op or
7750 * the package is not in the passed in UID.
7751 */
7752 public int startOp(@NonNull String op, int uid, @Nullable String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007753 @Nullable String attributionTag, @Nullable String message) {
7754 return startOp(strOpToOp(op), uid, packageName, false, attributionTag, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007755 }
7756
7757 /**
7758 * Report that an application has started executing a long-running operation.
Svet Ganovf7b47252018-02-26 11:11:27 -08007759 *
7760 * @param op The operation to start. One of the OP_* constants.
7761 * @param uid The user id of the application attempting to perform the operation.
7762 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007763 * @param attributionTag The {@link Context#createAttributionContext attribution tag} or
7764 * {@code null} for default attribution
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007765 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
7766 * @param message Description why op was started
7767 *
Svet Ganovf7b47252018-02-26 11:11:27 -08007768 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
7769 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
7770 * causing the app to crash).
Svet Ganovf7b47252018-02-26 11:11:27 -08007771 *
7772 * @throws SecurityException If the app has been configured to crash on this op or
7773 * the package is not in the passed in UID.
7774 *
7775 * @hide
7776 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007777 public int startOp(int op, int uid, @Nullable String packageName, boolean startIfModeDefault,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007778 @Nullable String attributionTag, @Nullable String message) {
7779 final int mode = startOpNoThrow(op, uid, packageName, startIfModeDefault, attributionTag,
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007780 message);
Svet Ganovf7b47252018-02-26 11:11:27 -08007781 if (mode == MODE_ERRORED) {
7782 throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007783 }
Svet Ganovf7b47252018-02-26 11:11:27 -08007784 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007785 }
7786
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007787 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007788 * @deprecated use {@link #startOpNoThrow(String, int, String, String, String)} instead
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007789 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007790 @Deprecated
7791 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007792 return startOpNoThrow(op, uid, packageName, null, null);
Svet Ganovf7b47252018-02-26 11:11:27 -08007793 }
7794
7795 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007796 * @deprecated Use {@link #startOpNoThrow(int, int, String, boolean, String, String} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007797 *
7798 * @hide
7799 */
7800 @Deprecated
7801 public int startOpNoThrow(int op, int uid, String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007802 return startOpNoThrow(op, uid, packageName, false, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007803 }
7804
7805 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007806 * @deprecated Use {@link #startOpNoThrow(int, int, String, boolean, String, String} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007807 *
7808 * @hide
7809 */
7810 @Deprecated
7811 public int startOpNoThrow(int op, int uid, String packageName, boolean startIfModeDefault) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007812 return startOpNoThrow(op, uid, packageName, startIfModeDefault, null, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007813 }
7814
7815 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007816 * Like {@link #startOp(String, int, String, String, String)} but instead of throwing a
Svet Ganovf7b47252018-02-26 11:11:27 -08007817 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
7818 *
7819 * @param op The operation to start. One of the OP_* constants.
7820 * @param uid The user id of the application attempting to perform the operation.
7821 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007822 * @param attributionTag The {@link Context#createAttributionContext attribution tag} or
7823 * {@code null} for default attribution
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007824 * @param message Description why op was started
7825 *
Svet Ganovf7b47252018-02-26 11:11:27 -08007826 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
7827 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
7828 * causing the app to crash).
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007829 */
7830 public int startOpNoThrow(@NonNull String op, int uid, @NonNull String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007831 @NonNull String attributionTag, @Nullable String message) {
7832 return startOpNoThrow(strOpToOp(op), uid, packageName, false, attributionTag, message);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007833 }
7834
7835 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007836 * Like {@link #startOp(int, int, String, boolean, String, String)} but instead of throwing a
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007837 * {@link SecurityException} it returns {@link #MODE_ERRORED}.
7838 *
7839 * @param op The operation to start. One of the OP_* constants.
7840 * @param uid The user id of the application attempting to perform the operation.
7841 * @param packageName The name of the application attempting to perform the operation.
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007842 * @param attributionTag The {@link Context#createAttributionContext attribution tag} or
7843 * {@code null} for default attribution
Svet Ganovf7b47252018-02-26 11:11:27 -08007844 * @param startIfModeDefault Whether to start if mode is {@link #MODE_DEFAULT}.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007845 * @param message Description why op was started
7846 *
7847 * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
7848 * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
7849 * causing the app to crash).
Svet Ganovf7b47252018-02-26 11:11:27 -08007850 *
7851 * @hide
7852 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007853 public int startOpNoThrow(int op, int uid, @NonNull String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007854 boolean startIfModeDefault, @Nullable String attributionTag, @Nullable String message) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007855 try {
David Cheung2ead9662020-02-19 16:11:06 -08007856 collectNoteOpCallsForValidation(op);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007857 int collectionMode = getNotedOpCollectionMode(uid, packageName, op);
7858 if (collectionMode == COLLECT_ASYNC) {
7859 if (message == null) {
7860 // Set stack trace as default message
7861 message = getFormattedStackTrace();
7862 }
7863 }
7864
Philip P. Moltmann6c6403e2019-12-09 10:08:29 -08007865 int mode = mService.startOperation(getClientId(), op, uid, packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007866 attributionTag, startIfModeDefault, collectionMode == COLLECT_ASYNC, message);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007867
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007868 if (mode == MODE_ALLOWED) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007869 if (collectionMode == COLLECT_SELF) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007870 collectNotedOpForSelf(op, attributionTag);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007871 } else if (collectionMode == COLLECT_SYNC) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007872 collectNotedOpSync(op, attributionTag);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08007873 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007874 }
7875
7876 return mode;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007877 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07007878 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007879 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007880 }
7881
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007882 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007883 * @deprecated Use {@link #finishOp(String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007884 *
Dianne Hackborn9bb0ee92013-09-22 12:31:38 -07007885 * @hide
Dianne Hackborn1304f4a2013-07-09 18:17:27 -07007886 */
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007887 @Deprecated
7888 public void finishOp(int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007889 finishOp(op, Process.myUid(), mContext.getOpPackageName(), null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007890 }
7891
7892 /**
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007893 * @deprecated Use {@link #finishOp(String, int, String, String)} instead
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007894 */
7895 public void finishOp(@NonNull String op, int uid, @NonNull String packageName) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007896 finishOp(strOpToOp(op), uid, packageName, null);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007897 }
7898
7899 /**
7900 * Report that an application is no longer performing an operation that had previously
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007901 * been started with {@link #startOp(String, int, String, String, String)}. There is no
7902 * validation of input or result; the parameters supplied here must be the exact same ones
7903 * previously passed in when starting the operation.
7904 */
7905 public void finishOp(@NonNull String op, int uid, @NonNull String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007906 @Nullable String attributionTag) {
7907 finishOp(strOpToOp(op), uid, packageName, attributionTag);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007908 }
7909
7910 /**
7911 * @deprecated Use {@link #finishOp(int, int, String, String)} instead
7912 *
7913 * @hide
7914 */
7915 public void finishOp(int op, int uid, @NonNull String packageName) {
7916 finishOp(op, uid, packageName, null);
7917 }
7918
7919 /**
7920 * Report that an application is no longer performing an operation that had previously
7921 * been started with {@link #startOp(int, int, String, boolean, String, String)}. There is no
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007922 * validation of input or result; the parameters supplied here must be the exact same ones
7923 * previously passed in when starting the operation.
7924 *
7925 * @hide
7926 */
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007927 public void finishOp(int op, int uid, @NonNull String packageName,
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007928 @Nullable String attributionTag) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007929 try {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08007930 mService.finishOperation(getClientId(), op, uid, packageName, attributionTag);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007931 } catch (RemoteException e) {
Jeff Sharkeyf8880562016-02-26 13:03:01 -07007932 throw e.rethrowFromSystemServer();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007933 }
7934 }
7935
Svet Ganovf7b47252018-02-26 11:11:27 -08007936 /**
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08007937 * Checks whether the given op for a package is active, i.e. did someone call {@link #startOp}
7938 * without {@link #finishOp} yet.
Jeff Sharkey7095ab92019-08-20 16:50:28 -06007939 * <p>
7940 * If you don't hold the {@code android.Manifest.permission#WATCH_APPOPS}
7941 * permission you can query only for your UID.
7942 *
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007943 * @see #finishOp(String, int, String, String)
7944 * @see #startOp(String, int, String, String, String)
Jeff Sharkey7095ab92019-08-20 16:50:28 -06007945 */
7946 public boolean isOpActive(@NonNull String op, int uid, @NonNull String packageName) {
7947 return isOperationActive(strOpToOp(op), uid, packageName);
7948 }
7949
7950 /**
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007951 * Start collection of noted appops on this thread.
7952 *
7953 * <p>Called at the beginning of a two way binder transaction.
7954 *
7955 * @see #finishNotedAppOpsCollection()
7956 *
7957 * @hide
7958 */
7959 public static void startNotedAppOpsCollection(int callingUid) {
7960 sBinderThreadCallingUid.set(callingUid);
7961 }
7962
7963 /**
7964 * State of a temporarily paused noted app-ops collection.
7965 *
7966 * @see #pauseNotedAppOpsCollection()
7967 *
7968 * @hide
7969 */
7970 public static class PausedNotedAppOpsCollection {
7971 final int mUid;
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007972 final @Nullable ArrayMap<String, long[]> mCollectedNotedAppOps;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007973
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007974 PausedNotedAppOpsCollection(int uid, @Nullable ArrayMap<String,
7975 long[]> collectedNotedAppOps) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007976 mUid = uid;
7977 mCollectedNotedAppOps = collectedNotedAppOps;
7978 }
7979 }
7980
7981 /**
7982 * Temporarily suspend collection of noted app-ops when binder-thread calls into the other
7983 * process. During such a call there might be call-backs coming back on the same thread which
7984 * should not be accounted to the current collection.
7985 *
7986 * @return a state needed to resume the collection
7987 *
7988 * @hide
7989 */
7990 public static @Nullable PausedNotedAppOpsCollection pauseNotedAppOpsCollection() {
7991 Integer previousUid = sBinderThreadCallingUid.get();
7992 if (previousUid != null) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07007993 ArrayMap<String, long[]> previousCollectedNotedAppOps =
7994 sAppOpsNotedInThisBinderTransaction.get();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07007995
7996 sBinderThreadCallingUid.remove();
7997 sAppOpsNotedInThisBinderTransaction.remove();
7998
7999 return new PausedNotedAppOpsCollection(previousUid, previousCollectedNotedAppOps);
8000 }
8001
8002 return null;
8003 }
8004
8005 /**
8006 * Resume a collection paused via {@link #pauseNotedAppOpsCollection}.
8007 *
8008 * @param prevCollection The state of the previous collection
8009 *
8010 * @hide
8011 */
8012 public static void resumeNotedAppOpsCollection(
8013 @Nullable PausedNotedAppOpsCollection prevCollection) {
8014 if (prevCollection != null) {
8015 sBinderThreadCallingUid.set(prevCollection.mUid);
8016
8017 if (prevCollection.mCollectedNotedAppOps != null) {
8018 sAppOpsNotedInThisBinderTransaction.set(prevCollection.mCollectedNotedAppOps);
8019 }
8020 }
8021 }
8022
8023 /**
8024 * Finish collection of noted appops on this thread.
8025 *
8026 * <p>Called at the end of a two way binder transaction.
8027 *
8028 * @see #startNotedAppOpsCollection(int)
8029 *
8030 * @hide
8031 */
8032 public static void finishNotedAppOpsCollection() {
8033 sBinderThreadCallingUid.remove();
8034 sAppOpsNotedInThisBinderTransaction.remove();
8035 }
8036
8037 /**
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008038 * Collect a noted op for the current process.
8039 *
8040 * @param op The noted op
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008041 * @param attributionTag The attribution tag the op is noted for
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008042 */
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008043 private void collectNotedOpForSelf(int op, @Nullable String attributionTag) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008044 synchronized (sLock) {
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008045 if (sOnOpNotedCallback != null) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008046 sOnOpNotedCallback.onSelfNoted(new SyncNotedAppOp(op, attributionTag));
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008047 }
8048 }
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008049 sMessageCollector.onSelfNoted(new SyncNotedAppOp(op, attributionTag));
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008050 }
8051
8052 /**
8053 * Collect a noted op when inside of a two-way binder call.
8054 *
8055 * <p> Delivered to caller via {@link #prefixParcelWithAppOpsIfNeeded}
8056 *
8057 * @param op The noted op
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008058 * @param attributionTag The attribution tag the op is noted for
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008059 */
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008060 private void collectNotedOpSync(int op, @Nullable String attributionTag) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008061 // If this is inside of a two-way binder call:
8062 // We are inside of a two-way binder call. Delivered to caller via
8063 // {@link #prefixParcelWithAppOpsIfNeeded}
8064 ArrayMap<String, long[]> appOpsNoted = sAppOpsNotedInThisBinderTransaction.get();
8065 if (appOpsNoted == null) {
8066 appOpsNoted = new ArrayMap<>(1);
8067 sAppOpsNotedInThisBinderTransaction.set(appOpsNoted);
8068 }
8069
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008070 long[] appOpsNotedForAttribution = appOpsNoted.get(attributionTag);
8071 if (appOpsNotedForAttribution == null) {
8072 appOpsNotedForAttribution = new long[2];
8073 appOpsNoted.put(attributionTag, appOpsNotedForAttribution);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008074 }
8075
8076 if (op < 64) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008077 appOpsNotedForAttribution[0] |= 1L << op;
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008078 } else {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008079 appOpsNotedForAttribution[1] |= 1L << (op - 64);
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008080 }
8081 }
8082
8083 /** @hide */
8084 @Retention(RetentionPolicy.SOURCE)
8085 @IntDef(value = {
8086 DONT_COLLECT,
8087 COLLECT_SELF,
8088 COLLECT_SYNC,
8089 COLLECT_ASYNC
8090 })
8091 private @interface NotedOpCollectionMode {}
8092 private static final int DONT_COLLECT = 0;
8093 private static final int COLLECT_SELF = 1;
8094 private static final int COLLECT_SYNC = 2;
8095 private static final int COLLECT_ASYNC = 3;
8096
8097 /**
8098 * Mark an app-op as noted.
8099 */
8100 private @NotedOpCollectionMode int getNotedOpCollectionMode(int uid,
8101 @Nullable String packageName, int op) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07008102 if (packageName == null) {
8103 packageName = "android";
8104 }
8105
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008106 // check it the appops needs to be collected and cache result
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008107 if (sAppOpsToNote[op] == SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008108 boolean shouldCollectNotes;
8109 try {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008110 shouldCollectNotes = mService.shouldCollectNotes(op);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008111 } catch (RemoteException e) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008112 return DONT_COLLECT;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008113 }
8114
8115 if (shouldCollectNotes) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008116 sAppOpsToNote[op] = SHOULD_COLLECT_NOTE_OP;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008117 } else {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008118 sAppOpsToNote[op] = SHOULD_NOT_COLLECT_NOTE_OP;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008119 }
8120 }
8121
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008122 if (sAppOpsToNote[op] != SHOULD_COLLECT_NOTE_OP) {
8123 return DONT_COLLECT;
8124 }
8125
8126 synchronized (sLock) {
8127 if (uid == Process.myUid()
8128 && packageName.equals(ActivityThread.currentOpPackageName())) {
8129 return COLLECT_SELF;
8130 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008131 }
8132
8133 Integer binderUid = sBinderThreadCallingUid.get();
8134
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07008135 if (binderUid != null && binderUid == uid) {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008136 return COLLECT_SYNC;
Philip P. Moltmann9bcc4062019-09-06 12:27:59 -07008137 } else {
Philip P. Moltmannda554e42019-12-20 11:21:02 -08008138 return COLLECT_ASYNC;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008139 }
8140 }
8141
8142 /**
8143 * Append app-ops noted in the current two-way binder transaction to parcel.
8144 *
8145 * <p>This is called on the callee side of a two way binder transaction just before the
8146 * transaction returns.
8147 *
8148 * @param p the parcel to append the noted app-ops to
8149 *
8150 * @hide
8151 */
8152 public static void prefixParcelWithAppOpsIfNeeded(@NonNull Parcel p) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07008153 ArrayMap<String, long[]> notedAppOps = sAppOpsNotedInThisBinderTransaction.get();
8154 if (notedAppOps == null) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008155 return;
8156 }
8157
8158 p.writeInt(Parcel.EX_HAS_NOTED_APPOPS_REPLY_HEADER);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07008159
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008160 int numAttributionWithNotesAppOps = notedAppOps.size();
8161 p.writeInt(numAttributionWithNotesAppOps);
Philip P. Moltmann59076d82019-08-19 15:00:40 -07008162
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008163 for (int i = 0; i < numAttributionWithNotesAppOps; i++) {
Philip P. Moltmann59076d82019-08-19 15:00:40 -07008164 p.writeString(notedAppOps.keyAt(i));
8165 p.writeLong(notedAppOps.valueAt(i)[0]);
8166 p.writeLong(notedAppOps.valueAt(i)[1]);
8167 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008168 }
8169
8170 /**
8171 * Read app-ops noted during a two-way binder transaction from parcel.
8172 *
8173 * <p>This is called on the calling side of a two way binder transaction just after the
8174 * transaction returns.
8175 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008176 * @param p The parcel to read from
8177 *
8178 * @hide
8179 */
8180 public static void readAndLogNotedAppops(@NonNull Parcel p) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008181 int numAttributionsWithNotedAppOps = p.readInt();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008182
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008183 for (int i = 0; i < numAttributionsWithNotedAppOps; i++) {
8184 String attributionTag = p.readString();
Philip P. Moltmann59076d82019-08-19 15:00:40 -07008185 long[] rawNotedAppOps = new long[2];
8186 rawNotedAppOps[0] = p.readLong();
8187 rawNotedAppOps[1] = p.readLong();
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008188
Philip P. Moltmann59076d82019-08-19 15:00:40 -07008189 if (rawNotedAppOps[0] != 0 || rawNotedAppOps[1] != 0) {
8190 BitSet notedAppOps = BitSet.valueOf(rawNotedAppOps);
8191
8192 synchronized (sLock) {
8193 for (int code = notedAppOps.nextSetBit(0); code != -1;
8194 code = notedAppOps.nextSetBit(code + 1)) {
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008195 if (sOnOpNotedCallback != null) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008196 sOnOpNotedCallback.onNoted(new SyncNotedAppOp(code, attributionTag));
Stanislav Zholnine44f1342020-06-02 20:26:20 +01008197 } else {
Stanislav Zholnin456b4962020-06-18 16:52:50 +01008198 String message = getFormattedStackTrace();
8199 sUnforwardedOps.add(
8200 new AsyncNotedAppOp(code, Process.myUid(), attributionTag,
8201 message, System.currentTimeMillis()));
Stanislav Zholnine44f1342020-06-02 20:26:20 +01008202 if (sUnforwardedOps.size() > MAX_UNFORWARDED_OPS) {
8203 sUnforwardedOps.remove(0);
8204 }
Philip P. Moltmann59076d82019-08-19 15:00:40 -07008205 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008206 }
8207 }
Stanislav Zholnin90516b92020-01-20 14:03:06 +00008208 for (int code = notedAppOps.nextSetBit(0); code != -1;
8209 code = notedAppOps.nextSetBit(code + 1)) {
Philip P. Moltmann12ac3f42020-03-05 15:01:29 -08008210 sMessageCollector.onNoted(new SyncNotedAppOp(code, attributionTag));
Stanislav Zholnin90516b92020-01-20 14:03:06 +00008211 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008212 }
8213 }
8214 }
8215
8216 /**
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008217 * Set a new {@link OnOpNotedCallback}.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008218 *
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008219 * <p>There can only ever be one collector per process. If there currently is another callback
8220 * set, this will fail.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008221 *
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008222 * @param asyncExecutor executor to execute {@link OnOpNotedCallback#onAsyncNoted} on, {@code
8223 * null} to unset
8224 * @param callback listener to set, {@code null} to unset
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008225 *
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008226 * @throws IllegalStateException If another callback is already registered
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008227 */
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008228 public void setOnOpNotedCallback(@Nullable @CallbackExecutor Executor asyncExecutor,
8229 @Nullable OnOpNotedCallback callback) {
8230 Preconditions.checkState((callback == null) == (asyncExecutor == null));
8231
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008232 synchronized (sLock) {
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008233 if (callback == null) {
8234 Preconditions.checkState(sOnOpNotedCallback != null,
8235 "No callback is currently registered");
8236
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008237 try {
8238 mService.stopWatchingAsyncNoted(mContext.getPackageName(),
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008239 sOnOpNotedCallback.mAsyncCb);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008240 } catch (RemoteException e) {
8241 e.rethrowFromSystemServer();
8242 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008243
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008244 sOnOpNotedCallback = null;
8245 } else {
8246 Preconditions.checkState(sOnOpNotedCallback == null,
8247 "Another callback is already registered");
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008248
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008249 callback.mAsyncExecutor = asyncExecutor;
8250 sOnOpNotedCallback = callback;
8251
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008252 List<AsyncNotedAppOp> missedAsyncOps = null;
8253 try {
8254 mService.startWatchingAsyncNoted(mContext.getPackageName(),
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008255 sOnOpNotedCallback.mAsyncCb);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008256 missedAsyncOps = mService.extractAsyncOps(mContext.getPackageName());
8257 } catch (RemoteException e) {
8258 e.rethrowFromSystemServer();
8259 }
8260
8261 if (missedAsyncOps != null) {
8262 int numMissedAsyncOps = missedAsyncOps.size();
8263 for (int i = 0; i < numMissedAsyncOps; i++) {
8264 final AsyncNotedAppOp asyncNotedAppOp = missedAsyncOps.get(i);
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008265 if (sOnOpNotedCallback != null) {
8266 sOnOpNotedCallback.getAsyncNotedExecutor().execute(
8267 () -> sOnOpNotedCallback.onAsyncNoted(asyncNotedAppOp));
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008268 }
8269 }
8270 }
Stanislav Zholnine44f1342020-06-02 20:26:20 +01008271 synchronized (this) {
8272 int numMissedSyncOps = sUnforwardedOps.size();
8273 for (int i = 0; i < numMissedSyncOps; i++) {
Stanislav Zholnin456b4962020-06-18 16:52:50 +01008274 final AsyncNotedAppOp syncNotedAppOp = sUnforwardedOps.get(i);
Stanislav Zholnine44f1342020-06-02 20:26:20 +01008275 if (sOnOpNotedCallback != null) {
8276 sOnOpNotedCallback.getAsyncNotedExecutor().execute(
Stanislav Zholnin456b4962020-06-18 16:52:50 +01008277 () -> sOnOpNotedCallback.onAsyncNoted(syncNotedAppOp));
Stanislav Zholnine44f1342020-06-02 20:26:20 +01008278 }
8279 }
8280 sUnforwardedOps.clear();
8281 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008282 }
8283 }
8284 }
8285
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008286 // TODO moltmann: Remove
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008287 /**
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008288 * Will be removed before R ships, leave it just to not break apps immediately.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008289 *
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008290 * @removed
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008291 *
8292 * @hide
8293 */
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008294 @SystemApi
8295 @Deprecated
8296 public void setNotedAppOpsCollector(@Nullable AppOpsCollector collector) {
8297 synchronized (sLock) {
8298 if (collector != null) {
8299 if (isListeningForOpNoted()) {
8300 setOnOpNotedCallback(null, null);
8301 }
8302 setOnOpNotedCallback(new HandlerExecutor(Handler.getMain()), collector);
8303 } else if (sOnOpNotedCallback != null) {
8304 setOnOpNotedCallback(null, null);
8305 }
8306 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008307 }
8308
8309 /**
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008310 * @return {@code true} iff the process currently is currently collecting noted appops.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008311 *
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008312 * @see #setOnOpNotedCallback
8313 *
8314 * @hide
8315 */
8316 public static boolean isListeningForOpNoted() {
Stanislav Zholnind4968a02020-04-18 21:01:13 +01008317 return sOnOpNotedCallback != null || isCollectingStackTraces();
8318 }
8319
8320 /**
8321 * @return {@code true} iff the process is currently sampled for stacktrace collection.
8322 *
8323 * @see #setOnOpNotedCallback
8324 *
8325 * @hide
8326 */
8327 private static boolean isCollectingStackTraces() {
8328 if (sConfig.getSampledOpCode() == OP_NONE &&
8329 sConfig.getExpirationTimeSinceBootMillis() >= SystemClock.elapsedRealtime()) {
8330 return false;
8331 }
8332 return true;
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008333 }
8334
8335 /**
8336 * Callback an app can {@link #setOnOpNotedCallback set} to monitor the app-ops the
8337 * system has tracked for it. I.e. each time any app calls {@link #noteOp} or {@link #startOp}
8338 * one of a method of this object is called.
8339 *
8340 * <p><b>There will be a call for all app-ops related to runtime permissions, but not
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08008341 * necessarily for all other app-ops.
Philip P. Moltmann9e367002020-02-03 17:01:05 -08008342 *
8343 * <pre>
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008344 * setOnOpNotedCallback(getMainExecutor(), new OnOpNotedCallback() {
Philip P. Moltmann9e367002020-02-03 17:01:05 -08008345 * ArraySet<Pair<String, String>> opsNotedForThisProcess = new ArraySet<>();
8346 *
8347 * private synchronized void addAccess(String op, String accessLocation) {
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08008348 * // Ops are often noted when runtime permission protected APIs were called.
Philip P. Moltmann9e367002020-02-03 17:01:05 -08008349 * // In this case permissionToOp() allows to resolve the permission<->op
8350 * opsNotedForThisProcess.add(new Pair(accessType, accessLocation));
8351 * }
8352 *
8353 * public void onNoted(SyncNotedAppOp op) {
8354 * // Accesses is currently happening, hence stack trace describes location of access
8355 * addAccess(op.getOp(), Arrays.toString(Thread.currentThread().getStackTrace()));
8356 * }
8357 *
8358 * public void onSelfNoted(SyncNotedAppOp op) {
8359 * onNoted(op);
8360 * }
8361 *
8362 * public void onAsyncNoted(AsyncNotedAppOp asyncOp) {
8363 * // Stack trace is not useful for async ops as accessed happened on different thread
8364 * addAccess(asyncOp.getOp(), asyncOp.getMessage());
8365 * }
8366 * });
8367 * </pre>
8368 *
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008369 * @see #setOnOpNotedCallback
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008370 */
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008371 public abstract static class OnOpNotedCallback {
8372 private @NonNull Executor mAsyncExecutor;
8373
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008374 /** Callback registered with the system. This will receive the async notes ops */
8375 private final IAppOpsAsyncNotedCallback mAsyncCb = new IAppOpsAsyncNotedCallback.Stub() {
8376 @Override
8377 public void opNoted(AsyncNotedAppOp op) {
Daulet Zhanguzin0af97d62019-12-30 15:41:28 +00008378 Objects.requireNonNull(op);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008379
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008380 long token = Binder.clearCallingIdentity();
8381 try {
8382 getAsyncNotedExecutor().execute(() -> onAsyncNoted(op));
8383 } finally {
8384 Binder.restoreCallingIdentity(token);
8385 }
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008386 }
8387 };
8388
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008389 // TODO moltmann: Remove
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008390 /**
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008391 * Will be removed before R ships.
8392 *
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008393 * @return The executor for the system to use when calling {@link #onAsyncNoted}.
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008394 *
8395 * @hide
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008396 */
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008397 protected @NonNull Executor getAsyncNotedExecutor() {
8398 return mAsyncExecutor;
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008399 }
8400
8401 /**
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08008402 * Called when an app-op was {@link #noteOp noted} for this package inside of a synchronous
8403 * API call, i.e. a API call that returned data or waited until the action was performed.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008404 *
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08008405 * <p>Called on the calling thread before the API returns. This allows the app to e.g.
8406 * collect stack traces to figure out where the access came from.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008407 *
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008408 * @param op op noted
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008409 */
8410 public abstract void onNoted(@NonNull SyncNotedAppOp op);
8411
8412 /**
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08008413 * Called when this app noted an app-op for its own package,
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008414 *
Philip P. Moltmanna04b9ab2020-02-13 09:54:04 -08008415 * <p>This is very similar to {@link #onNoted} only that the tracking was not caused by the
8416 * API provider in a separate process, but by one in the app's own process.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008417 *
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008418 * @param op op noted
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008419 */
8420 public abstract void onSelfNoted(@NonNull SyncNotedAppOp op);
8421
8422 /**
8423 * Called when an app-op was noted for this package which cannot be delivered via the other
8424 * two mechanisms.
8425 *
8426 * <p>Called as soon as possible after the app-op was noted, but the delivery delay is not
8427 * guaranteed. Due to how async calls work in Android this might even be delivered slightly
8428 * before the private data is delivered to the app.
8429 *
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008430 * <p>If the app is not running or no {@link OnOpNotedCallback} is registered a small amount
8431 * of noted app-ops are buffered and then delivered as soon as a listener is registered.
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008432 *
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008433 * @param asyncOp op noted
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008434 */
8435 public abstract void onAsyncNoted(@NonNull AsyncNotedAppOp asyncOp);
8436 }
8437
Philip P. Moltmann5892a8f2020-03-03 12:05:55 -08008438 // TODO moltmann: Remove
8439 /**
8440 * Will be removed before R ships, leave it just to not break apps immediately.
8441 *
8442 * @removed
8443 *
8444 * @hide
8445 */
8446 @SystemApi
8447 @Deprecated
8448 public abstract static class AppOpsCollector extends OnOpNotedCallback {
8449 public @NonNull Executor getAsyncNotedExecutor() {
8450 return new HandlerExecutor(Handler.getMain());
8451 }
8452 };
8453
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008454 /**
8455 * Generate a stack trace used for noted app-ops logging.
8456 *
8457 * <p>This strips away the first few and last few stack trace elements as they are not
8458 * interesting to apps.
8459 */
8460 private static String getFormattedStackTrace() {
8461 StackTraceElement[] trace = new Exception().getStackTrace();
8462
8463 int firstInteresting = 0;
8464 for (int i = 0; i < trace.length; i++) {
8465 if (trace[i].getClassName().startsWith(AppOpsManager.class.getName())
8466 || trace[i].getClassName().startsWith(Parcel.class.getName())
8467 || trace[i].getClassName().contains("$Stub$Proxy")
8468 || trace[i].getClassName().startsWith(DatabaseUtils.class.getName())
8469 || trace[i].getClassName().startsWith("android.content.ContentProviderProxy")
8470 || trace[i].getClassName().startsWith(ContentResolver.class.getName())) {
8471 firstInteresting = i;
8472 } else {
8473 break;
8474 }
8475 }
8476
8477 int lastInteresting = trace.length - 1;
8478 for (int i = trace.length - 1; i >= 0; i--) {
8479 if (trace[i].getClassName().startsWith(HandlerThread.class.getName())
8480 || trace[i].getClassName().startsWith(Handler.class.getName())
8481 || trace[i].getClassName().startsWith(Looper.class.getName())
8482 || trace[i].getClassName().startsWith(Binder.class.getName())
8483 || trace[i].getClassName().startsWith(RuntimeInit.class.getName())
8484 || trace[i].getClassName().startsWith(ZygoteInit.class.getName())
8485 || trace[i].getClassName().startsWith(ActivityThread.class.getName())
8486 || trace[i].getClassName().startsWith(Method.class.getName())
8487 || trace[i].getClassName().startsWith("com.android.server.SystemServer")) {
8488 lastInteresting = i;
8489 } else {
8490 break;
8491 }
8492 }
8493
8494 StringBuilder sb = new StringBuilder();
8495 for (int i = firstInteresting; i <= lastInteresting; i++) {
Stanislav Zholnin90516b92020-01-20 14:03:06 +00008496 if (i != firstInteresting) {
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008497 sb.append('\n');
8498 }
Stanislav Zholnin90516b92020-01-20 14:03:06 +00008499 if (sb.length() + trace[i].toString().length() > 600) {
8500 break;
8501 }
8502 sb.append(trace[i]);
Philip P. Moltmann2b08aaf2019-06-10 08:49:11 -07008503 }
8504
8505 return sb.toString();
8506 }
8507
8508 /**
Svet Ganovf7b47252018-02-26 11:11:27 -08008509 * Checks whether the given op for a UID and package is active.
8510 *
8511 * <p> If you don't hold the {@link android.Manifest.permission#WATCH_APPOPS} permission
8512 * you can query only for your UID.
8513 *
8514 * @see #startWatchingActive(int[], OnOpActiveChangedListener)
8515 * @see #stopWatchingMode(OnOpChangedListener)
Philip P. Moltmann59076d82019-08-19 15:00:40 -07008516 * @see #finishOp(int, int, String, String)
8517 * @see #startOp(int, int, String, boolean, String, String)
Svet Ganovf7b47252018-02-26 11:11:27 -08008518 *
8519 * @hide */
8520 @TestApi
8521 // TODO: Uncomment below annotation once b/73559440 is fixed
8522 // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true)
Jeff Sharkey35e46d22017-06-09 10:01:20 -06008523 public boolean isOperationActive(int code, int uid, String packageName) {
8524 try {
8525 return mService.isOperationActive(code, uid, packageName);
8526 } catch (RemoteException e) {
8527 throw e.rethrowFromSystemServer();
8528 }
8529 }
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00008530
8531 /**
Svet Ganov8455ba22019-01-02 13:05:56 -08008532 * Configures the app ops persistence for testing.
8533 *
8534 * @param mode The mode in which the historical registry operates.
8535 * @param baseSnapshotInterval The base interval on which we would be persisting a snapshot of
8536 * the historical data. The history is recursive where every subsequent step encompasses
8537 * {@code compressionStep} longer interval with {@code compressionStep} distance between
8538 * snapshots.
8539 * @param compressionStep The compression step in every iteration.
8540 *
8541 * @see #HISTORICAL_MODE_DISABLED
8542 * @see #HISTORICAL_MODE_ENABLED_ACTIVE
8543 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
8544 *
8545 * @hide
8546 */
8547 @TestApi
8548 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
8549 public void setHistoryParameters(@HistoricalMode int mode, long baseSnapshotInterval,
8550 int compressionStep) {
8551 try {
8552 mService.setHistoryParameters(mode, baseSnapshotInterval, compressionStep);
8553 } catch (RemoteException e) {
8554 throw e.rethrowFromSystemServer();
8555 }
8556 }
8557
8558 /**
8559 * Offsets the history by the given duration.
8560 *
8561 * @param offsetMillis The offset duration.
8562 *
8563 * @hide
8564 */
8565 @TestApi
8566 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
8567 public void offsetHistory(long offsetMillis) {
8568 try {
8569 mService.offsetHistory(offsetMillis);
8570 } catch (RemoteException e) {
8571 throw e.rethrowFromSystemServer();
8572 }
8573 }
8574
8575 /**
8576 * Adds ops to the history directly. This could be useful for testing especially
8577 * when the historical registry operates in {@link #HISTORICAL_MODE_ENABLED_PASSIVE}
8578 * mode.
8579 *
8580 * @param ops The ops to add to the history.
8581 *
8582 * @see #setHistoryParameters(int, long, int)
8583 * @see #HISTORICAL_MODE_ENABLED_PASSIVE
8584 *
8585 * @hide
8586 */
8587 @TestApi
8588 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
8589 public void addHistoricalOps(@NonNull HistoricalOps ops) {
8590 try {
8591 mService.addHistoricalOps(ops);
8592 } catch (RemoteException e) {
8593 throw e.rethrowFromSystemServer();
8594 }
8595 }
8596
8597 /**
8598 * Resets the app ops persistence for testing.
8599 *
8600 * @see #setHistoryParameters(int, long, int)
8601 *
8602 * @hide
8603 */
8604 @TestApi
8605 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
8606 public void resetHistoryParameters() {
8607 try {
8608 mService.resetHistoryParameters();
8609 } catch (RemoteException e) {
8610 throw e.rethrowFromSystemServer();
8611 }
8612 }
8613
8614 /**
8615 * Clears all app ops history.
8616 *
8617 * @hide
8618 */
8619 @TestApi
8620 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
8621 public void clearHistory() {
8622 try {
8623 mService.clearHistory();
8624 } catch (RemoteException e) {
8625 throw e.rethrowFromSystemServer();
8626 }
8627 }
8628
8629 /**
Svet Ganov185ddf62020-06-04 21:40:26 -07008630 * Reboots the ops history.
8631 *
8632 * @param offlineDurationMillis The duration to wait between
8633 * tearing down and initializing the history. Must be greater
8634 * than or equal to zero.
8635 *
8636 * @hide
8637 */
8638 @TestApi
8639 @RequiresPermission(Manifest.permission.MANAGE_APPOPS)
8640 public void rebootHistory(long offlineDurationMillis) {
8641 try {
8642 mService.rebootHistory(offlineDurationMillis);
8643 } catch (RemoteException e) {
8644 throw e.rethrowFromSystemServer();
8645 }
8646 }
8647
8648 /**
Stanislav Zholnin90516b92020-01-20 14:03:06 +00008649 * Pulls current AppOps access report and picks package and op to watch for next access report
Stanislav Zholninb2ed79a2020-03-24 14:14:45 +00008650 * Returns null if no reports were collected since last call. There is no guarantee of report
8651 * collection, hence this method should be called periodically even if no report was collected
8652 * to pick different package and op to watch.
Stanislav Zholnin90516b92020-01-20 14:03:06 +00008653 * @hide
8654 */
8655 @SystemApi
8656 @TestApi
8657 @RequiresPermission(Manifest.permission.GET_APP_OPS_STATS)
8658 public @Nullable RuntimeAppOpAccessMessage collectRuntimeAppOpAccessMessage() {
8659 try {
8660 return mService.collectRuntimeAppOpAccessMessage();
8661 } catch (RemoteException e) {
8662 throw e.rethrowFromSystemServer();
8663 }
8664 }
8665
8666 /**
Peter Visontay5a2a1ef2017-12-18 20:34:03 +00008667 * Returns all supported operation names.
8668 * @hide
8669 */
8670 @SystemApi
8671 @TestApi
8672 public static String[] getOpStrs() {
8673 return Arrays.copyOf(sOpToString, sOpToString.length);
8674 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07008675
Philip P. Moltmann24576812018-05-07 10:42:05 -07008676
8677 /**
8678 * @return number of App ops
8679 * @hide
8680 */
8681 @TestApi
8682 public static int getNumOps() {
8683 return _NUM_OP;
8684 }
8685
Dianne Hackbornc216a262018-04-26 13:46:22 -07008686 /**
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08008687 * Gets the last of the event.
Svet Ganovaf189e32019-02-15 18:45:29 -08008688 *
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08008689 * @param events The events
8690 * @param flags The UID flags
8691 * @param beginUidState The maximum UID state (inclusive)
8692 * @param endUidState The minimum UID state (inclusive)
8693 *
8694 * @return The last event of {@code null}
Dianne Hackbornc216a262018-04-26 13:46:22 -07008695 */
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08008696 private static @Nullable NoteOpEvent getLastEvent(
8697 @Nullable LongSparseArray<NoteOpEvent> events, @UidState int beginUidState,
8698 @UidState int endUidState, @OpFlags int flags) {
8699 if (events == null) {
8700 return null;
Svet Ganovaf189e32019-02-15 18:45:29 -08008701 }
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08008702
8703 NoteOpEvent lastEvent = null;
Svet Ganovaf189e32019-02-15 18:45:29 -08008704 while (flags != 0) {
8705 final int flag = 1 << Integer.numberOfTrailingZeros(flags);
8706 flags &= ~flag;
8707 for (int uidState : UID_STATES) {
8708 if (uidState < beginUidState || uidState > endUidState) {
8709 continue;
8710 }
8711 final long key = makeKey(uidState, flag);
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08008712
8713 NoteOpEvent event = events.get(key);
Philip P. Moltmannd8c0bda2019-12-19 19:55:35 -08008714 if (lastEvent == null
8715 || event != null && event.getNoteTime() > lastEvent.getNoteTime()) {
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08008716 lastEvent = event;
8717 }
Dianne Hackbornc216a262018-04-26 13:46:22 -07008718 }
8719 }
Svet Ganovaf189e32019-02-15 18:45:29 -08008720
Philip P. Moltmann49bd9e12019-11-26 15:18:16 -08008721 return lastEvent;
8722 }
Svet Ganovaf189e32019-02-15 18:45:29 -08008723
Philip P. Moltmann4aacd712020-01-03 12:32:20 -08008724 private static boolean equalsLongSparseLongArray(@Nullable LongSparseLongArray a,
8725 @Nullable LongSparseLongArray b) {
8726 if (a == b) {
8727 return true;
8728 }
8729
8730 if (a == null || b == null) {
8731 return false;
8732 }
8733
8734 if (a.size() != b.size()) {
8735 return false;
8736 }
8737
8738 int numEntries = a.size();
8739 for (int i = 0; i < numEntries; i++) {
8740 if (a.keyAt(i) != b.keyAt(i) || a.valueAt(i) != b.valueAt(i)) {
8741 return false;
8742 }
8743 }
8744
8745 return true;
8746 }
8747
Svet Ganovaf189e32019-02-15 18:45:29 -08008748 private static void writeLongSparseLongArrayToParcel(
8749 @Nullable LongSparseLongArray array, @NonNull Parcel parcel) {
8750 if (array != null) {
8751 final int size = array.size();
8752 parcel.writeInt(size);
8753 for (int i = 0; i < size; i++) {
8754 parcel.writeLong(array.keyAt(i));
8755 parcel.writeLong(array.valueAt(i));
8756 }
8757 } else {
8758 parcel.writeInt(-1);
8759 }
8760 }
8761
8762 private static @Nullable LongSparseLongArray readLongSparseLongArrayFromParcel(
8763 @NonNull Parcel parcel) {
8764 final int size = parcel.readInt();
8765 if (size < 0) {
8766 return null;
8767 }
8768 final LongSparseLongArray array = new LongSparseLongArray(size);
8769 for (int i = 0; i < size; i++) {
8770 array.append(parcel.readLong(), parcel.readLong());
8771 }
8772 return array;
8773 }
8774
Svet Ganovaf189e32019-02-15 18:45:29 -08008775 /**
8776 * Collects the keys from an array to the result creating the result if needed.
8777 *
8778 * @param array The array whose keys to collect.
8779 * @param result The optional result store collected keys.
8780 * @return The result collected keys array.
8781 */
8782 private static LongSparseArray<Object> collectKeys(@Nullable LongSparseLongArray array,
8783 @Nullable LongSparseArray<Object> result) {
8784 if (array != null) {
8785 if (result == null) {
8786 result = new LongSparseArray<>();
8787 }
8788 final int accessSize = array.size();
8789 for (int i = 0; i < accessSize; i++) {
8790 result.put(array.keyAt(i), null);
8791 }
8792 }
8793 return result;
Dianne Hackbornc216a262018-04-26 13:46:22 -07008794 }
Svet Ganov8455ba22019-01-02 13:05:56 -08008795
8796 /** @hide */
8797 public static String uidStateToString(@UidState int uidState) {
8798 switch (uidState) {
8799 case UID_STATE_PERSISTENT: {
8800 return "UID_STATE_PERSISTENT";
8801 }
8802 case UID_STATE_TOP: {
8803 return "UID_STATE_TOP";
8804 }
Amith Yamasania0a30a12019-01-22 11:38:06 -08008805 case UID_STATE_FOREGROUND_SERVICE_LOCATION: {
8806 return "UID_STATE_FOREGROUND_SERVICE_LOCATION";
8807 }
Svet Ganov8455ba22019-01-02 13:05:56 -08008808 case UID_STATE_FOREGROUND_SERVICE: {
8809 return "UID_STATE_FOREGROUND_SERVICE";
8810 }
8811 case UID_STATE_FOREGROUND: {
8812 return "UID_STATE_FOREGROUND";
8813 }
8814 case UID_STATE_BACKGROUND: {
8815 return "UID_STATE_BACKGROUND";
8816 }
8817 case UID_STATE_CACHED: {
8818 return "UID_STATE_CACHED";
8819 }
8820 default: {
8821 return "UNKNOWN";
8822 }
8823 }
8824 }
8825
8826 /** @hide */
8827 public static int parseHistoricalMode(@NonNull String mode) {
8828 switch (mode) {
8829 case "HISTORICAL_MODE_ENABLED_ACTIVE": {
8830 return HISTORICAL_MODE_ENABLED_ACTIVE;
8831 }
8832 case "HISTORICAL_MODE_ENABLED_PASSIVE": {
8833 return HISTORICAL_MODE_ENABLED_PASSIVE;
8834 }
8835 default: {
8836 return HISTORICAL_MODE_DISABLED;
8837 }
8838 }
8839 }
8840
8841 /** @hide */
8842 public static String historicalModeToString(@HistoricalMode int mode) {
8843 switch (mode) {
8844 case HISTORICAL_MODE_DISABLED: {
8845 return "HISTORICAL_MODE_DISABLED";
8846 }
8847 case HISTORICAL_MODE_ENABLED_ACTIVE: {
8848 return "HISTORICAL_MODE_ENABLED_ACTIVE";
8849 }
8850 case HISTORICAL_MODE_ENABLED_PASSIVE: {
8851 return "HISTORICAL_MODE_ENABLED_PASSIVE";
8852 }
8853 default: {
8854 return "UNKNOWN";
8855 }
8856 }
8857 }
Ng Zhi An65a99b62018-10-01 11:57:53 -07008858
8859 private static int getSystemAlertWindowDefault() {
8860 final Context context = ActivityThread.currentApplication();
8861 if (context == null) {
8862 return AppOpsManager.MODE_DEFAULT;
8863 }
8864
8865 // system alert window is disable on low ram phones starting from Q
8866 final PackageManager pm = context.getPackageManager();
8867 // TVs are constantly plugged in and has less concern for memory/power
8868 if (ActivityManager.isLowRamDeviceStatic()
8869 && !pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK, 0)) {
8870 return AppOpsManager.MODE_IGNORED;
8871 }
8872
8873 return AppOpsManager.MODE_DEFAULT;
8874 }
Stanislav Zholnin90516b92020-01-20 14:03:06 +00008875
8876 /**
8877 * Calculate left circular distance for two numbers modulo size.
8878 * @hide
8879 */
8880 public static int leftCircularDistance(int from, int to, int size) {
8881 return (to + size - from) % size;
8882 }
David Cheung2ead9662020-02-19 16:11:06 -08008883
8884 /**
8885 * Helper method for noteOp, startOp and noteProxyOp to call AppOpsService to collect/log
8886 * stack traces
8887 *
8888 * <p> For each call, the stacktrace op code, package name and long version code will be
8889 * passed along where it will be logged/collected
8890 *
8891 * @param op The operation to note
8892 */
8893 private void collectNoteOpCallsForValidation(int op) {
8894 if (NOTE_OP_COLLECTION_ENABLED) {
8895 try {
8896 mService.collectNoteOpCallsForValidation(getFormattedStackTrace(),
8897 op, mContext.getOpPackageName(), mContext.getApplicationInfo().longVersionCode);
8898 } catch (RemoteException e) {
8899 // Swallow error, only meant for logging ops, should not affect flow of the code
8900 }
8901 }
8902 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08008903}