Merge "Make drag and drop comply with cross profile copy paste policy" into nyc-dev am: 0a253a67d9
am: 6ab7862af3
* commit '6ab7862af371f35c1ab71dbfa00c32ed07b6d40c':
Make drag and drop comply with cross profile copy paste policy
This commit is contained in:
@@ -24,6 +24,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipDescription;
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
@@ -33,6 +34,10 @@ import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.os.IUserManager;
|
||||
import android.util.Slog;
|
||||
import android.view.Display;
|
||||
import android.view.DragEvent;
|
||||
@@ -73,6 +78,8 @@ class DragState {
|
||||
IBinder mLocalWin;
|
||||
int mPid;
|
||||
int mUid;
|
||||
int mSourceUserId;
|
||||
boolean mCrossProfileCopyAllowed;
|
||||
ClipData mData;
|
||||
ClipDescription mDataDescription;
|
||||
int mTouchSource;
|
||||
@@ -221,6 +228,18 @@ class DragState {
|
||||
mNotifiedWindows.clear();
|
||||
mDragInProgress = true;
|
||||
|
||||
mSourceUserId = UserHandle.getUserId(mUid);
|
||||
|
||||
final IUserManager userManager =
|
||||
(IUserManager) ServiceManager.getService(Context.USER_SERVICE);
|
||||
try {
|
||||
mCrossProfileCopyAllowed = !userManager.getUserRestrictions(mSourceUserId).getBoolean(
|
||||
UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG_WM, "Remote Exception calling UserManager: " + e);
|
||||
mCrossProfileCopyAllowed = false;
|
||||
}
|
||||
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "broadcasting DRAG_STARTED at (" + touchX + ", " + touchY + ")");
|
||||
}
|
||||
@@ -234,7 +253,7 @@ class DragState {
|
||||
}
|
||||
}
|
||||
|
||||
/* helper - send a caller-provided event, presumed to be DRAG_STARTED, if the
|
||||
/* helper - send a ACTION_DRAG_STARTED event, if the
|
||||
* designated window is potentially a drop recipient. There are race situations
|
||||
* around DRAG_ENDED broadcast, so we make sure that once we've declared that
|
||||
* the drag has ended, we never send out another DRAG_STARTED for this drag action.
|
||||
@@ -244,19 +263,7 @@ class DragState {
|
||||
*/
|
||||
private void sendDragStartedLw(WindowState newWin, float touchX, float touchY,
|
||||
ClipDescription desc) {
|
||||
// Don't actually send the event if the drag is supposed to be pinned
|
||||
// to the originating window but 'newWin' is not that window.
|
||||
if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
|
||||
final IBinder winBinder = newWin.mClient.asBinder();
|
||||
if (winBinder != mLocalWin) {
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "Not dispatching local DRAG_STARTED to " + newWin);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mDragInProgress && newWin.isPotentialDragTarget()) {
|
||||
if (mDragInProgress && isValidDropTarget(newWin)) {
|
||||
DragEvent event = obtainDragEvent(newWin, DragEvent.ACTION_DRAG_STARTED,
|
||||
touchX, touchY, null, desc, null, null, false);
|
||||
try {
|
||||
@@ -274,17 +281,33 @@ class DragState {
|
||||
}
|
||||
}
|
||||
|
||||
/* helper - construct and send a DRAG_STARTED event only if the window has not
|
||||
private boolean isValidDropTarget(WindowState targetWin) {
|
||||
if (targetWin == null) {
|
||||
return false;
|
||||
}
|
||||
if (!targetWin.isPotentialDragTarget()) {
|
||||
return false;
|
||||
}
|
||||
if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
|
||||
// Drag is limited to the current window.
|
||||
if (mLocalWin != targetWin.mClient.asBinder()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return mCrossProfileCopyAllowed ||
|
||||
mSourceUserId == UserHandle.getUserId(targetWin.getOwningUid());
|
||||
}
|
||||
|
||||
/* helper - send a ACTION_DRAG_STARTED event only if the window has not
|
||||
* previously been notified, i.e. it became visible after the drag operation
|
||||
* was begun. This is a rare case.
|
||||
*/
|
||||
void sendDragStartedIfNeededLw(WindowState newWin) {
|
||||
if (mDragInProgress) {
|
||||
// If we have sent the drag-started, we needn't do so again
|
||||
for (WindowState ws : mNotifiedWindows) {
|
||||
if (ws == newWin) {
|
||||
return;
|
||||
}
|
||||
if (isWindowNotified(newWin)) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "need to send DRAG_STARTED to new window " + newWin);
|
||||
@@ -293,6 +316,15 @@ class DragState {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isWindowNotified(WindowState newWin) {
|
||||
for (WindowState ws : mNotifiedWindows) {
|
||||
if (ws == newWin) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void broadcastDragEndedLw() {
|
||||
final int myPid = Process.myPid();
|
||||
|
||||
@@ -389,14 +421,13 @@ class DragState {
|
||||
if (DEBUG_DRAG) Slog.d(TAG_WM, "No touched win at x=" + x + " y=" + y);
|
||||
return;
|
||||
}
|
||||
if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
|
||||
final IBinder touchedBinder = touchedWin.mClient.asBinder();
|
||||
if (touchedBinder != mLocalWin) {
|
||||
// This drag is pinned only to the originating window, but the drag
|
||||
// point is outside that window. Pretend it's over empty space.
|
||||
touchedWin = null;
|
||||
}
|
||||
|
||||
if (!isWindowNotified(touchedWin)) {
|
||||
// The drag point is over a window which was not notified about a drag start.
|
||||
// Pretend it's over empty space.
|
||||
touchedWin = null;
|
||||
}
|
||||
|
||||
try {
|
||||
final int myPid = Process.myPid();
|
||||
|
||||
@@ -445,7 +476,7 @@ class DragState {
|
||||
mCurrentX = x;
|
||||
mCurrentY = y;
|
||||
|
||||
if (touchedWin == null) {
|
||||
if (!isWindowNotified(touchedWin)) {
|
||||
// "drop" outside a valid window -- no recipient to apply a
|
||||
// timeout to, and we can send the drag-ended message immediately.
|
||||
mDragResult = false;
|
||||
@@ -455,6 +486,9 @@ class DragState {
|
||||
if (DEBUG_DRAG) {
|
||||
Slog.d(TAG_WM, "sending DROP to " + touchedWin);
|
||||
}
|
||||
if (mSourceUserId != UserHandle.getUserId(touchedWin.getOwningUid())){
|
||||
mData.fixUris(mSourceUserId);
|
||||
}
|
||||
final int myPid = Process.myPid();
|
||||
final IBinder token = touchedWin.mClient.asBinder();
|
||||
DragEvent evt = obtainDragEvent(touchedWin, DragEvent.ACTION_DROP, x, y,
|
||||
|
||||
@@ -769,7 +769,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
mDragState.mUid,
|
||||
dropTargetWin.getOwningPackage(),
|
||||
mDragState.mFlags & DRAG_FLAGS_URI_PERMISSIONS,
|
||||
UserHandle.getUserId(mDragState.mUid),
|
||||
mDragState.mSourceUserId,
|
||||
UserHandle.getUserId(dropTargetWin.getOwningUid()));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user