diff options
Diffstat (limited to 'core/java')
-rw-r--r-- | core/java/android/app/ActivityManagerNative.java | 23 | ||||
-rw-r--r-- | core/java/android/app/ActivityThread.java | 28 | ||||
-rw-r--r-- | core/java/android/app/ContextImpl.java | 15 | ||||
-rw-r--r-- | core/java/android/app/IActivityManager.java | 9 | ||||
-rw-r--r-- | core/java/android/content/ContentProvider.java | 6 | ||||
-rw-r--r-- | core/java/android/content/ContentResolver.java | 58 |
6 files changed, 115 insertions, 24 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index a180837..89812ab 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1272,6 +1272,15 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case GET_PROVIDER_MIME_TYPE_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + Uri uri = Uri.CREATOR.createFromParcel(data); + String type = getProviderMimeType(uri); + reply.writeNoException(); + reply.writeString(type); + return true; + } + case NEW_URI_PERMISSION_OWNER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String name = data.readString(); @@ -2847,6 +2856,20 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } + public String getProviderMimeType(Uri uri) + throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + uri.writeToParcel(data, 0); + mRemote.transact(GET_PROVIDER_MIME_TYPE_TRANSACTION, data, reply, 0); + reply.readException(); + String res = reply.readString(); + data.recycle(); + reply.recycle(); + return res; + } + public IBinder newUriPermissionOwner(String name) throws RemoteException { Parcel data = Parcel.obtain(); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 6d1bf96..a10a823 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3287,12 +3287,20 @@ public final class ActivityThread { } } - private final IContentProvider getProvider(Context context, String name) { + private final IContentProvider getExistingProvider(Context context, String name) { synchronized(mProviderMap) { final ProviderClientRecord pr = mProviderMap.get(name); if (pr != null) { return pr.mProvider; } + return null; + } + } + + private final IContentProvider getProvider(Context context, String name) { + IContentProvider existing = getExistingProvider(context, name); + if (existing != null) { + return existing; } IActivityManager.ContentProviderHolder holder = null; @@ -3337,6 +3345,22 @@ public final class ActivityThread { return provider; } + public final IContentProvider acquireExistingProvider(Context c, String name) { + IContentProvider provider = getExistingProvider(c, name); + if(provider == null) + return null; + IBinder jBinder = provider.asBinder(); + synchronized(mProviderMap) { + ProviderRefCount prc = mProviderRefCountMap.get(jBinder); + if(prc == null) { + mProviderRefCountMap.put(jBinder, new ProviderRefCount(1)); + } else { + prc.count++; + } //end else + } //end synchronized + return provider; + } + public final boolean releaseProvider(IContentProvider provider) { if(provider == null) { return false; @@ -3345,7 +3369,7 @@ public final class ActivityThread { synchronized(mProviderMap) { ProviderRefCount prc = mProviderRefCountMap.get(jBinder); if(prc == null) { - if(localLOGV) Slog.v(TAG, "releaseProvider::Weird shouldnt be here"); + if(localLOGV) Slog.v(TAG, "releaseProvider::Weird shouldn't be here"); return false; } else { prc.count--; diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 09ef710..1bbf9ea 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1626,22 +1626,23 @@ class ContextImpl extends Context { // ---------------------------------------------------------------------- private static final class ApplicationContentResolver extends ContentResolver { - public ApplicationContentResolver(Context context, - ActivityThread mainThread) - { + public ApplicationContentResolver(Context context, ActivityThread mainThread) { super(context); mMainThread = mainThread; } @Override - protected IContentProvider acquireProvider(Context context, String name) - { + protected IContentProvider acquireProvider(Context context, String name) { return mMainThread.acquireProvider(context, name); } @Override - public boolean releaseProvider(IContentProvider provider) - { + protected IContentProvider acquireExistingProvider(Context context, String name) { + return mMainThread.acquireExistingProvider(context, name); + } + + @Override + public boolean releaseProvider(IContentProvider provider) { return mMainThread.releaseProvider(provider); } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index f9bd461..28af0d3 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -313,6 +313,8 @@ public interface IActivityManager extends IInterface { public void crashApplication(int uid, int initialPid, String packageName, String message) throws RemoteException; + + public String getProviderMimeType(Uri uri) throws RemoteException; public IBinder newUriPermissionOwner(String name) throws RemoteException; public void grantUriPermissionFromOwner(IBinder owner, int fromUid, String targetPkg, @@ -526,7 +528,8 @@ 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; + int GET_PROVIDER_MIME_TYPE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+114; + int NEW_URI_PERMISSION_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+115; + int GRANT_URI_PERMISSION_FROM_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+116; + int REVOKE_URI_PERMISSION_FROM_OWNER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+117; } diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index dc4e9c4..1d6e8b8 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -544,6 +544,12 @@ public abstract class ContentProvider implements ComponentCallbacks { * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals: * Processes and Threads</a>. * + * <p>Note that there are no permissions needed for an application to + * access this information; if your content provider requires read and/or + * write permissions, or is not exported, all applications can still call + * this method regardless of their access permissions. This allows them + * to retrieve the MIME type for a URI when dispatching intents. + * * @param uri the URI to query. * @return a MIME type string, or null if there is no type. */ diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index 69f7611..81ff414 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -17,6 +17,7 @@ package android.content; import android.accounts.Account; +import android.app.ActivityManagerNative; import android.app.ActivityThread; import android.app.AppGlobals; import android.content.pm.PackageManager.NameNotFoundException; @@ -176,6 +177,12 @@ public abstract class ContentResolver { /** @hide */ protected abstract IContentProvider acquireProvider(Context c, String name); + /** Providing a default implementation of this, to avoid having to change + * a lot of other things, but implementations of ContentResolver should + * implement it. @hide */ + protected IContentProvider acquireExistingProvider(Context c, String name) { + return acquireProvider(c, name); + } /** @hide */ public abstract boolean releaseProvider(IContentProvider icp); @@ -186,20 +193,29 @@ public abstract class ContentResolver { * using the content:// scheme. * @return A MIME type for the content, or null if the URL is invalid or the type is unknown */ - public final String getType(Uri url) - { - IContentProvider provider = acquireProvider(url); - if (provider == null) { + public final String getType(Uri url) { + IContentProvider provider = acquireExistingProvider(url); + if (provider != null) { + try { + return provider.getType(url); + } catch (RemoteException e) { + return null; + } catch (java.lang.Exception e) { + return null; + } finally { + releaseProvider(provider); + } + } + + if (!SCHEME_CONTENT.equals(url.getScheme())) { return null; } + try { - return provider.getType(url); + String type = ActivityManagerNative.getDefault().getProviderMimeType(url); + return type; } catch (RemoteException e) { return null; - } catch (java.lang.Exception e) { - return null; - } finally { - releaseProvider(provider); } } @@ -717,14 +733,13 @@ public abstract class ContentResolver { } /** - * Returns the content provider for the given content URI.. + * Returns the content provider for the given content URI. * * @param uri The URI to a content provider * @return The ContentProvider for the given URI, or null if no content provider is found. * @hide */ - public final IContentProvider acquireProvider(Uri uri) - { + public final IContentProvider acquireProvider(Uri uri) { if (!SCHEME_CONTENT.equals(uri.getScheme())) { return null; } @@ -736,6 +751,25 @@ public abstract class ContentResolver { } /** + * Returns the content provider for the given content URI if the process + * already has a reference on it. + * + * @param uri The URI to a content provider + * @return The ContentProvider for the given URI, or null if no content provider is found. + * @hide + */ + public final IContentProvider acquireExistingProvider(Uri uri) { + if (!SCHEME_CONTENT.equals(uri.getScheme())) { + return null; + } + String auth = uri.getAuthority(); + if (auth != null) { + return acquireExistingProvider(mContext, uri.getAuthority()); + } + return null; + } + + /** * @hide */ public final IContentProvider acquireProvider(String name) { |