From 39792d2262352ae775091876d5488d2412a2ff92 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Thu, 19 Aug 2010 18:01:52 -0700 Subject: [PATCH] Fix bugs with granting permissions through onNewIntent(). It would grant the permission to the temporary ActivityRecord, not the real one, so it never got cleaned up. Also allow granting of permissions to services because... well, it would be really really useful. And it introduces some refactoring that we'll need to support cut/paste. Change-Id: If521f509042e7baad7f5dc9bec84b6ba0d90ba09 --- .../android/content/pm/ApplicationInfo.java | 18 ++- .../server/am/ActivityManagerService.java | 141 ++++++++++------ .../com/android/server/am/ActivityRecord.java | 58 +++++-- .../com/android/server/am/ActivityStack.java | 31 ++-- .../android/server/am/BroadcastRecord.java | 68 ++++---- .../com/android/server/am/ServiceRecord.java | 150 +++++++++++++++--- .../com/android/server/am/UriPermission.java | 47 +++--- 7 files changed, 357 insertions(+), 156 deletions(-) diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 7901b155467aa..244d126b89bb2 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -389,15 +389,17 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { if (permission != null) { pw.println(prefix + "permission=" + permission); } - pw.println(prefix + "uid=" + uid + " taskAffinity=" + taskAffinity); - if (theme != 0) { - pw.println(prefix + "theme=0x" + Integer.toHexString(theme)); - } - pw.println(prefix + "flags=0x" + Integer.toHexString(flags) - + " processName=" + processName); + pw.println(prefix + "processName=" + processName); + pw.println(prefix + "taskAffinity=" + taskAffinity); + pw.println(prefix + "uid=" + uid + " flags=0x" + Integer.toHexString(flags) + + " theme=0x" + Integer.toHexString(theme)); pw.println(prefix + "sourceDir=" + sourceDir); - pw.println(prefix + "publicSourceDir=" + publicSourceDir); - pw.println(prefix + "resourceDirs=" + resourceDirs); + if (!sourceDir.equals(publicSourceDir)) { + pw.println(prefix + "publicSourceDir=" + publicSourceDir); + } + if (resourceDirs != null) { + pw.println(prefix + "resourceDirs=" + resourceDirs); + } pw.println(prefix + "dataDir=" + dataDir); if (sharedLibraryFiles != null) { pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 9d31502fbca4a..b37cd89897454 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -4093,16 +4093,23 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } - void grantUriPermissionLocked(int callingUid, - String targetPkg, Uri uri, int modeFlags, ActivityRecord activity) { + /** + * Check if the targetPkg can be granted permission to access uri by + * the callingUid using the given modeFlags. Throws a security exception + * if callingUid is not allowed to do this. Returns the uid of the target + * if the URI permission grant should be performed; returns -1 if it is not + * needed (for example targetPkg already has permission to access the URI). + */ + int checkGrantUriPermissionLocked(int callingUid, String targetPkg, + Uri uri, int modeFlags) { modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); if (modeFlags == 0) { - return; + return -1; } if (DEBUG_URI_PERMISSION) Slog.v(TAG, - "Requested grant " + targetPkg + " permission to " + uri); + "Checking grant " + targetPkg + " permission to " + uri); final IPackageManager pm = AppGlobals.getPackageManager(); @@ -4110,7 +4117,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Can't grant URI permission for non-content URI: " + uri); - return; + return -1; } String name = uri.getAuthority(); @@ -4127,7 +4134,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } if (pi == null) { Slog.w(TAG, "No content provider found for: " + name); - return; + return -1; } int targetUid; @@ -4136,10 +4143,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (targetUid < 0) { if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg); - return; + return -1; } } catch (RemoteException ex) { - return; + return -1; } // First... does the target actually need this permission? @@ -4147,7 +4154,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // No need to grant the target this permission. if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Target " + targetPkg + " already has full permission to " + uri); - return; + return -1; } // Second... is the provider allowing granting of URI permissions? @@ -4184,12 +4191,23 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } } - // Okay! So here we are: the caller has the assumed permission + return targetUid; + } + + void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, + Uri uri, int modeFlags, UriPermissionOwner owner) { + modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION + | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + if (modeFlags == 0) { + return; + } + + // So here we are: the caller has the assumed permission // to the uri, and the target doesn't. Let's now give this to // the target. if (DEBUG_URI_PERMISSION) Slog.v(TAG, - "Granting " + targetPkg + " permission to " + uri); + "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); HashMap targetUris = mGrantedUriPermissions.get(targetUid); @@ -4205,39 +4223,65 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } perm.modeFlags |= modeFlags; - if (activity == null) { + if (owner == null) { perm.globalModeFlags |= modeFlags; } else if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { - perm.readActivities.add(activity); - if (activity.readUriPermissions == null) { - activity.readUriPermissions = new HashSet(); - } - activity.readUriPermissions.add(perm); + perm.readOwners.add(owner); + owner.addReadPermission(perm); } else if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { - perm.writeActivities.add(activity); - if (activity.writeUriPermissions == null) { - activity.writeUriPermissions = new HashSet(); - } - activity.writeUriPermissions.add(perm); + perm.writeOwners.add(owner); + owner.addWritePermission(perm); } } - void grantUriPermissionFromIntentLocked(int callingUid, - String targetPkg, Intent intent, ActivityRecord activity) { + void grantUriPermissionLocked(int callingUid, + String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { + int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags); + if (targetUid < 0) { + return; + } + + grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); + } + + /** + * Like checkGrantUriPermissionLocked, but takes an Intent. + */ + int checkGrantUriPermissionFromIntentLocked(int callingUid, + String targetPkg, Intent intent) { if (DEBUG_URI_PERMISSION) Slog.v(TAG, - "Grant URI perm to " + (intent != null ? intent.getData() : null) + "Checking URI perm to " + (intent != null ? intent.getData() : null) + " from " + intent + "; flags=0x" + Integer.toHexString(intent != null ? intent.getFlags() : 0)); if (intent == null) { - return; + return -1; } Uri data = intent.getData(); if (data == null) { + return -1; + } + return checkGrantUriPermissionLocked(callingUid, targetPkg, data, + intent.getFlags()); + } + + /** + * Like grantUriPermissionUncheckedLocked, but takes an Intent. + */ + void grantUriPermissionUncheckedFromIntentLocked(int targetUid, + String targetPkg, Intent intent, UriPermissionOwner owner) { + grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(), + intent.getFlags(), owner); + } + + void grantUriPermissionFromIntentLocked(int callingUid, + String targetPkg, Intent intent, UriPermissionOwner owner) { + int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent); + if (targetUid < 0) { return; } - grantUriPermissionLocked(callingUid, targetPkg, data, - intent.getFlags(), activity); + + grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner); } public void grantUriPermission(IApplicationThread caller, String targetPkg, @@ -8187,18 +8231,23 @@ public final class ActivityManagerService extends ActivityManagerNative implemen return; } - int i = 0; - while (i < N) { + while (r.pendingStarts.size() > 0) { try { - ServiceRecord.StartItem si = r.pendingStarts.get(i); + ServiceRecord.StartItem si = r.pendingStarts.remove(0); if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to service: " + r.name + " " + r.intent + " args=" + si.intent); - if (si.intent == null && N > 1) { + if (si.intent == null) { // If somehow we got a dummy start at the front, then // just drop it here. - i++; continue; } + si.deliveredTime = SystemClock.uptimeMillis(); + r.deliveredStarts.add(si); + si.deliveryCount++; + if (si.targetPermissionUid >= 0) { + grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid, + r.packageName, si.intent, si); + } bumpServiceExecutingLocked(r); if (!oomAdjusted) { oomAdjusted = true; @@ -8212,10 +8261,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen flags |= Service.START_FLAG_REDELIVERY; } r.app.thread.scheduleServiceArgs(r, si.id, flags, si.intent); - si.deliveredTime = SystemClock.uptimeMillis(); - r.deliveredStarts.add(si); - si.deliveryCount++; - i++; } catch (RemoteException e) { // Remote process gone... we'll let the normal cleanup take // care of this. @@ -8225,14 +8270,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen break; } } - if (i == N) { - r.pendingStarts.clear(); - } else { - while (i > 0) { - i--; - r.pendingStarts.remove(i); - } - } } private final boolean requestServiceBindingLocked(ServiceRecord r, @@ -8315,7 +8352,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (r.lastStartId < 1) { r.lastStartId = 1; } - r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, null)); + r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, null, -1)); } sendServiceArgsLocked(r, true); @@ -8335,6 +8372,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (N > 0) { for (int i=N-1; i>=0; i--) { ServiceRecord.StartItem si = r.deliveredStarts.get(i); + si.removeUriPermissionsLocked(); if (si.intent == null) { // We'll generate this again if needed. } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT @@ -8574,7 +8612,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen r.foregroundNoti = null; // Clear start entries. - r.deliveredStarts.clear(); + r.clearDeliveredStartsLocked(); r.pendingStarts.clear(); if (r.app != null) { @@ -8634,6 +8672,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen ? res.permission : "private to package"); } ServiceRecord r = res.record; + int targetPermissionUid = checkGrantUriPermissionFromIntentLocked( + callingUid, r.packageName, service); if (unscheduleServiceRestartLocked(r)) { if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r.shortName); @@ -8644,7 +8684,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (r.lastStartId < 1) { r.lastStartId = 1; } - r.pendingStarts.add(new ServiceRecord.StartItem(r.lastStartId, service)); + r.pendingStarts.add(new ServiceRecord.StartItem(r, r.lastStartId, + service, targetPermissionUid)); r.lastActivity = SystemClock.uptimeMillis(); synchronized (r.stats.getBatteryStats()) { r.stats.startRunningLocked(); @@ -8769,7 +8810,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen ServiceRecord.StartItem si = r.findDeliveredStart(startId, false); if (si != null) { while (r.deliveredStarts.size() > 0) { - if (r.deliveredStarts.remove(0) == si) { + ServiceRecord.StartItem cur = r.deliveredStarts.remove(0); + cur.removeUriPermissionsLocked(); + if (cur == si) { break; } } diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index 79756a7af272e..80a41b7fb31b7 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -29,6 +29,7 @@ import android.graphics.Bitmap; import android.os.Bundle; import android.os.Message; import android.os.Process; +import android.os.RemoteException; import android.os.SystemClock; import android.util.EventLog; import android.util.Log; @@ -43,7 +44,7 @@ import java.util.HashSet; /** * An entry in the history stack, representing an activity. */ -class ActivityRecord extends IApplicationToken.Stub { +class ActivityRecord extends IApplicationToken.Stub implements UriPermissionOwner { final ActivityManagerService service; // owner final ActivityStack stack; // owner final ActivityInfo info; // all about me @@ -340,16 +341,22 @@ class ActivityRecord extends IApplicationToken.Stub { * Deliver a new Intent to an existing activity, so that its onNewIntent() * method will be called at the proper time. */ - final void deliverNewIntentLocked(Intent intent) { + final void deliverNewIntentLocked(int callingUid, Intent intent) { boolean sent = false; if (state == ActivityState.RESUMED && app != null && app.thread != null) { try { ArrayList ar = new ArrayList(); - ar.add(new Intent(intent)); + intent = new Intent(intent); + ar.add(intent); + service.grantUriPermissionFromIntentLocked(callingUid, packageName, + intent, this); app.thread.scheduleNewIntent(ar, this); sent = true; - } catch (Exception e) { + } catch (RemoteException e) { + Slog.w(ActivityManagerService.TAG, + "Exception thrown sending new intent to " + this, e); + } catch (NullPointerException e) { Slog.w(ActivityManagerService.TAG, "Exception thrown sending new intent to " + this, e); } @@ -362,23 +369,25 @@ class ActivityRecord extends IApplicationToken.Stub { void removeUriPermissionsLocked() { if (readUriPermissions != null) { for (UriPermission perm : readUriPermissions) { - perm.readActivities.remove(this); - if (perm.readActivities.size() == 0 && (perm.globalModeFlags + perm.readOwners.remove(this); + if (perm.readOwners.size() == 0 && (perm.globalModeFlags &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) { perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; - service.removeUriPermissionIfNeededLocked(perm); + service.removeUriPermissionIfNeededLocked(perm); } } + readUriPermissions = null; } if (writeUriPermissions != null) { for (UriPermission perm : writeUriPermissions) { - perm.writeActivities.remove(this); - if (perm.writeActivities.size() == 0 && (perm.globalModeFlags + perm.writeOwners.remove(this); + if (perm.writeOwners.size() == 0 && (perm.globalModeFlags &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) { perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; service.removeUriPermissionIfNeededLocked(perm); } } + writeUriPermissions = null; } } @@ -569,6 +578,37 @@ class ActivityRecord extends IApplicationToken.Stub { state == ActivityState.RESUMED; } + @Override + public void addReadPermission(UriPermission perm) { + if (readUriPermissions == null) { + readUriPermissions = new HashSet(); + } + readUriPermissions.add(perm); + } + + @Override + public void addWritePermission(UriPermission perm) { + if (writeUriPermissions == null) { + writeUriPermissions = new HashSet(); + } + writeUriPermissions.add(perm); + } + + @Override + public void removeReadPermission(UriPermission perm) { + readUriPermissions.remove(perm); + if (readUriPermissions.size() == 0) { + readUriPermissions = null; + } + } + + @Override + public void removeWritePermission(UriPermission perm) { + writeUriPermissions.remove(perm); + if (writeUriPermissions.size() == 0) { + writeUriPermissions = null; + } + } public String toString() { if (stringName != null) { diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index de7b15cc0091f..a5f7e96866fe3 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -2033,16 +2033,6 @@ public class ActivityStack { } } - if (grantedUriPermissions != null && callingUid > 0) { - for (int i=0; i= 0) { ActivityRecord top = moveActivityToFrontLocked(where); logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task); - top.deliverNewIntentLocked(r.intent); + top.deliverNewIntentLocked(callingUid, r.intent); if (doResume) { resumeTopActivityLocked(null); } @@ -2333,6 +2323,17 @@ public class ActivityStack { if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new guessed " + r.task); } + + if (grantedUriPermissions != null && callingUid > 0) { + for (int i=0; i connections = new HashMap(); // IBinder -> ConnectionRecord of all bound clients - - // Maximum number of delivery attempts before giving up. - static final int MAX_DELIVERY_COUNT = 3; - - // Maximum number of times it can fail during execution before giving up. - static final int MAX_DONE_EXECUTING_COUNT = 6; - - static class StartItem { - final int id; - final Intent intent; - long deliveredTime; - int deliveryCount; - int doneExecutingCount; - - StartItem(int _id, Intent _intent) { - id = _id; - intent = _intent; - } - } - final ArrayList deliveredStarts = new ArrayList(); - // start() arguments which been delivered. - final ArrayList pendingStarts = new ArrayList(); - // start() arguments that haven't yet been delivered. ProcessRecord app; // where this service is running or null. boolean isForeground; // is service currently in foreground mode? @@ -112,6 +96,104 @@ class ServiceRecord extends Binder { String stringName; // caching of toString + static class StartItem implements UriPermissionOwner { + final ServiceRecord sr; + final int id; + final Intent intent; + final int targetPermissionUid; + long deliveredTime; + int deliveryCount; + int doneExecutingCount; + + String stringName; // caching of toString + + HashSet readUriPermissions; // special access to reading uris. + HashSet writeUriPermissions; // special access to writing uris. + + StartItem(ServiceRecord _sr, int _id, Intent _intent, int _targetPermissionUid) { + sr = _sr; + id = _id; + intent = _intent; + targetPermissionUid = _targetPermissionUid; + } + + void removeUriPermissionsLocked() { + if (readUriPermissions != null) { + for (UriPermission perm : readUriPermissions) { + perm.readOwners.remove(this); + if (perm.readOwners.size() == 0 && (perm.globalModeFlags + &Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0) { + perm.modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; + sr.ams.removeUriPermissionIfNeededLocked(perm); + } + } + readUriPermissions = null; + } + if (writeUriPermissions != null) { + for (UriPermission perm : writeUriPermissions) { + perm.writeOwners.remove(this); + if (perm.writeOwners.size() == 0 && (perm.globalModeFlags + &Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0) { + perm.modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; + sr.ams.removeUriPermissionIfNeededLocked(perm); + } + } + writeUriPermissions = null; + } + } + + @Override + public void addReadPermission(UriPermission perm) { + if (readUriPermissions == null) { + readUriPermissions = new HashSet(); + } + readUriPermissions.add(perm); + } + + @Override + public void addWritePermission(UriPermission perm) { + if (writeUriPermissions == null) { + writeUriPermissions = new HashSet(); + } + writeUriPermissions.add(perm); + } + + @Override + public void removeReadPermission(UriPermission perm) { + readUriPermissions.remove(perm); + if (readUriPermissions.size() == 0) { + readUriPermissions = null; + } + } + + @Override + public void removeWritePermission(UriPermission perm) { + writeUriPermissions.remove(perm); + if (writeUriPermissions.size() == 0) { + writeUriPermissions = null; + } + } + + public String toString() { + if (stringName != null) { + return stringName; + } + StringBuilder sb = new StringBuilder(128); + sb.append("ServiceRecord{") + .append(Integer.toHexString(System.identityHashCode(sr))) + .append(' ').append(sr.shortName) + .append(" StartItem ") + .append(Integer.toHexString(System.identityHashCode(this))) + .append(" id=").append(id).append('}'); + return stringName = sb.toString(); + } + } + + final ArrayList deliveredStarts = new ArrayList(); + // start() arguments which been delivered. + final ArrayList pendingStarts = new ArrayList(); + // start() arguments that haven't yet been delivered. + void dumpStartList(PrintWriter pw, String prefix, List list, long now) { final int N = list.size(); for (int i=0; i= 0) { + pw.print(prefix); pw.print(" targetPermissionUid="); + pw.println(si.targetPermissionUid); + } + if (si.readUriPermissions != null) { + pw.print(prefix); pw.print(" readUriPermissions="); + pw.println(si.readUriPermissions); + } + if (si.writeUriPermissions != null) { + pw.print(prefix); pw.print(" writeUriPermissions="); + pw.println(si.writeUriPermissions); + } } } @@ -324,6 +419,13 @@ class ServiceRecord extends Binder { } } + public void clearDeliveredStartsLocked() { + for (int i=deliveredStarts.size()-1; i>=0; i--) { + deliveredStarts.get(i).removeUriPermissionsLocked(); + } + deliveredStarts.clear(); + } + public String toString() { if (stringName != null) { return stringName; diff --git a/services/java/com/android/server/am/UriPermission.java b/services/java/com/android/server/am/UriPermission.java index 81450c5758f8b..93c59cc1dd990 100644 --- a/services/java/com/android/server/am/UriPermission.java +++ b/services/java/com/android/server/am/UriPermission.java @@ -22,13 +22,20 @@ import android.net.Uri; import java.io.PrintWriter; import java.util.HashSet; +interface UriPermissionOwner { + void addReadPermission(UriPermission perm); + void addWritePermission(UriPermission perm); + void removeReadPermission(UriPermission perm); + void removeWritePermission(UriPermission perm); +} + class UriPermission { final int uid; final Uri uri; int modeFlags = 0; int globalModeFlags = 0; - final HashSet readActivities = new HashSet(); - final HashSet writeActivities = new HashSet(); + final HashSet readOwners = new HashSet(); + final HashSet writeOwners = new HashSet(); String stringName; @@ -41,27 +48,21 @@ class UriPermission { if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { globalModeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; modeFlags &= ~Intent.FLAG_GRANT_READ_URI_PERMISSION; - if (readActivities.size() > 0) { - for (ActivityRecord r : readActivities) { - r.readUriPermissions.remove(this); - if (r.readUriPermissions.size() == 0) { - r.readUriPermissions = null; - } + if (readOwners.size() > 0) { + for (UriPermissionOwner r : readOwners) { + r.removeReadPermission(this); } - readActivities.clear(); + readOwners.clear(); } } if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { globalModeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; modeFlags &= ~Intent.FLAG_GRANT_WRITE_URI_PERMISSION; - if (readActivities.size() > 0) { - for (ActivityRecord r : readActivities) { - r.writeUriPermissions.remove(this); - if (r.writeUriPermissions.size() == 0) { - r.writeUriPermissions = null; - } + if (readOwners.size() > 0) { + for (UriPermissionOwner r : writeOwners) { + r.removeWritePermission(this); } - readActivities.clear(); + readOwners.clear(); } } } @@ -85,11 +86,17 @@ class UriPermission { pw.print(" uid="); pw.print(uid); pw.print(" globalModeFlags=0x"); pw.println(Integer.toHexString(globalModeFlags)); - if (readActivities.size() != 0) { - pw.print(prefix); pw.print("readActivities="); pw.println(readActivities); + if (readOwners.size() != 0) { + pw.print(prefix); pw.println("readOwners:"); + for (UriPermissionOwner owner : readOwners) { + pw.print(prefix); pw.print(" * "); pw.println(owner); + } } - if (writeActivities.size() != 0) { - pw.print(prefix); pw.print("writeActivities="); pw.println(writeActivities); + if (writeOwners.size() != 0) { + pw.print(prefix); pw.println("writeOwners:"); + for (UriPermissionOwner owner : writeOwners) { + pw.print(prefix); pw.print(" * "); pw.println(owner); + } } } }