Merge "Only provide the resolved activity info to the global intercept window" into sc-dev am: b827a8ac83

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15117326

Change-Id: I8ef45f5e04adb4abf1a63686300a91e7ffb74b26
This commit is contained in:
Winson Chung
2021-07-01 17:50:38 +00:00
committed by Automerger Merge Worker
3 changed files with 59 additions and 8 deletions

View File

@@ -179,6 +179,10 @@ public class ClipData implements Parcelable {
final ArrayList<Item> mItems; final ArrayList<Item> mItems;
// This is false by default unless the ClipData is obtained via
// {@link #copyForTransferWithActivityInfo}.
private boolean mParcelItemActivityInfos;
/** /**
* Description of a single item in a ClipData. * Description of a single item in a ClipData.
* *
@@ -204,9 +208,11 @@ public class ClipData implements Parcelable {
final Intent mIntent; final Intent mIntent;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Uri mUri; Uri mUri;
// Additional activity info resolved by the system
ActivityInfo mActivityInfo;
private TextLinks mTextLinks; private TextLinks mTextLinks;
// Additional activity info resolved by the system. This is only parceled with the ClipData
// if the data is obtained from {@link #copyForTransferWithActivityInfo}
private ActivityInfo mActivityInfo;
/** @hide */ /** @hide */
public Item(Item other) { public Item(Item other) {
@@ -214,6 +220,8 @@ public class ClipData implements Parcelable {
mHtmlText = other.mHtmlText; mHtmlText = other.mHtmlText;
mIntent = other.mIntent; mIntent = other.mIntent;
mUri = other.mUri; mUri = other.mUri;
mActivityInfo = other.mActivityInfo;
mTextLinks = other.mTextLinks;
} }
/** /**
@@ -816,6 +824,24 @@ public class ClipData implements Parcelable {
mItems = new ArrayList<Item>(other.mItems); mItems = new ArrayList<Item>(other.mItems);
} }
/**
* Returns a copy of the ClipData which will parcel the Item's activity infos.
* @hide
*/
public ClipData copyForTransferWithActivityInfo() {
ClipData copy = new ClipData(this);
copy.mParcelItemActivityInfos = true;
return copy;
}
/**
* Returns whether this clip data will parcel the Item's activity infos.
* @hide
*/
public boolean willParcelWithActivityInfo() {
return mParcelItemActivityInfos;
}
/** /**
* Create a new ClipData holding data of the type * Create a new ClipData holding data of the type
* {@link ClipDescription#MIMETYPE_TEXT_PLAIN}. * {@link ClipDescription#MIMETYPE_TEXT_PLAIN}.
@@ -1208,7 +1234,7 @@ public class ClipData implements Parcelable {
dest.writeString8(item.mHtmlText); dest.writeString8(item.mHtmlText);
dest.writeTypedObject(item.mIntent, flags); dest.writeTypedObject(item.mIntent, flags);
dest.writeTypedObject(item.mUri, flags); dest.writeTypedObject(item.mUri, flags);
dest.writeTypedObject(item.mActivityInfo, flags); dest.writeTypedObject(mParcelItemActivityInfos ? item.mActivityInfo : null, flags);
dest.writeTypedObject(item.mTextLinks, flags); dest.writeTypedObject(item.mTextLinks, flags);
} }
} }

View File

@@ -316,7 +316,7 @@ class DragState {
final int myPid = Process.myPid(); final int myPid = Process.myPid();
final IBinder clientToken = touchedWin.mClient.asBinder(); final IBinder clientToken = touchedWin.mClient.asBinder();
final DragEvent event = obtainDragEvent(DragEvent.ACTION_DROP, x, y, final DragEvent event = obtainDragEvent(DragEvent.ACTION_DROP, x, y,
true /* includeData */, targetInterceptsGlobalDrag(touchedWin), mData, targetInterceptsGlobalDrag(touchedWin),
dragAndDropPermissions); dragAndDropPermissions);
try { try {
touchedWin.mClient.dispatchDragEvent(event); touchedWin.mClient.dispatchDragEvent(event);
@@ -462,8 +462,10 @@ class DragState {
boolean containsAppExtras) { boolean containsAppExtras) {
final boolean interceptsGlobalDrag = targetInterceptsGlobalDrag(newWin); final boolean interceptsGlobalDrag = targetInterceptsGlobalDrag(newWin);
if (mDragInProgress && isValidDropTarget(newWin, containsAppExtras, interceptsGlobalDrag)) { if (mDragInProgress && isValidDropTarget(newWin, containsAppExtras, interceptsGlobalDrag)) {
// Only allow the extras to be dispatched to a global-intercepting drag target
ClipData data = interceptsGlobalDrag ? mData.copyForTransferWithActivityInfo() : null;
DragEvent event = obtainDragEvent(DragEvent.ACTION_DRAG_STARTED, touchX, touchY, DragEvent event = obtainDragEvent(DragEvent.ACTION_DRAG_STARTED, touchX, touchY,
interceptsGlobalDrag, false /* includeDragSurface */, data, false /* includeDragSurface */,
null /* dragAndDropPermission */); null /* dragAndDropPermission */);
try { try {
newWin.mClient.dispatchDragEvent(event); newWin.mClient.dispatchDragEvent(event);
@@ -614,11 +616,11 @@ class DragState {
return mDragInProgress; return mDragInProgress;
} }
private DragEvent obtainDragEvent(int action, float x, float y, boolean includeData, private DragEvent obtainDragEvent(int action, float x, float y, ClipData data,
boolean includeDragSurface, IDragAndDropPermissions dragAndDropPermissions) { boolean includeDragSurface, IDragAndDropPermissions dragAndDropPermissions) {
return DragEvent.obtain(action, x, y, mThumbOffsetX, mThumbOffsetY, return DragEvent.obtain(action, x, y, mThumbOffsetX, mThumbOffsetY,
null /* localState */, mDataDescription, null /* localState */, mDataDescription, data,
includeData ? mData : null, includeDragSurface ? mSurfaceControl : null, includeDragSurface ? mSurfaceControl : null,
dragAndDropPermissions, false /* result */); dragAndDropPermissions, false /* result */);
} }

View File

@@ -22,6 +22,7 @@ import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK; import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.DragEvent.ACTION_DRAG_STARTED; import static android.view.DragEvent.ACTION_DRAG_STARTED;
import static android.view.DragEvent.ACTION_DROP;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -31,7 +32,9 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
@@ -267,12 +270,32 @@ public class DragDropControllerTests extends WindowTestsBase {
assertTrue(globalInterceptWindowDragEvents.get(0).getAction() assertTrue(globalInterceptWindowDragEvents.get(0).getAction()
== ACTION_DRAG_STARTED); == ACTION_DRAG_STARTED);
// Verify that only the global intercept window receives the clip data with the
// resolved activity info for the drag
assertNull(localWindowDragEvents.get(0).getClipData());
assertTrue(globalInterceptWindowDragEvents.get(0).getClipData()
.willParcelWithActivityInfo());
mTarget.reportDropWindow(globalInterceptWindow.mInputChannelToken, 0, 0); mTarget.reportDropWindow(globalInterceptWindow.mInputChannelToken, 0, 0);
mTarget.handleMotionEvent(false, 0, 0); mTarget.handleMotionEvent(false, 0, 0);
mToken = globalInterceptWindow.mClient.asBinder(); mToken = globalInterceptWindow.mClient.asBinder();
// Verify the drop event is only sent for the global intercept window
assertTrue(nonLocalWindowDragEvents.isEmpty());
assertTrue(last(localWindowDragEvents).getAction() != ACTION_DROP);
assertTrue(last(globalInterceptWindowDragEvents).getAction() == ACTION_DROP);
// Verify that item extras were not sent with the drop event
assertNull(last(localWindowDragEvents).getClipData());
assertFalse(last(globalInterceptWindowDragEvents).getClipData()
.willParcelWithActivityInfo());
}); });
} }
private DragEvent last(ArrayList<DragEvent> list) {
return list.get(list.size() - 1);
}
@Test @Test
public void testValidateAppActivityArguments() { public void testValidateAppActivityArguments() {
final Session session = new Session(mWm, new IWindowSessionCallback.Stub() { final Session session = new Session(mWm, new IWindowSessionCallback.Stub() {