use of android.content.IContentProvider in project android_frameworks_base by crdroidandroid.
the class ActivityThread method acquireProvider.
public final IContentProvider acquireProvider(Context c, String auth, int userId, boolean stable) {
final ProviderKey key = new ProviderKey(auth, userId);
final IContentProvider provider = acquireExistingProvider(c, key, stable);
if (provider != null) {
return provider;
}
ProviderAcquiringCount pac;
synchronized (mProviderMap) {
pac = mProviderAcquiringCountMap.get(key);
if (pac == null) {
pac = new ProviderAcquiringCount(1);
mProviderAcquiringCountMap.put(key, pac);
} else {
pac.acquiringCount++;
}
}
// There is a possible race here. Another thread may try to acquire
// the same provider at the same time. When this happens, we want to ensure
// that the first one wins.
// Note that we cannot hold the lock while acquiring and installing the
// provider since it might take a long time to run and it could also potentially
// be re-entrant in the case where the provider is in the same process.
IActivityManager.ContentProviderHolder holder = null;
synchronized (pac) {
try {
holder = ActivityManagerNative.getDefault().getContentProvider(getApplicationThread(), auth, userId, stable);
} catch (RemoteException ex) {
}
}
synchronized (mProviderMap) {
if (--pac.acquiringCount == 0) {
mProviderAcquiringCountMap.remove(key);
}
}
if (holder == null) {
Slog.e(TAG, "Failed to find provider info for " + auth);
return null;
}
// Install provider will increment the reference count for us, and break
// any ties in the race.
holder = installProvider(c, holder, holder.info, true, /*noisy*/
holder.noReleaseNeeded, stable);
return holder.provider;
}
use of android.content.IContentProvider in project platform_frameworks_base by android.
the class ActivityManagerService method unstableProviderDied.
public void unstableProviderDied(IBinder connection) {
ContentProviderConnection conn;
try {
conn = (ContentProviderConnection) connection;
} catch (ClassCastException e) {
String msg = "refContentProvider: " + connection + " not a ContentProviderConnection";
Slog.w(TAG, msg);
throw new IllegalArgumentException(msg);
}
if (conn == null) {
throw new NullPointerException("connection is null");
}
// Safely retrieve the content provider associated with the connection.
IContentProvider provider;
synchronized (this) {
provider = conn.provider.provider;
}
if (provider == null) {
// Um, yeah, we're way ahead of you.
return;
}
// Make sure the caller is being honest with us.
if (provider.asBinder().pingBinder()) {
// Er, no, still looks good to us.
synchronized (this) {
Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() + " says " + conn + " died, but we don't agree");
return;
}
}
// Well look at that! It's dead!
synchronized (this) {
if (conn.provider.provider != provider) {
// But something changed... good enough.
return;
}
ProcessRecord proc = conn.provider.proc;
if (proc == null || proc.thread == null) {
// Seems like the process is already cleaned up.
return;
}
// As far as we're concerned, this is just like receiving a
// death notification... just a bit prematurely.
Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid + ") early provider death");
final long ident = Binder.clearCallingIdentity();
try {
appDiedLocked(proc);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
}
use of android.content.IContentProvider in project android_frameworks_base by ParanoidAndroid.
the class SettingsCmd method run.
public void run() {
boolean valid = false;
String arg;
try {
while ((arg = nextArg()) != null) {
if ("--user".equals(arg)) {
if (mUser != -1) {
// --user specified more than once; invalid
break;
}
mUser = Integer.parseInt(nextArg());
} else if (mVerb == CommandVerb.UNSPECIFIED) {
if ("get".equalsIgnoreCase(arg)) {
mVerb = CommandVerb.GET;
} else if ("put".equalsIgnoreCase(arg)) {
mVerb = CommandVerb.PUT;
} else {
// invalid
System.err.println("Invalid command: " + arg);
break;
}
} else if (mTable == null) {
if (!"system".equalsIgnoreCase(arg) && !"secure".equalsIgnoreCase(arg) && !"global".equalsIgnoreCase(arg)) {
System.err.println("Invalid namespace '" + arg + "'");
// invalid
break;
}
mTable = arg.toLowerCase();
} else if (mVerb == CommandVerb.GET) {
mKey = arg;
if (mNextArg >= mArgs.length) {
valid = true;
} else {
System.err.println("Too many arguments");
}
break;
} else if (mKey == null) {
mKey = arg;
// keep going; there's another PUT arg
} else {
// PUT, final arg
mValue = arg;
if (mNextArg >= mArgs.length) {
valid = true;
} else {
System.err.println("Too many arguments");
}
break;
}
}
} catch (Exception e) {
valid = false;
}
if (valid) {
if (mUser < 0) {
mUser = UserHandle.USER_OWNER;
}
try {
IActivityManager activityManager = ActivityManagerNative.getDefault();
IContentProvider provider = null;
IBinder token = new Binder();
try {
ContentProviderHolder holder = activityManager.getContentProviderExternal("settings", UserHandle.USER_OWNER, token);
if (holder == null) {
throw new IllegalStateException("Could not find settings provider");
}
provider = holder.provider;
switch(mVerb) {
case GET:
System.out.println(getForUser(provider, mUser, mTable, mKey));
break;
case PUT:
putForUser(provider, mUser, mTable, mKey, mValue);
break;
default:
System.err.println("Unspecified command");
break;
}
} finally {
if (provider != null) {
activityManager.removeContentProviderExternal("settings", token);
}
}
} catch (Exception e) {
System.err.println("Error while accessing settings provider");
e.printStackTrace();
}
} else {
printUsage();
}
}
use of android.content.IContentProvider in project android_frameworks_base by ParanoidAndroid.
the class ActivityThread method acquireExistingProvider.
public final IContentProvider acquireExistingProvider(Context c, String auth, int userId, boolean stable) {
synchronized (mProviderMap) {
final ProviderKey key = new ProviderKey(auth, userId);
final ProviderClientRecord pr = mProviderMap.get(key);
if (pr == null) {
return null;
}
IContentProvider provider = pr.mProvider;
IBinder jBinder = provider.asBinder();
if (!jBinder.isBinderAlive()) {
// The hosting process of the provider has died; we can't
// use this one.
Log.i(TAG, "Acquiring provider " + auth + " for user " + userId + ": existing object's process dead");
handleUnstableProviderDiedLocked(jBinder, true);
return null;
}
// Only increment the ref count if we have one. If we don't then the
// provider is not reference counted and never needs to be released.
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if (prc != null) {
incProviderRefLocked(prc, stable);
}
return provider;
}
}
use of android.content.IContentProvider in project android_frameworks_base by ParanoidAndroid.
the class ActivityThread method installProvider.
/**
* Installs the provider.
*
* Providers that are local to the process or that come from the system server
* may be installed permanently which is indicated by setting noReleaseNeeded to true.
* Other remote providers are reference counted. The initial reference count
* for all reference counted providers is one. Providers that are not reference
* counted do not have a reference count (at all).
*
* This method detects when a provider has already been installed. When this happens,
* it increments the reference count of the existing provider (if appropriate)
* and returns the existing provider. This can happen due to concurrent
* attempts to acquire the same provider.
*/
private IActivityManager.ContentProviderHolder installProvider(Context context, IActivityManager.ContentProviderHolder holder, ProviderInfo info, boolean noisy, boolean noReleaseNeeded, boolean stable) {
ContentProvider localProvider = null;
IContentProvider provider;
if (holder == null || holder.provider == null) {
if (DEBUG_PROVIDER || noisy) {
Slog.d(TAG, "Loading provider " + info.authority + ": " + info.name);
}
Context c = null;
ApplicationInfo ai = info.applicationInfo;
if (context.getPackageName().equals(ai.packageName)) {
c = context;
} else if (mInitialApplication != null && mInitialApplication.getPackageName().equals(ai.packageName)) {
c = mInitialApplication;
} else {
try {
c = context.createPackageContext(ai.packageName, Context.CONTEXT_INCLUDE_CODE);
} catch (PackageManager.NameNotFoundException e) {
// Ignore
}
}
if (c == null) {
Slog.w(TAG, "Unable to get context for package " + ai.packageName + " while loading content provider " + info.name);
return null;
}
try {
final java.lang.ClassLoader cl = c.getClassLoader();
localProvider = (ContentProvider) cl.loadClass(info.name).newInstance();
provider = localProvider.getIContentProvider();
if (provider == null) {
Slog.e(TAG, "Failed to instantiate class " + info.name + " from sourceDir " + info.applicationInfo.sourceDir);
return null;
}
if (DEBUG_PROVIDER)
Slog.v(TAG, "Instantiating local provider " + info.name);
// XXX Need to create the correct context for this provider.
localProvider.attachInfo(c, info);
} catch (java.lang.Exception e) {
if (!mInstrumentation.onException(null, e)) {
throw new RuntimeException("Unable to get provider " + info.name + ": " + e.toString(), e);
}
return null;
}
} else {
provider = holder.provider;
if (DEBUG_PROVIDER)
Slog.v(TAG, "Installing external provider " + info.authority + ": " + info.name);
}
IActivityManager.ContentProviderHolder retHolder;
synchronized (mProviderMap) {
if (DEBUG_PROVIDER)
Slog.v(TAG, "Checking to add " + provider + " / " + info.name);
IBinder jBinder = provider.asBinder();
if (localProvider != null) {
ComponentName cname = new ComponentName(info.packageName, info.name);
ProviderClientRecord pr = mLocalProvidersByName.get(cname);
if (pr != null) {
if (DEBUG_PROVIDER) {
Slog.v(TAG, "installProvider: lost the race, " + "using existing local provider");
}
provider = pr.mProvider;
} else {
holder = new IActivityManager.ContentProviderHolder(info);
holder.provider = provider;
holder.noReleaseNeeded = true;
pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
mLocalProviders.put(jBinder, pr);
mLocalProvidersByName.put(cname, pr);
}
retHolder = pr.mHolder;
} else {
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
if (prc != null) {
if (DEBUG_PROVIDER) {
Slog.v(TAG, "installProvider: lost the race, updating ref count");
}
// system process).
if (!noReleaseNeeded) {
incProviderRefLocked(prc, stable);
try {
ActivityManagerNative.getDefault().removeContentProvider(holder.connection, stable);
} catch (RemoteException e) {
//do nothing content provider object is dead any way
}
}
} else {
ProviderClientRecord client = installProviderAuthoritiesLocked(provider, localProvider, holder);
if (noReleaseNeeded) {
prc = new ProviderRefCount(holder, client, 1000, 1000);
} else {
prc = stable ? new ProviderRefCount(holder, client, 1, 0) : new ProviderRefCount(holder, client, 0, 1);
}
mProviderRefCountMap.put(jBinder, prc);
}
retHolder = prc.holder;
}
}
return retHolder;
}
Aggregations