// 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. ContentProviderHolderholder=null; try { holder = ActivityManager.getService().getContentProvider( getApplicationThread(), auth, userId, stable); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } if (holder == null) { Slog.e(TAG, "Failed to find provider info for " + auth); returnnull; }
// 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; }
// CloseGuard defaults to true and can be quite spammy. We // disable it here, but selectively enable it later (via // StrictMode) on debug builds, but using DropBox, not logs. CloseGuard.setEnabled(false);
Environment.initForCurrentUser();
// Set the reporter for event logging in libcore EventLogger.setReporter(newEventLoggingReporter());
// Make sure TrustedCertificateStore looks in the right place for CA certificates finalFileconfigDir= Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir);
// If the app is being launched for full backup or restore, bring it up in // a restricted environment with the base application class. app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app;
** 启动当前进程的ContentProvider并调用其onCreate方法 **
1 2 3 4 5 6 7 8 9 10
// don't bring up providers in restricted mode; they may depend on the // app's custom Application class if (!data.restrictedBackupMode) { if (!ArrayUtils.isEmpty(data.providers)) { installContentProviders(app, data.providers); // For process that contains content providers, we want to // ensure that the JIT is enabled "at some point". mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); } }
final java.lang.ClassLoadercl= c.getClassLoader(); localProvider = (ContentProvider)cl.loadClass(info.name).newInstance(); provider = localProvider.getIContentProvider(); // XXX Need to create the correct context for this provider. localProvider.attachInfo(c, info);
/* * Only allow it to be set once, so after the content service gives * this to us clients can't change it. */ if (mContext == null) { mContext = context; if (context != null) { mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService( Context.APP_OPS_SERVICE); } mMyUid = Process.myUid(); if (info != null) { setReadPermission(info.readPermission); setWritePermission(info.writePermission); setPathPermissions(info.pathPermissions); mExported = info.exported; mSingleUser = (info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0; setAuthorities(info.authority); } ContentProvider.this.onCreate(); } }
// Do this after providers, since instrumentation tests generally start their // test thread at this point, and we don't want that racing. try { mInstrumentation.onCreate(data.instrumentationArgs); } catch (Exception e) { thrownewRuntimeException( "Exception thrown in onCreate() of " + data.instrumentationName + ": " + e.toString(), e); } try { mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { if (!mInstrumentation.onException(app, e)) { thrownewRuntimeException( "Unable to create application " + app.getClass().getName() + ": " + e.toString(), e); } }
@Override public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection, @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) { validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { // The caller has no access to the data, so return an empty cursor with // the columns in the requested order. The caller may ask for an invalid // column and we would not catch that but this is not a problem in practice. // We do not call ContentProvider#query with a modified where clause since // the implementation is not guaranteed to be backed by a SQL database, hence // it may not handle properly the tautology where clause we would have created. if (projection != null) { returnnewMatrixCursor(projection, 0); }
// Null projection means all columns but we have no idea which they are. // However, the caller may be expecting to access them my index. Hence, // we have to execute the query as if allowed to get a cursor with the // columns. We then use the column names to return an empty cursor. Cursorcursor= ContentProvider.this.query( uri, projection, queryArgs, CancellationSignal.fromTransport(cancellationSignal)); if (cursor == null) { returnnull; }
// Return an empty cursor for all columns. returnnewMatrixCursor(cursor.getColumnNames(), 0); } finalStringoriginal= setCallingPackage(callingPkg); try { return ContentProvider.this.query( uri, projection, queryArgs, CancellationSignal.fromTransport(cancellationSignal)); } finally { setCallingPackage(original); } }