Merge "Add launch complete status to launchPendingIntent" into tm-dev
This commit is contained in:
commit
3ece298e8b
@ -2784,6 +2784,9 @@ package android.companion.virtual {
|
||||
|
||||
public final class VirtualDeviceManager {
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.companion.virtual.VirtualDeviceManager.VirtualDevice createVirtualDevice(int, @NonNull android.companion.virtual.VirtualDeviceParams);
|
||||
field public static final int LAUNCH_FAILURE_NO_ACTIVITY = 2; // 0x2
|
||||
field public static final int LAUNCH_FAILURE_PENDING_INTENT_CANCELED = 1; // 0x1
|
||||
field public static final int LAUNCH_SUCCESS = 0; // 0x0
|
||||
}
|
||||
|
||||
public static interface VirtualDeviceManager.ActivityListener {
|
||||
@ -2791,11 +2794,6 @@ package android.companion.virtual {
|
||||
method public void onTopActivityChanged(int, @NonNull android.content.ComponentName);
|
||||
}
|
||||
|
||||
public static interface VirtualDeviceManager.LaunchCallback {
|
||||
method public void onLaunchFailed();
|
||||
method public void onLaunchSuccess();
|
||||
}
|
||||
|
||||
public static class VirtualDeviceManager.VirtualDevice implements java.lang.AutoCloseable {
|
||||
method public void addActivityListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
|
||||
method @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void close();
|
||||
@ -2804,7 +2802,7 @@ package android.companion.virtual {
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualKeyboard createVirtualKeyboard(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualMouse createVirtualMouse(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public android.hardware.input.VirtualTouchscreen createVirtualTouchscreen(@NonNull android.hardware.display.VirtualDisplay, @NonNull String, int, int);
|
||||
method public void launchPendingIntent(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull android.companion.virtual.VirtualDeviceManager.LaunchCallback);
|
||||
method public void launchPendingIntent(int, @NonNull android.app.PendingIntent, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.IntConsumer);
|
||||
method public void removeActivityListener(@NonNull android.companion.virtual.VirtualDeviceManager.ActivityListener);
|
||||
method @NonNull @RequiresPermission(android.Manifest.permission.CREATE_VIRTUAL_DEVICE) public void setShowPointerIcon(boolean);
|
||||
}
|
||||
|
@ -17,13 +17,13 @@
|
||||
package android.companion.virtual;
|
||||
|
||||
import android.annotation.CallbackExecutor;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.SystemService;
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.companion.AssociationInfo;
|
||||
import android.companion.virtual.audio.VirtualAudioDevice;
|
||||
@ -48,7 +48,12 @@ import android.os.ResultReceiver;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.Surface;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
/**
|
||||
* System level service for managing virtual devices.
|
||||
@ -70,6 +75,35 @@ public final class VirtualDeviceManager {
|
||||
| DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH
|
||||
| DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_DISPLAY_GROUP;
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(
|
||||
prefix = "LAUNCH_",
|
||||
value = {
|
||||
LAUNCH_SUCCESS,
|
||||
LAUNCH_FAILURE_PENDING_INTENT_CANCELED,
|
||||
LAUNCH_FAILURE_NO_ACTIVITY})
|
||||
@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
|
||||
public @interface PendingIntentLaunchStatus {}
|
||||
|
||||
/**
|
||||
* Status for {@link VirtualDevice#launchPendingIntent}, indicating that the launch was
|
||||
* successful.
|
||||
*/
|
||||
public static final int LAUNCH_SUCCESS = 0;
|
||||
|
||||
/**
|
||||
* Status for {@link VirtualDevice#launchPendingIntent}, indicating that the launch failed
|
||||
* because the pending intent was canceled.
|
||||
*/
|
||||
public static final int LAUNCH_FAILURE_PENDING_INTENT_CANCELED = 1;
|
||||
|
||||
/**
|
||||
* Status for {@link VirtualDevice#launchPendingIntent}, indicating that the launch failed
|
||||
* because no activity starts were detected as a result of calling the pending intent.
|
||||
*/
|
||||
public static final int LAUNCH_FAILURE_NO_ACTIVITY = 2;
|
||||
|
||||
private final IVirtualDeviceManager mService;
|
||||
private final Context mContext;
|
||||
|
||||
@ -173,16 +207,20 @@ public final class VirtualDeviceManager {
|
||||
* intent, the activity will be started on the virtual display using
|
||||
* {@link android.app.ActivityOptions#setLaunchDisplayId}. If the intent is a service or
|
||||
* broadcast intent, an attempt will be made to catch activities started as a result of
|
||||
* sending the pending intent and move them to the given display.
|
||||
* sending the pending intent and move them to the given display. When it completes,
|
||||
* {@code listener} will be called with the status of whether the launch attempt is
|
||||
* successful or not.
|
||||
* @param executor The executor to run {@code launchCallback} on.
|
||||
* @param launchCallback Callback that is called when the pending intent launching is
|
||||
* complete.
|
||||
* @param listener Listener that is called when the pending intent launching is complete.
|
||||
* The argument is {@link #LAUNCH_SUCCESS} if the launch successfully started an activity
|
||||
* on the virtual display, or one of the {@code LAUNCH_FAILED} status explaining why it
|
||||
* failed.
|
||||
*/
|
||||
public void launchPendingIntent(
|
||||
int displayId,
|
||||
@NonNull PendingIntent pendingIntent,
|
||||
@NonNull Executor executor,
|
||||
@NonNull LaunchCallback launchCallback) {
|
||||
@NonNull IntConsumer listener) {
|
||||
try {
|
||||
mVirtualDevice.launchPendingIntent(
|
||||
displayId,
|
||||
@ -191,13 +229,7 @@ public final class VirtualDeviceManager {
|
||||
@Override
|
||||
protected void onReceiveResult(int resultCode, Bundle resultData) {
|
||||
super.onReceiveResult(resultCode, resultData);
|
||||
executor.execute(() -> {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
launchCallback.onLaunchSuccess();
|
||||
} else {
|
||||
launchCallback.onLaunchFailed();
|
||||
}
|
||||
});
|
||||
executor.execute(() -> listener.accept(resultCode));
|
||||
}
|
||||
});
|
||||
} catch (RemoteException e) {
|
||||
@ -439,28 +471,13 @@ public final class VirtualDeviceManager {
|
||||
* {@link #addActivityListener}.
|
||||
*
|
||||
* @param listener The listener to remove.
|
||||
* @see #addActivityListener(ActivityListener, Executor)
|
||||
* @see #addActivityListener(Executor, ActivityListener)
|
||||
*/
|
||||
public void removeActivityListener(@NonNull ActivityListener listener) {
|
||||
mActivityListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for launching pending intents on the virtual device.
|
||||
*/
|
||||
public interface LaunchCallback {
|
||||
/**
|
||||
* Called when the pending intent launched successfully.
|
||||
*/
|
||||
void onLaunchSuccess();
|
||||
|
||||
/**
|
||||
* Called when the pending intent failed to launch.
|
||||
*/
|
||||
void onLaunchFailed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener for activity changes in this virtual device.
|
||||
*/
|
||||
|
@ -33,6 +33,7 @@ import android.app.admin.DevicePolicyManager;
|
||||
import android.companion.AssociationInfo;
|
||||
import android.companion.virtual.IVirtualDevice;
|
||||
import android.companion.virtual.IVirtualDeviceActivityListener;
|
||||
import android.companion.virtual.VirtualDeviceManager;
|
||||
import android.companion.virtual.VirtualDeviceManager.ActivityListener;
|
||||
import android.companion.virtual.VirtualDeviceParams;
|
||||
import android.companion.virtual.audio.IAudioConfigChangedCallback;
|
||||
@ -79,6 +80,12 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
|
||||
implements IBinder.DeathRecipient {
|
||||
|
||||
private static final String TAG = "VirtualDeviceImpl";
|
||||
|
||||
/**
|
||||
* Timeout until {@link #launchPendingIntent} stops waiting for an activity to be launched.
|
||||
*/
|
||||
private static final long PENDING_TRAMPOLINE_TIMEOUT_MS = 5000;
|
||||
|
||||
private final Object mVirtualDeviceLock = new Object();
|
||||
|
||||
private final Context mContext;
|
||||
@ -195,20 +202,27 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub
|
||||
if (pendingIntent.isActivity()) {
|
||||
try {
|
||||
sendPendingIntent(displayId, pendingIntent);
|
||||
resultReceiver.send(Activity.RESULT_OK, null);
|
||||
resultReceiver.send(VirtualDeviceManager.LAUNCH_SUCCESS, null);
|
||||
} catch (PendingIntent.CanceledException e) {
|
||||
Slog.w(TAG, "Pending intent canceled", e);
|
||||
resultReceiver.send(Activity.RESULT_CANCELED, null);
|
||||
resultReceiver.send(
|
||||
VirtualDeviceManager.LAUNCH_FAILURE_PENDING_INTENT_CANCELED, null);
|
||||
}
|
||||
} else {
|
||||
PendingTrampoline pendingTrampoline = new PendingTrampoline(pendingIntent,
|
||||
resultReceiver, displayId);
|
||||
mPendingTrampolineCallback.startWaitingForPendingTrampoline(pendingTrampoline);
|
||||
mContext.getMainThreadHandler().postDelayed(() -> {
|
||||
pendingTrampoline.mResultReceiver.send(
|
||||
VirtualDeviceManager.LAUNCH_FAILURE_NO_ACTIVITY, null);
|
||||
mPendingTrampolineCallback.stopWaitingForPendingTrampoline(pendingTrampoline);
|
||||
}, PENDING_TRAMPOLINE_TIMEOUT_MS);
|
||||
try {
|
||||
sendPendingIntent(displayId, pendingIntent);
|
||||
} catch (PendingIntent.CanceledException e) {
|
||||
Slog.w(TAG, "Pending intent canceled", e);
|
||||
resultReceiver.send(Activity.RESULT_CANCELED, null);
|
||||
resultReceiver.send(
|
||||
VirtualDeviceManager.LAUNCH_FAILURE_PENDING_INTENT_CANCELED, null);
|
||||
mPendingTrampolineCallback.stopWaitingForPendingTrampoline(pendingTrampoline);
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import static com.android.server.wm.ActivityInterceptorCallback.VIRTUAL_DEVICE_S
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityOptions;
|
||||
import android.companion.AssociationInfo;
|
||||
import android.companion.CompanionDeviceManager;
|
||||
@ -29,6 +28,7 @@ import android.companion.CompanionDeviceManager.OnAssociationsChangedListener;
|
||||
import android.companion.virtual.IVirtualDevice;
|
||||
import android.companion.virtual.IVirtualDeviceActivityListener;
|
||||
import android.companion.virtual.IVirtualDeviceManager;
|
||||
import android.companion.virtual.VirtualDeviceManager;
|
||||
import android.companion.virtual.VirtualDeviceParams;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
@ -64,7 +64,7 @@ public class VirtualDeviceManagerService extends SystemService {
|
||||
|
||||
private final Object mVirtualDeviceManagerLock = new Object();
|
||||
private final VirtualDeviceManagerImpl mImpl;
|
||||
private VirtualDeviceManagerInternal mLocalService;
|
||||
private final VirtualDeviceManagerInternal mLocalService;
|
||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
private final PendingTrampolineMap mPendingTrampolines = new PendingTrampolineMap(mHandler);
|
||||
/**
|
||||
@ -115,7 +115,7 @@ public class VirtualDeviceManagerService extends SystemService {
|
||||
if (pt == null) {
|
||||
return null;
|
||||
}
|
||||
pt.mResultReceiver.send(Activity.RESULT_OK, null);
|
||||
pt.mResultReceiver.send(VirtualDeviceManager.LAUNCH_SUCCESS, null);
|
||||
ActivityOptions options = info.checkedOptions;
|
||||
if (options == null) {
|
||||
options = ActivityOptions.makeBasic();
|
||||
@ -314,7 +314,8 @@ public class VirtualDeviceManagerService extends SystemService {
|
||||
pendingTrampoline.mPendingIntent.getCreatorPackage(),
|
||||
pendingTrampoline);
|
||||
if (existing != null) {
|
||||
existing.mResultReceiver.send(Activity.RESULT_CANCELED, null);
|
||||
existing.mResultReceiver.send(
|
||||
VirtualDeviceManager.LAUNCH_FAILURE_NO_ACTIVITY, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user