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

Commit 3ae1513b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Enforce nanoapp permissions for ContextHub APIs" into sc-dev am: d271b73c

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13436063

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I6e07433716380b85088ffb0c04d1a87e793bc707
parents 051ec9fc d271b73c
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.app.ActivityThread;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
@@ -849,9 +850,18 @@ public final class ContextHubManager {
            attributionTag = context.getAttributionTag();
        }

        // Workaround for old APIs not providing a context
        String packageName;
        if (context != null) {
            packageName = context.getPackageName();
        } else {
            packageName = ActivityThread.currentPackageName();
        }

        IContextHubClient clientProxy;
        try {
            clientProxy = mService.createClient(hubInfo.getId(), clientInterface, attributionTag);
            clientProxy = mService.createClient(
                    hubInfo.getId(), clientInterface, attributionTag, packageName);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+2 −1
Original line number Diff line number Diff line
@@ -60,7 +60,8 @@ interface IContextHubService {

    // Creates a client to send and receive messages
    IContextHubClient createClient(
            int contextHubId, in IContextHubClientCallback client, in String attributionTag);
            int contextHubId, in IContextHubClientCallback client, in String attributionTag,
            in String packageName);

    // Creates a PendingIntent-based client to send and receive messages
    IContextHubClient createPendingIntentClient(
+105 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2021 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 com.android.server.location.contexthub;

import static java.util.concurrent.TimeUnit.SECONDS;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;

/**
 * A class that manages a timer used to keep track of how much time is left before a
 * {@link ContextHubClientBroker} has its authorization state changed with a nanoapp from
 * DENIED_GRACE_PERIOD to DENIED. Much of this implementation is copied from
 * {@link android.os.CountDownTimer} while adding the ability to specify the provided looper.
 *
 * @hide
 */
public class AuthStateDenialTimer {
    private static final long TIMEOUT_MS = SECONDS.toMillis(60);

    private final ContextHubClientBroker mClient;
    private final long mNanoAppId;
    private final Handler mHandler;

    /**
     * Indicates when the timer should stop in the future.
     */
    private long mStopTimeInFuture;

    /**
     * boolean representing if the timer was cancelled
     */
    private boolean mCancelled = false;

    public AuthStateDenialTimer(ContextHubClientBroker client, long nanoAppId, Looper looper) {
        mClient = client;
        mNanoAppId = nanoAppId;
        mHandler = new CountDownHandler(looper);
    }

    /**
     * Cancel the countdown.
     */
    public synchronized void cancel() {
        mCancelled = true;
        mHandler.removeMessages(MSG);
    }

    /**
     * Start the countdown.
     */
    public synchronized void start() {
        mCancelled = false;
        mStopTimeInFuture = SystemClock.elapsedRealtime() + TIMEOUT_MS;
        mHandler.sendMessage(mHandler.obtainMessage(MSG));
    }

    /**
     * Called when the timer has expired.
     */
    public void onFinish() {
        mClient.handleAuthStateTimerExpiry(mNanoAppId);
    }

    // Message type used to trigger the timer.
    private static final int MSG = 1;

    private class CountDownHandler extends Handler {

        CountDownHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            synchronized (AuthStateDenialTimer.this) {
                if (mCancelled) {
                    return;
                }
                final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime();
                if (millisLeft <= 0) {
                    onFinish();
                } else {
                    sendMessageDelayed(obtainMessage(MSG), millisLeft);
                }
            }
        }
    };
}
+355 −37

File changed.

Preview size limit exceeded, changes collapsed.

+32 −12
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;

@@ -136,8 +137,7 @@ import java.util.function.Consumer;
        }
    }

    /* package */ ContextHubClientManager(
            Context context, IContextHubWrapper contextHubProxy) {
    /* package */ ContextHubClientManager(Context context, IContextHubWrapper contextHubProxy) {
        mContext = context;
        mContextHubProxy = contextHubProxy;
    }
@@ -155,13 +155,15 @@ import java.util.function.Consumer;
     */
    /* package */ IContextHubClient registerClient(
            ContextHubInfo contextHubInfo, IContextHubClientCallback clientCallback,
            String attributionTag) {
            String attributionTag, ContextHubTransactionManager transactionManager,
            String packageName) {
        ContextHubClientBroker broker;
        synchronized (this) {
            short hostEndPointId = getHostEndPointId();
            broker = new ContextHubClientBroker(
                    mContext, mContextHubProxy, this /* clientManager */, contextHubInfo,
                    hostEndPointId, clientCallback, attributionTag);
                    hostEndPointId, clientCallback, attributionTag, transactionManager,
                    packageName);
            mHostEndPointIdToClientMap.put(hostEndPointId, broker);
            mRegistrationRecordDeque.add(
                    new RegistrationRecord(broker.toString(), ACTION_REGISTERED));
@@ -194,7 +196,7 @@ import java.util.function.Consumer;
     */
    /* package */ IContextHubClient registerClient(
            ContextHubInfo contextHubInfo, PendingIntent pendingIntent, long nanoAppId,
            String attributionTag) {
            String attributionTag, ContextHubTransactionManager transactionManager) {
        ContextHubClientBroker broker;
        String registerString = "Regenerated";
        synchronized (this) {
@@ -204,7 +206,8 @@ import java.util.function.Consumer;
                short hostEndPointId = getHostEndPointId();
                broker = new ContextHubClientBroker(
                        mContext, mContextHubProxy, this /* clientManager */, contextHubInfo,
                        hostEndPointId, pendingIntent, nanoAppId, attributionTag);
                        hostEndPointId, pendingIntent, nanoAppId, attributionTag,
                        transactionManager);
                mHostEndPointIdToClientMap.put(hostEndPointId, broker);
                registerString = "Registered";
                mRegistrationRecordDeque.add(
@@ -225,8 +228,13 @@ import java.util.function.Consumer;
     *
     * @param contextHubId the ID of the hub where the nanoapp sent the message from
     * @param message the message send by a nanoapp
     * @param nanoappPermissions the set of permissions the nanoapp holds
     * @param messagePermissions the set of permissions that should be used for attributing
     * permissions when this message is consumed by a client
     */
    /* package */ void onMessageFromNanoApp(int contextHubId, ContextHubMsg message) {
    /* package */ void onMessageFromNanoApp(
            int contextHubId, ContextHubMsg message, List<String> nanoappPermissions,
            List<String> messagePermissions) {
        NanoAppMessage clientMessage = ContextHubServiceUtil.createNanoAppMessage(message);

        if (DEBUG_LOG_ENABLED) {
@@ -234,11 +242,19 @@ import java.util.function.Consumer;
        }

        if (clientMessage.isBroadcastMessage()) {
            broadcastMessage(contextHubId, clientMessage);
            // Broadcast messages shouldn't be sent with any permissions tagged per CHRE API
            // requirements.
            if (!messagePermissions.isEmpty()) {
                Log.wtf(TAG, "Received broadcast message with permissions from " + message.appName);
            }

            broadcastMessage(
                    contextHubId, clientMessage, nanoappPermissions, messagePermissions);
        } else {
            ContextHubClientBroker proxy = mHostEndPointIdToClientMap.get(message.hostEndPoint);
            if (proxy != null) {
                proxy.sendMessageToClient(clientMessage);
                proxy.sendMessageToClient(
                        clientMessage, nanoappPermissions, messagePermissions);
            } else {
                Log.e(TAG, "Cannot send message to unregistered client (host endpoint ID = "
                        + message.hostEndPoint + ")");
@@ -333,8 +349,12 @@ import java.util.function.Consumer;
     * @param contextHubId the ID of the hub where the nanoapp sent the message from
     * @param message      the message send by a nanoapp
     */
    private void broadcastMessage(int contextHubId, NanoAppMessage message) {
        forEachClientOfHub(contextHubId, client -> client.sendMessageToClient(message));
    private void broadcastMessage(
            int contextHubId, NanoAppMessage message, List<String> nanoappPermissions,
            List<String> messagePermissions) {
        forEachClientOfHub(contextHubId,
                client -> client.sendMessageToClient(
                        message, nanoappPermissions, messagePermissions));
    }

    /**
Loading