Merge "Only provide the resolved activity info to the global intercept window" into sc-dev am: b827a8ac83 am: 6e004f8baf
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15117326 Change-Id: Ic7580ea30f9e7c68fe65debb309d46d4cb48f7d2
This commit is contained in:
@@ -179,6 +179,10 @@ public class ClipData implements Parcelable {
|
||||
|
||||
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.
|
||||
*
|
||||
@@ -204,9 +208,11 @@ public class ClipData implements Parcelable {
|
||||
final Intent mIntent;
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
Uri mUri;
|
||||
// Additional activity info resolved by the system
|
||||
ActivityInfo mActivityInfo;
|
||||
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 */
|
||||
public Item(Item other) {
|
||||
@@ -214,6 +220,8 @@ public class ClipData implements Parcelable {
|
||||
mHtmlText = other.mHtmlText;
|
||||
mIntent = other.mIntent;
|
||||
mUri = other.mUri;
|
||||
mActivityInfo = other.mActivityInfo;
|
||||
mTextLinks = other.mTextLinks;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -816,6 +824,24 @@ public class ClipData implements Parcelable {
|
||||
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
|
||||
* {@link ClipDescription#MIMETYPE_TEXT_PLAIN}.
|
||||
@@ -1208,7 +1234,7 @@ public class ClipData implements Parcelable {
|
||||
dest.writeString8(item.mHtmlText);
|
||||
dest.writeTypedObject(item.mIntent, flags);
|
||||
dest.writeTypedObject(item.mUri, flags);
|
||||
dest.writeTypedObject(item.mActivityInfo, flags);
|
||||
dest.writeTypedObject(mParcelItemActivityInfos ? item.mActivityInfo : null, flags);
|
||||
dest.writeTypedObject(item.mTextLinks, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@ class DragState {
|
||||
final int myPid = Process.myPid();
|
||||
final IBinder clientToken = touchedWin.mClient.asBinder();
|
||||
final DragEvent event = obtainDragEvent(DragEvent.ACTION_DROP, x, y,
|
||||
true /* includeData */, targetInterceptsGlobalDrag(touchedWin),
|
||||
mData, targetInterceptsGlobalDrag(touchedWin),
|
||||
dragAndDropPermissions);
|
||||
try {
|
||||
touchedWin.mClient.dispatchDragEvent(event);
|
||||
@@ -462,8 +462,10 @@ class DragState {
|
||||
boolean containsAppExtras) {
|
||||
final boolean interceptsGlobalDrag = targetInterceptsGlobalDrag(newWin);
|
||||
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,
|
||||
interceptsGlobalDrag, false /* includeDragSurface */,
|
||||
data, false /* includeDragSurface */,
|
||||
null /* dragAndDropPermission */);
|
||||
try {
|
||||
newWin.mClient.dispatchDragEvent(event);
|
||||
@@ -614,11 +616,11 @@ class DragState {
|
||||
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) {
|
||||
return DragEvent.obtain(action, x, y, mThumbOffsetX, mThumbOffsetY,
|
||||
null /* localState */, mDataDescription,
|
||||
includeData ? mData : null, includeDragSurface ? mSurfaceControl : null,
|
||||
null /* localState */, mDataDescription, data,
|
||||
includeDragSurface ? mSurfaceControl : null,
|
||||
dragAndDropPermissions, false /* result */);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import static android.content.ClipDescription.MIMETYPE_APPLICATION_SHORTCUT;
|
||||
import static android.content.ClipDescription.MIMETYPE_APPLICATION_TASK;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
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.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.when;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
@@ -267,12 +270,32 @@ public class DragDropControllerTests extends WindowTestsBase {
|
||||
assertTrue(globalInterceptWindowDragEvents.get(0).getAction()
|
||||
== 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.handleMotionEvent(false, 0, 0);
|
||||
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
|
||||
public void testValidateAppActivityArguments() {
|
||||
final Session session = new Session(mWm, new IWindowSessionCallback.Stub() {
|
||||
|
||||
Reference in New Issue
Block a user