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

Commit 609ea115 authored by Vladimir Komsiyski's avatar Vladimir Komsiyski Committed by Android (Google) Code Review
Browse files

Merge "Enforce user consent for CC sessions." into main

parents 4b5ffe3d 8c806af8
Loading
Loading
Loading
Loading
+38 −3
Original line number Diff line number Diff line
@@ -20,6 +20,11 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.hardware.input.VirtualKeyEvent;
import android.hardware.input.VirtualTouchEvent;
import android.os.Binder;
@@ -43,13 +48,17 @@ import java.util.concurrent.Executor;
 */
public final class ComputerControlSession implements AutoCloseable {

    /** @hide */
    public static final String ACTION_REQUEST_ACCESS =
            "android.companion.virtual.computercontrol.action.REQUEST_ACCESS";

    /**
     * Error code indicating that a new session cannot be created because the maximum number of
     * allowed concurrent sessions has been reached.
     *
     * <p>This is a transient error and the session creation request can be retried later.</p>
     */
    public static final int ERROR_SESSION_LIMIT_REACHED = -1;
    public static final int ERROR_SESSION_LIMIT_REACHED = 1;

    /**
     * Error code indicating that a new session cannot be created because the lock screen (also
@@ -59,13 +68,19 @@ public final class ComputerControlSession implements AutoCloseable {
     *
     * @see android.app.KeyguardManager#isKeyguardLocked()
     */
    public static final int ERROR_KEYGUARD_LOCKED = -2;
    public static final int ERROR_KEYGUARD_LOCKED = 2;

    /**
     * Error code indicating that the user did not approve the creation of a new session.
     */
    public static final int ERROR_PERMISSION_DENIED = 3;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "ERROR_", value = {
            ERROR_SESSION_LIMIT_REACHED,
            ERROR_KEYGUARD_LOCKED})
            ERROR_KEYGUARD_LOCKED,
            ERROR_PERMISSION_DENIED})
    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
    public @interface SessionCreationError {
    }
@@ -137,6 +152,19 @@ public final class ComputerControlSession implements AutoCloseable {
    /** Callback for computer control session events. */
    public interface Callback {

        /**
         * Called when the session request needs to approved by the user.
         *
         * <p>Applications should launch the {@link Activity} "encapsulated" in {@code intentSender}
         * {@link IntentSender} object by calling
         * {@link Activity#startIntentSenderForResult(IntentSender, int, Intent, int, int, int)} or
         * {@link Context#startIntentSender(IntentSender, Intent, int, int, int)}
         *
         * @param intentSender an {@link IntentSender} which applications should use to launch
         *   the UI for the user to allow the creation of the session.
         */
        void onSessionPending(@NonNull IntentSender intentSender);

        /** Called when the session has been successfully created. */
        void onSessionCreated(@NonNull ComputerControlSession session);

@@ -165,6 +193,13 @@ public final class ComputerControlSession implements AutoCloseable {
            mCallback = callback;
        }

        @Override
        public void onSessionPending(@NonNull PendingIntent pendingIntent) {
            Binder.withCleanCallingIdentity(() ->
                    mExecutor.execute(() ->
                            mCallback.onSessionPending(pendingIntent.getIntentSender())));
        }

        @Override
        public void onSessionCreated(IComputerControlSession session) {
            Binder.withCleanCallingIdentity(() ->
+4 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.companion.virtual.computercontrol;

import android.app.PendingIntent;
import android.companion.virtual.computercontrol.IComputerControlSession;

/**
@@ -25,6 +26,9 @@ import android.companion.virtual.computercontrol.IComputerControlSession;
 */
oneway interface IComputerControlSessionCallback {

    /** Called when the session request needs to approved by the user. */
    void onSessionPending(in PendingIntent pendingIntent);

    /** Called when the session has been successfully created. */
    void onSessionCreated(in IComputerControlSession session);

+10 −0
Original line number Diff line number Diff line
@@ -246,3 +246,13 @@ flag {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
    name: "computer_control_consent"
    namespace: "virtual_devices"
    description: "Show a consent dialog for computer control session creation"
    bug: "437901655"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+13 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.RequiresPermission;
import android.companion.virtual.VirtualDeviceManager;
import android.companion.virtual.computercontrol.ComputerControlSessionParams;
import android.content.Context;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.view.accessibility.AccessibilityManager;

@@ -96,6 +97,18 @@ public class ComputerControlExtensions {
        var sessionCallback =
                new android.companion.virtual.computercontrol.ComputerControlSession.Callback() {

                    @Override
                    public void onSessionPending(@NonNull IntentSender intentSender) {
                        // TODO(b/437901655): Pass this to the caller.
                        try {
                            params.getContext().startIntentSender(intentSender, null, 0, 0, 0);
                        } catch (IntentSender.SendIntentException e) {
                            callback.onSessionCreationFailed(
                                    android.companion.virtual.computercontrol
                                            .ComputerControlSession.ERROR_PERMISSION_DENIED);
                        }
                    }

                    @Override
                    public void onSessionCreated(
                            @NonNull android.companion.virtual.computercontrol
+4 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.companion.virtual;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Process;
import android.os.UserHandle;
import android.util.Slog;

@@ -39,6 +40,9 @@ class PermissionUtils {
     */
    public static boolean validateCallingPackageName(Context context, String callingPackage) {
        final int callingUid = Binder.getCallingUid();
        if (callingUid == Process.SYSTEM_UID) {
            return true;
        }
        final long token = Binder.clearCallingIdentity();
        try {
            int packageUid = context.getPackageManager()
Loading