Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d7d28e67 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

App ops: media ops, set up to be callable from native code.

This is to help implementation of bug #8181262 and maybe
bug #8181261

Adds some definition for media ops (though nothing is yet using
them), and re-arranges things a bit so we can implement native
calling in to the app ops service.

Also add some java docs.

Change-Id: I637959745db820e676f23a35a5d2224f51bc6689
parent b41af58f
Loading
Loading
Loading
Loading
+24 −1
Original line number Original line Diff line number Diff line
@@ -1915,7 +1915,30 @@ public class ActivityManager {
        return PackageManager.PERMISSION_DENIED;
        return PackageManager.PERMISSION_DENIED;
    }
    }


    /** @hide */
    /**
     * @hide
     * Helper for dealing with incoming user arguments to system service calls.
     * Takes care of checking permissions and converting USER_CURRENT to the
     * actual current user.
     *
     * @param callingPid The pid of the incoming call, as per Binder.getCallingPid().
     * @param callingUid The uid of the incoming call, as per Binder.getCallingUid().
     * @param userId The user id argument supplied by the caller -- this is the user
     * they want to run as.
     * @param allowAll If true, we will allow USER_ALL.  This means you must be prepared
     * to get a USER_ALL returned and deal with it correctly.  If false,
     * an exception will be thrown if USER_ALL is supplied.
     * @param requireFull If true, the caller must hold
     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} to be able to run as a
     * different user than their current process; otherwise they must hold
     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS}.
     * @param name Optional textual name of the incoming call; only for generating error messages.
     * @param callerPackage Optional package name of caller; only for error messages.
     *
     * @return Returns the user ID that the call should run as.  Will always be a concrete
     * user number, unless <var>allowAll</var> is true in which case it could also be
     * USER_ALL.
     */
    public static int handleIncomingUser(int callingPid, int callingUid, int userId,
    public static int handleIncomingUser(int callingPid, int callingUid, int userId,
            boolean allowAll, boolean requireFull, String name, String callerPackage) {
            boolean allowAll, boolean requireFull, String name, String callerPackage) {
        if (UserHandle.getUserId(callingUid) == userId) {
        if (UserHandle.getUserId(callingUid) == userId) {
+63 −2
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package android.app;
package android.app;


import android.Manifest;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsCallback;


@@ -29,7 +30,25 @@ import android.os.Parcelable;
import android.os.Process;
import android.os.Process;
import android.os.RemoteException;
import android.os.RemoteException;


/** @hide */
/**
 * API for interacting with "application operation" tracking.  Allows you 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 (through a
 * SecurityException back to the caller; the normal operation calls will do this for you).
 *
 * @hide
 */
public class AppOpsManager {
public class AppOpsManager {
    final Context mContext;
    final Context mContext;
    final IAppOpsService mService;
    final IAppOpsService mService;
@@ -71,8 +90,11 @@ public class AppOpsManager {
    public static final int OP_WRITE_SETTINGS = 23;
    public static final int OP_WRITE_SETTINGS = 23;
    public static final int OP_SYSTEM_ALERT_WINDOW = 24;
    public static final int OP_SYSTEM_ALERT_WINDOW = 24;
    public static final int OP_ACCESS_NOTIFICATIONS = 25;
    public static final int OP_ACCESS_NOTIFICATIONS = 25;
    public static final int OP_CAMERA = 26;
    public static final int OP_RECORD_AUDIO = 27;
    public static final int OP_PLAY_AUDIO = 28;
    /** @hide */
    /** @hide */
    public static final int _NUM_OP = 26;
    public static final int _NUM_OP = 29;


    /**
    /**
     * This maps each operation to the operation that serves as the
     * This maps each operation to the operation that serves as the
@@ -109,6 +131,9 @@ public class AppOpsManager {
            OP_WRITE_SETTINGS,
            OP_WRITE_SETTINGS,
            OP_SYSTEM_ALERT_WINDOW,
            OP_SYSTEM_ALERT_WINDOW,
            OP_ACCESS_NOTIFICATIONS,
            OP_ACCESS_NOTIFICATIONS,
            OP_CAMERA,
            OP_RECORD_AUDIO,
            OP_PLAY_AUDIO,
    };
    };


    /**
    /**
@@ -142,6 +167,9 @@ public class AppOpsManager {
            "WRITE_SETTINGS",
            "WRITE_SETTINGS",
            "SYSTEM_ALERT_WINDOW",
            "SYSTEM_ALERT_WINDOW",
            "ACCESS_NOTIFICATIONS",
            "ACCESS_NOTIFICATIONS",
            "CAMERA",
            "RECORD_AUDIO",
            "PLAY_AUDIO",
    };
    };


    /**
    /**
@@ -175,21 +203,36 @@ public class AppOpsManager {
            android.Manifest.permission.WRITE_SETTINGS,
            android.Manifest.permission.WRITE_SETTINGS,
            android.Manifest.permission.SYSTEM_ALERT_WINDOW,
            android.Manifest.permission.SYSTEM_ALERT_WINDOW,
            android.Manifest.permission.ACCESS_NOTIFICATIONS,
            android.Manifest.permission.ACCESS_NOTIFICATIONS,
            android.Manifest.permission.CAMERA,
            android.Manifest.permission.RECORD_AUDIO,
            null, // no permission for playing audio
    };
    };


    /**
     * Retrieve the op switch that controls the given operation.
     */
    public static int opToSwitch(int op) {
    public static int opToSwitch(int op) {
        return sOpToSwitch[op];
        return sOpToSwitch[op];
    }
    }


    /**
     * Retrieve a non-localized name for the operation, for debugging output.
     */
    public static String opToName(int op) {
    public static String opToName(int op) {
        if (op == OP_NONE) return "NONE";
        if (op == OP_NONE) return "NONE";
        return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
        return op < sOpNames.length ? sOpNames[op] : ("Unknown(" + op + ")");
    }
    }


    /**
     * Retrieve the permission associated with an operation, or null if there is not one.
     */
    public static String opToPermission(int op) {
    public static String opToPermission(int op) {
        return sOpPerms[op];
        return sOpPerms[op];
    }
    }


    /**
     * Class holding all of the operation information associated with an app.
     */
    public static class PackageOps implements Parcelable {
    public static class PackageOps implements Parcelable {
        private final String mPackageName;
        private final String mPackageName;
        private final int mUid;
        private final int mUid;
@@ -249,6 +292,9 @@ public class AppOpsManager {
        };
        };
    }
    }


    /**
     * Class holding the information about one unique operation of an application.
     */
    public static class OpEntry implements Parcelable {
    public static class OpEntry implements Parcelable {
        private final int mOp;
        private final int mOp;
        private final int mMode;
        private final int mMode;
@@ -321,6 +367,9 @@ public class AppOpsManager {
        };
        };
    }
    }


    /**
     * Callback for notification of changes to operation state.
     */
    public interface Callback {
    public interface Callback {
        public void opChanged(int op, String packageName);
        public void opChanged(int op, String packageName);
    }
    }
@@ -330,6 +379,11 @@ public class AppOpsManager {
        mService = service;
        mService = service;
    }
    }


    /**
     * 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.
     */
    public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
    public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
        try {
        try {
            return mService.getPackagesForOps(ops);
            return mService.getPackagesForOps(ops);
@@ -338,6 +392,13 @@ public class AppOpsManager {
        return null;
        return null;
    }
    }


    /**
     * 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.
     */
    public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
    public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
        try {
        try {
            return mService.getOpsForPackage(uid, packageName, ops);
            return mService.getOpsForPackage(uid, packageName, ops);
+2 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,8 @@


package com.android.internal.app;
package com.android.internal.app;


// This interface is also used by native code, so must
// be kept in sync with frameworks/native/include/binder/IAppOpsCallback.h
oneway interface IAppOpsCallback {
oneway interface IAppOpsCallback {
    void opChanged(int op, String packageName);
    void opChanged(int op, String packageName);
}
}
+7 −3
Original line number Original line Diff line number Diff line
@@ -20,13 +20,17 @@ import android.app.AppOpsManager;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsCallback;


interface IAppOpsService {
interface IAppOpsService {
    List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
    // These first methods are also called by native code, so must
    List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
    // be kept in sync with frameworks/native/include/binder/IAppOpsService.h
    void setMode(int code, int uid, String packageName, int mode);
    int checkOperation(int code, int uid, String packageName);
    int checkOperation(int code, int uid, String packageName);
    int noteOperation(int code, int uid, String packageName);
    int noteOperation(int code, int uid, String packageName);
    int startOperation(int code, int uid, String packageName);
    int startOperation(int code, int uid, String packageName);
    void finishOperation(int code, int uid, String packageName);
    void finishOperation(int code, int uid, String packageName);
    void startWatchingMode(int op, String packageName, IAppOpsCallback callback);
    void startWatchingMode(int op, String packageName, IAppOpsCallback callback);
    void stopWatchingMode(IAppOpsCallback callback);
    void stopWatchingMode(IAppOpsCallback callback);

    // Remaining methods are only used in Java.
    List<AppOpsManager.PackageOps> getPackagesForOps(in int[] ops);
    List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, in int[] ops);
    void setMode(int code, int uid, String packageName, int mode);
}
}