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

Commit 435a4fa5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Support ADB command for denying client auth" into sc-dev am: ad09e265

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

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Iecad6a27f81c5b95d55de317ec3940157e4cc5eb
parents 13def9b6 ad09e265
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -425,6 +425,10 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
        }
    }

    /* package */ String getPackageName() {
        return mPackage;
    }

    /**
     * Used to override the attribution tag with a newer value if a PendingIntent broker is
     * retrieved.
@@ -645,6 +649,13 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
     */
    private void updateNanoAppAuthState(
            long nanoAppId, boolean hasPermissions, boolean gracePeriodExpired) {
        updateNanoAppAuthState(
                nanoAppId, hasPermissions, gracePeriodExpired, false /* forceDenied */);
    }

    /* package */ void updateNanoAppAuthState(
            long nanoAppId, boolean hasPermissions, boolean gracePeriodExpired,
            boolean forceDenied) {
        int curAuthState;
        int newAuthState;
        synchronized (mMessageChannelNanoappIdMap) {
@@ -655,7 +666,10 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
            // GRANTED -> DENIED_GRACE_PERIOD only if permissions have been lost
            // DENIED_GRACE_PERIOD -> DENIED only if the grace period expires
            // DENIED/DENIED_GRACE_PERIOD -> GRANTED only if permissions are granted again
            if (gracePeriodExpired) {
            // any state -> DENIED if "forceDenied" is true
            if (forceDenied) {
                newAuthState = AUTHORIZATION_DENIED;
            } else if (gracePeriodExpired) {
                if (curAuthState == AUTHORIZATION_DENIED_GRACE_PERIOD) {
                    newAuthState = AUTHORIZATION_DENIED;
                }
@@ -667,13 +681,12 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
                }
            }

            if (newAuthState == AUTHORIZATION_GRANTED) {
            if (newAuthState != AUTHORIZATION_DENIED_GRACE_PERIOD) {
                AuthStateDenialTimer timer = mNappToAuthTimerMap.remove(nanoAppId);
                if (timer != null) {
                    timer.cancel();
                }
            } else if (curAuthState == AUTHORIZATION_GRANTED
                    && newAuthState == AUTHORIZATION_DENIED_GRACE_PERIOD) {
            } else if (curAuthState == AUTHORIZATION_GRANTED) {
                AuthStateDenialTimer timer =
                        new AuthStateDenialTimer(this, nanoAppId, Looper.getMainLooper());
                mNappToAuthTimerMap.put(nanoAppId, timer);
+15 −14
Original line number Diff line number Diff line
@@ -318,6 +318,21 @@ import java.util.function.Consumer;
        forEachClientOfHub(contextHubId, client -> client.onNanoAppAborted(nanoAppId, abortCode));
    }

    /**
     * Runs a command for each client that is attached to a hub with the given ID.
     *
     * @param contextHubId the ID of the hub
     * @param callback     the command to invoke for the client
     */
    /* package */ void forEachClientOfHub(
            int contextHubId, Consumer<ContextHubClientBroker> callback) {
        for (ContextHubClientBroker broker : mHostEndPointIdToClientMap.values()) {
            if (broker.getAttachedContextHubId() == contextHubId) {
                callback.accept(broker);
            }
        }
    }

    /**
     * Returns an available host endpoint ID.
     *
@@ -357,20 +372,6 @@ import java.util.function.Consumer;
                        message, nanoappPermissions, messagePermissions));
    }

    /**
     * Runs a command for each client that is attached to a hub with the given ID.
     *
     * @param contextHubId the ID of the hub
     * @param callback     the command to invoke for the client
     */
    private void forEachClientOfHub(int contextHubId, Consumer<ContextHubClientBroker> callback) {
        for (ContextHubClientBroker broker : mHostEndPointIdToClientMap.values()) {
            if (broker.getAttachedContextHubId() == contextHubId) {
                callback.accept(broker);
            }
        }
    }

    /**
     * Retrieves a ContextHubClientBroker object with a matching PendingIntent and Context Hub ID.
     *
+18 −0
Original line number Diff line number Diff line
@@ -50,6 +50,8 @@ import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
@@ -365,6 +367,12 @@ public class ContextHubService extends IContextHubService.Stub {
        return wrapper;
    }

    @Override
    public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
            String[] args, ShellCallback callback, ResultReceiver result) {
        new ContextHubShellCommand(mContext, this).exec(this, in, out, err, args, callback, result);
    }

    @Override
    public int registerCallback(IContextHubCallback callback) throws RemoteException {
        checkPermissions();
@@ -933,6 +941,16 @@ public class ContextHubService extends IContextHubService.Stub {
        // dump eventLog
    }

    /* package */ void denyClientAuthState(int contextHubId, String packageName, long nanoAppId) {
        mClientManager.forEachClientOfHub(contextHubId, client -> {
            if (client.getPackageName().equals(packageName)) {
                client.updateNanoAppAuthState(
                        nanoAppId, false /* hasPermissions */, false /* gracePeriodExpired */,
                        true /* forceDenied */);
            }
        });
    }

    private void dump(ProtoOutputStream proto) {
        mContextHubIdToInfoMap.values().forEach(hubInfo -> {
            long token = proto.start(ContextHubServiceProto.CONTEXT_HUB_INFO);
+71 −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 android.content.Context;
import android.os.ShellCommand;

import java.io.PrintWriter;

/**
 * ShellCommands for ContextHubService.
 *
 * Use with {@code adb shell cmd contexthub ...}.
 *
 * @hide
 */
public class ContextHubShellCommand extends ShellCommand {

    // Internal service impl -- must perform security checks before touching.
    private final ContextHubService mInternal;

    public ContextHubShellCommand(Context context, ContextHubService service) {
        mInternal = service;

        context.enforceCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_CONTEXT_HUB, "ContextHubShellCommand");
    }

    @Override
    public int onCommand(String cmd) {
        if ("deny".equals(cmd)) {
            return runDisableAuth();
        }

        return handleDefaultCommands(cmd);
    }

    private int runDisableAuth() {
        int contextHubId = Integer.decode(getNextArgRequired());
        String packageName = getNextArgRequired();
        long nanoAppId = Long.decode(getNextArgRequired());

        mInternal.denyClientAuthState(contextHubId, packageName, nanoAppId);
        return 0;
    }

    @Override
    public void onHelp() {
        PrintWriter pw = getOutPrintWriter();
        pw.println("ContextHub commands:");
        pw.println("  help");
        pw.println("      Print this help text.");
        pw.println("  deny [contextHubId] [packageName] [nanoAppId]");
        pw.println("    Immediately transitions the package's authentication state to denied so");
        pw.println("    can no longer communciate with the nanoapp.");
    }
}