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

Commit 7771fc74 authored by Arthur Ishiguro's avatar Arthur Ishiguro
Browse files

Refactors permission related logic in utility class

Bug: 381102453
Flag: EXEMPT refactor
Test: Compile, verify CHQTS pass

Change-Id: Ib57a31182dafad08101934f93d2a414b99488cc0
parent bd0648d5
Loading
Loading
Loading
Loading
+9 −54
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.server.location.contexthub;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.hardware.location.ContextHubManager.AUTHORIZATION_DENIED;
import static android.hardware.location.ContextHubManager.AUTHORIZATION_DENIED_GRACE_PERIOD;
import static android.hardware.location.ContextHubManager.AUTHORIZATION_GRANTED;
@@ -25,7 +24,6 @@ import android.Manifest;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.chre.flags.Flags;
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
@@ -655,7 +653,13 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
        // If in the grace period, don't check permissions state since it'll cause cleanup
        // messages to be dropped.
        if (authState == AUTHORIZATION_DENIED
                || !notePermissions(messagePermissions, RECEIVE_MSG_NOTE + nanoAppId)) {
                || !ContextHubServiceUtil.notePermissions(
                        mAppOpsManager,
                        mUid,
                        mPackage,
                        mAttributionTag,
                        messagePermissions,
                        RECEIVE_MSG_NOTE + nanoAppId)) {
            Log.e(TAG, "Dropping message from " + Long.toHexString(nanoAppId) + ". " + mPackage
                    + " doesn't have permission");
            return ErrorCode.PERMISSION_DENIED;
@@ -753,56 +757,6 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
        }
    }

    /**
     * Checks that this client has all of the provided permissions.
     *
     * @param permissions list of permissions to check
     * @return true if the client has all of the permissions granted
     */
    boolean hasPermissions(List<String> permissions) {
        for (String permission : permissions) {
            if (mContext.checkPermission(permission, mPid, mUid) != PERMISSION_GRANTED) {
                Log.e(TAG, "no permission for " + permission);
                return false;
            }
        }
        return true;
    }

    /**
     * Attributes the provided permissions to the package of this client.
     *
     * @param permissions list of permissions covering data the client is about to receive
     * @param noteMessage message that should be noted alongside permissions attribution to
     *     facilitate debugging
     * @return true if client has ability to use all of the provided permissions
     */
    boolean notePermissions(List<String> permissions, String noteMessage) {
        for (String permission : permissions) {
            int opCode = AppOpsManager.permissionToOpCode(permission);
            if (opCode != AppOpsManager.OP_NONE) {
                try {
                    if (mAppOpsManager.noteOp(opCode, mUid, mPackage, mAttributionTag, noteMessage)
                            != AppOpsManager.MODE_ALLOWED) {
                        return false;
                    }
                } catch (SecurityException e) {
                    Log.e(
                            TAG,
                            "SecurityException: noteOp for pkg "
                                    + mPackage
                                    + " opcode "
                                    + opCode
                                    + ": "
                                    + e.getMessage());
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * @return true if the client is a PendingIntent client that has been cancelled.
     */
@@ -868,7 +822,8 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
        synchronized (mMessageChannelNanoappIdMap) {
            // Check permission granted state synchronously since this method can be invoked from
            // multiple threads.
            boolean hasPermissions = hasPermissions(nanoappPermissions);
            boolean hasPermissions =
                    ContextHubServiceUtil.hasPermissions(mContext, mPid, mUid, nanoappPermissions);

            curAuthState = mMessageChannelNanoappIdMap.getOrDefault(
                    nanoAppId, AUTHORIZATION_UNKNOWN);
+69 −0
Original line number Diff line number Diff line
@@ -16,7 +16,10 @@

package com.android.server.location.contexthub;

import static android.content.pm.PackageManager.PERMISSION_GRANTED;

import android.Manifest;
import android.app.AppOpsManager;
import android.content.Context;
import android.hardware.contexthub.EndpointInfo;
import android.hardware.contexthub.HubEndpoint;
@@ -535,4 +538,70 @@ import java.util.List;
                return HubEndpoint.REASON_FAILURE;
        }
    }

    /**
     * Checks that the module with the provided context/pid/uid has all of the provided permissions.
     *
     * @param context The context to validate permissions for
     * @param pid The PID to validate permissions for
     * @param uid The UID to validate permissions for
     * @param permissions The collection of permissions to check
     * @return true if the module has all of the permissions granted
     */
    /* package */
    static boolean hasPermissions(
            Context context, int pid, int uid, Collection<String> permissions) {
        for (String permission : permissions) {
            if (context.checkPermission(permission, pid, uid) != PERMISSION_GRANTED) {
                Log.e(TAG, "no permission for " + permission);
                return false;
            }
        }
        return true;
    }

    /**
     * Attributes the provided permissions to the package of this client.
     *
     * @param appOpsManager The app ops manager to use
     * @param uid The UID of the module to note permissions for
     * @param packageName The package name of the module to note permissions for
     * @param attributionTag The attribution tag of the module to note permissions for
     * @param permissions The list of permissions covering data the client is about to receive
     * @param noteMessage The message that should be noted alongside permissions attribution to
     *     facilitate debugging
     * @return true if client has ability to use all of the provided permissions
     */
    /* package */
    static boolean notePermissions(
            AppOpsManager appOpsManager,
            int uid,
            String packageName,
            String attributionTag,
            List<String> permissions,
            String noteMessage) {
        for (String permission : permissions) {
            int opCode = AppOpsManager.permissionToOpCode(permission);
            if (opCode != AppOpsManager.OP_NONE) {
                try {
                    if (appOpsManager.noteOp(opCode, uid, packageName, attributionTag, noteMessage)
                            != AppOpsManager.MODE_ALLOWED) {
                        return false;
                    }
                } catch (SecurityException e) {
                    Log.e(
                            TAG,
                            "SecurityException: noteOp for pkg "
                                    + packageName
                                    + " opcode "
                                    + opCode
                                    + ": "
                                    + e.getMessage());
                    return false;
                }
            }
        }

        return true;
    }
}