private static void preMakeApplication(Context hostContext, ComponentInfo pluginInfo) { try { Object loadedApk = sPluginLoadedApkCache.get(pluginInfo.packageName); if (loadedApk != null && FieldUtils.readField(loadedApk, "mApplication") == null) { if (Looper.getMainLooper() != Looper.myLooper()) { Object lock = new Object(); mExec.set(false); mHandle.post(new 1(loadedApk, pluginInfo, lock)); if (!mExec.get()) { synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { } } return; } return; } MethodUtils.invokeMethod(loadedApk, "makeApplication", Boolean.valueOf(false), ActivityThreadCompat.getInstrumentation()); } } catch (Exception e2) { JLog.logApk("插件preMakeApplication 失败 e=" + e2.getMessage()); } }
private void doAdjust(HashMap<String, String> processMap, HashMap<String, ? extends ComponentInfo> infos) throws Exception { for (HashMap.Entry<String, ? extends ComponentInfo> entry : infos.entrySet()) { ComponentInfo info = entry.getValue(); if (info != null) { String targetProcess = processMap.get(info.processName); // 如果原始进程名称为空,说明解析插件 apk 时有问题(未解析每个组件的进程名称)。 // 此处抛出异常。 if (!TextUtils.isEmpty(targetProcess)) { info.processName = targetProcess; } if (LOG) { Log.d(PLUGIN_TAG, info.name + ":" + info.processName); } } } }
public String getStubProcessByTarget(ComponentInfo targetInfo) { for (ProcessItem processItem : items.values()) { if (processItem.pkgs.contains(targetInfo.packageName) && TextUtils.equals(processItem.targetProcessName, targetInfo.processName)) { return processItem.stubProcessName; } else { try { boolean signed = false; for (String pkg : processItem.pkgs) { if (PluginManager.getInstance().checkSignatures(targetInfo.packageName, pkg) == PackageManager.SIGNATURE_MATCH) { signed = true; break; } } if (signed && TextUtils.equals(processItem.targetProcessName, targetInfo.processName)) { return processItem.stubProcessName; } } catch (Exception e) { Log.e(TAG, "getStubProcessByTarget:error", e); } } } return null; }
public String getStubProcessByTarget(ComponentInfo targetInfo) { for (ProcessItem processItem : items.values()) { if (processItem.pkgs.contains(targetInfo.packageName) && TextUtils.equals(processItem.targetProcessName, targetInfo.processName)) { return processItem.stubProcessName; } else { try { boolean signed = false; for (String pkg : processItem.pkgs) { if (PluginManager.getInstance().checkSignatures(targetInfo.packageName, pkg) == PackageManager.SIGNATURE_MATCH) { signed = true; break; } } if (signed && TextUtils.equals(processItem.targetProcessName, targetInfo.processName)) { return processItem.stubProcessName; } } catch (Exception e) { e.printStackTrace(); } } } return null; }
private boolean isDevicePlugin(final ComponentInfo compInfo) { if (!compInfo.exported) { return false; } Bundle metaData = compInfo.metaData; if (metaData == null) { return false; } if (metaData.get(PLUGIN_META_DATA) == null) { return false; } if (!(metaData.get(PLUGIN_META_DATA) instanceof Integer)) { return false; } DevicePluginXml xml = DevicePluginXmlUtil.getXml(mContext, compInfo); return xml != null; }
/** * <href a="http://developer.android.com/reference/android/content/pm/ComponentInfo.html">ComponentInfo</href> */ private static void parseComponentItem(XmlResourceParser parser, ComponentInfo info) { final int attCount = parser.getAttributeCount(); for (int i = 0; i < attCount; i++) { String attName = parser.getAttributeName(i); String attValue = parser.getAttributeValue(i); if (ATTR_PROCESS.equals(attName)) { String cName = attValue; info.processName = cName; } else if (ATTR_EXPORTED.equals(attName)) { info.exported = Boolean.parseBoolean(attName); } else if (ATTR_ENABLED.equals(attName)) { info.enabled = Boolean.parseBoolean(attName); } else if (ATTR_DESCRIPTION.equals(attName)) { info.descriptionRes = toResId(attValue); } } parsePackageItem(parser, info); }
@SuppressWarnings("deprecation") public static boolean isComponentEnabled(PackageManager manager, ComponentName component) { switch (manager.getComponentEnabledSetting(component)) { case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: return false; case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: return true; case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: default: try { PackageInfo packageInfo = manager.getPackageInfo( component.getPackageName(), PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS | PackageManager.GET_DISABLED_COMPONENTS); List<ComponentInfo> components = new ArrayList<>(); if (packageInfo.activities != null) { Collections.addAll(components, packageInfo.activities); } if (packageInfo.services != null) { Collections.addAll(components, packageInfo.services); } if (packageInfo.providers != null) { Collections.addAll(components, packageInfo.providers); } for (ComponentInfo componentInfo : components) { if (componentInfo.name.equals(component.getClassName())) { return componentInfo.isEnabled(); } } return false; } catch (PackageManager.NameNotFoundException e) { // the package isn't installed on the device return false; } } }
public static boolean isComponentEnabled(PackageManager pm, String pkg, String cls) { ComponentName componentName = new ComponentName(pkg, cls); int componentEnabledSetting = pm.getComponentEnabledSetting(componentName); switch (componentEnabledSetting) { case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: return false; case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: return true; case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: default: // We need to get the application info to get the component's default state try { PackageInfo packageInfo = pm.getPackageInfo(pkg, PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS | PackageManager.GET_DISABLED_COMPONENTS); List<ComponentInfo> components = new ArrayList<>(); if (packageInfo.activities != null) Collections.addAll(components, packageInfo.activities); if (packageInfo.services != null) Collections.addAll(components, packageInfo.services); if (packageInfo.providers != null) Collections.addAll(components, packageInfo.providers); for (ComponentInfo componentInfo : components) { if (componentInfo.name.equals(cls)) { return componentInfo.enabled; //This is the default value (set in AndroidManifest.xml) //return componentInfo.isEnabled(); //Whole package dependant } } // the component is not declared in the AndroidManifest return false; } catch (PackageManager.NameNotFoundException e) { // the package isn't installed on the device return false; } } }
private <T extends ComponentInfo> ResolveInfo queryIntentResolveInfo(Intent intent,Class<T> infoClass ){ if(intent==null){ return null; } AdditionalComponentIntentResolver resolver = null; if(infoClass == ActivityInfo.class){ resolver = mExternalActivity; }else{ resolver = mExternalServices; } if(resolver!=null) { ComponentName comp = intent.getComponent(); if (comp == null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { if (intent.getSelector() != null) { intent = intent.getSelector(); comp = intent.getComponent(); } } } if (comp != null) { Object obj = resolver.mComponents.get(comp); if (obj!=null){ try { final ResolveInfo ri = new ExternalResolverInfo(); if(resolver == mExternalActivity) { ri.activityInfo = (ActivityInfo) obj.getClass().getField("info").get(obj); }else{ ri.serviceInfo = (ServiceInfo) obj.getClass().getField("info").get(obj); } return ri; }catch(Exception e){ return null; } }else{ return null; } }else{ // 先检测包名 if (!TextUtils.isEmpty(intent.getPackage()) && !TextUtils.equals(intent.getPackage(), RuntimeVariables.androidApplication.getPackageName())) { return null; } List<ResolveInfo> list = resolver.queryIntent(intent, intent.resolveTypeIfNeeded(RuntimeVariables.androidApplication.getContentResolver()), false); if(list!=null && list.size()>0){ return new ExternalResolverInfo(list.get(0)); }else{ return null; } } }else{ return null; } }
public static String getProcessName(ComponentInfo componentInfo) { String processName = componentInfo.processName; if (processName == null) { processName = componentInfo.packageName; componentInfo.processName = processName; } return processName; }
public static boolean isSameComponent(ComponentInfo first, ComponentInfo second) { if (first != null && second != null) { String pkg1 = first.packageName + ""; String pkg2 = second.packageName + ""; String name1 = first.name + ""; String name2 = second.name + ""; return pkg1.equals(pkg2) && name1.equals(name2); } return false; }
public static void fixComponentInfo(PackageSetting setting, ComponentInfo info, int userId) { if (info != null) { if (TextUtils.isEmpty(info.processName)) { info.processName = info.packageName; } info.name = fixComponentClassName(info.packageName, info.name); if (info.processName == null) { info.processName = info.applicationInfo.processName; } } }
/** * 从 ComponentInfo 获取 插件名称 */ public static String getPluginName(ComponentInfo ci) { if (ci != null && ci.packageName != null) { int indexOfLastDot = ci.packageName.lastIndexOf("."); if (indexOfLastDot > 0) { return ci.packageName.substring(indexOfLastDot + 1); } } return ""; }
void setTargetProcessName(ComponentInfo stubInfo, ComponentInfo targetInfo) { for (ProcessItem item : items.values()) { if (TextUtils.equals(item.stubProcessName, stubInfo.processName)) { if (!item.pkgs.contains(targetInfo.packageName)) { item.pkgs.add(targetInfo.packageName); } item.targetProcessName = targetInfo.processName; } } }
public static void fixComponentInfo(AppSetting appSetting, ComponentInfo info, int userId) { if (info != null) { if (TextUtils.isEmpty(info.processName)) { info.processName = info.packageName; } fixApplicationInfo(appSetting, info.applicationInfo, userId); info.name = fixComponentClassName(info.packageName, info.name); if (info.processName == null) { info.processName = info.applicationInfo.processName; } } }
public Component(final ParseComponentArgs args, final ComponentInfo outInfo) { this(args, (PackageItemInfo)outInfo); if (args.outError[0] != null) { return; } if (args.processRes != 0) { CharSequence pname; if (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.FROYO) { // pname = args.sa.getNonConfigurationString(args.processRes, // Configuration.NATIVE_CONFIG_VERSION); pname = args.sa.getNonResourceString(args.processRes); } else { // Some older apps have been seen to use a resource reference // here that on older builds was ignored (with a warning). We // need to continue to do this for them so they don't break. pname = args.sa.getNonResourceString(args.processRes); } outInfo.processName = buildProcessName(owner.applicationInfo.packageName, owner.applicationInfo.processName, pname, args.sepProcesses, args.outError); } if (args.descriptionRes != 0) { outInfo.descriptionRes = args.sa.getResourceId(args.descriptionRes, 0); } outInfo.enabled = args.sa.getBoolean(args.enabledRes, true); }
public static boolean isComponentInfoMatch(ComponentInfo a, ComponentInfo b) { if (a == null && b == null) { return true; } else if (a != null && b != null) { return TextUtils.equals(a.name, b.name) && TextUtils.equals(a.packageName, b.packageName); } else { return false; } }
public static boolean containsComponent(Collection<? extends ComponentInfo> collection, ComponentInfo componentInfo) { Iterator<? extends ComponentInfo> iterator = collection.iterator(); while (iterator.hasNext()) { if (isComponentInfoMatch(iterator.next(), componentInfo)) { return true; } } return false; }
public static boolean removeComponent(Collection<? extends ComponentInfo> collection, ComponentInfo componentInfo) { Iterator<? extends ComponentInfo> iterator = collection.iterator(); while (iterator.hasNext()) { if (isComponentInfoMatch(iterator.next(), componentInfo)) { iterator.remove(); return true; } } return false; }
private ProcessInfo getOrCreateProcess(ComponentInfo componentInfo) { String processName = getProcessName(componentInfo.processName, componentInfo.packageName); ProcessInfo processInfo = mStubProcessInfoMap.get(processName); if (processInfo == null) { processInfo = new ProcessInfo(processName); mStubProcessInfoMap.put(processName, processInfo); } return processInfo; }
/** * デバイスプラグインのxmlファイルを参照し、スコープに対応する有効期限設定値があれば返す. * * @param context コンテキスト * @param pluginComponent デバイスプラグインを宣言するコンポーネント * @return not null: xmlで定義されているスコープ名と有効期限[msec]が対応付けされたMap / null: * 有効期限設定値無し */ public static Map<String, DevicePluginXmlProfile> getSupportProfiles(final Context context, final ComponentInfo pluginComponent) { if (pluginComponent != null) { if (pluginComponent.metaData != null) { DevicePluginXml xml = getXml(context, pluginComponent); if (xml != null) { return xml.getSupportedProfiles(); } } } return null; }
private static ComponentInfo getComponentInfo(final Context context, final String packageName) { ComponentInfo compInfo = getServiceInfo(context, packageName); if (compInfo != null) { return compInfo; } return getReceiverInfo(context, packageName); }
/** * Shows at most one dialog using the intent extras and the restored state of the activity. * * @param savedInstanceState restored state */ private void showDialogIfNeeded(Bundle savedInstanceState) { // Check if the intent has the ICON_COLOR_CHANGED action; if so, show a new dialog. if (getIntent().getBooleanExtra(IconColorReceiver.EXTRA_ICON_COLOR_CHANGED, false)) { // Clear the flag in the intent so that the dialog doesn't show up anymore getIntent().putExtra(IconColorReceiver.EXTRA_ICON_COLOR_CHANGED, false); // Display a dialog showcasing the new icon! ImageView imageView = new ImageView(this); PackageManager manager = getPackageManager(); try { ComponentInfo info = manager.getActivityInfo(getComponentName(), 0); imageView.setImageDrawable(ContextCompat.getDrawable(getBaseContext(), info.getIconResource())); } catch (PackageManager.NameNotFoundException ignored) { } new QKDialog() .setContext(this) .setTitle(getString(R.string.icon_ready)) .setMessage(R.string.icon_ready_message) .setCustomView(imageView) .setPositiveButton(R.string.okay, null) .show(); // Only show the MMS setup fragment if it hasn't already been dismissed } else if (!wasMmsSetupFragmentDismissed(savedInstanceState)) { beginMmsSetup(); } }
@Override public void onClick(View widget) { Uri uri = Uri.parse(getURL()); Context context = widget.getContext(); Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()); try { PackageManager pm = context.getPackageManager(); ResolveInfo info = pm.resolveActivity(intent, 0); boolean badResolve = info == null; if (info != null) { ComponentInfo componentInfo = AndroidUtils.getComponentInfo(info); badResolve = componentInfo == null || componentInfo.name.contains("frameworkpackagestubs"); } if (badResolve) { // toast CustomToast.showText("Can't open " + uri, Toast.LENGTH_LONG); } else { context.startActivity(intent); } } catch (ActivityNotFoundException e) { Log.w("URLSpan", "Actvity was not found for intent, " + intent.toString()); } }
@Nullable public static ComponentInfo getComponentInfo(@NonNull ResolveInfo info) { if (info.activityInfo != null) return info.activityInfo; if (info.serviceInfo != null) return info.serviceInfo; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { return getComponentInfo_v19(info); } return null; }
@Nullable @TargetApi(Build.VERSION_CODES.KITKAT) private static ComponentInfo getComponentInfo_v19(@NonNull ResolveInfo info) { if (info.providerInfo != null) return info.providerInfo; return null; }