Merge changes I7277880e,Ia5584bd6 into klp-dev
* changes: Provide calling package to ContentProviders. Separate root and document management.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -615,6 +615,23 @@ public class AppOpsManager {
|
||||
return MODE_IGNORED;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
@@ -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
|
||||
@@ -460,6 +513,28 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -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);
|
||||
@@ -1451,15 +1526,6 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
||||
@@ -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.
|
||||
@@ -461,6 +466,17 @@ public final class DocumentsContract {
|
||||
.authority(authority).appendPath(PATH_ROOT).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -551,6 +551,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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user