diff options
author | Dianne Hackborn <hackbod@google.com> | 2013-07-29 18:11:02 -0700 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2013-07-29 18:11:02 -0700 |
commit | f0989840a00e53751241d0c97bf0e5a1866f6d4c (patch) | |
tree | b3df9998dca37cc000ded046bb49070c6b06a455 /services/java/com/android/server/ClipboardService.java | |
parent | 6077115d74a17ee14ce18c0bc8a2758ef00a636b (diff) |
Fix pub issue #58043: Copy crash in Android 4.3...
...when clipboard listener attached
We need to clear the calling identity before dispatching change
notifications. Also make this more robust, so that in the face
of any failure we will clean up the broadcast state.
Change-Id: I305a8a62738595f1fe5643a063099de5ed7cb062
Diffstat (limited to 'services/java/com/android/server/ClipboardService.java')
-rw-r--r-- | services/java/com/android/server/ClipboardService.java | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/services/java/com/android/server/ClipboardService.java b/services/java/com/android/server/ClipboardService.java index 058857ddb605..0bf03b5ff453 100644 --- a/services/java/com/android/server/ClipboardService.java +++ b/services/java/com/android/server/ClipboardService.java @@ -154,31 +154,36 @@ public class ClipboardService extends IClipboard.Stub { if (clip != null && clip.getItemCount() <= 0) { throw new IllegalArgumentException("No items"); } - if (mAppOps.noteOp(AppOpsManager.OP_WRITE_CLIPBOARD, Binder.getCallingUid(), + final int callingUid = Binder.getCallingUid(); + if (mAppOps.noteOp(AppOpsManager.OP_WRITE_CLIPBOARD, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) { return; } - checkDataOwnerLocked(clip, Binder.getCallingUid()); + checkDataOwnerLocked(clip, callingUid); clearActiveOwnersLocked(); PerUserClipboard clipboard = getClipboard(); clipboard.primaryClip = clip; + final long ident = Binder.clearCallingIdentity(); final int n = clipboard.primaryClipListeners.beginBroadcast(); - for (int i = 0; i < n; i++) { - try { - ListenerInfo li = (ListenerInfo) - clipboard.primaryClipListeners.getBroadcastCookie(i); - if (mAppOps.checkOpNoThrow(AppOpsManager.OP_READ_CLIPBOARD, li.mUid, - li.mPackageName) == AppOpsManager.MODE_ALLOWED) { - clipboard.primaryClipListeners.getBroadcastItem(i) - .dispatchPrimaryClipChanged(); + try { + for (int i = 0; i < n; i++) { + try { + ListenerInfo li = (ListenerInfo) + clipboard.primaryClipListeners.getBroadcastCookie(i); + if (mAppOps.checkOpNoThrow(AppOpsManager.OP_READ_CLIPBOARD, li.mUid, + li.mPackageName) == AppOpsManager.MODE_ALLOWED) { + clipboard.primaryClipListeners.getBroadcastItem(i) + .dispatchPrimaryClipChanged(); + } + } catch (RemoteException e) { + // The RemoteCallbackList will take care of removing + // the dead object for us. } - } catch (RemoteException e) { - - // The RemoteCallbackList will take care of removing - // the dead object for us. } + } finally { + clipboard.primaryClipListeners.finishBroadcast(); + Binder.restoreCallingIdentity(ident); } - clipboard.primaryClipListeners.finishBroadcast(); } } |