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

Commit 1950aa07 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I63b26a67,Ib57a3118 into main

* changes:
  Converts Java reason to HAL reason
  Refactors permission related logic in utility class
parents 5091b48b 9f820688
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);
+2 −1
Original line number Diff line number Diff line
@@ -145,7 +145,8 @@ public class ContextHubEndpointBroker extends IContextHubEndpoint.Stub
        super.closeSession_enforcePermission();
        if (!mIsRegistered.get()) throw new IllegalStateException("Endpoint is not registered");
        try {
            mContextHubProxy.closeEndpointSession(sessionId, (byte) reason);
            mContextHubProxy.closeEndpointSession(
                    sessionId, ContextHubServiceUtil.toHalReason(reason));
        } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) {
            Log.e(TAG, "Exception while calling HAL closeEndpointSession", e);
            throw e;
+96 −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,97 @@ import java.util.List;
                return HubEndpoint.REASON_FAILURE;
        }
    }

    /**
     * Converts a byte integer defined by Reason.aidl to HubEndpoint.Reason values exposed to apps.
     *
     * @param reason The Reason.aidl value
     * @return The converted HubEndpoint.Reason value
     */
    /* package */
    static byte toHalReason(@HubEndpoint.Reason int reason) {
        switch (reason) {
            case HubEndpoint.REASON_FAILURE:
                return Reason.UNSPECIFIED;
            case HubEndpoint.REASON_OPEN_ENDPOINT_SESSION_REQUEST_REJECTED:
                return Reason.OPEN_ENDPOINT_SESSION_REQUEST_REJECTED;
            case HubEndpoint.REASON_CLOSE_ENDPOINT_SESSION_REQUESTED:
                return Reason.CLOSE_ENDPOINT_SESSION_REQUESTED;
            case HubEndpoint.REASON_ENDPOINT_INVALID:
                return Reason.ENDPOINT_INVALID;
            case HubEndpoint.REASON_ENDPOINT_STOPPED:
                return Reason.ENDPOINT_GONE;
            case HubEndpoint.REASON_PERMISSION_DENIED:
                return Reason.PERMISSION_DENIED;
            default:
                Log.w(TAG, "toHalReason: invalid reason: " + reason);
                return Reason.UNSPECIFIED;
        }
    }

    /**
     * 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;
    }
}