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

Commit c79159b4 authored by Guojing Yuan's avatar Guojing Yuan Committed by Android (Google) Code Review
Browse files

Merge "[CDM] Support Perm Sync toggle setting" into main

parents c044e7d2 ba390e8c
Loading
Loading
Loading
Loading
+35 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.app.NotificationManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.companion.datatransfer.PermissionSyncRequest;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -180,7 +181,7 @@ public final class CompanionDeviceManager {
    public @interface DataSyncTypes {}

    /**
     * Used by {@link #enableSystemDataSync(int, int)}}.
     * Used by {@link #enableSystemDataSyncForTypes(int, int)}}.
     * Sync call metadata like muting, ending and silencing a call.
     *
     */
@@ -551,6 +552,39 @@ public final class CompanionDeviceManager {
        }
    }

    /**
     * @hide
     */
    public void enablePermissionsSync(int associationId) {
        try {
            mService.enablePermissionsSync(associationId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     */
    public void disablePermissionsSync(int associationId) {
        try {
            mService.disablePermissionsSync(associationId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     */
    public PermissionSyncRequest getPermissionSyncRequest(int associationId) {
        try {
            return mService.getPermissionSyncRequest(associationId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * <p>Calling this API requires a uses-feature
     * {@link PackageManager#FEATURE_COMPANION_DEVICE_SETUP} declaration in the manifest</p>
+7 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.companion.IOnTransportsChangedListener;
import android.companion.ISystemDataTransferCallback;
import android.companion.AssociationInfo;
import android.companion.AssociationRequest;
import android.companion.datatransfer.PermissionSyncRequest;
import android.content.ComponentName;

/**
@@ -113,6 +114,12 @@ interface ICompanionDeviceManager {

    void disableSystemDataSync(int associationId, int flags);

    void enablePermissionsSync(int associationId);

    void disablePermissionsSync(int associationId);

    PermissionSyncRequest getPermissionSyncRequest(int associationId);

    @EnforcePermission("MANAGE_COMPANION_DEVICES")
    void enableSecureTransport(boolean enabled);

+20 −1
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import android.companion.IOnAssociationsChangedListener;
import android.companion.IOnMessageReceivedListener;
import android.companion.IOnTransportsChangedListener;
import android.companion.ISystemDataTransferCallback;
import android.companion.datatransfer.PermissionSyncRequest;
import android.companion.utils.FeatureUtils;
import android.content.ComponentName;
import android.content.Context;
@@ -872,6 +873,24 @@ public class CompanionDeviceManagerService extends SystemService {
            mAssociationRequestsProcessor.disableSystemDataSync(associationId, flags);
        }

        @Override
        public void enablePermissionsSync(int associationId) {
            getAssociationWithCallerChecks(associationId);
            mSystemDataTransferProcessor.enablePermissionsSync(associationId);
        }

        @Override
        public void disablePermissionsSync(int associationId) {
            getAssociationWithCallerChecks(associationId);
            mSystemDataTransferProcessor.disablePermissionsSync(associationId);
        }

        @Override
        public PermissionSyncRequest getPermissionSyncRequest(int associationId) {
            getAssociationWithCallerChecks(associationId);
            return mSystemDataTransferProcessor.getPermissionSyncRequest(associationId);
        }

        @Override
        @EnforcePermission(MANAGE_COMPANION_DEVICES)
        public void enableSecureTransport(boolean enabled) {
@@ -1041,7 +1060,7 @@ public class CompanionDeviceManagerService extends SystemService {
                String[] args, ShellCallback callback, ResultReceiver resultReceiver)
                throws RemoteException {
            new CompanionDeviceShellCommand(CompanionDeviceManagerService.this, mAssociationStore,
                    mDevicePresenceMonitor, mTransportManager, mSystemDataTransferRequestStore,
                    mDevicePresenceMonitor, mTransportManager, mSystemDataTransferProcessor,
                    mAssociationRequestsProcessor)
                    .exec(this, in, out, err, args, callback, resultReceiver);
        }
+52 −12
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ import android.os.Binder;
import android.os.ShellCommand;
import android.util.proto.ProtoOutputStream;

import com.android.server.companion.datatransfer.SystemDataTransferRequestStore;
import com.android.server.companion.datatransfer.SystemDataTransferProcessor;
import com.android.server.companion.datatransfer.contextsync.BitmapUtils;
import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController;
import com.android.server.companion.presence.CompanionDevicePresenceMonitor;
@@ -44,20 +44,20 @@ class CompanionDeviceShellCommand extends ShellCommand {
    private final CompanionDevicePresenceMonitor mDevicePresenceMonitor;
    private final CompanionTransportManager mTransportManager;

    private final SystemDataTransferRequestStore mSystemDataTransferRequestStore;
    private final SystemDataTransferProcessor mSystemDataTransferProcessor;
    private final AssociationRequestsProcessor mAssociationRequestsProcessor;

    CompanionDeviceShellCommand(CompanionDeviceManagerService service,
            AssociationStoreImpl associationStore,
            CompanionDevicePresenceMonitor devicePresenceMonitor,
            CompanionTransportManager transportManager,
            SystemDataTransferRequestStore systemDataTransferRequestStore,
            SystemDataTransferProcessor systemDataTransferProcessor,
            AssociationRequestsProcessor associationRequestsProcessor) {
        mService = service;
        mAssociationStore = associationStore;
        mDevicePresenceMonitor = devicePresenceMonitor;
        mTransportManager = transportManager;
        mSystemDataTransferRequestStore = systemDataTransferRequestStore;
        mSystemDataTransferProcessor = systemDataTransferProcessor;
        mAssociationRequestsProcessor = associationRequestsProcessor;
    }

@@ -261,16 +261,47 @@ class CompanionDeviceShellCommand extends ShellCommand {
                    break;
                }

                case "allow-permission-sync": {
                    int userId = getNextIntArgRequired();
                case "get-perm-sync-state": {
                    associationId = getNextIntArgRequired();
                    PermissionSyncRequest request =
                            mSystemDataTransferProcessor.getPermissionSyncRequest(associationId);
                    out.println((request == null ? "null" : request.isUserConsented()));
                    break;
                }

                case "remove-perm-sync-state": {
                    associationId = getNextIntArgRequired();
                    PermissionSyncRequest request =
                            mSystemDataTransferProcessor.getPermissionSyncRequest(associationId);
                    out.print((request == null ? "null" : request.isUserConsented()));
                    mSystemDataTransferProcessor.removePermissionSyncRequest(associationId);
                    request = mSystemDataTransferProcessor.getPermissionSyncRequest(associationId);
                    // should print " -> null"
                    out.println(" -> " + (request == null ? "null" : request.isUserConsented()));
                    break;
                }

                case "enable-perm-sync": {
                    associationId = getNextIntArgRequired();
                    boolean enabled = getNextBooleanArgRequired();
                    PermissionSyncRequest request = new PermissionSyncRequest(associationId);
                    request.setUserId(userId);
                    request.setUserConsented(enabled);
                    mSystemDataTransferRequestStore.writeRequest(userId, request);
                    PermissionSyncRequest request =
                            mSystemDataTransferProcessor.getPermissionSyncRequest(associationId);
                    out.print((request == null ? "null" : request.isUserConsented()));
                    mSystemDataTransferProcessor.enablePermissionsSync(associationId);
                    request = mSystemDataTransferProcessor.getPermissionSyncRequest(associationId);
                    out.println(" -> " + request.isUserConsented()); // should print " -> true"
                    break;
                }

                case "disable-perm-sync": {
                    associationId = getNextIntArgRequired();
                    PermissionSyncRequest request =
                            mSystemDataTransferProcessor.getPermissionSyncRequest(associationId);
                    out.print((request == null ? "null" : request.isUserConsented()));
                    mSystemDataTransferProcessor.disablePermissionsSync(associationId);
                    request = mSystemDataTransferProcessor.getPermissionSyncRequest(associationId);
                    out.println(" -> " + request.isUserConsented()); // should print " -> false"
                    break;
                }

                default:
                    return handleDefaultCommands(cmd);
@@ -346,5 +377,14 @@ class CompanionDeviceShellCommand extends ShellCommand {

        pw.println("  create-emulated-transport <ASSOCIATION_ID>");
        pw.println("      Create an EmulatedTransport for testing purposes only");

        pw.println("  enable-perm-sync <ASSOCIATION_ID>");
        pw.println("      Enable perm sync for the association.");
        pw.println("  disable-perm-sync <ASSOCIATION_ID>");
        pw.println("      Disable perm sync for the association.");
        pw.println("  get-perm-sync-state <ASSOCIATION_ID>");
        pw.println("      Get perm sync state for the association.");
        pw.println("  remove-perm-sync-state <ASSOCIATION_ID>");
        pw.println("      Remove perm sync state for the association.");
    }
}
+61 −22
Original line number Diff line number Diff line
@@ -139,6 +139,13 @@ public class SystemDataTransferProcessor {
            @UserIdInt int userId, int associationId) {
        if (PackageUtils.isPackageAllowlisted(mContext, mPackageManager, packageName)) {
            Slog.i(LOG_TAG, "User consent Intent should be skipped. Returning null.");
            // Auto enable perm sync for the whitelisted packages, but don't override user decision
            PermissionSyncRequest request = getPermissionSyncRequest(associationId);
            if (request == null) {
                PermissionSyncRequest newRequest = new PermissionSyncRequest(associationId);
                newRequest.setUserConsented(true);
                mSystemDataTransferRequestStore.writeRequest(userId, newRequest);
            }
            return null;
        }

@@ -185,22 +192,11 @@ public class SystemDataTransferProcessor {
        final AssociationInfo association = resolveAssociation(packageName, userId, associationId);

        // Check if the request has been consented by the user.
        if (PackageUtils.isPackageAllowlisted(mContext, mPackageManager, packageName)) {
            Slog.i(LOG_TAG, "Skip user consent check due to the same OEM package.");
        } else {
            List<SystemDataTransferRequest> storedRequests =
                    mSystemDataTransferRequestStore.readRequestsByAssociationId(userId,
                            associationId);
            boolean hasConsented = false;
            for (SystemDataTransferRequest storedRequest : storedRequests) {
                if (storedRequest instanceof PermissionSyncRequest
                        && storedRequest.isUserConsented()) {
                    hasConsented = true;
                    break;
                }
            }
            if (!hasConsented) {
                String message = "User " + userId + " hasn't consented permission sync.";
        PermissionSyncRequest request = getPermissionSyncRequest(associationId);
        if (request == null || !request.isUserConsented()) {
            String message =
                    "User " + userId + " hasn't consented permission sync for associationId ["
                            + associationId + ".";
            Slog.e(LOG_TAG, message);
            try {
                callback.onError(message);
@@ -208,7 +204,6 @@ public class SystemDataTransferProcessor {
            }
            return;
        }
        }

        // Start permission sync
        final long callingIdentityToken = Binder.clearCallingIdentity();
@@ -225,6 +220,50 @@ public class SystemDataTransferProcessor {
        }
    }

    /**
     * Enable perm sync for the association
     */
    public void enablePermissionsSync(int associationId) {
        int userId = mAssociationStore.getAssociationById(associationId).getUserId();
        PermissionSyncRequest request = new PermissionSyncRequest(associationId);
        request.setUserConsented(true);
        mSystemDataTransferRequestStore.writeRequest(userId, request);
    }

    /**
     * Disable perm sync for the association
     */
    public void disablePermissionsSync(int associationId) {
        int userId = mAssociationStore.getAssociationById(associationId).getUserId();
        PermissionSyncRequest request = new PermissionSyncRequest(associationId);
        request.setUserConsented(false);
        mSystemDataTransferRequestStore.writeRequest(userId, request);
    }

    /**
     * Get perm sync request for the association.
     */
    @Nullable
    public PermissionSyncRequest getPermissionSyncRequest(int associationId) {
        int userId = mAssociationStore.getAssociationById(associationId).getUserId();
        List<SystemDataTransferRequest> requests =
                mSystemDataTransferRequestStore.readRequestsByAssociationId(userId, associationId);
        for (SystemDataTransferRequest request : requests) {
            if (request instanceof PermissionSyncRequest) {
                return (PermissionSyncRequest) request;
            }
        }
        return null;
    }

    /**
     * Remove perm sync request for the association.
     */
    public void removePermissionSyncRequest(int associationId) {
        int userId = mAssociationStore.getAssociationById(associationId).getUserId();
        mSystemDataTransferRequestStore.removeRequestsByAssociationId(userId, associationId);
    }

    private void onReceivePermissionRestore(byte[] message) {
        Slog.i(LOG_TAG, "Applying permissions.");
        // Start applying permissions
Loading