am 3003a017: Merge "Don\'t retain global ref to last inflated context." into gingerbread

Merge commit '3003a017d312a55e3804d6cf4a80044b1f1d7993' into gingerbread-plus-aosp

* commit '3003a017d312a55e3804d6cf4a80044b1f1d7993':
  Don't retain global ref to last inflated context.
This commit is contained in:
Dianne Hackborn
2010-08-25 22:02:18 -07:00
committed by Android Git Automerger
9 changed files with 378 additions and 147 deletions

View File

@@ -1248,8 +1248,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
case IS_USER_A_MONKEY_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
reply.writeInt(isUserAMonkey() ? 1 : 0);
boolean areThey = isUserAMonkey();
reply.writeNoException();
reply.writeInt(areThey ? 1 : 0);
return true;
}
@@ -1263,8 +1264,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
case IS_IMMERSIVE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
reply.writeInt(isImmersive(token) ? 1 : 0);
boolean isit = isImmersive(token);
reply.writeNoException();
reply.writeInt(isit ? 1 : 0);
return true;
}
@@ -1279,8 +1281,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
case IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
reply.writeInt(isTopActivityImmersive() ? 1 : 0);
boolean isit = isTopActivityImmersive();
reply.writeNoException();
reply.writeInt(isit ? 1 : 0);
return true;
}
@@ -1295,6 +1298,40 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
case NEW_URI_PERMISSION_OWNER_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
String name = data.readString();
IBinder perm = newUriPermissionOwner(name);
reply.writeNoException();
reply.writeStrongBinder(perm);
return true;
}
case GRANT_URI_PERMISSION_FROM_OWNER_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder owner = data.readStrongBinder();
int fromUid = data.readInt();
String targetPkg = data.readString();
Uri uri = Uri.CREATOR.createFromParcel(data);
int mode = data.readInt();
grantUriPermissionFromOwner(owner, fromUid, targetPkg, uri, mode);
reply.writeNoException();
return true;
}
case REVOKE_URI_PERMISSION_FROM_OWNER_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder owner = data.readStrongBinder();
Uri uri = null;
if (data.readInt() != 0) {
Uri.CREATOR.createFromParcel(data);
}
int mode = data.readInt();
revokeUriPermissionFromOwner(owner, uri, mode);
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
@@ -2841,8 +2878,8 @@ class ActivityManagerProxy implements IActivityManager
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(token);
mRemote.transact(IS_IMMERSIVE_TRANSACTION, data, reply, 0);
boolean res = reply.readInt() == 1;
reply.readException();
boolean res = reply.readInt() == 1;
data.recycle();
reply.recycle();
return res;
@@ -2854,8 +2891,8 @@ class ActivityManagerProxy implements IActivityManager
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
mRemote.transact(IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION, data, reply, 0);
boolean res = reply.readInt() == 1;
reply.readException();
boolean res = reply.readInt() == 1;
data.recycle();
reply.recycle();
return res;
@@ -2875,6 +2912,55 @@ class ActivityManagerProxy implements IActivityManager
data.recycle();
reply.recycle();
}
public IBinder newUriPermissionOwner(String name)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeString(name);
mRemote.transact(NEW_URI_PERMISSION_OWNER_TRANSACTION, data, reply, 0);
reply.readException();
IBinder res = reply.readStrongBinder();
data.recycle();
reply.recycle();
return res;
}
public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
Uri uri, int mode) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(owner);
data.writeInt(fromUid);
data.writeString(targetPkg);
uri.writeToParcel(data, 0);
data.writeInt(mode);
mRemote.transact(GRANT_URI_PERMISSION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
public void revokeUriPermissionFromOwner(IBinder owner, Uri uri,
int mode) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(owner);
if (uri != null) {
data.writeInt(1);
uri.writeToParcel(data, 0);
} else {
data.writeInt(0);
}
data.writeInt(mode);
mRemote.transact(REVOKE_URI_PERMISSION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
private IBinder mRemote;
}

View File

@@ -318,6 +318,12 @@ public interface IActivityManager extends IInterface {
public void crashApplication(int uid, int initialPid, String packageName,
String message) throws RemoteException;
public IBinder newUriPermissionOwner(String name) throws RemoteException;
public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg,
Uri uri, int mode) throws RemoteException;
public void revokeUriPermissionFromOwner(IBinder owner, Uri uri,
int mode) throws RemoteException;
/*
* Private non-Binder interfaces
*/
@@ -524,4 +530,7 @@ public interface IActivityManager extends IInterface {
int SET_IMMERSIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+111;
int IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+112;
int CRASH_APPLICATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+113;
int NEW_URI_PERMISSION_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+114;
int GRANT_URI_PERMISSION_FROM_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+115;
int REVOKE_URI_PERMISSION_FROM_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+116;
}

View File

@@ -434,6 +434,10 @@ public abstract class LayoutInflater {
throw ex;
}
// Told retain static reference on context.
mConstructorArgs[0] = null;
mConstructorArgs[1] = null;
return result;
}
}

View File

@@ -4297,12 +4297,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
+ " when granting permission to uri " + uri);
}
if (targetPkg == null) {
Slog.w(TAG, "grantUriPermission: null target");
return;
throw new IllegalArgumentException("null target");
}
if (uri == null) {
Slog.w(TAG, "grantUriPermission: null uri");
return;
throw new IllegalArgumentException("null uri");
}
grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
@@ -4454,6 +4452,56 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
}
}
@Override
public IBinder newUriPermissionOwner(String name) {
synchronized(this) {
UriPermissionOwner owner = new UriPermissionOwner(this, name);
return owner.getExternalTokenLocked();
}
}
@Override
public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
Uri uri, int modeFlags) {
synchronized(this) {
UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
if (owner == null) {
throw new IllegalArgumentException("Unknown owner: " + token);
}
if (fromUid != Binder.getCallingUid()) {
if (Binder.getCallingUid() != Process.myUid()) {
// Only system code can grant URI permissions on behalf
// of other users.
throw new SecurityException("nice try");
}
}
if (targetPkg == null) {
throw new IllegalArgumentException("null target");
}
if (uri == null) {
throw new IllegalArgumentException("null uri");
}
grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
}
}
@Override
public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
synchronized(this) {
UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
if (owner == null) {
throw new IllegalArgumentException("Unknown owner: " + token);
}
if (uri == null) {
owner.removeUriPermissionsLocked(mode);
} else {
owner.removeUriPermissionLocked(uri, mode);
}
}
}
public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
synchronized (this) {
ProcessRecord app =
@@ -8284,7 +8332,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
si.deliveryCount++;
if (si.targetPermissionUid >= 0) {
grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
r.packageName, si.intent, si);
r.packageName, si.intent, si.getUriPermissionsLocked());
}
if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING start of " + r);
bumpServiceExecutingLocked(r);

View File

@@ -44,7 +44,7 @@ import java.util.HashSet;
/**
* An entry in the history stack, representing an activity.
*/
class ActivityRecord extends IApplicationToken.Stub implements UriPermissionOwner {
class ActivityRecord extends IApplicationToken.Stub {
final ActivityManagerService service; // owner
final ActivityStack stack; // owner
final ActivityInfo info; // all about me
@@ -78,8 +78,7 @@ class ActivityRecord extends IApplicationToken.Stub implements UriPermissionOwne
HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
ArrayList newIntents; // any pending new intents for single-top mode
HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
HashSet<UriPermission> readUriPermissions; // special access to reading uris.
HashSet<UriPermission> writeUriPermissions; // special access to writing uris.
UriPermissionOwner uriPermissions; // current special URI access perms.
ProcessRecord app; // if non-null, hosting application
Bitmap thumbnail; // icon representation of paused screen
CharSequence description; // textual description of paused screen
@@ -141,11 +140,15 @@ class ActivityRecord extends IApplicationToken.Stub implements UriPermissionOwne
if (pendingResults != null) {
pw.print(prefix); pw.print("pendingResults="); pw.println(pendingResults);
}
if (readUriPermissions != null) {
pw.print(prefix); pw.print("readUriPermissions="); pw.println(readUriPermissions);
}
if (writeUriPermissions != null) {
pw.print(prefix); pw.print("writeUriPermissions="); pw.println(writeUriPermissions);
if (uriPermissions != null) {
if (uriPermissions.readUriPermissions != null) {
pw.print(prefix); pw.print("readUriPermissions=");
pw.println(uriPermissions.readUriPermissions);
}
if (uriPermissions.writeUriPermissions != null) {
pw.print(prefix); pw.print("writeUriPermissions=");
pw.println(uriPermissions.writeUriPermissions);
}
}
pw.print(prefix); pw.print("launchFailed="); pw.print(launchFailed);
pw.print(" haveState="); pw.print(haveState);
@@ -301,6 +304,13 @@ class ActivityRecord extends IApplicationToken.Stub implements UriPermissionOwne
}
}
UriPermissionOwner getUriPermissionsLocked() {
if (uriPermissions == null) {
uriPermissions = new UriPermissionOwner(service, this);
}
return uriPermissions;
}
void addResultLocked(ActivityRecord from, String resultWho,
int requestCode, int resultCode,
Intent resultData) {
@@ -350,7 +360,7 @@ class ActivityRecord extends IApplicationToken.Stub implements UriPermissionOwne
intent = new Intent(intent);
ar.add(intent);
service.grantUriPermissionFromIntentLocked(callingUid, packageName,
intent, this);
intent, getUriPermissionsLocked());
app.thread.scheduleNewIntent(ar, this);
sent = true;
} catch (RemoteException e) {
@@ -367,27 +377,9 @@ class ActivityRecord extends IApplicationToken.Stub implements UriPermissionOwne
}
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;
service.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;
service.removeUriPermissionIfNeededLocked(perm);
}
}
writeUriPermissions = null;
if (uriPermissions != null) {
uriPermissions.removeUriPermissionsLocked();
uriPermissions = null;
}
}
@@ -578,38 +570,6 @@ class ActivityRecord extends IApplicationToken.Stub implements UriPermissionOwne
state == ActivityState.RESUMED;
}
@Override
public void addReadPermission(UriPermission perm) {
if (readUriPermissions == null) {
readUriPermissions = new HashSet<UriPermission>();
}
readUriPermissions.add(perm);
}
@Override
public void addWritePermission(UriPermission perm) {
if (writeUriPermissions == null) {
writeUriPermissions = new HashSet<UriPermission>();
}
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;

View File

@@ -2327,12 +2327,12 @@ public class ActivityStack {
if (grantedUriPermissions != null && callingUid > 0) {
for (int i=0; i<grantedUriPermissions.length; i++) {
mService.grantUriPermissionLocked(callingUid, r.packageName,
grantedUriPermissions[i], grantedMode, r);
grantedUriPermissions[i], grantedMode, r.getUriPermissionsLocked());
}
}
mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
intent, r);
intent, r.getUriPermissionsLocked());
if (newTask) {
EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId);
@@ -2557,7 +2557,7 @@ public class ActivityStack {
if (callingUid > 0) {
mService.grantUriPermissionFromIntentLocked(callingUid, r.packageName,
data, r);
data, r.getUriPermissionsLocked());
}
if (DEBUG_RESULTS) Slog.v(TAG, "Send activity result to " + r
@@ -2885,7 +2885,7 @@ public class ActivityStack {
+ " res=" + resultCode + " data=" + resultData);
if (r.info.applicationInfo.uid > 0) {
mService.grantUriPermissionFromIntentLocked(r.info.applicationInfo.uid,
r.packageName, resultData, r);
r.packageName, resultData, r.getUriPermissionsLocked());
}
resultTo.addResultLocked(r, r.resultWho, r.requestCode, resultCode,
resultData);

View File

@@ -96,7 +96,7 @@ class ServiceRecord extends Binder {
String stringName; // caching of toString
static class StartItem implements UriPermissionOwner {
static class StartItem {
final ServiceRecord sr;
final int id;
final Intent intent;
@@ -104,12 +104,10 @@ class ServiceRecord extends Binder {
long deliveredTime;
int deliveryCount;
int doneExecutingCount;
UriPermissionOwner uriPermissions;
String stringName; // caching of toString
HashSet<UriPermission> readUriPermissions; // special access to reading uris.
HashSet<UriPermission> writeUriPermissions; // special access to writing uris.
StartItem(ServiceRecord _sr, int _id, Intent _intent, int _targetPermissionUid) {
sr = _sr;
id = _id;
@@ -117,60 +115,17 @@ class ServiceRecord extends Binder {
targetPermissionUid = _targetPermissionUid;
}
UriPermissionOwner getUriPermissionsLocked() {
if (uriPermissions == null) {
uriPermissions = new UriPermissionOwner(sr.ams, this);
}
return uriPermissions;
}
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<UriPermission>();
}
readUriPermissions.add(perm);
}
@Override
public void addWritePermission(UriPermission perm) {
if (writeUriPermissions == null) {
writeUriPermissions = new HashSet<UriPermission>();
}
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;
if (uriPermissions != null) {
uriPermissions.removeUriPermissionsLocked();
uriPermissions = null;
}
}
@@ -218,13 +173,15 @@ class ServiceRecord extends Binder {
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);
if (si.uriPermissions != null) {
if (si.uriPermissions.readUriPermissions != null) {
pw.print(prefix); pw.print(" readUriPermissions=");
pw.println(si.uriPermissions.readUriPermissions);
}
if (si.uriPermissions.writeUriPermissions != null) {
pw.print(prefix); pw.print(" writeUriPermissions=");
pw.println(si.uriPermissions.writeUriPermissions);
}
}
}
}

View File

@@ -22,13 +22,14 @@ 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);
}
/**
* Description of a permission granted to an app to access a particular URI.
*
* CTS tests for this functionality can be run with "runtest cts-appsecurity".
*
* Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert
* /src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
*/
class UriPermission {
final int uid;
final Uri uri;

View File

@@ -0,0 +1,166 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.am;
import android.content.Intent;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import java.util.HashSet;
import java.util.Iterator;
class UriPermissionOwner {
final ActivityManagerService service;
final Object owner;
Binder externalToken;
HashSet<UriPermission> readUriPermissions; // special access to reading uris.
HashSet<UriPermission> writeUriPermissions; // special access to writing uris.
class ExternalToken extends Binder {
UriPermissionOwner getOwner() {
return UriPermissionOwner.this;
}
}
UriPermissionOwner(ActivityManagerService _service, Object _owner) {
service = _service;
owner = _owner;
}
Binder getExternalTokenLocked() {
if (externalToken != null) {
externalToken = new ExternalToken();
}
return externalToken;
}
static UriPermissionOwner fromExternalToken(IBinder token) {
if (token instanceof ExternalToken) {
return ((ExternalToken)token).getOwner();
}
return null;
}
void removeUriPermissionsLocked() {
removeUriPermissionsLocked(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
void removeUriPermissionsLocked(int mode) {
if ((mode&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0
&& 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;
service.removeUriPermissionIfNeededLocked(perm);
}
}
readUriPermissions = null;
}
if ((mode&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0
&& 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;
service.removeUriPermissionIfNeededLocked(perm);
}
}
writeUriPermissions = null;
}
}
void removeUriPermissionLocked(Uri uri, int mode) {
if ((mode&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0
&& readUriPermissions != null) {
Iterator<UriPermission> it = readUriPermissions.iterator();
while (it.hasNext()) {
UriPermission perm = it.next();
if (uri.equals(perm.uri)) {
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);
}
it.remove();
}
}
if (readUriPermissions.size() == 0) {
readUriPermissions = null;
}
}
if ((mode&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0
&& writeUriPermissions != null) {
Iterator<UriPermission> it = writeUriPermissions.iterator();
while (it.hasNext()) {
UriPermission perm = it.next();
if (uri.equals(perm.uri)) {
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);
}
it.remove();
}
}
if (writeUriPermissions.size() == 0) {
writeUriPermissions = null;
}
}
}
public void addReadPermission(UriPermission perm) {
if (readUriPermissions == null) {
readUriPermissions = new HashSet<UriPermission>();
}
readUriPermissions.add(perm);
}
public void addWritePermission(UriPermission perm) {
if (writeUriPermissions == null) {
writeUriPermissions = new HashSet<UriPermission>();
}
writeUriPermissions.add(perm);
}
public void removeReadPermission(UriPermission perm) {
readUriPermissions.remove(perm);
if (readUriPermissions.size() == 0) {
readUriPermissions = null;
}
}
public void removeWritePermission(UriPermission perm) {
writeUriPermissions.remove(perm);
if (writeUriPermissions.size() == 0) {
writeUriPermissions = null;
}
}
@Override
public String toString() {
return owner.toString();
}
}