resolved conflicts for merge of 66d633d2 to master

Change-Id: I6c38d7c4d127954dfca17082215c587a3cd4a586
This commit is contained in:
Dianne Hackborn
2010-08-25 23:14:44 -07:00
9 changed files with 380 additions and 149 deletions

View File

@@ -4301,12 +4301,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,
@@ -4458,6 +4456,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 =
@@ -8288,7 +8336,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();
}
}