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

Commit 8c806af8 authored by Vladimir Komsiyski's avatar Vladimir Komsiyski
Browse files

Enforce user consent for CC sessions.

Bug: 437901655
Flag: android.companion.virtualdevice.flags.computer_control_consent
Test: atest
Change-Id: Ife263b9558fe4722c5d2d65eaf829dae0ee3ca14
parent e9b44c27
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