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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -434,6 +434,10 @@ public abstract class LayoutInflater {
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// Told retain static reference on context.
|
||||
mConstructorArgs[0] = null;
|
||||
mConstructorArgs[1] = null;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
166
services/java/com/android/server/am/UriPermissionOwner.java
Normal file
166
services/java/com/android/server/am/UriPermissionOwner.java
Normal 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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user