Loading api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -8972,6 +8972,7 @@ package android.content { public class ClipboardManager extends android.text.ClipboardManager { method public void addPrimaryClipChangedListener(android.content.ClipboardManager.OnPrimaryClipChangedListener); method public void clearPrimaryClip(); method public android.content.ClipData getPrimaryClip(); method public android.content.ClipDescription getPrimaryClipDescription(); method public deprecated java.lang.CharSequence getText(); core/java/android/content/ClipboardManager.java +34 −20 Original line number Diff line number Diff line Loading @@ -16,13 +16,16 @@ package android.content; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; import android.os.Handler; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import com.android.internal.util.Preconditions; import java.util.ArrayList; /** Loading @@ -45,6 +48,7 @@ import java.util.ArrayList; @SystemService(Context.CLIPBOARD_SERVICE) public class ClipboardManager extends android.text.ClipboardManager { private final Context mContext; private final Handler mHandler; private final IClipboard mService; private final ArrayList<OnPrimaryClipChangedListener> mPrimaryClipChangedListeners Loading @@ -52,20 +56,11 @@ public class ClipboardManager extends android.text.ClipboardManager { private final IOnPrimaryClipChangedListener.Stub mPrimaryClipChangedServiceListener = new IOnPrimaryClipChangedListener.Stub() { public void dispatchPrimaryClipChanged() { mHandler.sendEmptyMessage(MSG_REPORT_PRIMARY_CLIP_CHANGED); } }; static final int MSG_REPORT_PRIMARY_CLIP_CHANGED = 1; private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_REPORT_PRIMARY_CLIP_CHANGED: public void dispatchPrimaryClipChanged() { mHandler.post(() -> { reportPrimaryClipChanged(); } }); } }; Loading @@ -89,6 +84,7 @@ public class ClipboardManager extends android.text.ClipboardManager { /** {@hide} */ public ClipboardManager(Context context, Handler handler) throws ServiceNotFoundException { mContext = context; mHandler = handler; mService = IClipboard.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.CLIPBOARD_SERVICE)); } Loading @@ -98,22 +94,38 @@ public class ClipboardManager extends android.text.ClipboardManager { * is involved in normal cut and paste operations. * * @param clip The clipped data item to set. * @see #getPrimaryClip() * @see #clearPrimaryClip() */ public void setPrimaryClip(ClipData clip) { public void setPrimaryClip(@NonNull ClipData clip) { try { if (clip != null) { Preconditions.checkNotNull(clip); clip.prepareToLeaveProcess(true); } mService.setPrimaryClip(clip, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Clears any current primary clip on the clipboard. * * @see #setPrimaryClip(ClipData) */ public void clearPrimaryClip() { try { mService.clearPrimaryClip(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns the current primary clip on the clipboard. * * @see #setPrimaryClip(ClipData) */ public ClipData getPrimaryClip() { public @Nullable ClipData getPrimaryClip() { try { return mService.getPrimaryClip(mContext.getOpPackageName()); } catch (RemoteException e) { Loading @@ -124,8 +136,10 @@ public class ClipboardManager extends android.text.ClipboardManager { /** * Returns a description of the current primary clip on the clipboard * but not a copy of its data. * * @see #setPrimaryClip(ClipData) */ public ClipDescription getPrimaryClipDescription() { public @Nullable ClipDescription getPrimaryClipDescription() { try { return mService.getPrimaryClipDescription(mContext.getOpPackageName()); } catch (RemoteException e) { Loading core/java/android/content/IClipboard.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.IOnPrimaryClipChangedListener; */ interface IClipboard { void setPrimaryClip(in ClipData clip, String callingPackage); void clearPrimaryClip(String callingPackage); ClipData getPrimaryClip(String pkg); ClipDescription getPrimaryClipDescription(String callingPackage); boolean hasPrimaryClip(String callingPackage); Loading services/core/java/com/android/server/am/ActivityManagerService.java +19 −0 Original line number Diff line number Diff line Loading @@ -9410,6 +9410,25 @@ public class ActivityManagerService extends IActivityManager.Stub allowed = false; } } if (pi.pathPermissions != null) { final int N = pi.pathPermissions.length; for (int i=0; i<N; i++) { if (pi.pathPermissions[i] != null && pi.pathPermissions[i].match(grantUri.uri.getPath())) { if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { if (pi.pathPermissions[i].getReadPermission() != null) { allowed = false; } } if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { if (pi.pathPermissions[i].getWritePermission() != null) { allowed = false; } } break; } } } if (allowed) { return -1; } services/core/java/com/android/server/clipboard/ClipboardService.java +93 −59 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.clipboard; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.AppOpsManager; Loading @@ -24,9 +25,9 @@ import android.app.KeyguardManager; import android.content.ClipData; import android.content.ClipDescription; import android.content.ContentProvider; import android.content.Context; import android.content.IClipboard; import android.content.IOnPrimaryClipChangedListener; import android.content.Context; import android.content.Intent; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; Loading @@ -37,7 +38,6 @@ import android.os.Binder; import android.os.IBinder; import android.os.IUserManager; import android.os.Parcel; import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -49,14 +49,10 @@ import android.util.SparseArray; import com.android.server.SystemService; import java.util.HashSet; import java.util.List; import java.lang.Thread; import java.lang.Runnable; import java.lang.InterruptedException; import java.io.IOException; import java.io.RandomAccessFile; import java.util.HashSet; import java.util.List; // The following class is Android Emulator specific. It is used to read and // write contents of the host system's clipboard. Loading Loading @@ -182,7 +178,8 @@ public class ClipboardService extends SystemService { new String[]{"text/plain"}, new ClipData.Item(contents)); synchronized(mClipboards) { setPrimaryClipInternal(getClipboard(0), clip); setPrimaryClipInternal(getClipboard(0), clip, android.os.Process.SYSTEM_UID); } } }); Loading Loading @@ -218,7 +215,10 @@ public class ClipboardService extends SystemService { final RemoteCallbackList<IOnPrimaryClipChangedListener> primaryClipListeners = new RemoteCallbackList<IOnPrimaryClipChangedListener>(); /** Current primary clip. */ ClipData primaryClip; /** UID that set {@link #primaryClip}. */ int primaryClipUid = android.os.Process.NOBODY_UID; final HashSet<String> activePermissionOwners = new HashSet<String>(); Loading Loading @@ -246,58 +246,28 @@ public class ClipboardService extends SystemService { @Override public void setPrimaryClip(ClipData clip, String callingPackage) { synchronized (this) { if (clip != null && clip.getItemCount() <= 0) { if (clip == null || clip.getItemCount() <= 0) { throw new IllegalArgumentException("No items"); } if (clip.getItemAt(0).getText() != null && mHostClipboardMonitor != null) { mHostClipboardMonitor.setHostClipboard( clip.getItemAt(0).getText().toString()); } final int callingUid = Binder.getCallingUid(); if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage, callingUid)) { return; } checkDataOwnerLocked(clip, callingUid); final int userId = UserHandle.getUserId(callingUid); PerUserClipboard clipboard = getClipboard(userId); revokeUris(clipboard); setPrimaryClipInternal(clipboard, clip); List<UserInfo> related = getRelatedProfiles(userId); if (related != null) { int size = related.size(); if (size > 1) { // Related profiles list include the current profile. boolean canCopy = false; try { canCopy = !mUm.getUserRestrictions(userId).getBoolean( UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE); } catch (RemoteException e) { Slog.e(TAG, "Remote Exception calling UserManager: " + e); } // Copy clip data to related users if allowed. If disallowed, then remove // primary clip in related users to prevent pasting stale content. if (!canCopy) { clip = null; } else { // We want to fix the uris of the related user's clip without changing the // uris of the current user's clip. // So, copy the ClipData, and then copy all the items, so that nothing // is shared in memmory. clip = new ClipData(clip); for (int i = clip.getItemCount() - 1; i >= 0; i--) { clip.setItemAt(i, new ClipData.Item(clip.getItemAt(i))); } clip.fixUrisLight(userId); } for (int i = 0; i < size; i++) { int id = related.get(i).id; if (id != userId) { setPrimaryClipInternal(getClipboard(id), clip); } setPrimaryClipInternal(clip, callingUid); } } @Override public void clearPrimaryClip(String callingPackage) { synchronized (this) { final int callingUid = Binder.getCallingUid(); if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage, callingUid)) { return; } setPrimaryClipInternal(null, callingUid); } } Loading Loading @@ -398,12 +368,74 @@ public class ClipboardService extends SystemService { return related; } void setPrimaryClipInternal(PerUserClipboard clipboard, ClipData clip) { void setPrimaryClipInternal(@Nullable ClipData clip, int callingUid) { // Push clipboard to host, if any if (mHostClipboardMonitor != null) { if (clip == null) { // Someone really wants the clipboard cleared, so push empty mHostClipboardMonitor.setHostClipboard(""); } else if (clip.getItemCount() > 0) { final CharSequence text = clip.getItemAt(0).getText(); if (text != null) { mHostClipboardMonitor.setHostClipboard(text.toString()); } } } // Update this user final int userId = UserHandle.getUserId(callingUid); setPrimaryClipInternal(getClipboard(userId), clip, callingUid); // Update related users List<UserInfo> related = getRelatedProfiles(userId); if (related != null) { int size = related.size(); if (size > 1) { // Related profiles list include the current profile. boolean canCopy = false; try { canCopy = !mUm.getUserRestrictions(userId).getBoolean( UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE); } catch (RemoteException e) { Slog.e(TAG, "Remote Exception calling UserManager: " + e); } // Copy clip data to related users if allowed. If disallowed, then remove // primary clip in related users to prevent pasting stale content. if (!canCopy) { clip = null; } else { // We want to fix the uris of the related user's clip without changing the // uris of the current user's clip. // So, copy the ClipData, and then copy all the items, so that nothing // is shared in memmory. clip = new ClipData(clip); for (int i = clip.getItemCount() - 1; i >= 0; i--) { clip.setItemAt(i, new ClipData.Item(clip.getItemAt(i))); } clip.fixUrisLight(userId); } for (int i = 0; i < size; i++) { int id = related.get(i).id; if (id != userId) { setPrimaryClipInternal(getClipboard(id), clip, callingUid); } } } } } void setPrimaryClipInternal(PerUserClipboard clipboard, @Nullable ClipData clip, int callingUid) { revokeUris(clipboard); clipboard.activePermissionOwners.clear(); if (clip == null && clipboard.primaryClip == null) { return; } clipboard.primaryClip = clip; if (clip != null) { clipboard.primaryClipUid = callingUid; } else { clipboard.primaryClipUid = android.os.Process.NOBODY_UID; } if (clip != null) { final ClipDescription description = clip.getDescription(); if (description != null) { Loading Loading @@ -479,12 +511,12 @@ public class ClipboardService extends SystemService { } } private final void grantUriLocked(Uri uri, String pkg, int userId) { private final void grantUriLocked(Uri uri, int primaryClipUid, String pkg, int userId) { long ident = Binder.clearCallingIdentity(); try { int sourceUserId = ContentProvider.getUserIdFromUri(uri, userId); uri = ContentProvider.getUriWithoutUserId(uri); mAm.grantUriPermissionFromOwner(mPermissionOwner, Process.myUid(), pkg, mAm.grantUriPermissionFromOwner(mPermissionOwner, primaryClipUid, pkg, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, sourceUserId, userId); } catch (RemoteException e) { } finally { Loading @@ -492,13 +524,14 @@ public class ClipboardService extends SystemService { } } private final void grantItemLocked(ClipData.Item item, String pkg, int userId) { private final void grantItemLocked(ClipData.Item item, int primaryClipUid, String pkg, int userId) { if (item.getUri() != null) { grantUriLocked(item.getUri(), pkg, userId); grantUriLocked(item.getUri(), primaryClipUid, pkg, userId); } Intent intent = item.getIntent(); if (intent != null && intent.getData() != null) { grantUriLocked(intent.getData(), pkg, userId); grantUriLocked(intent.getData(), primaryClipUid, pkg, userId); } } Loading @@ -524,7 +557,8 @@ public class ClipboardService extends SystemService { if (clipboard.primaryClip != null && !clipboard.activePermissionOwners.contains(pkg)) { final int N = clipboard.primaryClip.getItemCount(); for (int i=0; i<N; i++) { grantItemLocked(clipboard.primaryClip.getItemAt(i), pkg, UserHandle.getUserId(uid)); grantItemLocked(clipboard.primaryClip.getItemAt(i), clipboard.primaryClipUid, pkg, UserHandle.getUserId(uid)); } clipboard.activePermissionOwners.add(pkg); } Loading Loading
api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -8972,6 +8972,7 @@ package android.content { public class ClipboardManager extends android.text.ClipboardManager { method public void addPrimaryClipChangedListener(android.content.ClipboardManager.OnPrimaryClipChangedListener); method public void clearPrimaryClip(); method public android.content.ClipData getPrimaryClip(); method public android.content.ClipDescription getPrimaryClipDescription(); method public deprecated java.lang.CharSequence getText();
core/java/android/content/ClipboardManager.java +34 −20 Original line number Diff line number Diff line Loading @@ -16,13 +16,16 @@ package android.content; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemService; import android.os.Handler; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import com.android.internal.util.Preconditions; import java.util.ArrayList; /** Loading @@ -45,6 +48,7 @@ import java.util.ArrayList; @SystemService(Context.CLIPBOARD_SERVICE) public class ClipboardManager extends android.text.ClipboardManager { private final Context mContext; private final Handler mHandler; private final IClipboard mService; private final ArrayList<OnPrimaryClipChangedListener> mPrimaryClipChangedListeners Loading @@ -52,20 +56,11 @@ public class ClipboardManager extends android.text.ClipboardManager { private final IOnPrimaryClipChangedListener.Stub mPrimaryClipChangedServiceListener = new IOnPrimaryClipChangedListener.Stub() { public void dispatchPrimaryClipChanged() { mHandler.sendEmptyMessage(MSG_REPORT_PRIMARY_CLIP_CHANGED); } }; static final int MSG_REPORT_PRIMARY_CLIP_CHANGED = 1; private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MSG_REPORT_PRIMARY_CLIP_CHANGED: public void dispatchPrimaryClipChanged() { mHandler.post(() -> { reportPrimaryClipChanged(); } }); } }; Loading @@ -89,6 +84,7 @@ public class ClipboardManager extends android.text.ClipboardManager { /** {@hide} */ public ClipboardManager(Context context, Handler handler) throws ServiceNotFoundException { mContext = context; mHandler = handler; mService = IClipboard.Stub.asInterface( ServiceManager.getServiceOrThrow(Context.CLIPBOARD_SERVICE)); } Loading @@ -98,22 +94,38 @@ public class ClipboardManager extends android.text.ClipboardManager { * is involved in normal cut and paste operations. * * @param clip The clipped data item to set. * @see #getPrimaryClip() * @see #clearPrimaryClip() */ public void setPrimaryClip(ClipData clip) { public void setPrimaryClip(@NonNull ClipData clip) { try { if (clip != null) { Preconditions.checkNotNull(clip); clip.prepareToLeaveProcess(true); } mService.setPrimaryClip(clip, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Clears any current primary clip on the clipboard. * * @see #setPrimaryClip(ClipData) */ public void clearPrimaryClip() { try { mService.clearPrimaryClip(mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** * Returns the current primary clip on the clipboard. * * @see #setPrimaryClip(ClipData) */ public ClipData getPrimaryClip() { public @Nullable ClipData getPrimaryClip() { try { return mService.getPrimaryClip(mContext.getOpPackageName()); } catch (RemoteException e) { Loading @@ -124,8 +136,10 @@ public class ClipboardManager extends android.text.ClipboardManager { /** * Returns a description of the current primary clip on the clipboard * but not a copy of its data. * * @see #setPrimaryClip(ClipData) */ public ClipDescription getPrimaryClipDescription() { public @Nullable ClipDescription getPrimaryClipDescription() { try { return mService.getPrimaryClipDescription(mContext.getOpPackageName()); } catch (RemoteException e) { Loading
core/java/android/content/IClipboard.aidl +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ import android.content.IOnPrimaryClipChangedListener; */ interface IClipboard { void setPrimaryClip(in ClipData clip, String callingPackage); void clearPrimaryClip(String callingPackage); ClipData getPrimaryClip(String pkg); ClipDescription getPrimaryClipDescription(String callingPackage); boolean hasPrimaryClip(String callingPackage); Loading
services/core/java/com/android/server/am/ActivityManagerService.java +19 −0 Original line number Diff line number Diff line Loading @@ -9410,6 +9410,25 @@ public class ActivityManagerService extends IActivityManager.Stub allowed = false; } } if (pi.pathPermissions != null) { final int N = pi.pathPermissions.length; for (int i=0; i<N; i++) { if (pi.pathPermissions[i] != null && pi.pathPermissions[i].match(grantUri.uri.getPath())) { if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { if (pi.pathPermissions[i].getReadPermission() != null) { allowed = false; } } if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { if (pi.pathPermissions[i].getWritePermission() != null) { allowed = false; } } break; } } } if (allowed) { return -1; }
services/core/java/com/android/server/clipboard/ClipboardService.java +93 −59 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.clipboard; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.AppOpsManager; Loading @@ -24,9 +25,9 @@ import android.app.KeyguardManager; import android.content.ClipData; import android.content.ClipDescription; import android.content.ContentProvider; import android.content.Context; import android.content.IClipboard; import android.content.IOnPrimaryClipChangedListener; import android.content.Context; import android.content.Intent; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; Loading @@ -37,7 +38,6 @@ import android.os.Binder; import android.os.IBinder; import android.os.IUserManager; import android.os.Parcel; import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ServiceManager; Loading @@ -49,14 +49,10 @@ import android.util.SparseArray; import com.android.server.SystemService; import java.util.HashSet; import java.util.List; import java.lang.Thread; import java.lang.Runnable; import java.lang.InterruptedException; import java.io.IOException; import java.io.RandomAccessFile; import java.util.HashSet; import java.util.List; // The following class is Android Emulator specific. It is used to read and // write contents of the host system's clipboard. Loading Loading @@ -182,7 +178,8 @@ public class ClipboardService extends SystemService { new String[]{"text/plain"}, new ClipData.Item(contents)); synchronized(mClipboards) { setPrimaryClipInternal(getClipboard(0), clip); setPrimaryClipInternal(getClipboard(0), clip, android.os.Process.SYSTEM_UID); } } }); Loading Loading @@ -218,7 +215,10 @@ public class ClipboardService extends SystemService { final RemoteCallbackList<IOnPrimaryClipChangedListener> primaryClipListeners = new RemoteCallbackList<IOnPrimaryClipChangedListener>(); /** Current primary clip. */ ClipData primaryClip; /** UID that set {@link #primaryClip}. */ int primaryClipUid = android.os.Process.NOBODY_UID; final HashSet<String> activePermissionOwners = new HashSet<String>(); Loading Loading @@ -246,58 +246,28 @@ public class ClipboardService extends SystemService { @Override public void setPrimaryClip(ClipData clip, String callingPackage) { synchronized (this) { if (clip != null && clip.getItemCount() <= 0) { if (clip == null || clip.getItemCount() <= 0) { throw new IllegalArgumentException("No items"); } if (clip.getItemAt(0).getText() != null && mHostClipboardMonitor != null) { mHostClipboardMonitor.setHostClipboard( clip.getItemAt(0).getText().toString()); } final int callingUid = Binder.getCallingUid(); if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage, callingUid)) { return; } checkDataOwnerLocked(clip, callingUid); final int userId = UserHandle.getUserId(callingUid); PerUserClipboard clipboard = getClipboard(userId); revokeUris(clipboard); setPrimaryClipInternal(clipboard, clip); List<UserInfo> related = getRelatedProfiles(userId); if (related != null) { int size = related.size(); if (size > 1) { // Related profiles list include the current profile. boolean canCopy = false; try { canCopy = !mUm.getUserRestrictions(userId).getBoolean( UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE); } catch (RemoteException e) { Slog.e(TAG, "Remote Exception calling UserManager: " + e); } // Copy clip data to related users if allowed. If disallowed, then remove // primary clip in related users to prevent pasting stale content. if (!canCopy) { clip = null; } else { // We want to fix the uris of the related user's clip without changing the // uris of the current user's clip. // So, copy the ClipData, and then copy all the items, so that nothing // is shared in memmory. clip = new ClipData(clip); for (int i = clip.getItemCount() - 1; i >= 0; i--) { clip.setItemAt(i, new ClipData.Item(clip.getItemAt(i))); } clip.fixUrisLight(userId); } for (int i = 0; i < size; i++) { int id = related.get(i).id; if (id != userId) { setPrimaryClipInternal(getClipboard(id), clip); } setPrimaryClipInternal(clip, callingUid); } } @Override public void clearPrimaryClip(String callingPackage) { synchronized (this) { final int callingUid = Binder.getCallingUid(); if (!clipboardAccessAllowed(AppOpsManager.OP_WRITE_CLIPBOARD, callingPackage, callingUid)) { return; } setPrimaryClipInternal(null, callingUid); } } Loading Loading @@ -398,12 +368,74 @@ public class ClipboardService extends SystemService { return related; } void setPrimaryClipInternal(PerUserClipboard clipboard, ClipData clip) { void setPrimaryClipInternal(@Nullable ClipData clip, int callingUid) { // Push clipboard to host, if any if (mHostClipboardMonitor != null) { if (clip == null) { // Someone really wants the clipboard cleared, so push empty mHostClipboardMonitor.setHostClipboard(""); } else if (clip.getItemCount() > 0) { final CharSequence text = clip.getItemAt(0).getText(); if (text != null) { mHostClipboardMonitor.setHostClipboard(text.toString()); } } } // Update this user final int userId = UserHandle.getUserId(callingUid); setPrimaryClipInternal(getClipboard(userId), clip, callingUid); // Update related users List<UserInfo> related = getRelatedProfiles(userId); if (related != null) { int size = related.size(); if (size > 1) { // Related profiles list include the current profile. boolean canCopy = false; try { canCopy = !mUm.getUserRestrictions(userId).getBoolean( UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE); } catch (RemoteException e) { Slog.e(TAG, "Remote Exception calling UserManager: " + e); } // Copy clip data to related users if allowed. If disallowed, then remove // primary clip in related users to prevent pasting stale content. if (!canCopy) { clip = null; } else { // We want to fix the uris of the related user's clip without changing the // uris of the current user's clip. // So, copy the ClipData, and then copy all the items, so that nothing // is shared in memmory. clip = new ClipData(clip); for (int i = clip.getItemCount() - 1; i >= 0; i--) { clip.setItemAt(i, new ClipData.Item(clip.getItemAt(i))); } clip.fixUrisLight(userId); } for (int i = 0; i < size; i++) { int id = related.get(i).id; if (id != userId) { setPrimaryClipInternal(getClipboard(id), clip, callingUid); } } } } } void setPrimaryClipInternal(PerUserClipboard clipboard, @Nullable ClipData clip, int callingUid) { revokeUris(clipboard); clipboard.activePermissionOwners.clear(); if (clip == null && clipboard.primaryClip == null) { return; } clipboard.primaryClip = clip; if (clip != null) { clipboard.primaryClipUid = callingUid; } else { clipboard.primaryClipUid = android.os.Process.NOBODY_UID; } if (clip != null) { final ClipDescription description = clip.getDescription(); if (description != null) { Loading Loading @@ -479,12 +511,12 @@ public class ClipboardService extends SystemService { } } private final void grantUriLocked(Uri uri, String pkg, int userId) { private final void grantUriLocked(Uri uri, int primaryClipUid, String pkg, int userId) { long ident = Binder.clearCallingIdentity(); try { int sourceUserId = ContentProvider.getUserIdFromUri(uri, userId); uri = ContentProvider.getUriWithoutUserId(uri); mAm.grantUriPermissionFromOwner(mPermissionOwner, Process.myUid(), pkg, mAm.grantUriPermissionFromOwner(mPermissionOwner, primaryClipUid, pkg, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION, sourceUserId, userId); } catch (RemoteException e) { } finally { Loading @@ -492,13 +524,14 @@ public class ClipboardService extends SystemService { } } private final void grantItemLocked(ClipData.Item item, String pkg, int userId) { private final void grantItemLocked(ClipData.Item item, int primaryClipUid, String pkg, int userId) { if (item.getUri() != null) { grantUriLocked(item.getUri(), pkg, userId); grantUriLocked(item.getUri(), primaryClipUid, pkg, userId); } Intent intent = item.getIntent(); if (intent != null && intent.getData() != null) { grantUriLocked(intent.getData(), pkg, userId); grantUriLocked(intent.getData(), primaryClipUid, pkg, userId); } } Loading @@ -524,7 +557,8 @@ public class ClipboardService extends SystemService { if (clipboard.primaryClip != null && !clipboard.activePermissionOwners.contains(pkg)) { final int N = clipboard.primaryClip.getItemCount(); for (int i=0; i<N; i++) { grantItemLocked(clipboard.primaryClip.getItemAt(i), pkg, UserHandle.getUserId(uid)); grantItemLocked(clipboard.primaryClip.getItemAt(i), clipboard.primaryClipUid, pkg, UserHandle.getUserId(uid)); } clipboard.activePermissionOwners.add(pkg); } Loading