[CDM perm sync] Introduce a new startSystemDataTransfer API with

callback

This new trigger API accpets a callback which would be executed when the
system data transfer finishes successfully or with error.

The callback hasn't been fully implemented because we need signals from
transport layer when the transfer finishes.

Bug: 237030169

Test: m builds
Change-Id: I7e57d3e53e5f019c8730df10f7ec6c840e446f67
This commit is contained in:
Guojing Yuan
2022-06-27 22:15:50 +00:00
parent 27ba4891e7
commit 592a33f868
7 changed files with 125 additions and 6 deletions

View File

@@ -9008,7 +9008,8 @@ package android.companion {
method @Deprecated public boolean hasNotificationAccess(android.content.ComponentName);
method public void requestNotificationAccess(android.content.ComponentName);
method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
method public void startSystemDataTransfer(int) throws android.companion.DeviceNotAssociatedException;
method @Deprecated public void startSystemDataTransfer(int) throws android.companion.DeviceNotAssociatedException;
method public void startSystemDataTransfer(int, @NonNull java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<java.lang.Void,android.companion.CompanionException>) throws android.companion.DeviceNotAssociatedException;
method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
field public static final String EXTRA_ASSOCIATION = "android.companion.extra.ASSOCIATION";
field @Deprecated public static final String EXTRA_DEVICE = "android.companion.extra.DEVICE";
@@ -9034,6 +9035,9 @@ package android.companion {
field public static final String SERVICE_INTERFACE = "android.companion.CompanionDeviceService";
}
public class CompanionException extends java.lang.RuntimeException {
}
public interface DeviceFilter<D extends android.os.Parcelable> extends android.os.Parcelable {
}

View File

@@ -38,6 +38,7 @@ import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.net.MacAddress;
import android.os.Handler;
import android.os.OutcomeReceiver;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -964,12 +965,44 @@ public final class CompanionDeviceManager {
* @param associationId The unique {@link AssociationInfo#getId ID} assigned to the Association
* of the companion device recorded by CompanionDeviceManager
* @throws DeviceNotAssociatedException Exception if the companion device is not associated
*
* @deprecated Use {@link #startSystemDataTransfer(int, Executor, OutcomeReceiver)} instead.
*/
@Deprecated
@UserHandleAware
public void startSystemDataTransfer(int associationId) throws DeviceNotAssociatedException {
try {
mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(),
associationId);
associationId, null);
} catch (RemoteException e) {
ExceptionUtils.propagateIfInstanceOf(e.getCause(), DeviceNotAssociatedException.class);
throw e.rethrowFromSystemServer();
}
}
/**
* Start system data transfer which has been previously approved by the user.
*
* <p>Before calling this method, the app needs to make sure there's a communication channel
* between two devices, and has prompted user consent dialogs built by one of these methods:
* {@link #buildPermissionTransferUserConsentIntent(int)}.
* The transfer may fail if the communication channel is disconnected during the transfer.</p>
*
* @param associationId The unique {@link AssociationInfo#getId ID} assigned to the Association
* of the companion device recorded by CompanionDeviceManager
* @param executor The executor which will be used to invoke the result callback.
* @param result The callback to notify the app of the result of the system data transfer.
* @throws DeviceNotAssociatedException Exception if the companion device is not associated
*/
@UserHandleAware
public void startSystemDataTransfer(
int associationId,
@NonNull Executor executor,
@NonNull OutcomeReceiver<Void, CompanionException> result)
throws DeviceNotAssociatedException {
try {
mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(),
associationId, new SystemDataTransferCallbackProxy(executor, result));
} catch (RemoteException e) {
ExceptionUtils.propagateIfInstanceOf(e.getCause(), DeviceNotAssociatedException.class);
throw e.rethrowFromSystemServer();
@@ -1045,6 +1078,27 @@ public final class CompanionDeviceManager {
}
}
private static class SystemDataTransferCallbackProxy extends ISystemDataTransferCallback.Stub {
private final Executor mExecutor;
private final OutcomeReceiver<Void, CompanionException> mCallback;
private SystemDataTransferCallbackProxy(Executor executor,
OutcomeReceiver<Void, CompanionException> callback) {
mExecutor = executor;
mCallback = callback;
}
@Override
public void onResult() {
mExecutor.execute(() -> mCallback.onResult(null));
}
@Override
public void onError(String error) {
mExecutor.execute(() -> mCallback.onError(new CompanionException(error)));
}
}
/**
* Representation of an active system data transport.
* <p>

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2022 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 android.companion;
import android.annotation.NonNull;
/**
* {@code CompanionException} can be thrown during the companion system data transfer process.
*/
public class CompanionException extends RuntimeException {
/** @hide */
public CompanionException(@NonNull String message) {
super(message);
}
}

View File

@@ -19,6 +19,7 @@ package android.companion;
import android.app.PendingIntent;
import android.companion.IAssociationRequestCallback;
import android.companion.IOnAssociationsChangedListener;
import android.companion.ISystemDataTransferCallback;
import android.companion.AssociationInfo;
import android.companion.AssociationRequest;
import android.content.ComponentName;
@@ -75,7 +76,8 @@ interface ICompanionDeviceManager {
PendingIntent buildPermissionTransferUserConsentIntent(String callingPackage, int userId,
int associationId);
void startSystemDataTransfer(String packageName, int userId, int associationId);
void startSystemDataTransfer(String packageName, int userId, int associationId,
in ISystemDataTransferCallback callback);
void attachSystemDataTransport(String packageName, int userId, int associationId, in ParcelFileDescriptor fd);

View File

@@ -0,0 +1,24 @@
/*
* Copyright (C) 2022 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 per missions and
* limitations under the License.
*/
package android.companion;
/** @hide */
interface ISystemDataTransferCallback {
oneway void onResult();
oneway void onError(String error);
}

View File

@@ -62,6 +62,7 @@ import android.companion.DeviceNotAssociatedException;
import android.companion.IAssociationRequestCallback;
import android.companion.ICompanionDeviceManager;
import android.companion.IOnAssociationsChangedListener;
import android.companion.ISystemDataTransferCallback;
import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
@@ -722,9 +723,10 @@ public class CompanionDeviceManagerService extends SystemService {
}
@Override
public void startSystemDataTransfer(String packageName, int userId, int associationId) {
public void startSystemDataTransfer(String packageName, int userId, int associationId,
ISystemDataTransferCallback callback) {
mSystemDataTransferProcessor.startSystemDataTransfer(packageName, userId,
associationId);
associationId, callback);
}
@Override

View File

@@ -29,6 +29,7 @@ import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.companion.AssociationInfo;
import android.companion.DeviceNotAssociatedException;
import android.companion.ISystemDataTransferCallback;
import android.companion.datatransfer.PermissionSyncRequest;
import android.companion.datatransfer.SystemDataTransferRequest;
import android.content.ComponentName;
@@ -167,8 +168,11 @@ public class SystemDataTransferProcessor {
/**
* Start system data transfer. It should first try to establish a secure channel and then sync
* system data.
*
* TODO: execute callback when the transfer finishes successfully or with errors.
*/
public void startSystemDataTransfer(String packageName, int userId, int associationId) {
public void startSystemDataTransfer(String packageName, int userId, int associationId,
ISystemDataTransferCallback callback) {
Slog.i(LOG_TAG, "Start system data transfer for package [" + packageName
+ "] userId [" + userId + "] associationId [" + associationId + "]");