FileDocCategorySizeDatePackage
AppOpsManager.javaAPI DocAndroid 5.1 API51807Thu Mar 12 22:22:10 GMT 2015android.app

AppOpsManager

public class AppOpsManager extends Object
API for interacting with "application operation" tracking.

This API is not generally intended for third party application developers; most features are only available to system applications. Obtain an instance of it through {@link Context#getSystemService(String) Context.getSystemService} with {@link Context#APP_OPS_SERVICE Context.APP_OPS_SERVICE}.

Fields Summary
final android.content.Context
mContext

App ops allows callers to:

  • Note when operations are happening, and find out if they are allowed for the current caller.
  • Disallow specific apps from doing specific operations.
  • Collect all of the current information about operations that have been executed or are not being allowed.
  • Monitor for changes in whether an operation is allowed.

Each operation is identified by a single integer; these integers are a fixed set of operations, enumerated by the OP_* constants.

When checking operations, the result is a "mode" integer indicating the current setting for the operation under that caller: MODE_ALLOWED, MODE_IGNORED (don't execute the operation but fake its behavior enough so that the caller doesn't crash), MODE_ERRORED (throw a SecurityException back to the caller; the normal operation calls will do this for you).
final com.android.internal.app.IAppOpsService
mService
final android.util.ArrayMap
mModeWatchers
static android.os.IBinder
sToken
public static final int
MODE_ALLOWED
Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is allowed to perform the given operation.
public static final int
MODE_IGNORED
Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller is not allowed to perform the given operation, and this attempt should silently fail (it should not cause the app to crash).
public static final int
MODE_ERRORED
Result from {@link #checkOpNoThrow}, {@link #noteOpNoThrow}, {@link #startOpNoThrow}: the given caller is not allowed to perform the given operation, and this attempt should cause it to have a fatal error, typically a {@link SecurityException}.
public static final int
MODE_DEFAULT
Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: the given caller should use its default security check. This mode is not normally used; it should only be used with appop permissions, and callers must explicitly check for it and deal with it.
public static final int
OP_NONE
public static final int
OP_COARSE_LOCATION
public static final int
OP_FINE_LOCATION
public static final int
OP_GPS
public static final int
OP_VIBRATE
public static final int
OP_READ_CONTACTS
public static final int
OP_WRITE_CONTACTS
public static final int
OP_READ_CALL_LOG
public static final int
OP_WRITE_CALL_LOG
public static final int
OP_READ_CALENDAR
public static final int
OP_WRITE_CALENDAR
public static final int
OP_WIFI_SCAN
public static final int
OP_POST_NOTIFICATION
public static final int
OP_NEIGHBORING_CELLS
public static final int
OP_CALL_PHONE
public static final int
OP_READ_SMS
public static final int
OP_WRITE_SMS
public static final int
OP_RECEIVE_SMS
public static final int
OP_RECEIVE_EMERGECY_SMS
public static final int
OP_RECEIVE_MMS
public static final int
OP_RECEIVE_WAP_PUSH
public static final int
OP_SEND_SMS
public static final int
OP_READ_ICC_SMS
public static final int
OP_WRITE_ICC_SMS
public static final int
OP_WRITE_SETTINGS
public static final int
OP_SYSTEM_ALERT_WINDOW
public static final int
OP_ACCESS_NOTIFICATIONS
public static final int
OP_CAMERA
public static final int
OP_RECORD_AUDIO
public static final int
OP_PLAY_AUDIO
public static final int
OP_READ_CLIPBOARD
public static final int
OP_WRITE_CLIPBOARD
public static final int
OP_TAKE_MEDIA_BUTTONS
public static final int
OP_TAKE_AUDIO_FOCUS
public static final int
OP_AUDIO_MASTER_VOLUME
public static final int
OP_AUDIO_VOICE_VOLUME
public static final int
OP_AUDIO_RING_VOLUME
public static final int
OP_AUDIO_MEDIA_VOLUME
public static final int
OP_AUDIO_ALARM_VOLUME
public static final int
OP_AUDIO_NOTIFICATION_VOLUME
public static final int
OP_AUDIO_BLUETOOTH_VOLUME
public static final int
OP_WAKE_LOCK
public static final int
OP_MONITOR_LOCATION
public static final int
OP_MONITOR_HIGH_POWER_LOCATION
public static final int
OP_GET_USAGE_STATS
public static final int
OP_MUTE_MICROPHONE
public static final int
OP_TOAST_WINDOW
public static final int
OP_PROJECT_MEDIA
public static final int
OP_ACTIVATE_VPN
public static final int
_NUM_OP
public static final String
OPSTR_COARSE_LOCATION
Access to coarse location information.
public static final String
OPSTR_FINE_LOCATION
Access to fine location information.
public static final String
OPSTR_MONITOR_LOCATION
Continually monitoring location data.
public static final String
OPSTR_MONITOR_HIGH_POWER_LOCATION
Continually monitoring location data with a relatively high power request.
public static final String
OPSTR_GET_USAGE_STATS
Access to {@link android.app.usage.UsageStatsManager}.
public static final String
OPSTR_ACTIVATE_VPN
Activate a VPN connection without user intervention. @hide
private static int[]
sOpToSwitch
This maps each operation to the operation that serves as the switch to determine whether it is allowed. Generally this is a 1:1 mapping, but for some things (like location) that have multiple low-level operations being tracked that should be presented to the user as one switch then this can be used to make them all controlled by the same single operation.
private static String[]
sOpToString
This maps each operation to the public string constant for it. If it doesn't have a public string constant, it maps to null.
private static String[]
sOpNames
This provides a simple name for each operation to be used in debug output.
private static String[]
sOpPerms
This optionally maps a permission to an operation. If there is no permission associated with an operation, it is null.
private static String[]
sOpRestrictions
Specifies whether an Op should be restricted by a user restriction. Each Op should be filled with a restriction string from UserManager or null to specify it is not affected by any user restriction.
private static boolean[]
sOpAllowSystemRestrictionBypass
This specifies whether each option should allow the system (and system ui) to bypass the user restriction when active.
private static int[]
sOpDefaultMode
This specifies the default mode for each operation.
private static boolean[]
sOpDisableReset
This specifies whether each option is allowed to be reset when resetting all app preferences. Disable reset for app ops that are under strong control of some part of the system (such as OP_WRITE_SMS, which should be allowed only for whichever app is selected as the current SMS app).
private static HashMap
sOpStrToOp
Constructors Summary
AppOpsManager(android.content.Context context, com.android.internal.app.IAppOpsService service)

        mContext = context;
        mService = service;
    
Methods Summary
private java.lang.StringbuildSecurityExceptionMsg(int op, int uid, java.lang.String packageName)

        return packageName + " from uid " + uid + " not allowed to perform " + sOpNames[op];
    
public intcheckAudioOp(int op, int stream, int uid, java.lang.String packageName)
Like {@link #checkOp} but at a stream-level for audio operations.

hide

        try {
            final int mode = mService.checkAudioOperation(op, stream, uid, packageName);
            if (mode == MODE_ERRORED) {
                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
            }
            return mode;
        } catch (RemoteException e) {
        }
        return MODE_IGNORED;
    
public intcheckAudioOpNoThrow(int op, int stream, int uid, java.lang.String packageName)
Like {@link #checkAudioOp} but instead of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.

hide

        try {
            return mService.checkAudioOperation(op, stream, uid, packageName);
        } catch (RemoteException e) {
        }
        return MODE_IGNORED;
    
public intcheckOp(java.lang.String op, int uid, java.lang.String packageName)
Do a quick check for whether an application might be able to perform an operation. This is not a security check; you must use {@link #noteOp(String, int, String)} or {@link #startOp(String, int, String)} for your actual security checks, which also ensure that the given uid and package name are consistent. This function can just be used for a quick check to see if an operation has been disabled for the application, as an early reject of some work. This does not modify the time stamp or other data about the operation.

param
op The operation to check. One of the OPSTR_* constants.
param
uid The user id of the application attempting to perform the operation.
param
packageName The name of the application attempting to perform the operation.
return
Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without causing the app to crash).
throws
SecurityException If the app has been configured to crash on this op.

        return checkOp(strOpToOp(op), uid, packageName);
    
public intcheckOp(int op, int uid, java.lang.String packageName)
Do a quick check for whether an application might be able to perform an operation. This is not a security check; you must use {@link #noteOp(int, int, String)} or {@link #startOp(int, int, String)} for your actual security checks, which also ensure that the given uid and package name are consistent. This function can just be used for a quick check to see if an operation has been disabled for the application, as an early reject of some work. This does not modify the time stamp or other data about the operation.

param
op The operation to check. One of the OP_* constants.
param
uid The user id of the application attempting to perform the operation.
param
packageName The name of the application attempting to perform the operation.
return
Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without causing the app to crash).
throws
SecurityException If the app has been configured to crash on this op.
hide

        try {
            int mode = mService.checkOperation(op, uid, packageName);
            if (mode == MODE_ERRORED) {
                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
            }
            return mode;
        } catch (RemoteException e) {
        }
        return MODE_IGNORED;
    
public intcheckOpNoThrow(java.lang.String op, int uid, java.lang.String packageName)
Like {@link #checkOp} but instead of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.

        return checkOpNoThrow(strOpToOp(op), uid, packageName);
    
public intcheckOpNoThrow(int op, int uid, java.lang.String packageName)
Like {@link #checkOp} but instead of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.

hide

        try {
            return mService.checkOperation(op, uid, packageName);
        } catch (RemoteException e) {
        }
        return MODE_IGNORED;
    
public voidcheckPackage(int uid, java.lang.String packageName)
Do a quick check to validate if a package name belongs to a UID.

throws
SecurityException if the package name doesn't belong to the given UID, or if ownership cannot be verified.

        try {
            if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
                throw new SecurityException(
                        "Package " + packageName + " does not belong to " + uid);
            }
        } catch (RemoteException e) {
            throw new SecurityException("Unable to verify package ownership", e);
        }
    
public voidfinishOp(java.lang.String op, int uid, java.lang.String packageName)
Report that an application is no longer performing an operation that had previously been started with {@link #startOp(String, int, String)}. There is no validation of input or result; the parameters supplied here must be the exact same ones previously passed in when starting the operation.

        finishOp(strOpToOp(op), uid, packageName);
    
public voidfinishOp(int op, int uid, java.lang.String packageName)
Report that an application is no longer performing an operation that had previously been started with {@link #startOp(int, int, String)}. There is no validation of input or result; the parameters supplied here must be the exact same ones previously passed in when starting the operation.

hide

        try {
            mService.finishOperation(getToken(mService), op, uid, packageName);
        } catch (RemoteException e) {
        }
    
public voidfinishOp(int op)

hide

        finishOp(op, Process.myUid(), mContext.getOpPackageName());
    
public java.util.ListgetOpsForPackage(int uid, java.lang.String packageName, int[] ops)
Retrieve current operation state for one application.

param
uid The uid of the application of interest.
param
packageName The name of the application of interest.
param
ops The set of operations you are interested in, or null if you want all of them.
hide

        try {
            return mService.getOpsForPackage(uid, packageName, ops);
        } catch (RemoteException e) {
        }
        return null;
    
public java.util.ListgetPackagesForOps(int[] ops)
Retrieve current operation state for all applications.

param
ops The set of operations you are interested in, or null if you want all of them.
hide

        try {
            return mService.getPackagesForOps(ops);
        } catch (RemoteException e) {
        }
        return null;
    
public static android.os.IBindergetToken(com.android.internal.app.IAppOpsService service)

hide

        synchronized (AppOpsManager.class) {
            if (sToken != null) {
                return sToken;
            }
            try {
                sToken = service.getToken(new Binder());
            } catch (RemoteException e) {
                // System is dead, whatevs.
            }
            return sToken;
        }
    
public intnoteOp(java.lang.String op, int uid, java.lang.String packageName)
Make note of an application performing an operation. Note that you must pass in both the uid and name of the application to be checked; this function will verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution time of the operation for this app will be updated to the current time.

param
op The operation to note. One of the OPSTR_* constants.
param
uid The user id of the application attempting to perform the operation.
param
packageName The name of the application attempting to perform the operation.
return
Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without causing the app to crash).
throws
SecurityException If the app has been configured to crash on this op.

        return noteOp(strOpToOp(op), uid, packageName);
    
public intnoteOp(int op, int uid, java.lang.String packageName)
Make note of an application performing an operation. Note that you must pass in both the uid and name of the application to be checked; this function will verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution time of the operation for this app will be updated to the current time.

param
op The operation to note. One of the OP_* constants.
param
uid The user id of the application attempting to perform the operation.
param
packageName The name of the application attempting to perform the operation.
return
Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without causing the app to crash).
throws
SecurityException If the app has been configured to crash on this op.
hide

        try {
            int mode = mService.noteOperation(op, uid, packageName);
            if (mode == MODE_ERRORED) {
                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
            }
            return mode;
        } catch (RemoteException e) {
        }
        return MODE_IGNORED;
    
public intnoteOp(int op)

hide

        return noteOp(op, Process.myUid(), mContext.getOpPackageName());
    
public intnoteOpNoThrow(java.lang.String op, int uid, java.lang.String packageName)
Like {@link #noteOp} but instead of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.

        return noteOpNoThrow(strOpToOp(op), uid, packageName);
    
public intnoteOpNoThrow(int op, int uid, java.lang.String packageName)
Like {@link #noteOp} but instead of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.

hide

        try {
            return mService.noteOperation(op, uid, packageName);
        } catch (RemoteException e) {
        }
        return MODE_IGNORED;
    
public static booleanopAllowSystemBypassRestriction(int op)
Retrieve whether the op allows the system (and system ui) to bypass the user restriction.

hide

        return sOpAllowSystemRestrictionBypass[op];
    
public static booleanopAllowsReset(int op)
Retrieve whether the op allows itself to be reset.

hide

        return !sOpDisableReset[op];
    
public static intopToDefaultMode(int op)
Retrieve the default mode for the operation.

hide

        return sOpDefaultMode[op];
    
public static java.lang.StringopToName(int op)
Retrieve a non-localized name for the operation, for debugging output.

hide

        if (op == OP_NONE) return "NONE";
        return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
    
public static java.lang.StringopToPermission(int op)
Retrieve the permission associated with an operation, or null if there is not one.

hide

        return sOpPerms[op];
    
public static java.lang.StringopToRestriction(int op)
Retrieve the user restriction associated with an operation, or null if there is not one.

hide

        return sOpRestrictions[op];
    
public static intopToSwitch(int op)
Retrieve the op switch that controls the given operation.

hide


     
        if (sOpToSwitch.length != _NUM_OP) {
            throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length
                    + " should be " + _NUM_OP);
        }
        if (sOpToString.length != _NUM_OP) {
            throw new IllegalStateException("sOpToString length " + sOpToString.length
                    + " should be " + _NUM_OP);
        }
        if (sOpNames.length != _NUM_OP) {
            throw new IllegalStateException("sOpNames length " + sOpNames.length
                    + " should be " + _NUM_OP);
        }
        if (sOpPerms.length != _NUM_OP) {
            throw new IllegalStateException("sOpPerms length " + sOpPerms.length
                    + " should be " + _NUM_OP);
        }
        if (sOpDefaultMode.length != _NUM_OP) {
            throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length
                    + " should be " + _NUM_OP);
        }
        if (sOpDisableReset.length != _NUM_OP) {
            throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length
                    + " should be " + _NUM_OP);
        }
        if (sOpRestrictions.length != _NUM_OP) {
            throw new IllegalStateException("sOpRestrictions length " + sOpRestrictions.length
                    + " should be " + _NUM_OP);
        }
        if (sOpAllowSystemRestrictionBypass.length != _NUM_OP) {
            throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length "
                    + sOpRestrictions.length + " should be " + _NUM_OP);
        }
        for (int i=0; i<_NUM_OP; i++) {
            if (sOpToString[i] != null) {
                sOpStrToOp.put(sOpToString[i], i);
            }
        }
    
        return sOpToSwitch[op];
    
public voidresetAllModes()

hide

        try {
            mService.resetAllModes(UserHandle.myUserId(), null);
        } catch (RemoteException e) {
        }
    
public voidsetMode(int code, int uid, java.lang.String packageName, int mode)

hide

        try {
            mService.setMode(code, uid, packageName, mode);
        } catch (RemoteException e) {
        }
    
public voidsetRestriction(int code, int usage, int mode, java.lang.String[] exceptionPackages)
Set a non-persisted restriction on an audio operation at a stream-level. Restrictions are temporary additional constraints imposed on top of the persisted rules defined by {@link #setMode}.

param
code The operation to restrict.
param
usage The {@link android.media.AudioAttributes} usage value.
param
mode The restriction mode (MODE_IGNORED,MODE_ERRORED) or MODE_ALLOWED to unrestrict.
param
exceptionPackages Optional list of packages to exclude from the restriction.
hide

        try {
            final int uid = Binder.getCallingUid();
            mService.setAudioRestriction(code, usage, uid, mode, exceptionPackages);
        } catch (RemoteException e) {
        }
    
public intstartOp(java.lang.String op, int uid, java.lang.String packageName)
Report that an application has started executing a long-running operation. Note that you must pass in both the uid and name of the application to be checked; this function will verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution time of the operation for this app will be updated to the current time and the operation will be marked as "running". In this case you must later call {@link #finishOp(String, int, String)} to report when the application is no longer performing the operation.

param
op The operation to start. One of the OPSTR_* constants.
param
uid The user id of the application attempting to perform the operation.
param
packageName The name of the application attempting to perform the operation.
return
Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without causing the app to crash).
throws
SecurityException If the app has been configured to crash on this op.

        return startOp(strOpToOp(op), uid, packageName);
    
public intstartOp(int op, int uid, java.lang.String packageName)
Report that an application has started executing a long-running operation. Note that you must pass in both the uid and name of the application to be checked; this function will verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call succeeds, the last execution time of the operation for this app will be updated to the current time and the operation will be marked as "running". In this case you must later call {@link #finishOp(int, int, String)} to report when the application is no longer performing the operation.

param
op The operation to start. One of the OP_* constants.
param
uid The user id of the application attempting to perform the operation.
param
packageName The name of the application attempting to perform the operation.
return
Returns {@link #MODE_ALLOWED} if the operation is allowed, or {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without causing the app to crash).
throws
SecurityException If the app has been configured to crash on this op.
hide

        try {
            int mode = mService.startOperation(getToken(mService), op, uid, packageName);
            if (mode == MODE_ERRORED) {
                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
            }
            return mode;
        } catch (RemoteException e) {
        }
        return MODE_IGNORED;
    
public intstartOp(int op)

hide

        return startOp(op, Process.myUid(), mContext.getOpPackageName());
    
public intstartOpNoThrow(java.lang.String op, int uid, java.lang.String packageName)
Like {@link #startOp} but instead of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.

        return startOpNoThrow(strOpToOp(op), uid, packageName);
    
public intstartOpNoThrow(int op, int uid, java.lang.String packageName)
Like {@link #startOp} but instead of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.

hide

        try {
            return mService.startOperation(getToken(mService), op, uid, packageName);
        } catch (RemoteException e) {
        }
        return MODE_IGNORED;
    
public voidstartWatchingMode(java.lang.String op, java.lang.String packageName, android.app.AppOpsManager$OnOpChangedListener callback)
Monitor for changes to the operating mode for the given op in the given app package.

param
op The operation to monitor, one of OPSTR_*.
param
packageName The name of the application to monitor.
param
callback Where to report changes.

        startWatchingMode(strOpToOp(op), packageName, callback);
    
public voidstartWatchingMode(int op, java.lang.String packageName, android.app.AppOpsManager$OnOpChangedListener callback)
Monitor for changes to the operating mode for the given op in the given app package.

param
op The operation to monitor, one of OP_*.
param
packageName The name of the application to monitor.
param
callback Where to report changes.
hide

        synchronized (mModeWatchers) {
            IAppOpsCallback cb = mModeWatchers.get(callback);
            if (cb == null) {
                cb = new IAppOpsCallback.Stub() {
                    public void opChanged(int op, String packageName) {
                        if (callback instanceof OnOpChangedInternalListener) {
                            ((OnOpChangedInternalListener)callback).onOpChanged(op, packageName);
                        }
                        if (sOpToString[op] != null) {
                            callback.onOpChanged(sOpToString[op], packageName);
                        }
                    }
                };
                mModeWatchers.put(callback, cb);
            }
            try {
                mService.startWatchingMode(op, packageName, cb);
            } catch (RemoteException e) {
            }
        }
    
public voidstopWatchingMode(android.app.AppOpsManager$OnOpChangedListener callback)
Stop monitoring that was previously started with {@link #startWatchingMode}. All monitoring associated with this callback will be removed.

        synchronized (mModeWatchers) {
            IAppOpsCallback cb = mModeWatchers.get(callback);
            if (cb != null) {
                try {
                    mService.stopWatchingMode(cb);
                } catch (RemoteException e) {
                }
            }
        }
    
public static intstrDebugOpToOp(java.lang.String op)

hide

        for (int i=0; i<sOpNames.length; i++) {
            if (sOpNames[i].equals(op)) {
                return i;
            }
        }
        throw new IllegalArgumentException("Unknown operation string: " + op);
    
public static intstrOpToOp(java.lang.String op)
{@hide}

        Integer val = sOpStrToOp.get(op);
        if (val == null) {
            throw new IllegalArgumentException("Unknown operation string: " + op);
        }
        return val;