/** * OpenAtlasForAndroid Project * The MIT License (MIT) Copyright (OpenAtlasForAndroid) 2015 Bunny Blue,achellies * <p> * Permission is hereby granted, free of charge, to any person obtaining a copy of this software * and associated documentation files (the "Software"), to deal in the Software * without restriction, including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to the following conditions: * <p> * The above copyright notice and this permission notice shall be included in all copies * or substantial portions of the Software. * <p> * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * @author BunnyBlue **/ package com.openatlas.runtime; import android.content.res.AssetManager; import android.content.res.XmlResourceParser; import android.os.Bundle; import android.util.AttributeSet; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.util.HashSet; import java.util.Set; public class PackageLite { public String applicationClassName; public int applicationDescription; public int applicationIcon; public int applicationLabel; public final Set<String> components; public final Set<String> disableComponents; public Bundle metaData; public String packageName; public int versionCode; public String versionName; static String tag = "PackageLite"; PackageLite() { this.components = new HashSet<String>(); this.disableComponents = new HashSet<String>(); } public static PackageLite parse(File file) { XmlResourceParser openXmlResourceParser = null; try { AssetManager assetManager = AssetManager.class .newInstance(); Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class); int intValue = (Integer) addAssetPath.invoke(assetManager, file.getAbsolutePath()); if (intValue != 0) { openXmlResourceParser = assetManager.openXmlResourceParser( intValue, "AndroidManifest.xml"); } else { openXmlResourceParser = assetManager.openXmlResourceParser( intValue, "AndroidManifest.xml"); } if (openXmlResourceParser != null) { try { PackageLite parse = parse(openXmlResourceParser); if (parse == null) { parse = new PackageLite(); } openXmlResourceParser.close(); return parse; } catch (Exception e) { e.printStackTrace(); } } return null; } catch (Exception e) { } finally { if (openXmlResourceParser != null) { openXmlResourceParser.close(); } } return null; } protected static PackageLite parse(XmlResourceParser xmlResourceParser) throws Exception { int currentTag = xmlResourceParser.next(); PackageLite mPackageLite = new PackageLite(); while (currentTag != XmlPullParser.END_DOCUMENT) { switch (currentTag) { case XmlPullParser.START_DOCUMENT: break; case XmlPullParser.START_TAG: if (xmlResourceParser.getName().equals("manifest")) { parserManifestAttribute(xmlResourceParser, mPackageLite); } if (xmlResourceParser.getName().equals("application")) { if (!parseApplication(mPackageLite, (xmlResourceParser), (xmlResourceParser))) { return null; } return mPackageLite; } break; case XmlPullParser.END_DOCUMENT: xmlResourceParser.close(); break; case XmlPullParser.END_TAG: break; default: break; } currentTag = xmlResourceParser.next(); } return mPackageLite; } /** * parser ManifestAttribute such package name and so on * @param xmlResourceParser * @param mPackageLite */ private static void parserManifestAttribute( XmlResourceParser xmlResourceParser, PackageLite mPackageLite) { for (int i = 0; i < xmlResourceParser.getAttributeCount(); i++) { String value = xmlResourceParser.getAttributeName(i); if (value.equalsIgnoreCase("package")) { mPackageLite.packageName = xmlResourceParser .getAttributeValue(i); } if (value.equals("versionCode")) { mPackageLite.versionCode = xmlResourceParser .getAttributeIntValue(i, 0); } else if (value.equals("versionName")) { mPackageLite.versionName = xmlResourceParser .getAttributeValue(i); } } } private static boolean parseApplication(PackageLite packageLite, XmlPullParser xmlPullParser, AttributeSet attributeSet) throws Exception { int i; String str = packageLite.packageName; for (i = 0; i < attributeSet.getAttributeCount(); i++) { String attributeName = attributeSet.getAttributeName(i); if (attributeName.equals("name")) { packageLite.applicationClassName = buildClassName(str, attributeSet.getAttributeValue(i)); } else if (attributeName.equals("icon")) { packageLite.applicationIcon = attributeSet .getAttributeResourceValue(i, 0); } else if (attributeName.equals("label")) { packageLite.applicationLabel = attributeSet .getAttributeResourceValue(i, 0); } else if (attributeName.equals("description")) { packageLite.applicationDescription = attributeSet .getAttributeResourceValue(i, 0); } } final int innerDepth = xmlPullParser.getDepth(); int type; while ((type = xmlPullParser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || xmlPullParser.getDepth() > innerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String tagName = xmlPullParser.getName(); if (tagName.equals("activity")) { parseComponentData(packageLite, xmlPullParser, attributeSet, false); } else if (tagName.equals("receiver")) { parseComponentData(packageLite, xmlPullParser, attributeSet, true); } else if (tagName.equals("service")) { parseComponentData(packageLite, xmlPullParser, attributeSet, true); } else if (tagName.equals("provider")) { parseComponentData(packageLite, xmlPullParser, attributeSet, false); } else if (tagName.equals("activity-alias")) { } else if (xmlPullParser.getName().equals("meta-data")) { packageLite.metaData = parseMetaData(xmlPullParser, attributeSet, packageLite.metaData); } else if (tagName.equals("uses-library")) { } else if (tagName.equals("uses-package")) { } else { } } return true; } private static Bundle parseMetaData(XmlPullParser xmlPullParser, AttributeSet attributeSet, Bundle bundle) throws XmlPullParserException, IOException { int i = 0; if (bundle == null) { bundle = new Bundle(); } String value = null; String name = null; int i2 = 0; while (i < attributeSet.getAttributeCount()) { String attributeName = attributeSet.getAttributeName(i); if (attributeName.equals("name")) { name = attributeSet.getAttributeValue(i); i2++; } else if (attributeName.equals("value")) { value = attributeSet.getAttributeValue(i); i2++; } if (i2 >= 2) { break; } i++; } if (!(name == null || value == null)) { bundle.putString(name, value); } return bundle; } private static String buildClassName(String str, CharSequence charSequence) { if (charSequence == null || charSequence.length() <= 0) { System.out.println("Empty class name in package " + str); return null; } String obj = charSequence.toString(); char charAt = obj.charAt(0); if (charAt == '.') { return (str + obj).intern(); } if (obj.indexOf(46) < 0) { StringBuilder stringBuilder = new StringBuilder(str); stringBuilder.append('.'); stringBuilder.append(obj); return stringBuilder.toString().intern(); } else if (charAt >= 'a' && charAt <= 'z') { return obj.intern(); } else { System.out.println("Bad class name " + obj + " in package " + str); return null; } } @SuppressWarnings("unused") @Deprecated private static void skipCurrentTag(XmlPullParser xmlPullParser) throws XmlPullParserException, IOException { int depth = xmlPullParser.getDepth(); while (true) { int next = xmlPullParser.next(); if (next == XmlPullParser.END_DOCUMENT) { return; } if (next == XmlPullParser.END_TAG && xmlPullParser.getDepth() <= depth) { return; } } } private static void parseComponentData(PackageLite packageLite, XmlPullParser xmlPullParser, AttributeSet attributeSet, boolean isDisable) throws XmlPullParserException { String pkgName = packageLite.packageName; for (int index = 0; index < attributeSet.getAttributeCount(); index++) { if (attributeSet.getAttributeName(index).equals("name")) { String mComponentName = attributeSet.getAttributeValue(index); if (mComponentName.startsWith(".")) { mComponentName = pkgName.concat(mComponentName); } packageLite.components.add(mComponentName); if (isDisable ){ packageLite.disableComponents.add(mComponentName); } } } } }