下面列出了android.content.pm.PackageParser#Provider() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
int flags, List<PackageParser.Provider> packageProviders, int userId) {
if (!sUserManager.exists(userId)) {
return null;
}
if (packageProviders == null) {
return null;
}
mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
final int providersSize = packageProviders.size();
ArrayList<PackageParser.ProviderIntentInfo[]> listCut = new ArrayList<>(providersSize);
ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
for (int i = 0; i < providersSize; ++i) {
intentFilters = packageProviders.get(i).intents;
if (intentFilters != null && intentFilters.size() > 0) {
PackageParser.ProviderIntentInfo[] array =
new PackageParser.ProviderIntentInfo[intentFilters.size()];
intentFilters.toArray(array);
listCut.add(array);
}
}
return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
}
@Override
public VParceledListSlice<ProviderInfo> queryContentProviders(String processName, int vuid, int flags) {
int userId = VUserHandle.getUserId(vuid);
checkUserId(userId);
ArrayList<ProviderInfo> finalList = new ArrayList<>(3);
// reader
synchronized (mPackages) {
for (PackageParser.Provider p : mProvidersByComponent.values()) {
AppSetting setting = (AppSetting) p.owner.mExtras;
if (processName == null || setting.appId == VUserHandle.getAppId(vuid) && p.info.processName.equals(processName)) {
ProviderInfo providerInfo = PackageParserCompat.generateProviderInfo(p, flags);
ComponentFixer.fixApplicationInfo(setting, providerInfo.applicationInfo, userId);
finalList.add(providerInfo);
}
}
}
if (!finalList.isEmpty()) {
Collections.sort(finalList, mProviderInitOrderSorter);
}
return new VParceledListSlice<>(finalList);
}
public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, int flags,
ArrayList<PackageParser.Provider> packageProviders) {
if (packageProviders == null) {
return null;
}
mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
final int N = packageProviders.size();
ArrayList<PackageParser.ProviderIntentInfo[]> listCut = new ArrayList<>(N);
ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
for (int i = 0; i < N; ++i) {
intentFilters = packageProviders.get(i).intents;
if (intentFilters != null && intentFilters.size() > 0) {
PackageParser.ProviderIntentInfo[] array = new PackageParser.ProviderIntentInfo[intentFilters
.size()];
intentFilters.toArray(array);
listCut.add(array);
}
}
return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut);
}
public List queryIntentForPackage(Intent intent, String resolvedType,
int flags, ArrayList<PackageParser.Provider> packageProviders) {
if (packageProviders == null) {
return null;
}
mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
int N = packageProviders.size();
ArrayList<ArrayList<PackageParser.ProviderIntentInfo>> listCut = new ArrayList<ArrayList<PackageParser.ProviderIntentInfo>>(
N);
ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
for (int i = 0; i < N; ++i) {
intentFilters = packageProviders.get(i).intents;
if (intentFilters != null && intentFilters.size() > 0) {
listCut.add(intentFilters);
}
}
return super.queryIntentFromList(intent, resolvedType, defaultOnly,
listCut);
}
ProviderInfo queryProvider(String authority, int flags, int userId) {
synchronized (mLock) {
final PackageParser.Provider p = mProvidersByAuthority.get(authority);
if (p == null) {
return null;
}
final PackageSetting ps = (PackageSetting) p.owner.mExtras;
if (ps == null) {
return null;
}
return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), userId);
}
}
@GuardedBy("mLock")
private void assertProvidersNotDefinedLocked(PackageParser.Package pkg)
throws PackageManagerException {
final int providersSize = pkg.providers.size();
int i;
for (i = 0; i < providersSize; i++) {
PackageParser.Provider p = pkg.providers.get(i);
if (p.info.authority != null) {
final String[] names = p.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
if (mProvidersByAuthority.containsKey(names[j])) {
final PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
final String otherPackageName =
(other != null && other.getComponentName() != null)
? other.getComponentName().getPackageName() : "?";
// if we're installing over the same already-installed package, this is ok
if (!otherPackageName.equals(pkg.packageName)) {
throw new PackageManagerException(
INSTALL_FAILED_CONFLICTING_PROVIDER,
"Can't install because provider name " + names[j]
+ " (in package " + pkg.applicationInfo.packageName
+ ") is already used by " + otherPackageName);
}
}
}
}
}
}
void addProvider(PackageParser.Provider p) {
if (mProviders.containsKey(p.getComponentName())) {
Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
return;
}
mProviders.put(p.getComponentName(), p);
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " "
+ (p.info.nonLocalizedLabel != null
? p.info.nonLocalizedLabel
: p.info.name)
+ ":");
Log.v(TAG, " Class=" + p.info.name);
}
final int intentsSize = p.intents.size();
int j;
for (j = 0; j < intentsSize; j++) {
PackageParser.ProviderIntentInfo intent = p.intents.get(j);
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " IntentFilter:");
intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
}
if (!intent.debugCheck()) {
Log.w(TAG, "==> For Provider " + p.info.name);
}
addFilter(intent);
}
}
public final void removeProvider(PackageParser.Provider p) {
mProviders.remove(p.getComponentName());
int NI = p.intents.size();
for (int j = 0; j < NI; j++) {
PackageParser.ProviderIntentInfo intent = p.intents.get(j);
removeFilter(intent);
}
}
protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
final PackageParser.Provider provider = (PackageParser.Provider) label;
out.print(prefix);
out.print(Integer.toHexString(System.identityHashCode(provider)));
out.print(' ');
provider.printComponentShortName(out);
if (count > 1) {
out.print(" (");
out.print(count);
out.print(" filters)");
}
out.println();
}
@Override
public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
checkUserId(userId);
synchronized (mPackages) {
PackageParser.Provider p = mProvidersByComponent.get(component);
if (p != null) {
ProviderInfo providerInfo = PackageParserCompat.generateProviderInfo(p, flags);
PackageParser.Package pkg = mPackages.get(providerInfo.packageName);
AppSetting settings = (AppSetting) pkg.mExtras;
ComponentFixer.fixComponentInfo(settings, providerInfo, userId);
return providerInfo;
}
}
return null;
}
@Override
public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
checkUserId(userId);
synchronized (mPackages) {
final PackageParser.Provider provider = mProvidersByAuthority.get(name);
if (provider != null) {
ProviderInfo providerInfo = PackageParserCompat.generateProviderInfo(provider, flags);
PackageParser.Package p = mPackages.get(providerInfo.packageName);
AppSetting settings = (AppSetting) p.mExtras;
ComponentFixer.fixComponentInfo(settings, providerInfo, userId);
return providerInfo;
}
}
return null;
}
@Override
protected boolean allowFilterResult(
PackageParser.ProviderIntentInfo filter, List<PackageParser.Provider> dest) {
for (int i = dest.size() - 1; i >= 0; i--) {
PackageParser.Provider destAi = dest.get(i);
if (destAi == filter.provider) {
return false;
}
}
return true;
}
public final void removeProvider(PackageParser.Provider p) {
mProviders.remove(p.getComponentName());
final int NI = p.intents.size();
int j;
for (j = 0; j < NI; j++) {
PackageParser.ProviderIntentInfo intent = p.intents.get(j);
removeFilter(intent);
}
}
public final void addProvider(PackageParser.Provider p) {
mProviders.put(p.getComponentName(), p);
int NI = p.intents.size();
for (int j = 0; j < NI; j++) {
PackageParser.ProviderIntentInfo intent = p.intents.get(j);
addFilter(intent);
}
}
/** Returns the given provider */
PackageParser.Provider getProvider(ComponentName component) {
synchronized (mLock) {
return mProviders.mProviders.get(component);
}
}
List<ResolveInfo> queryProviders(Intent intent, String resolvedType, int flags,
List<PackageParser.Provider> providers, int userId) {
synchronized (mLock) {
return mProviders.queryIntentForPackage(intent, resolvedType, flags, providers, userId);
}
}
@GuardedBy("mLock")
private void addProvidersLocked(PackageParser.Package pkg, boolean chatty) {
final int providersSize = pkg.providers.size();
StringBuilder r = null;
for (int i = 0; i < providersSize; i++) {
PackageParser.Provider p = pkg.providers.get(i);
p.info.processName = fixProcessName(pkg.applicationInfo.processName,
p.info.processName);
mProviders.addProvider(p);
p.syncable = p.info.isSyncable;
if (p.info.authority != null) {
String[] names = p.info.authority.split(";");
p.info.authority = null;
for (int j = 0; j < names.length; j++) {
if (j == 1 && p.syncable) {
// We only want the first authority for a provider to possibly be
// syncable, so if we already added this provider using a different
// authority clear the syncable flag. We copy the provider before
// changing it because the mProviders object contains a reference
// to a provider that we don't want to change.
// Only do this for the second authority since the resulting provider
// object can be the same for all future authorities for this provider.
p = new PackageParser.Provider(p);
p.syncable = false;
}
if (!mProvidersByAuthority.containsKey(names[j])) {
mProvidersByAuthority.put(names[j], p);
if (p.info.authority == null) {
p.info.authority = names[j];
} else {
p.info.authority = p.info.authority + ";" + names[j];
}
if (DEBUG_PACKAGE_SCANNING && chatty) {
Log.d(TAG, "Registered content provider: " + names[j]
+ ", className = " + p.info.name
+ ", isSyncable = " + p.info.isSyncable);
}
} else {
final PackageParser.Provider other =
mProvidersByAuthority.get(names[j]);
final ComponentName component =
(other != null && other.getComponentName() != null)
? other.getComponentName() : null;
final String packageName =
component != null ? component.getPackageName() : "?";
Slog.w(TAG, "Skipping provider name " + names[j]
+ " (in package " + pkg.applicationInfo.packageName + ")"
+ ": name already used by " + packageName);
}
}
}
if (DEBUG_PACKAGE_SCANNING && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
r.append(p.info.name);
}
}
if (DEBUG_PACKAGE_SCANNING && chatty) {
Log.d(TAG, " Providers: " + (r == null ? "<NONE>" : r));
}
}
public LoadedPlugin(PluginManager pluginManager, Context context, File apk) throws Exception {
this.mPluginManager = pluginManager;
this.mHostContext = context;
this.mLocation = apk.getAbsolutePath();
this.mPackage = PackageParserCompat.parsePackage(context, apk, PackageParser.PARSE_MUST_BE_APK);
this.mPackage.applicationInfo.metaData = this.mPackage.mAppMetaData;
this.mPackageInfo = new PackageInfo();
this.mPackageInfo.applicationInfo = this.mPackage.applicationInfo;
this.mPackageInfo.applicationInfo.sourceDir = apk.getAbsolutePath();
if (Build.VERSION.SDK_INT >= 28
|| (Build.VERSION.SDK_INT == 27 && Build.VERSION.PREVIEW_SDK_INT != 0)) { // Android P Preview
try {
this.mPackageInfo.signatures = this.mPackage.mSigningDetails.signatures;
} catch (Throwable e) {
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
this.mPackageInfo.signatures = info.signatures;
}
} else {
this.mPackageInfo.signatures = this.mPackage.mSignatures;
}
this.mPackageInfo.packageName = this.mPackage.packageName;
if (pluginManager.getLoadedPlugin(mPackageInfo.packageName) != null) {
throw new RuntimeException("plugin has already been loaded : " + mPackageInfo.packageName);
}
this.mPackageInfo.versionCode = this.mPackage.mVersionCode;
this.mPackageInfo.versionName = this.mPackage.mVersionName;
this.mPackageInfo.permissions = new PermissionInfo[0];
this.mPackageManager = createPluginPackageManager();
this.mPluginContext = createPluginContext(null);
this.mNativeLibDir = getDir(context, Constants.NATIVE_DIR);
this.mPackage.applicationInfo.nativeLibraryDir = this.mNativeLibDir.getAbsolutePath();
this.mResources = createResources(context, getPackageName(), apk);
this.mClassLoader = createClassLoader(context, apk, this.mNativeLibDir, context.getClassLoader());
tryToCopyNativeLib(apk);
// Cache instrumentations
Map<ComponentName, InstrumentationInfo> instrumentations = new HashMap<ComponentName, InstrumentationInfo>();
for (PackageParser.Instrumentation instrumentation : this.mPackage.instrumentation) {
instrumentations.put(instrumentation.getComponentName(), instrumentation.info);
}
this.mInstrumentationInfos = Collections.unmodifiableMap(instrumentations);
this.mPackageInfo.instrumentation = instrumentations.values().toArray(new InstrumentationInfo[instrumentations.size()]);
// Cache activities
Map<ComponentName, ActivityInfo> activityInfos = new HashMap<ComponentName, ActivityInfo>();
for (PackageParser.Activity activity : this.mPackage.activities) {
activity.info.metaData = activity.metaData;
activityInfos.put(activity.getComponentName(), activity.info);
}
this.mActivityInfos = Collections.unmodifiableMap(activityInfos);
this.mPackageInfo.activities = activityInfos.values().toArray(new ActivityInfo[activityInfos.size()]);
// Cache services
Map<ComponentName, ServiceInfo> serviceInfos = new HashMap<ComponentName, ServiceInfo>();
for (PackageParser.Service service : this.mPackage.services) {
serviceInfos.put(service.getComponentName(), service.info);
}
this.mServiceInfos = Collections.unmodifiableMap(serviceInfos);
this.mPackageInfo.services = serviceInfos.values().toArray(new ServiceInfo[serviceInfos.size()]);
// Cache providers
Map<String, ProviderInfo> providers = new HashMap<String, ProviderInfo>();
Map<ComponentName, ProviderInfo> providerInfos = new HashMap<ComponentName, ProviderInfo>();
for (PackageParser.Provider provider : this.mPackage.providers) {
providers.put(provider.info.authority, provider.info);
providerInfos.put(provider.getComponentName(), provider.info);
}
this.mProviders = Collections.unmodifiableMap(providers);
this.mProviderInfos = Collections.unmodifiableMap(providerInfos);
this.mPackageInfo.providers = providerInfos.values().toArray(new ProviderInfo[providerInfos.size()]);
// Register broadcast receivers dynamically
Map<ComponentName, ActivityInfo> receivers = new HashMap<ComponentName, ActivityInfo>();
for (PackageParser.Activity receiver : this.mPackage.receivers) {
receivers.put(receiver.getComponentName(), receiver.info);
BroadcastReceiver br = BroadcastReceiver.class.cast(getClassLoader().loadClass(receiver.getComponentName().getClassName()).newInstance());
for (PackageParser.ActivityIntentInfo aii : receiver.intents) {
this.mHostContext.registerReceiver(br, aii);
}
}
this.mReceiverInfos = Collections.unmodifiableMap(receivers);
this.mPackageInfo.receivers = receivers.values().toArray(new ActivityInfo[receivers.size()]);
// try to invoke plugin's application
invokeApplication();
}
@Override
protected PackageParser.Provider newResult(PackageParser.ProviderIntentInfo info,
int match) {
return info.provider;
}
/**
* 解析APK的manifest
*
* @param info
* 插件信息
*/
private void getPackageInfo(PluginInfo info) {
int flags = PackageManager.GET_ACTIVITIES | PackageManager.GET_CONFIGURATIONS
| PackageManager.GET_INSTRUMENTATION | PackageManager.GET_PERMISSIONS | PackageManager.GET_PROVIDERS
| PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES | PackageManager.GET_SIGNATURES;
// 需要获取Package对象,主要是处理隐式启动插件中的activity
PackageParser parser = new PackageParser(info.apkPath);
DisplayMetrics metrics = new DisplayMetrics();
metrics.setToDefaults();
File sourceFile = new File(info.apkPath);
PackageParser.Package pack = parser.parsePackage(sourceFile, info.apkPath, metrics, 0);
// 因为PackagePaser的generatePackageInfo方法不同版本参数相差太多,所以还是用packagemanager的api
// 但这样导致APK被解析了两次,上面获取Package是一次
PackageInfo packageInfo = mContext.getPackageManager().getPackageArchiveInfo(info.apkPath, flags);
info.packageName = packageInfo.packageName;
info.mPackageObj = pack;
info.mPackageInfo = packageInfo;
ArrayList<PackageParser.Activity> activitys = pack.activities;
int size = activitys.size();
for (int i = 0; i < size; i++) {
mActivitys.addActivity(activitys.get(i));
}
ArrayList<PackageParser.Service> services = pack.services;
size = services.size();
for (int i = 0; i < size; i++) {
mServices.addService(services.get(i));
}
ArrayList<PackageParser.Provider> providers = pack.providers;
size = providers.size();
for (int i = 0; i < size; i++) {
Provider p = providers.get(i);
String names[] = PATTERN_SEMICOLON.split(p.info.authority);
for (int j = 0; j < names.length; j++) {
mProviderInfoMap.put(names[i], p);
}
}
}