summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/ActivityManagerNative.java23
-rw-r--r--core/java/android/app/ActivityThread.java28
-rw-r--r--core/java/android/app/ContextImpl.java15
-rw-r--r--core/java/android/app/IActivityManager.java9
-rw-r--r--core/java/android/content/ContentProvider.java6
-rw-r--r--core/java/android/content/ContentResolver.java58
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) {