summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff Sharkey <jsharkey@android.com> 2013-09-06 16:26:34 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2013-09-06 16:26:34 +0000
commitdc8d704899716e97e59af8b6fe5f549e0229eda6 (patch)
tree321c3cab2769df443bc056926bc01e48c97d4974
parenta1d6a9b474ba095860838c6ed3e72f8d9f5058cd (diff)
parent911d7f411f36f2279aae44c89ff1d33a29140046 (diff)
Merge changes I7277880e,Ia5584bd6 into klp-dev
* changes: Provide calling package to ContentProviders. Separate root and document management.
-rw-r--r--api/current.txt3
-rw-r--r--core/java/android/app/AppOpsManager.java17
-rw-r--r--core/java/android/content/ContentProvider.java116
-rw-r--r--core/java/android/provider/DocumentsContract.java18
-rw-r--r--core/java/android/provider/DocumentsProvider.java38
-rw-r--r--core/java/com/android/internal/app/IAppOpsService.aidl1
-rw-r--r--packages/DocumentsUI/AndroidManifest.xml5
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java31
-rw-r--r--packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java4
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java5
-rw-r--r--services/java/com/android/server/AppOpsService.java15
-rw-r--r--services/java/com/android/server/DropBoxManagerService.java10
12 files changed, 198 insertions, 65 deletions
diff --git a/api/current.txt b/api/current.txt
index 8366333257cf..1443beefc929 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3172,6 +3172,7 @@ package android.app {
public class AppOpsManager {
method public int checkOp(int, int, java.lang.String);
method public int checkOpNoThrow(int, int, java.lang.String);
+ method public void checkPackage(int, java.lang.String);
method public void finishOp(int, int, java.lang.String);
method public void finishOp(int);
method public int noteOp(int, int, java.lang.String);
@@ -5624,6 +5625,7 @@ package android.content {
method public android.os.Bundle call(java.lang.String, java.lang.String, android.os.Bundle);
method public abstract int delete(android.net.Uri, java.lang.String, java.lang.String[]);
method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
+ method public final java.lang.String getCallingPackage();
method public final android.content.Context getContext();
method public final android.content.pm.PathPermission[] getPathPermissions();
method public final java.lang.String getReadPermission();
@@ -20747,6 +20749,7 @@ package android.provider {
method public static android.net.Uri buildChildDocumentsUri(java.lang.String, java.lang.String);
method public static android.net.Uri buildDocumentUri(java.lang.String, java.lang.String);
method public static android.net.Uri buildRecentDocumentsUri(java.lang.String, java.lang.String);
+ method public static android.net.Uri buildRootUri(java.lang.String, java.lang.String);
method public static android.net.Uri buildRootsUri(java.lang.String);
method public static android.net.Uri buildSearchDocumentsUri(java.lang.String, java.lang.String, java.lang.String);
method public static android.net.Uri createDocument(android.content.ContentResolver, android.net.Uri, java.lang.String, java.lang.String);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index fe09ce1988e8..19a028d39ae7 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -616,6 +616,23 @@ public class AppOpsManager {
}
/**
+ * Do a quick check to validate if a package name belongs to a UID.
+ *
+ * @throws SecurityException if the package name doesn't belong to the given
+ * UID, or if ownership cannot be verified.
+ */
+ public void checkPackage(int uid, String packageName) {
+ try {
+ if (mService.checkPackage(uid, packageName) != MODE_ALLOWED) {
+ throw new SecurityException(
+ "Package " + packageName + " does not belong to " + uid);
+ }
+ } catch (RemoteException e) {
+ throw new SecurityException("Unable to verify package ownership", e);
+ }
+ }
+
+ /**
* Make note of an application performing an operation. Note that you must pass
* in both the uid and name of the application to be checked; this function will verify
* that these two match, and if not, return {@link #MODE_IGNORED}. If this call
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index b9121c7f51bb..24c396a903ed 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -102,6 +102,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
private boolean mExported;
private boolean mNoPerms;
+ private final ThreadLocal<String> mCallingPackage = new ThreadLocal<String>();
+
private Transport mTransport = new Transport();
/**
@@ -194,8 +196,14 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
return rejectQuery(uri, projection, selection, selectionArgs, sortOrder,
CancellationSignal.fromTransport(cancellationSignal));
}
- return ContentProvider.this.query(uri, projection, selection, selectionArgs, sortOrder,
- CancellationSignal.fromTransport(cancellationSignal));
+ mCallingPackage.set(callingPkg);
+ try {
+ return ContentProvider.this.query(
+ uri, projection, selection, selectionArgs, sortOrder,
+ CancellationSignal.fromTransport(cancellationSignal));
+ } finally {
+ mCallingPackage.set(null);
+ }
}
@Override
@@ -208,7 +216,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
return rejectInsert(uri, initialValues);
}
- return ContentProvider.this.insert(uri, initialValues);
+ mCallingPackage.set(callingPkg);
+ try {
+ return ContentProvider.this.insert(uri, initialValues);
+ } finally {
+ mCallingPackage.set(null);
+ }
}
@Override
@@ -216,7 +229,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
return 0;
}
- return ContentProvider.this.bulkInsert(uri, initialValues);
+ mCallingPackage.set(callingPkg);
+ try {
+ return ContentProvider.this.bulkInsert(uri, initialValues);
+ } finally {
+ mCallingPackage.set(null);
+ }
}
@Override
@@ -238,7 +256,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
}
}
}
- return ContentProvider.this.applyBatch(operations);
+ mCallingPackage.set(callingPkg);
+ try {
+ return ContentProvider.this.applyBatch(operations);
+ } finally {
+ mCallingPackage.set(null);
+ }
}
@Override
@@ -246,7 +269,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
return 0;
}
- return ContentProvider.this.delete(uri, selection, selectionArgs);
+ mCallingPackage.set(callingPkg);
+ try {
+ return ContentProvider.this.delete(uri, selection, selectionArgs);
+ } finally {
+ mCallingPackage.set(null);
+ }
}
@Override
@@ -255,7 +283,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
return 0;
}
- return ContentProvider.this.update(uri, values, selection, selectionArgs);
+ mCallingPackage.set(callingPkg);
+ try {
+ return ContentProvider.this.update(uri, values, selection, selectionArgs);
+ } finally {
+ mCallingPackage.set(null);
+ }
}
@Override
@@ -263,8 +296,13 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
throws FileNotFoundException {
enforceFilePermission(callingPkg, uri, mode);
- return ContentProvider.this.openFile(
- uri, mode, CancellationSignal.fromTransport(cancellationSignal));
+ mCallingPackage.set(callingPkg);
+ try {
+ return ContentProvider.this.openFile(
+ uri, mode, CancellationSignal.fromTransport(cancellationSignal));
+ } finally {
+ mCallingPackage.set(null);
+ }
}
@Override
@@ -272,13 +310,23 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
throws FileNotFoundException {
enforceFilePermission(callingPkg, uri, mode);
- return ContentProvider.this.openAssetFile(
- uri, mode, CancellationSignal.fromTransport(cancellationSignal));
+ mCallingPackage.set(callingPkg);
+ try {
+ return ContentProvider.this.openAssetFile(
+ uri, mode, CancellationSignal.fromTransport(cancellationSignal));
+ } finally {
+ mCallingPackage.set(null);
+ }
}
@Override
public Bundle call(String callingPkg, String method, String arg, Bundle extras) {
- return ContentProvider.this.callFromPackage(callingPkg, method, arg, extras);
+ mCallingPackage.set(callingPkg);
+ try {
+ return ContentProvider.this.call(method, arg, extras);
+ } finally {
+ mCallingPackage.set(null);
+ }
}
@Override
@@ -290,8 +338,13 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType,
Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
enforceFilePermission(callingPkg, uri, "r");
- return ContentProvider.this.openTypedAssetFile(
- uri, mimeType, opts, CancellationSignal.fromTransport(cancellationSignal));
+ mCallingPackage.set(callingPkg);
+ try {
+ return ContentProvider.this.openTypedAssetFile(
+ uri, mimeType, opts, CancellationSignal.fromTransport(cancellationSignal));
+ } finally {
+ mCallingPackage.set(null);
+ }
}
@Override
@@ -461,6 +514,28 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
}
/**
+ * Return the package name of the caller that initiated the request being
+ * processed on the current thread. The returned package will have been
+ * verified to belong to the calling UID. Returns {@code null} if not
+ * currently processing a request.
+ * <p>
+ * This will always return {@code null} when processing
+ * {@link #getType(Uri)} or {@link #getStreamTypes(Uri, String)} requests.
+ *
+ * @see Binder#getCallingUid()
+ * @see Context#grantUriPermission(String, Uri, int)
+ * @throws SecurityException if the calling package doesn't belong to the
+ * calling UID.
+ */
+ public final String getCallingPackage() {
+ final String pkg = mCallingPackage.get();
+ if (pkg != null) {
+ mTransport.mAppOpsManager.checkPackage(Binder.getCallingUid(), pkg);
+ }
+ return pkg;
+ }
+
+ /**
* Change the permission required to read data from the content
* provider. This is normally set for you from its manifest information
* when the provider is first created.
@@ -529,8 +604,6 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
/** @hide */
public final void setAppOps(int readOp, int writeOp) {
if (!mNoPerms) {
- mTransport.mAppOpsManager = (AppOpsManager)mContext.getSystemService(
- Context.APP_OPS_SERVICE);
mTransport.mReadOp = readOp;
mTransport.mWriteOp = writeOp;
}
@@ -1413,6 +1486,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
*/
if (mContext == null) {
mContext = context;
+ mTransport.mAppOpsManager = (AppOpsManager) mContext.getSystemService(
+ Context.APP_OPS_SERVICE);
mMyUid = Process.myUid();
if (info != null) {
setReadPermission(info.readPermission);
@@ -1452,15 +1527,6 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
}
/**
- * @hide
- * Front-end to {@link #call(String, String, android.os.Bundle)} that provides the name
- * of the calling package.
- */
- public Bundle callFromPackage(String callingPackag, String method, String arg, Bundle extras) {
- return call(method, arg, extras);
- }
-
- /**
* Call a provider-defined method. This can be used to implement
* interfaces that are cheaper and/or unnatural for a table-like
* model.
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 13b6cfb9faf9..5333a250ccdd 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -72,7 +72,9 @@ public final class DocumentsContract {
public static final String META_DATA_DOCUMENT_PROVIDER = "android.content.DOCUMENT_PROVIDER";
/** {@hide} */
- public static final String ACTION_MANAGE_DOCUMENTS = "android.provider.action.MANAGE_DOCUMENTS";
+ public static final String ACTION_MANAGE_ROOT = "android.provider.action.MANAGE_ROOT";
+ /** {@hide} */
+ public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";
/**
* Constants related to a document, including {@link Cursor} columns names
@@ -346,6 +348,9 @@ public final class DocumentsContract {
*/
public static final String COLUMN_MIME_TYPES = "mime_types";
+ /** {@hide} */
+ public static final String MIME_TYPE_ITEM = "vnd.android.document/root";
+
/**
* Type of root that represents a storage service, such as a cloud-based
* service.
@@ -462,6 +467,17 @@ public final class DocumentsContract {
}
/**
+ * Build Uri representing the given {@link Root#COLUMN_ROOT_ID} in a
+ * document provider.
+ *
+ * @see #getRootId(Uri)
+ */
+ public static Uri buildRootUri(String authority, String rootId) {
+ return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ .authority(authority).appendPath(PATH_ROOT).appendPath(rootId).build();
+ }
+
+ /**
* Build Uri representing the recently modified documents of a specific
* root. When queried, a provider will return zero or more rows with columns
* defined by {@link Document}.
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 07cb2a91e7bd..1b0fc4d1f70d 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -34,7 +34,6 @@ import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.graphics.Point;
import android.net.Uri;
-import android.os.Binder;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
@@ -42,8 +41,6 @@ import android.os.ParcelFileDescriptor.OnCloseListener;
import android.provider.DocumentsContract.Document;
import android.util.Log;
-import com.android.internal.util.ArrayUtils;
-
import libcore.io.IoUtils;
import java.io.FileNotFoundException;
@@ -75,11 +72,12 @@ import java.io.FileNotFoundException;
public abstract class DocumentsProvider extends ContentProvider {
private static final String TAG = "DocumentsProvider";
- private static final int MATCH_ROOT = 1;
- private static final int MATCH_RECENT = 2;
- private static final int MATCH_DOCUMENT = 3;
- private static final int MATCH_CHILDREN = 4;
- private static final int MATCH_SEARCH = 5;
+ private static final int MATCH_ROOTS = 1;
+ private static final int MATCH_ROOT = 2;
+ private static final int MATCH_RECENT = 3;
+ private static final int MATCH_DOCUMENT = 4;
+ private static final int MATCH_CHILDREN = 5;
+ private static final int MATCH_SEARCH = 6;
private String mAuthority;
@@ -93,7 +91,8 @@ public abstract class DocumentsProvider extends ContentProvider {
mAuthority = info.authority;
mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
- mMatcher.addURI(mAuthority, "root", MATCH_ROOT);
+ mMatcher.addURI(mAuthority, "root", MATCH_ROOTS);
+ mMatcher.addURI(mAuthority, "root/*", MATCH_ROOT);
mMatcher.addURI(mAuthority, "root/*/recent", MATCH_RECENT);
mMatcher.addURI(mAuthority, "document/*", MATCH_DOCUMENT);
mMatcher.addURI(mAuthority, "document/*/children", MATCH_CHILDREN);
@@ -256,7 +255,7 @@ public abstract class DocumentsProvider extends ContentProvider {
String[] selectionArgs, String sortOrder) {
try {
switch (mMatcher.match(uri)) {
- case MATCH_ROOT:
+ case MATCH_ROOTS:
return queryRoots(projection);
case MATCH_RECENT:
return queryRecentDocuments(getRootId(uri), projection);
@@ -285,6 +284,8 @@ public abstract class DocumentsProvider extends ContentProvider {
public final String getType(Uri uri) {
try {
switch (mMatcher.match(uri)) {
+ case MATCH_ROOT:
+ return DocumentsContract.Root.MIME_TYPE_ITEM;
case MATCH_DOCUMENT:
return getDocumentType(getDocumentId(uri));
default:
@@ -328,15 +329,22 @@ public abstract class DocumentsProvider extends ContentProvider {
throw new UnsupportedOperationException("Update not supported");
}
- /** {@hide} */
+ /**
+ * Implementation is provided by the parent class. Can be overridden to
+ * provide additional functionality, but subclasses <em>must</em> always
+ * call the superclass. If the superclass returns {@code null}, the subclass
+ * may implement custom behavior.
+ *
+ * @see #openDocument(String, String, CancellationSignal)
+ * @see #deleteDocument(String)
+ */
@Override
- public final Bundle callFromPackage(
- String callingPackage, String method, String arg, Bundle extras) {
+ public Bundle call(String method, String arg, Bundle extras) {
final Context context = getContext();
if (!method.startsWith("android:")) {
// Let non-platform methods pass through
- return super.callFromPackage(callingPackage, method, arg, extras);
+ return super.call(method, arg, extras);
}
final String documentId = extras.getString(Document.COLUMN_DOCUMENT_ID);
@@ -364,7 +372,7 @@ public abstract class DocumentsProvider extends ContentProvider {
if (!callerHasManage) {
final Uri newDocumentUri = DocumentsContract.buildDocumentUri(
mAuthority, newDocumentId);
- context.grantUriPermission(callingPackage, newDocumentUri,
+ context.grantUriPermission(getCallingPackage(), newDocumentUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
| Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index b798a1a55b34..90566415b89d 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -23,6 +23,7 @@ interface IAppOpsService {
// These first methods are also called by native code, so must
// be kept in sync with frameworks/native/include/binder/IAppOpsService.h
int checkOperation(int code, int uid, String packageName);
+ int checkPackage(int uid, String packageName);
int noteOperation(int code, int uid, String packageName);
int startOperation(IBinder token, int code, int uid, String packageName);
void finishOperation(IBinder token, int code, int uid, String packageName);
diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml
index 45e26508494f..4c91bd3fcde8 100644
--- a/packages/DocumentsUI/AndroidManifest.xml
+++ b/packages/DocumentsUI/AndroidManifest.xml
@@ -30,11 +30,10 @@
<category android:name="android.intent.category.OPENABLE" />
<data android:mimeType="*/*" />
</intent-filter>
- <!-- data expected to point at existing root to manage -->
<intent-filter>
- <action android:name="android.provider.action.MANAGE_DOCUMENTS" />
+ <action android:name="android.provider.action.MANAGE_ROOT" />
<category android:name="android.intent.category.DEFAULT" />
- <data android:mimeType="vnd.android.document/directory" />
+ <data android:mimeType="vnd.android.document/root" />
</intent-filter>
</activity>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 4da6567ae6a6..8715055c7d8c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -145,7 +145,7 @@ public class DocumentsActivity extends Activity {
mState.action = ACTION_CREATE;
} else if (Intent.ACTION_GET_CONTENT.equals(action)) {
mState.action = ACTION_GET_CONTENT;
- } else if (DocumentsContract.ACTION_MANAGE_DOCUMENTS.equals(action)) {
+ } else if (DocumentsContract.ACTION_MANAGE_ROOT.equals(action)) {
mState.action = ACTION_MANAGE;
}
@@ -171,12 +171,13 @@ public class DocumentsActivity extends Activity {
}
if (mState.action == ACTION_MANAGE) {
- final Uri rootUri = intent.getData();
- final RootInfo root = mRoots.findRoot(rootUri);
+ final Uri uri = intent.getData();
+ final String rootId = DocumentsContract.getRootId(uri);
+ final RootInfo root = mRoots.getRoot(uri.getAuthority(), rootId);
if (root != null) {
onRootPicked(root, true);
} else {
- Log.w(TAG, "Failed to find root: " + rootUri);
+ Log.w(TAG, "Failed to find root: " + uri);
finish();
}
@@ -626,14 +627,24 @@ public class DocumentsActivity extends Activity {
// Replace selected file
SaveFragment.get(fm).setReplaceTarget(doc);
} else if (mState.action == ACTION_MANAGE) {
- // Open the document
- final Intent intent = new Intent(Intent.ACTION_VIEW);
- intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- intent.setData(doc.uri);
+ // First try managing the document; we expect manager to filter
+ // based on authority, so we don't grant.
+ final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT);
+ manage.setData(doc.uri);
+
try {
- startActivity(intent);
+ startActivity(manage);
} catch (ActivityNotFoundException ex) {
- Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
+ // Fall back to viewing
+ final Intent view = new Intent(Intent.ACTION_VIEW);
+ view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ view.setData(doc.uri);
+
+ try {
+ startActivity(view);
+ } catch (ActivityNotFoundException ex2) {
+ Toast.makeText(this, R.string.toast_no_application, Toast.LENGTH_SHORT).show();
+ }
}
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
index c65464a1e1d4..85d0988514c0 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/MimePredicate.java
@@ -16,13 +16,9 @@
package com.android.documentsui;
-import android.util.Log;
-
import com.android.documentsui.model.DocumentInfo;
import com.android.internal.util.Predicate;
-import java.util.Arrays;
-
public class MimePredicate implements Predicate<DocumentInfo> {
private final String[] mFilters;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index a5dab33d0fdf..bc02b0db1e43 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -567,8 +567,7 @@ public class SettingsProvider extends ContentProvider {
* Fast path that avoids the use of chatty remoted Cursors.
*/
@Override
- public Bundle callFromPackage(String callingPackage, String method, String request,
- Bundle args) {
+ public Bundle call(String method, String request, Bundle args) {
int callingUser = UserHandle.getCallingUserId();
if (args != null) {
int reqUser = args.getInt(Settings.CALL_METHOD_USER_KEY, callingUser);
@@ -623,7 +622,7 @@ public class SettingsProvider extends ContentProvider {
// Also need to take care of app op.
if (getAppOpsManager().noteOp(AppOpsManager.OP_WRITE_SETTINGS, Binder.getCallingUid(),
- callingPackage) != AppOpsManager.MODE_ALLOWED) {
+ getCallingPackage()) != AppOpsManager.MODE_ALLOWED) {
return null;
}
diff --git a/services/java/com/android/server/AppOpsService.java b/services/java/com/android/server/AppOpsService.java
index 7af95f3f84e6..c6c4a94177b4 100644
--- a/services/java/com/android/server/AppOpsService.java
+++ b/services/java/com/android/server/AppOpsService.java
@@ -552,6 +552,17 @@ public class AppOpsService extends IAppOpsService.Stub {
}
@Override
+ public int checkPackage(int uid, String packageName) {
+ synchronized (this) {
+ if (getOpsLocked(uid, packageName, true) != null) {
+ return AppOpsManager.MODE_ALLOWED;
+ } else {
+ return AppOpsManager.MODE_ERRORED;
+ }
+ }
+ }
+
+ @Override
public int noteOperation(int code, int uid, String packageName) {
verifyIncomingUid(uid);
verifyIncomingOp(code);
@@ -560,7 +571,7 @@ public class AppOpsService extends IAppOpsService.Stub {
if (ops == null) {
if (DEBUG) Log.d(TAG, "noteOperation: no op for code " + code + " uid " + uid
+ " package " + packageName);
- return AppOpsManager.MODE_IGNORED;
+ return AppOpsManager.MODE_ERRORED;
}
Op op = getOpLocked(ops, code, true);
if (op.duration == -1) {
@@ -594,7 +605,7 @@ public class AppOpsService extends IAppOpsService.Stub {
if (ops == null) {
if (DEBUG) Log.d(TAG, "startOperation: no op for code " + code + " uid " + uid
+ " package " + packageName);
- return AppOpsManager.MODE_IGNORED;
+ return AppOpsManager.MODE_ERRORED;
}
Op op = getOpLocked(ops, code, true);
final int switchCode = AppOpsManager.opToSwitch(code);
diff --git a/services/java/com/android/server/DropBoxManagerService.java b/services/java/com/android/server/DropBoxManagerService.java
index 5008270db770..29b04da9c564 100644
--- a/services/java/com/android/server/DropBoxManagerService.java
+++ b/services/java/com/android/server/DropBoxManagerService.java
@@ -24,6 +24,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.ContentObserver;
import android.net.Uri;
+import android.os.Binder;
import android.os.Debug;
import android.os.DropBoxManager;
import android.os.FileUtils;
@@ -265,8 +266,13 @@ public final class DropBoxManagerService extends IDropBoxManagerService.Stub {
}
public boolean isTagEnabled(String tag) {
- return !"disabled".equals(Settings.Global.getString(
- mContentResolver, Settings.Global.DROPBOX_TAG_PREFIX + tag));
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return !"disabled".equals(Settings.Global.getString(
+ mContentResolver, Settings.Global.DROPBOX_TAG_PREFIX + tag));
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
public synchronized DropBoxManager.Entry getNextEntry(String tag, long millis) {