public final class

AppOpsManagerCompat

extends java.lang.Object

 java.lang.Object

↳androidx.core.app.AppOpsManagerCompat

Gradle dependencies

compile group: 'androidx.core', name: 'core', version: '1.15.0-alpha02'

  • groupId: androidx.core
  • artifactId: core
  • version: 1.15.0-alpha02

Artifact androidx.core:core:1.15.0-alpha02 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.core:core com.android.support:support-compat

Androidx class mapping:

androidx.core.app.AppOpsManagerCompat android.support.v4.app.AppOpsManagerCompat

Overview

Helper for accessing features in .

Summary

Fields
public static final intMODE_ALLOWED

Result from AppOpsManagerCompat.noteOp(Context, String, int, String): the given caller is allowed to perform the given operation.

public static final intMODE_DEFAULT

Result from AppOpsManagerCompat.noteOp(Context, String, int, String): the given caller should use its default security check.

public static final intMODE_ERRORED

Result from AppOpsManagerCompat.noteOpNoThrow(Context, String, int, String): the given caller is not allowed to perform the given operation, and this attempt should cause it to have a fatal error, typically a java.lang.SecurityException.

public static final intMODE_IGNORED

Result from AppOpsManagerCompat.noteOp(Context, String, int, String): 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).

Methods
public static intcheckOrNoteProxyOp(Context context, int proxyUid, java.lang.String op, java.lang.String proxiedPackageName)

Check op for both proxy and proxied packages.

public static intnoteOp(Context context, java.lang.String op, int uid, java.lang.String packageName)

Make note of an application performing an operation.

public static intnoteOpNoThrow(Context context, java.lang.String op, int uid, java.lang.String packageName)

Like AppOpsManagerCompat.noteOp(Context, String, int, String) but instead of throwing a java.lang.SecurityException it returns AppOpsManagerCompat.MODE_ERRORED.

public static intnoteProxyOp(Context context, java.lang.String op, java.lang.String proxiedPackageName)

Make note of an application performing an operation on behalf of another application when handling an IPC.

public static intnoteProxyOpNoThrow(Context context, java.lang.String op, java.lang.String proxiedPackageName)

Like AppOpsManagerCompat.noteProxyOp(Context, String, String) but instead of throwing a java.lang.SecurityException it returns AppOpsManagerCompat.MODE_ERRORED.

public static java.lang.StringpermissionToOp(java.lang.String permission)

Gets the app op name associated with a given permission.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Fields

public static final int MODE_ALLOWED

Result from AppOpsManagerCompat.noteOp(Context, String, int, String): the given caller is allowed to perform the given operation.

public static final int MODE_IGNORED

Result from AppOpsManagerCompat.noteOp(Context, String, int, String): 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 AppOpsManagerCompat.noteOpNoThrow(Context, String, int, String): the given caller is not allowed to perform the given operation, and this attempt should cause it to have a fatal error, typically a java.lang.SecurityException.

public static final int MODE_DEFAULT

Result from AppOpsManagerCompat.noteOp(Context, String, int, String): 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.

Methods

public static java.lang.String permissionToOp(java.lang.String permission)

Gets the app op name associated with a given permission.

Compatibility

  • On API 22 and lower, this method always returns null

Parameters:

permission: The permission.

Returns:

The app op associated with the permission or null.

public static int noteOp(Context context, 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 AppOpsManagerCompat.MODE_IGNORED. If this call succeeds, the last execution time of the operation for this app will be updated to the current time.

Compatibility

Parameters:

context: Your context.
op: The operation to note. One of the OPSTR_* constants.
uid: The user id of the application attempting to perform the operation.
packageName: The name of the application attempting to perform the operation.

Returns:

Returns AppOpsManagerCompat.MODE_ALLOWED if the operation is allowed, or AppOpsManagerCompat.MODE_IGNORED if it is not allowed and should be silently ignored (without causing the app to crash).

public static int noteOpNoThrow(Context context, java.lang.String op, int uid, java.lang.String packageName)

Like AppOpsManagerCompat.noteOp(Context, String, int, String) but instead of throwing a java.lang.SecurityException it returns AppOpsManagerCompat.MODE_ERRORED.

Compatibility

public static int noteProxyOp(Context context, java.lang.String op, java.lang.String proxiedPackageName)

Make note of an application performing an operation on behalf of another application when handling an IPC. Note that you must pass the package name of the application that is being proxied while its UID will be inferred from the IPC state; this function will verify that the calling uid and proxied package name match, and if not, return AppOpsManagerCompat.MODE_IGNORED. If this call succeeds, the last execution time of the operation for the proxied app and your app will be updated to the current time.

Compatibility

Parameters:

context: Your context.
op: The operation to note. One of the OPSTR_* constants.
proxiedPackageName: The name of the application calling into the proxy application.

Returns:

Returns AppOpsManagerCompat.MODE_ALLOWED if the operation is allowed, or AppOpsManagerCompat.MODE_IGNORED if it is not allowed and should be silently ignored (without causing the app to crash).

public static int noteProxyOpNoThrow(Context context, java.lang.String op, java.lang.String proxiedPackageName)

Like AppOpsManagerCompat.noteProxyOp(Context, String, String) but instead of throwing a java.lang.SecurityException it returns AppOpsManagerCompat.MODE_ERRORED.

Compatibility

public static int checkOrNoteProxyOp(Context context, int proxyUid, java.lang.String op, java.lang.String proxiedPackageName)

Check op for both proxy and proxied packages. Do a quick check for whether an application might be able to perform an operation. This is not a security check. On API 23-28, fallback to AppOpsManagerCompat.noteProxyOpNoThrow(Context, String, String) On API 22 and lower, this method always returns AppOpsManagerCompat.MODE_IGNORED

Parameters:

context: Your context.
proxyUid: The uid of the proxy application.
op: The operation to note. One of the OPSTR_* constants.
proxiedPackageName: The name of the application calling into the proxy application.

Returns:

Returns AppOpsManagerCompat.MODE_ALLOWED if the operation is allowed, or

Source

/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.core.app;

import static android.os.Build.VERSION.SDK_INT;

import android.app.AppOpsManager;
import android.content.Context;
import android.os.Binder;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;

/**
 * Helper for accessing features in {@link android.app.AppOpsManager}.
 */
public final class AppOpsManagerCompat {

    /**
     * Result from {@link #noteOp}: the given caller is allowed to
     * perform the given operation.
     */
    public static final int MODE_ALLOWED = AppOpsManager.MODE_ALLOWED;

    /**
     * Result from {@link #noteOp}: the given caller is not allowed to perform
     * the given operation, and this attempt should <em>silently fail</em> (it
     * should not cause the app to crash).
     */
    public static final int MODE_IGNORED = AppOpsManager.MODE_IGNORED;

    /**
     * Result from {@link #noteOpNoThrow}: 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_ERRORED = AppOpsManager.MODE_ERRORED;

    /**
     * Result from {@link #noteOp}: 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 MODE_DEFAULT = AppOpsManager.MODE_DEFAULT;

    private AppOpsManagerCompat() {}

    /**
     * Gets the app op name associated with a given permission.
     * <p>
     * <strong>Compatibility</strong>
     * <ul>
     * <li>On API 22 and lower, this method always returns {@code null}
     * </ul>
     *
     * @param permission The permission.
     * @return The app op associated with the permission or null.
     */
    @Nullable
    public static String permissionToOp(@NonNull String permission) {
        if (SDK_INT >= 23) {
            return Api23Impl.permissionToOp(permission);
        } else {
            return null;
        }
    }

    /**
     * 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.
     * <p>
     * <strong>Compatibility</strong>
     * <ul>
     * <li>On API 18 and lower, this method always returns {@link #MODE_IGNORED}
     * </ul>
     * @param context Your context.
     * @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.
     */
    public static int noteOp(@NonNull Context context, @NonNull String op, int uid,
            @NonNull String packageName) {
        AppOpsManager appOpsManager =
                (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        return appOpsManager.noteOp(op, uid, packageName);
    }

    /**
     * Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
     * returns {@link #MODE_ERRORED}.
     * <p>
     * <strong>Compatibility</strong>
     * <ul>
     * <li>On API 18 and lower, this method always returns {@link #MODE_IGNORED}
     * </ul>
     */
    public static int noteOpNoThrow(@NonNull Context context, @NonNull String op, int uid,
            @NonNull String packageName) {
        AppOpsManager appOpsManager =
                (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        return appOpsManager.noteOpNoThrow(op, uid, packageName);
    }

    /**
     * Make note of an application performing an operation on behalf of another
     * application when handling an IPC. Note that you must pass the package name
     * of the application that is being proxied while its UID will be inferred from
     * the IPC state; this function will verify that the calling uid and proxied
     * package name match, and if not, return {@link #MODE_IGNORED}. If this call
     * succeeds, the last execution time of the operation for the proxied app and
     * your app will be updated to the current time.
     * <p>
     * <strong>Compatibility</strong>
     * <ul>
     * <li>On API 22 and lower, this method always returns {@link #MODE_IGNORED}
     * </ul>
     * @param context Your context.
     * @param op The operation to note.  One of the OPSTR_* constants.
     * @param proxiedPackageName The name of the application calling into the proxy application.
     * @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.
     */
    public static int noteProxyOp(@NonNull Context context, @NonNull String op,
            @NonNull String proxiedPackageName) {
        if (SDK_INT >= 23) {
            AppOpsManager appOpsManager = Api23Impl.getSystemService(context, AppOpsManager.class);
            return Api23Impl.noteProxyOp(appOpsManager, op, proxiedPackageName);
        } else {
            return MODE_IGNORED;
        }
    }

    /**
     * Like {@link #noteProxyOp(Context, String, String)} but instead
     * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
     * <p>
     * <strong>Compatibility</strong>
     * <ul>
     * <li>On API 22 and lower, this method always returns {@link #MODE_IGNORED}
     * </ul>
     */
    public static int noteProxyOpNoThrow(@NonNull Context context, @NonNull String op,
            @NonNull String proxiedPackageName) {
        if (SDK_INT >= 23) {
            AppOpsManager appOpsManager = Api23Impl.getSystemService(context, AppOpsManager.class);
            return Api23Impl.noteProxyOpNoThrow(appOpsManager, op, proxiedPackageName);
        } else {
            return MODE_IGNORED;
        }
    }

    /**
     * Check op for both proxy and proxied packages. Do a quick check for whether an application
     * might be able to perform an operation. This is not a security check.
     * On API 23-28, fallback to {@link #noteProxyOpNoThrow(Context, String, String)}
     * On API 22 and lower, this method always returns {@link #MODE_IGNORED}
     * @param context Your context.
     * @param proxyUid The uid of the proxy application.
     * @param op The operation to note.  One of the OPSTR_* constants.
     * @param proxiedPackageName The name of the application calling into the proxy application.
     * @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).
     */
    public static int checkOrNoteProxyOp(@NonNull Context context, int proxyUid,
            @NonNull String op, @NonNull String proxiedPackageName) {
        if (SDK_INT >= 29) {
            AppOpsManager appOpsManager = Api29Impl.getSystemService(context);
            // Check proxied op
            int proxiedUid = Binder.getCallingUid();
            int checkProxiedOpResult = Api29Impl.checkOpNoThrow(appOpsManager, op, proxiedUid,
                    proxiedPackageName);
            if (checkProxiedOpResult != MODE_ALLOWED) {
                return checkProxiedOpResult;
            }

            // Check proxy op
            String proxyPackageName = Api29Impl.getOpPackageName(context);
            return Api29Impl.checkOpNoThrow(appOpsManager, op, proxyUid, proxyPackageName);
        } else {
            // For API level 23-28 we want to fallback to noteProxyOpNoThrow()
            return noteProxyOpNoThrow(context, op, proxiedPackageName);
        }
    }

    /**
     * Nested class to avoid verification errors for methods introduced in Android 10 (API 29).
     */
    @RequiresApi(29)
    static class Api29Impl {
        private Api29Impl() {
        }

        /**
         * Return the AppOpsManager system service.
         */
        static @Nullable AppOpsManager getSystemService(@NonNull Context context) {
            return context.getSystemService(AppOpsManager.class);
        }

        /**
         * Use the AppOpsManager to perform checkOp().
         */
        static int checkOpNoThrow(@Nullable AppOpsManager appOpsManager,
                @NonNull String op, int uid, @NonNull String packageName) {
            if (appOpsManager == null) {
                return MODE_IGNORED;
            }

            return appOpsManager.checkOpNoThrow(op, uid, packageName);
        }

        /**
         * Return the packageName from the context.
         */
        static @NonNull String getOpPackageName(@NonNull Context context) {
            return context.getOpPackageName();
        }
    }

    @RequiresApi(23)
    static class Api23Impl {
        private Api23Impl() {
            // This class is not instantiable.
        }

        static String permissionToOp(String permission) {
            return AppOpsManager.permissionToOp(permission);
        }

        static <T> T getSystemService(Context context, Class<T> serviceClass) {
            return context.getSystemService(serviceClass);
        }

        static int noteProxyOp(AppOpsManager appOpsManager, String op, String proxiedPackageName) {
            return appOpsManager.noteProxyOp(op, proxiedPackageName);
        }

        static int noteProxyOpNoThrow(AppOpsManager appOpsManager, String op,
                String proxiedPackageName) {
            return appOpsManager.noteProxyOpNoThrow(op, proxiedPackageName);
        }
    }
}