Example usage for android.content.res Resources obtainAttributes

List of usage examples for android.content.res Resources obtainAttributes

Introduction

In this page you can find the example usage for android.content.res Resources obtainAttributes.

Prototype

public TypedArray obtainAttributes(AttributeSet set, @StyleableRes int[] attrs) 

Source Link

Document

Retrieve a set of basic attribute values from an AttributeSet, not performing styling of them using a theme and/or style resources.

Usage

From source file:android.content.pm.PackageParser.java

private Provider parseProvider(Package owner, Resources res, XmlPullParser parser, AttributeSet attrs,
        int flags, String[] outError) throws XmlPullParserException, IOException {
    TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestProvider);

    if (mParseProviderArgs == null) {
        mParseProviderArgs = new ParseComponentArgs(owner, outError,
                com.android.internal.R.styleable.AndroidManifestProvider_name,
                com.android.internal.R.styleable.AndroidManifestProvider_label,
                com.android.internal.R.styleable.AndroidManifestProvider_icon,
                com.android.internal.R.styleable.AndroidManifestProvider_logo,
                com.android.internal.R.styleable.AndroidManifestProvider_banner, mSeparateProcesses,
                com.android.internal.R.styleable.AndroidManifestProvider_process,
                com.android.internal.R.styleable.AndroidManifestProvider_description,
                com.android.internal.R.styleable.AndroidManifestProvider_enabled);
        mParseProviderArgs.tag = "<provider>";
    }/*from  ww w  .  ja  v a 2s .  c o m*/

    mParseProviderArgs.sa = sa;
    mParseProviderArgs.flags = flags;

    Provider p = new Provider(mParseProviderArgs, new ProviderInfo());
    if (outError[0] != null) {
        sa.recycle();
        return null;
    }

    boolean providerExportedDefault = false;

    if (owner.applicationInfo.targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR1) {
        // For compatibility, applications targeting API level 16 or lower
        // should have their content providers exported by default, unless they
        // specify otherwise.
        providerExportedDefault = true;
    }

    p.info.exported = sa.getBoolean(com.android.internal.R.styleable.AndroidManifestProvider_exported,
            providerExportedDefault);

    String cpname = sa
            .getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestProvider_authorities, 0);

    p.info.isSyncable = sa.getBoolean(com.android.internal.R.styleable.AndroidManifestProvider_syncable, false);

    String permission = sa
            .getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestProvider_permission, 0);
    String str = sa.getNonConfigurationString(
            com.android.internal.R.styleable.AndroidManifestProvider_readPermission, 0);
    if (str == null) {
        str = permission;
    }
    if (str == null) {
        p.info.readPermission = owner.applicationInfo.permission;
    } else {
        p.info.readPermission = str.length() > 0 ? str.toString().intern() : null;
    }
    str = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestProvider_writePermission,
            0);
    if (str == null) {
        str = permission;
    }
    if (str == null) {
        p.info.writePermission = owner.applicationInfo.permission;
    } else {
        p.info.writePermission = str.length() > 0 ? str.toString().intern() : null;
    }

    p.info.grantUriPermissions = sa
            .getBoolean(com.android.internal.R.styleable.AndroidManifestProvider_grantUriPermissions, false);

    p.info.multiprocess = sa.getBoolean(com.android.internal.R.styleable.AndroidManifestProvider_multiprocess,
            false);

    p.info.initOrder = sa.getInt(com.android.internal.R.styleable.AndroidManifestProvider_initOrder, 0);

    p.info.flags = 0;

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestProvider_singleUser, false)) {
        p.info.flags |= ProviderInfo.FLAG_SINGLE_USER;
        if (p.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
            Slog.w(TAG, "Provider exported request ignored due to singleUser: " + p.className + " at "
                    + mArchiveSourcePath + " " + parser.getPositionDescription());
            p.info.exported = false;
        }
    }

    sa.recycle();

    if ((owner.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
        // A heavy-weight application can not have providers in its main process
        // We can do direct compare because we intern all strings.
        if (p.info.processName == owner.packageName) {
            outError[0] = "Heavy-weight applications can not have providers in main process";
            return null;
        }
    }

    if (cpname == null) {
        outError[0] = "<provider> does not include authorities attribute";
        return null;
    }
    if (cpname.length() <= 0) {
        outError[0] = "<provider> has empty authorities attribute";
        return null;
    }
    p.info.authority = cpname.intern();

    if (!parseProviderTags(res, parser, attrs, p, outError)) {
        return null;
    }

    return p;
}

From source file:android.content.pm.PackageParser.java

/**
 * Parse the {@code application} XML tree at the current parse location in a
 * <em>split APK</em> manifest.
 * <p>/*  ww w . ja va  2 s  .com*/
 * Note that split APKs have many more restrictions on what they're capable
 * of doing, so many valid features of a base APK have been carefully
 * omitted here.
 */
private boolean parseSplitApplication(Package owner, Resources res, XmlPullParser parser, AttributeSet attrs,
        int flags, int splitIndex, String[] outError) throws XmlPullParserException, IOException {
    TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestApplication);

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_hasCode, true)) {
        owner.splitFlags[splitIndex] |= ApplicationInfo.FLAG_HAS_CODE;
    }

    final int innerDepth = parser.getDepth();
    int type;
    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
            && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
            continue;
        }

        String tagName = parser.getName();
        if (tagName.equals("activity")) {
            Activity a = parseActivity(owner, res, parser, attrs, flags, outError, false,
                    owner.baseHardwareAccelerated);
            if (a == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

            owner.activities.add(a);

        } else if (tagName.equals("receiver")) {
            Activity a = parseActivity(owner, res, parser, attrs, flags, outError, true, false);
            if (a == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

            owner.receivers.add(a);

        } else if (tagName.equals("service")) {
            Service s = parseService(owner, res, parser, attrs, flags, outError);
            if (s == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

            owner.services.add(s);

        } else if (tagName.equals("provider")) {
            Provider p = parseProvider(owner, res, parser, attrs, flags, outError);
            if (p == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

            owner.providers.add(p);

        } else if (tagName.equals("activity-alias")) {
            Activity a = parseActivityAlias(owner, res, parser, attrs, flags, outError);
            if (a == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

            owner.activities.add(a);

        } else if (parser.getName().equals("meta-data")) {
            // note: application meta-data is stored off to the side, so it can
            // remain null in the primary copy (we like to avoid extra copies because
            // it can be large)
            if ((owner.mAppMetaData = parseMetaData(res, parser, attrs, owner.mAppMetaData,
                    outError)) == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

        } else if (tagName.equals("uses-library")) {
            sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestUsesLibrary);

            // Note: don't allow this value to be a reference to a resource
            // that may change.
            String lname = sa
                    .getNonResourceString(com.android.internal.R.styleable.AndroidManifestUsesLibrary_name);
            boolean req = sa.getBoolean(com.android.internal.R.styleable.AndroidManifestUsesLibrary_required,
                    true);

            sa.recycle();

            if (lname != null) {
                lname = lname.intern();
                if (req) {
                    // Upgrade to treat as stronger constraint
                    owner.usesLibraries = ArrayUtils.add(owner.usesLibraries, lname);
                    owner.usesOptionalLibraries = ArrayUtils.remove(owner.usesOptionalLibraries, lname);
                } else {
                    // Ignore if someone already defined as required
                    if (!ArrayUtils.contains(owner.usesLibraries, lname)) {
                        owner.usesOptionalLibraries = ArrayUtils.add(owner.usesOptionalLibraries, lname);
                    }
                }
            }

            XmlUtils.skipCurrentTag(parser);

        } else if (tagName.equals("uses-package")) {
            // Dependencies for app installers; we don't currently try to
            // enforce this.
            XmlUtils.skipCurrentTag(parser);

        } else {
            if (!RIGID_PARSER) {
                Slog.w(TAG, "Unknown element under <application>: " + tagName + " at " + mArchiveSourcePath
                        + " " + parser.getPositionDescription());
                XmlUtils.skipCurrentTag(parser);
                continue;
            } else {
                outError[0] = "Bad element under <application>: " + tagName;
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }
        }
    }

    return true;
}

From source file:android.content.pm.PackageParser.java

private Activity parseActivityAlias(Package owner, Resources res, XmlPullParser parser, AttributeSet attrs,
        int flags, String[] outError) throws XmlPullParserException, IOException {
    TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestActivityAlias);

    String targetActivity = sa.getNonConfigurationString(
            com.android.internal.R.styleable.AndroidManifestActivityAlias_targetActivity,
            Configuration.NATIVE_CONFIG_VERSION);
    if (targetActivity == null) {
        outError[0] = "<activity-alias> does not specify android:targetActivity";
        sa.recycle();// w w w .j a  v  a 2  s.c  o m
        return null;
    }

    targetActivity = buildClassName(owner.applicationInfo.packageName, targetActivity, outError);
    if (targetActivity == null) {
        sa.recycle();
        return null;
    }

    if (mParseActivityAliasArgs == null) {
        mParseActivityAliasArgs = new ParseComponentArgs(owner, outError,
                com.android.internal.R.styleable.AndroidManifestActivityAlias_name,
                com.android.internal.R.styleable.AndroidManifestActivityAlias_label,
                com.android.internal.R.styleable.AndroidManifestActivityAlias_icon,
                com.android.internal.R.styleable.AndroidManifestActivityAlias_logo,
                com.android.internal.R.styleable.AndroidManifestActivityAlias_banner, mSeparateProcesses, 0,
                com.android.internal.R.styleable.AndroidManifestActivityAlias_description,
                com.android.internal.R.styleable.AndroidManifestActivityAlias_enabled);
        mParseActivityAliasArgs.tag = "<activity-alias>";
    }

    mParseActivityAliasArgs.sa = sa;
    mParseActivityAliasArgs.flags = flags;

    Activity target = null;

    final int NA = owner.activities.size();
    for (int i = 0; i < NA; i++) {
        Activity t = owner.activities.get(i);
        if (targetActivity.equals(t.info.name)) {
            target = t;
            break;
        }
    }

    if (target == null) {
        outError[0] = "<activity-alias> target activity " + targetActivity + " not found in manifest";
        sa.recycle();
        return null;
    }

    ActivityInfo info = new ActivityInfo();
    info.targetActivity = targetActivity;
    info.configChanges = target.info.configChanges;
    info.flags = target.info.flags;
    info.icon = target.info.icon;
    info.logo = target.info.logo;
    info.banner = target.info.banner;
    info.labelRes = target.info.labelRes;
    info.nonLocalizedLabel = target.info.nonLocalizedLabel;
    info.launchMode = target.info.launchMode;
    info.lockTaskLaunchMode = target.info.lockTaskLaunchMode;
    info.processName = target.info.processName;
    if (info.descriptionRes == 0) {
        info.descriptionRes = target.info.descriptionRes;
    }
    info.screenOrientation = target.info.screenOrientation;
    info.taskAffinity = target.info.taskAffinity;
    info.theme = target.info.theme;
    info.softInputMode = target.info.softInputMode;
    info.uiOptions = target.info.uiOptions;
    info.parentActivityName = target.info.parentActivityName;
    info.maxRecents = target.info.maxRecents;

    Activity a = new Activity(mParseActivityAliasArgs, info);
    if (outError[0] != null) {
        sa.recycle();
        return null;
    }

    final boolean setExported = sa
            .hasValue(com.android.internal.R.styleable.AndroidManifestActivityAlias_exported);
    if (setExported) {
        a.info.exported = sa.getBoolean(com.android.internal.R.styleable.AndroidManifestActivityAlias_exported,
                false);
    }

    String str;
    str = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestActivityAlias_permission,
            0);
    if (str != null) {
        a.info.permission = str.length() > 0 ? str.toString().intern() : null;
    }

    String parentName = sa.getNonConfigurationString(
            com.android.internal.R.styleable.AndroidManifestActivityAlias_parentActivityName,
            Configuration.NATIVE_CONFIG_VERSION);
    if (parentName != null) {
        String parentClassName = buildClassName(a.info.packageName, parentName, outError);
        if (outError[0] == null) {
            a.info.parentActivityName = parentClassName;
        } else {
            Log.e(TAG, "Activity alias " + a.info.name + " specified invalid parentActivityName " + parentName);
            outError[0] = null;
        }
    }

    sa.recycle();

    if (outError[0] != null) {
        return null;
    }

    int outerDepth = parser.getDepth();
    int type;
    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
            && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
            continue;
        }

        if (parser.getName().equals("intent-filter")) {
            ActivityIntentInfo intent = new ActivityIntentInfo(a);
            if (!parseIntent(res, parser, attrs, true, true, intent, outError)) {
                return null;
            }
            if (intent.countActions() == 0) {
                Slog.w(TAG, "No actions in intent filter at " + mArchiveSourcePath + " "
                        + parser.getPositionDescription());
            } else {
                a.intents.add(intent);
            }
        } else if (parser.getName().equals("meta-data")) {
            if ((a.metaData = parseMetaData(res, parser, attrs, a.metaData, outError)) == null) {
                return null;
            }
        } else {
            if (!RIGID_PARSER) {
                Slog.w(TAG, "Unknown element under <activity-alias>: " + parser.getName() + " at "
                        + mArchiveSourcePath + " " + parser.getPositionDescription());
                XmlUtils.skipCurrentTag(parser);
                continue;
            } else {
                outError[0] = "Bad element under <activity-alias>: " + parser.getName();
                return null;
            }
        }
    }

    if (!setExported) {
        a.info.exported = a.intents.size() > 0;
    }

    return a;
}

From source file:android.content.pm.PackageParser.java

private boolean parseIntent(Resources res, XmlPullParser parser, AttributeSet attrs, boolean allowGlobs,
        boolean allowAutoVerify, IntentInfo outInfo, String[] outError)
        throws XmlPullParserException, IOException {

    TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestIntentFilter);

    int priority = sa.getInt(com.android.internal.R.styleable.AndroidManifestIntentFilter_priority, 0);
    outInfo.setPriority(priority);/*from w w  w .  j  a  v a2s.co  m*/

    TypedValue v = sa.peekValue(com.android.internal.R.styleable.AndroidManifestIntentFilter_label);
    if (v != null && (outInfo.labelRes = v.resourceId) == 0) {
        outInfo.nonLocalizedLabel = v.coerceToString();
    }

    outInfo.icon = sa.getResourceId(com.android.internal.R.styleable.AndroidManifestIntentFilter_icon, 0);

    outInfo.logo = sa.getResourceId(com.android.internal.R.styleable.AndroidManifestIntentFilter_logo, 0);

    outInfo.banner = sa.getResourceId(com.android.internal.R.styleable.AndroidManifestIntentFilter_banner, 0);

    if (allowAutoVerify) {
        outInfo.setAutoVerify(
                sa.getBoolean(com.android.internal.R.styleable.AndroidManifestIntentFilter_autoVerify, false));
    }

    sa.recycle();

    int outerDepth = parser.getDepth();
    int type;
    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
            && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
            continue;
        }

        String nodeName = parser.getName();
        if (nodeName.equals("action")) {
            String value = attrs.getAttributeValue(ANDROID_RESOURCES, "name");
            if (value == null || value == "") {
                outError[0] = "No value supplied for <android:name>";
                return false;
            }
            XmlUtils.skipCurrentTag(parser);

            outInfo.addAction(value);
        } else if (nodeName.equals("category")) {
            String value = attrs.getAttributeValue(ANDROID_RESOURCES, "name");
            if (value == null || value == "") {
                outError[0] = "No value supplied for <android:name>";
                return false;
            }
            XmlUtils.skipCurrentTag(parser);

            outInfo.addCategory(value);

        } else if (nodeName.equals("data")) {
            sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestData);

            String str = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestData_mimeType, 0);
            if (str != null) {
                try {
                    outInfo.addDataType(str);
                } catch (IntentFilter.MalformedMimeTypeException e) {
                    outError[0] = e.toString();
                    sa.recycle();
                    return false;
                }
            }

            str = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestData_scheme, 0);
            if (str != null) {
                outInfo.addDataScheme(str);
            }

            str = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestData_ssp, 0);
            if (str != null) {
                outInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_LITERAL);
            }

            str = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestData_sspPrefix,
                    0);
            if (str != null) {
                outInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_PREFIX);
            }

            str = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestData_sspPattern,
                    0);
            if (str != null) {
                if (!allowGlobs) {
                    outError[0] = "sspPattern not allowed here; ssp must be literal";
                    return false;
                }
                outInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
            }

            String host = sa
                    .getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestData_host, 0);
            String port = sa
                    .getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestData_port, 0);
            if (host != null) {
                outInfo.addDataAuthority(host, port);
            }

            str = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestData_path, 0);
            if (str != null) {
                outInfo.addDataPath(str, PatternMatcher.PATTERN_LITERAL);
            }

            str = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestData_pathPrefix,
                    0);
            if (str != null) {
                outInfo.addDataPath(str, PatternMatcher.PATTERN_PREFIX);
            }

            str = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestData_pathPattern,
                    0);
            if (str != null) {
                if (!allowGlobs) {
                    outError[0] = "pathPattern not allowed here; path must be literal";
                    return false;
                }
                outInfo.addDataPath(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
            }

            sa.recycle();
            XmlUtils.skipCurrentTag(parser);
        } else if (!RIGID_PARSER) {
            Slog.w(TAG, "Unknown element under <intent-filter>: " + parser.getName() + " at "
                    + mArchiveSourcePath + " " + parser.getPositionDescription());
            XmlUtils.skipCurrentTag(parser);
        } else {
            outError[0] = "Bad element under <intent-filter>: " + parser.getName();
            return false;
        }
    }

    outInfo.hasDefault = outInfo.hasCategory(Intent.CATEGORY_DEFAULT);

    if (DEBUG_PARSER) {
        final StringBuilder cats = new StringBuilder("Intent d=");
        cats.append(outInfo.hasDefault);
        cats.append(", cat=");

        final Iterator<String> it = outInfo.categoriesIterator();
        if (it != null) {
            while (it.hasNext()) {
                cats.append(' ');
                cats.append(it.next());
            }
        }
        Slog.d(TAG, cats.toString());
    }

    return true;
}

From source file:android.content.pm.PackageParser.java

private Activity parseActivity(Package owner, Resources res, XmlPullParser parser, AttributeSet attrs,
        int flags, String[] outError, boolean receiver, boolean hardwareAccelerated)
        throws XmlPullParserException, IOException {
    TypedArray sa = res.obtainAttributes(attrs, R.styleable.AndroidManifestActivity);

    if (mParseActivityArgs == null) {
        mParseActivityArgs = new ParseComponentArgs(owner, outError, R.styleable.AndroidManifestActivity_name,
                R.styleable.AndroidManifestActivity_label, R.styleable.AndroidManifestActivity_icon,
                R.styleable.AndroidManifestActivity_logo, R.styleable.AndroidManifestActivity_banner,
                mSeparateProcesses, R.styleable.AndroidManifestActivity_process,
                R.styleable.AndroidManifestActivity_description, R.styleable.AndroidManifestActivity_enabled);
    }//from ww w  . j  a va 2s. c  om

    mParseActivityArgs.tag = receiver ? "<receiver>" : "<activity>";
    mParseActivityArgs.sa = sa;
    mParseActivityArgs.flags = flags;

    Activity a = new Activity(mParseActivityArgs, new ActivityInfo());
    if (outError[0] != null) {
        sa.recycle();
        return null;
    }

    boolean setExported = sa.hasValue(R.styleable.AndroidManifestActivity_exported);
    if (setExported) {
        a.info.exported = sa.getBoolean(R.styleable.AndroidManifestActivity_exported, false);
    }

    a.info.theme = sa.getResourceId(R.styleable.AndroidManifestActivity_theme, 0);

    a.info.uiOptions = sa.getInt(R.styleable.AndroidManifestActivity_uiOptions,
            a.info.applicationInfo.uiOptions);

    String parentName = sa.getNonConfigurationString(R.styleable.AndroidManifestActivity_parentActivityName,
            Configuration.NATIVE_CONFIG_VERSION);
    if (parentName != null) {
        String parentClassName = buildClassName(a.info.packageName, parentName, outError);
        if (outError[0] == null) {
            a.info.parentActivityName = parentClassName;
        } else {
            Log.e(TAG, "Activity " + a.info.name + " specified invalid parentActivityName " + parentName);
            outError[0] = null;
        }
    }

    String str;
    str = sa.getNonConfigurationString(R.styleable.AndroidManifestActivity_permission, 0);
    if (str == null) {
        a.info.permission = owner.applicationInfo.permission;
    } else {
        a.info.permission = str.length() > 0 ? str.toString().intern() : null;
    }

    str = sa.getNonConfigurationString(R.styleable.AndroidManifestActivity_taskAffinity,
            Configuration.NATIVE_CONFIG_VERSION);
    a.info.taskAffinity = buildTaskAffinityName(owner.applicationInfo.packageName,
            owner.applicationInfo.taskAffinity, str, outError);

    a.info.flags = 0;
    if (sa.getBoolean(R.styleable.AndroidManifestActivity_multiprocess, false)) {
        a.info.flags |= ActivityInfo.FLAG_MULTIPROCESS;
    }

    if (sa.getBoolean(R.styleable.AndroidManifestActivity_finishOnTaskLaunch, false)) {
        a.info.flags |= ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH;
    }

    if (sa.getBoolean(R.styleable.AndroidManifestActivity_clearTaskOnLaunch, false)) {
        a.info.flags |= ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH;
    }

    if (sa.getBoolean(R.styleable.AndroidManifestActivity_noHistory, false)) {
        a.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
    }

    if (sa.getBoolean(R.styleable.AndroidManifestActivity_alwaysRetainTaskState, false)) {
        a.info.flags |= ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE;
    }

    if (sa.getBoolean(R.styleable.AndroidManifestActivity_stateNotNeeded, false)) {
        a.info.flags |= ActivityInfo.FLAG_STATE_NOT_NEEDED;
    }

    if (sa.getBoolean(R.styleable.AndroidManifestActivity_excludeFromRecents, false)) {
        a.info.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
    }

    if (sa.getBoolean(R.styleable.AndroidManifestActivity_allowTaskReparenting,
            (owner.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING) != 0)) {
        a.info.flags |= ActivityInfo.FLAG_ALLOW_TASK_REPARENTING;
    }

    if (sa.getBoolean(R.styleable.AndroidManifestActivity_finishOnCloseSystemDialogs, false)) {
        a.info.flags |= ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
    }

    if (sa.getBoolean(R.styleable.AndroidManifestActivity_showOnLockScreen, false)
            || sa.getBoolean(R.styleable.AndroidManifestActivity_showForAllUsers, false)) {
        a.info.flags |= ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
    }

    if (sa.getBoolean(R.styleable.AndroidManifestActivity_immersive, false)) {
        a.info.flags |= ActivityInfo.FLAG_IMMERSIVE;
    }

    if (sa.getBoolean(R.styleable.AndroidManifestActivity_primaryUserOnly, false)) {
        a.info.flags |= ActivityInfo.FLAG_PRIMARY_USER_ONLY;
    }

    if (!receiver) {
        if (sa.getBoolean(R.styleable.AndroidManifestActivity_hardwareAccelerated, hardwareAccelerated)) {
            a.info.flags |= ActivityInfo.FLAG_HARDWARE_ACCELERATED;
        }

        a.info.launchMode = sa.getInt(R.styleable.AndroidManifestActivity_launchMode,
                ActivityInfo.LAUNCH_MULTIPLE);
        a.info.documentLaunchMode = sa.getInt(R.styleable.AndroidManifestActivity_documentLaunchMode,
                ActivityInfo.DOCUMENT_LAUNCH_NONE);
        a.info.maxRecents = sa.getInt(R.styleable.AndroidManifestActivity_maxRecents,
                ActivityManager.getDefaultAppRecentsLimitStatic());
        a.info.configChanges = sa.getInt(R.styleable.AndroidManifestActivity_configChanges, 0);
        a.info.softInputMode = sa.getInt(R.styleable.AndroidManifestActivity_windowSoftInputMode, 0);

        a.info.persistableMode = sa.getInteger(R.styleable.AndroidManifestActivity_persistableMode,
                ActivityInfo.PERSIST_ROOT_ONLY);

        if (sa.getBoolean(R.styleable.AndroidManifestActivity_allowEmbedded, false)) {
            a.info.flags |= ActivityInfo.FLAG_ALLOW_EMBEDDED;
        }

        if (sa.getBoolean(R.styleable.AndroidManifestActivity_autoRemoveFromRecents, false)) {
            a.info.flags |= ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS;
        }

        if (sa.getBoolean(R.styleable.AndroidManifestActivity_relinquishTaskIdentity, false)) {
            a.info.flags |= ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
        }

        if (sa.getBoolean(R.styleable.AndroidManifestActivity_resumeWhilePausing, false)) {
            a.info.flags |= ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
        }

        a.info.resizeable = sa.getBoolean(R.styleable.AndroidManifestActivity_resizeableActivity, false);
        if (a.info.resizeable) {
            // Fixed screen orientation isn't supported with resizeable activities.
            a.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
        } else {
            a.info.screenOrientation = sa.getInt(R.styleable.AndroidManifestActivity_screenOrientation,
                    ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
        }

        a.info.lockTaskLaunchMode = sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
    } else {
        a.info.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
        a.info.configChanges = 0;

        if (sa.getBoolean(R.styleable.AndroidManifestActivity_singleUser, false)) {
            a.info.flags |= ActivityInfo.FLAG_SINGLE_USER;
            if (a.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
                Slog.w(TAG, "Activity exported request ignored due to singleUser: " + a.className + " at "
                        + mArchiveSourcePath + " " + parser.getPositionDescription());
                a.info.exported = false;
                setExported = true;
            }
        }
    }

    sa.recycle();

    if (receiver && (owner.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
        // A heavy-weight application can not have receives in its main process
        // We can do direct compare because we intern all strings.
        if (a.info.processName == owner.packageName) {
            outError[0] = "Heavy-weight applications can not have receivers in main process";
        }
    }

    if (outError[0] != null) {
        return null;
    }

    int outerDepth = parser.getDepth();
    int type;
    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
            && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
            continue;
        }

        if (parser.getName().equals("intent-filter")) {
            ActivityIntentInfo intent = new ActivityIntentInfo(a);
            if (!parseIntent(res, parser, attrs, true, true, intent, outError)) {
                return null;
            }
            if (intent.countActions() == 0) {
                Slog.w(TAG, "No actions in intent filter at " + mArchiveSourcePath + " "
                        + parser.getPositionDescription());
            } else {
                a.intents.add(intent);
            }
        } else if (!receiver && parser.getName().equals("preferred")) {
            ActivityIntentInfo intent = new ActivityIntentInfo(a);
            if (!parseIntent(res, parser, attrs, false, false, intent, outError)) {
                return null;
            }
            if (intent.countActions() == 0) {
                Slog.w(TAG, "No actions in preferred at " + mArchiveSourcePath + " "
                        + parser.getPositionDescription());
            } else {
                if (owner.preferredActivityFilters == null) {
                    owner.preferredActivityFilters = new ArrayList<ActivityIntentInfo>();
                }
                owner.preferredActivityFilters.add(intent);
            }
        } else if (parser.getName().equals("meta-data")) {
            if ((a.metaData = parseMetaData(res, parser, attrs, a.metaData, outError)) == null) {
                return null;
            }
        } else {
            if (!RIGID_PARSER) {
                Slog.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
                if (receiver) {
                    Slog.w(TAG, "Unknown element under <receiver>: " + parser.getName() + " at "
                            + mArchiveSourcePath + " " + parser.getPositionDescription());
                } else {
                    Slog.w(TAG, "Unknown element under <activity>: " + parser.getName() + " at "
                            + mArchiveSourcePath + " " + parser.getPositionDescription());
                }
                XmlUtils.skipCurrentTag(parser);
                continue;
            } else {
                if (receiver) {
                    outError[0] = "Bad element under <receiver>: " + parser.getName();
                } else {
                    outError[0] = "Bad element under <activity>: " + parser.getName();
                }
                return null;
            }
        }
    }

    if (!setExported) {
        a.info.exported = a.intents.size() > 0;
    }

    return a;
}

From source file:android.content.pm.PackageParser.java

/**
 * Parse the {@code application} XML tree at the current parse location in a
 * <em>base APK</em> manifest.
 * <p>//from  ww w  .j  ava 2 s  .co  m
 * When adding new features, carefully consider if they should also be
 * supported by split APKs.
 */
private boolean parseBaseApplication(Package owner, Resources res, XmlPullParser parser, AttributeSet attrs,
        int flags, String[] outError) throws XmlPullParserException, IOException {
    final ApplicationInfo ai = owner.applicationInfo;
    final String pkgName = owner.applicationInfo.packageName;

    TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestApplication);

    String name = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestApplication_name,
            0);
    if (name != null) {
        ai.className = buildClassName(pkgName, name, outError);
        if (ai.className == null) {
            sa.recycle();
            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
            return false;
        }
    }

    String manageSpaceActivity = sa.getNonConfigurationString(
            com.android.internal.R.styleable.AndroidManifestApplication_manageSpaceActivity,
            Configuration.NATIVE_CONFIG_VERSION);
    if (manageSpaceActivity != null) {
        ai.manageSpaceActivityName = buildClassName(pkgName, manageSpaceActivity, outError);
    }

    boolean allowBackup = sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_allowBackup,
            true);
    if (allowBackup) {
        ai.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP;

        // backupAgent, killAfterRestore, fullBackupContent and restoreAnyVersion are only
        // relevant if backup is possible for the given application.
        String backupAgent = sa.getNonConfigurationString(
                com.android.internal.R.styleable.AndroidManifestApplication_backupAgent,
                Configuration.NATIVE_CONFIG_VERSION);
        if (backupAgent != null) {
            ai.backupAgentName = buildClassName(pkgName, backupAgent, outError);
            if (DEBUG_BACKUP) {
                Slog.v(TAG,
                        "android:backupAgent = " + ai.backupAgentName + " from " + pkgName + "+" + backupAgent);
            }

            if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_killAfterRestore,
                    true)) {
                ai.flags |= ApplicationInfo.FLAG_KILL_AFTER_RESTORE;
            }
            if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_restoreAnyVersion,
                    false)) {
                ai.flags |= ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
            }
            if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_fullBackupOnly,
                    false)) {
                ai.flags |= ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
            }
        }

        TypedValue v = sa
                .peekValue(com.android.internal.R.styleable.AndroidManifestApplication_fullBackupContent);
        if (v != null && (ai.fullBackupContent = v.resourceId) == 0) {
            if (DEBUG_BACKUP) {
                Slog.v(TAG, "fullBackupContent specified as boolean=" + (v.data == 0 ? "false" : "true"));
            }
            // "false" => -1, "true" => 0
            ai.fullBackupContent = (v.data == 0 ? -1 : 0);
        }
        if (DEBUG_BACKUP) {
            Slog.v(TAG, "fullBackupContent=" + ai.fullBackupContent + " for " + pkgName);
        }
    }

    TypedValue v = sa.peekValue(com.android.internal.R.styleable.AndroidManifestApplication_label);
    if (v != null && (ai.labelRes = v.resourceId) == 0) {
        ai.nonLocalizedLabel = v.coerceToString();
    }

    ai.icon = sa.getResourceId(com.android.internal.R.styleable.AndroidManifestApplication_icon, 0);
    ai.logo = sa.getResourceId(com.android.internal.R.styleable.AndroidManifestApplication_logo, 0);
    ai.banner = sa.getResourceId(com.android.internal.R.styleable.AndroidManifestApplication_banner, 0);
    ai.theme = sa.getResourceId(com.android.internal.R.styleable.AndroidManifestApplication_theme, 0);
    ai.descriptionRes = sa
            .getResourceId(com.android.internal.R.styleable.AndroidManifestApplication_description, 0);

    if ((flags & PARSE_IS_SYSTEM) != 0) {
        if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_persistent, false)) {
            ai.flags |= ApplicationInfo.FLAG_PERSISTENT;
        }
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_requiredForAllUsers, false)) {
        owner.mRequiredForAllUsers = true;
    }

    String restrictedAccountType = sa
            .getString(com.android.internal.R.styleable.AndroidManifestApplication_restrictedAccountType);
    if (restrictedAccountType != null && restrictedAccountType.length() > 0) {
        owner.mRestrictedAccountType = restrictedAccountType;
    }

    String requiredAccountType = sa
            .getString(com.android.internal.R.styleable.AndroidManifestApplication_requiredAccountType);
    if (requiredAccountType != null && requiredAccountType.length() > 0) {
        owner.mRequiredAccountType = requiredAccountType;
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_debuggable, false)) {
        ai.flags |= ApplicationInfo.FLAG_DEBUGGABLE;
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_vmSafeMode, false)) {
        ai.flags |= ApplicationInfo.FLAG_VM_SAFE_MODE;
    }

    owner.baseHardwareAccelerated = sa.getBoolean(
            com.android.internal.R.styleable.AndroidManifestApplication_hardwareAccelerated,
            owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.ICE_CREAM_SANDWICH);
    if (owner.baseHardwareAccelerated) {
        ai.flags |= ApplicationInfo.FLAG_HARDWARE_ACCELERATED;
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_hasCode, true)) {
        ai.flags |= ApplicationInfo.FLAG_HAS_CODE;
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_allowTaskReparenting,
            false)) {
        ai.flags |= ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING;
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_allowClearUserData, true)) {
        ai.flags |= ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_testOnly, false)) {
        ai.flags |= ApplicationInfo.FLAG_TEST_ONLY;
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_largeHeap, false)) {
        ai.flags |= ApplicationInfo.FLAG_LARGE_HEAP;
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_usesCleartextTraffic, true)) {
        ai.flags |= ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC;
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_supportsRtl,
            false /* default is no RTL support*/)) {
        ai.flags |= ApplicationInfo.FLAG_SUPPORTS_RTL;
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_multiArch, false)) {
        ai.flags |= ApplicationInfo.FLAG_MULTIARCH;
    }

    if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_extractNativeLibs, true)) {
        ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
    }

    String str;
    str = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestApplication_permission,
            0);
    ai.permission = (str != null && str.length() > 0) ? str.intern() : null;

    if (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.FROYO) {
        str = sa.getNonConfigurationString(
                com.android.internal.R.styleable.AndroidManifestApplication_taskAffinity,
                Configuration.NATIVE_CONFIG_VERSION);
    } 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.
        str = sa.getNonResourceString(com.android.internal.R.styleable.AndroidManifestApplication_taskAffinity);
    }
    ai.taskAffinity = buildTaskAffinityName(ai.packageName, ai.packageName, str, outError);

    if (outError[0] == null) {
        CharSequence pname;
        if (owner.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.FROYO) {
            pname = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestApplication_process,
                    Configuration.NATIVE_CONFIG_VERSION);
        } 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 = sa
                    .getNonResourceString(com.android.internal.R.styleable.AndroidManifestApplication_process);
        }
        ai.processName = buildProcessName(ai.packageName, null, pname, flags, mSeparateProcesses, outError);

        ai.enabled = sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_enabled, true);

        if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_isGame, false)) {
            ai.flags |= ApplicationInfo.FLAG_IS_GAME;
        }

        if (false) {
            if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_cantSaveState,
                    false)) {
                ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE;

                // A heavy-weight application can not be in a custom process.
                // We can do direct compare because we intern all strings.
                if (ai.processName != null && ai.processName != ai.packageName) {
                    outError[0] = "cantSaveState applications can not use custom processes";
                }
            }
        }
    }

    ai.uiOptions = sa.getInt(com.android.internal.R.styleable.AndroidManifestApplication_uiOptions, 0);

    sa.recycle();

    if (outError[0] != null) {
        mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
        return false;
    }

    final int innerDepth = parser.getDepth();
    int type;
    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
            && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
            continue;
        }

        String tagName = parser.getName();
        if (tagName.equals("activity")) {
            Activity a = parseActivity(owner, res, parser, attrs, flags, outError, false,
                    owner.baseHardwareAccelerated);
            if (a == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

            owner.activities.add(a);

        } else if (tagName.equals("receiver")) {
            Activity a = parseActivity(owner, res, parser, attrs, flags, outError, true, false);
            if (a == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

            owner.receivers.add(a);

        } else if (tagName.equals("service")) {
            Service s = parseService(owner, res, parser, attrs, flags, outError);
            if (s == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

            owner.services.add(s);

        } else if (tagName.equals("provider")) {
            Provider p = parseProvider(owner, res, parser, attrs, flags, outError);
            if (p == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

            owner.providers.add(p);

        } else if (tagName.equals("activity-alias")) {
            Activity a = parseActivityAlias(owner, res, parser, attrs, flags, outError);
            if (a == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

            owner.activities.add(a);

        } else if (parser.getName().equals("meta-data")) {
            // note: application meta-data is stored off to the side, so it can
            // remain null in the primary copy (we like to avoid extra copies because
            // it can be large)
            if ((owner.mAppMetaData = parseMetaData(res, parser, attrs, owner.mAppMetaData,
                    outError)) == null) {
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }

        } else if (tagName.equals("library")) {
            sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestLibrary);

            // Note: don't allow this value to be a reference to a resource
            // that may change.
            String lname = sa
                    .getNonResourceString(com.android.internal.R.styleable.AndroidManifestLibrary_name);

            sa.recycle();

            if (lname != null) {
                lname = lname.intern();
                if (!ArrayUtils.contains(owner.libraryNames, lname)) {
                    owner.libraryNames = ArrayUtils.add(owner.libraryNames, lname);
                }
            }

            XmlUtils.skipCurrentTag(parser);

        } else if (tagName.equals("uses-library")) {
            sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestUsesLibrary);

            // Note: don't allow this value to be a reference to a resource
            // that may change.
            String lname = sa
                    .getNonResourceString(com.android.internal.R.styleable.AndroidManifestUsesLibrary_name);
            boolean req = sa.getBoolean(com.android.internal.R.styleable.AndroidManifestUsesLibrary_required,
                    true);

            sa.recycle();

            if (lname != null) {
                lname = lname.intern();
                if (req) {
                    owner.usesLibraries = ArrayUtils.add(owner.usesLibraries, lname);
                } else {
                    owner.usesOptionalLibraries = ArrayUtils.add(owner.usesOptionalLibraries, lname);
                }
            }

            XmlUtils.skipCurrentTag(parser);

        } else if (tagName.equals("uses-package")) {
            // Dependencies for app installers; we don't currently try to
            // enforce this.
            XmlUtils.skipCurrentTag(parser);

        } else {
            if (!RIGID_PARSER) {
                Slog.w(TAG, "Unknown element under <application>: " + tagName + " at " + mArchiveSourcePath
                        + " " + parser.getPositionDescription());
                XmlUtils.skipCurrentTag(parser);
                continue;
            } else {
                outError[0] = "Bad element under <application>: " + tagName;
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }
        }
    }

    modifySharedLibrariesForBackwardCompatibility(owner);

    if (hasDomainURLs(owner)) {
        owner.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS;
    } else {
        owner.applicationInfo.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS;
    }

    return true;
}

From source file:android.content.pm.PackageParser.java

private boolean parseProviderTags(Resources res, XmlPullParser parser, AttributeSet attrs, Provider outInfo,
        String[] outError) throws XmlPullParserException, IOException {
    int outerDepth = parser.getDepth();
    int type;// www . j a v a 2  s  .  co  m
    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
            && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
            continue;
        }

        if (parser.getName().equals("intent-filter")) {
            ProviderIntentInfo intent = new ProviderIntentInfo(outInfo);
            if (!parseIntent(res, parser, attrs, true, false, intent, outError)) {
                return false;
            }
            outInfo.intents.add(intent);

        } else if (parser.getName().equals("meta-data")) {
            if ((outInfo.metaData = parseMetaData(res, parser, attrs, outInfo.metaData, outError)) == null) {
                return false;
            }

        } else if (parser.getName().equals("grant-uri-permission")) {
            TypedArray sa = res.obtainAttributes(attrs,
                    com.android.internal.R.styleable.AndroidManifestGrantUriPermission);

            PatternMatcher pa = null;

            String str = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestGrantUriPermission_path, 0);
            if (str != null) {
                pa = new PatternMatcher(str, PatternMatcher.PATTERN_LITERAL);
            }

            str = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestGrantUriPermission_pathPrefix, 0);
            if (str != null) {
                pa = new PatternMatcher(str, PatternMatcher.PATTERN_PREFIX);
            }

            str = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestGrantUriPermission_pathPattern, 0);
            if (str != null) {
                pa = new PatternMatcher(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
            }

            sa.recycle();

            if (pa != null) {
                if (outInfo.info.uriPermissionPatterns == null) {
                    outInfo.info.uriPermissionPatterns = new PatternMatcher[1];
                    outInfo.info.uriPermissionPatterns[0] = pa;
                } else {
                    final int N = outInfo.info.uriPermissionPatterns.length;
                    PatternMatcher[] newp = new PatternMatcher[N + 1];
                    System.arraycopy(outInfo.info.uriPermissionPatterns, 0, newp, 0, N);
                    newp[N] = pa;
                    outInfo.info.uriPermissionPatterns = newp;
                }
                outInfo.info.grantUriPermissions = true;
            } else {
                if (!RIGID_PARSER) {
                    Slog.w(TAG, "Unknown element under <path-permission>: " + parser.getName() + " at "
                            + mArchiveSourcePath + " " + parser.getPositionDescription());
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                } else {
                    outError[0] = "No path, pathPrefix, or pathPattern for <path-permission>";
                    return false;
                }
            }
            XmlUtils.skipCurrentTag(parser);

        } else if (parser.getName().equals("path-permission")) {
            TypedArray sa = res.obtainAttributes(attrs,
                    com.android.internal.R.styleable.AndroidManifestPathPermission);

            PathPermission pa = null;

            String permission = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestPathPermission_permission, 0);
            String readPermission = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestPathPermission_readPermission, 0);
            if (readPermission == null) {
                readPermission = permission;
            }
            String writePermission = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestPathPermission_writePermission, 0);
            if (writePermission == null) {
                writePermission = permission;
            }

            boolean havePerm = false;
            if (readPermission != null) {
                readPermission = readPermission.intern();
                havePerm = true;
            }
            if (writePermission != null) {
                writePermission = writePermission.intern();
                havePerm = true;
            }

            if (!havePerm) {
                if (!RIGID_PARSER) {
                    Slog.w(TAG, "No readPermission or writePermssion for <path-permission>: " + parser.getName()
                            + " at " + mArchiveSourcePath + " " + parser.getPositionDescription());
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                } else {
                    outError[0] = "No readPermission or writePermssion for <path-permission>";
                    return false;
                }
            }

            String path = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestPathPermission_path, 0);
            if (path != null) {
                pa = new PathPermission(path, PatternMatcher.PATTERN_LITERAL, readPermission, writePermission);
            }

            path = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestPathPermission_pathPrefix, 0);
            if (path != null) {
                pa = new PathPermission(path, PatternMatcher.PATTERN_PREFIX, readPermission, writePermission);
            }

            path = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestPathPermission_pathPattern, 0);
            if (path != null) {
                pa = new PathPermission(path, PatternMatcher.PATTERN_SIMPLE_GLOB, readPermission,
                        writePermission);
            }

            sa.recycle();

            if (pa != null) {
                if (outInfo.info.pathPermissions == null) {
                    outInfo.info.pathPermissions = new PathPermission[1];
                    outInfo.info.pathPermissions[0] = pa;
                } else {
                    final int N = outInfo.info.pathPermissions.length;
                    PathPermission[] newp = new PathPermission[N + 1];
                    System.arraycopy(outInfo.info.pathPermissions, 0, newp, 0, N);
                    newp[N] = pa;
                    outInfo.info.pathPermissions = newp;
                }
            } else {
                if (!RIGID_PARSER) {
                    Slog.w(TAG, "No path, pathPrefix, or pathPattern for <path-permission>: " + parser.getName()
                            + " at " + mArchiveSourcePath + " " + parser.getPositionDescription());
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                }
                outError[0] = "No path, pathPrefix, or pathPattern for <path-permission>";
                return false;
            }
            XmlUtils.skipCurrentTag(parser);

        } else {
            if (!RIGID_PARSER) {
                Slog.w(TAG, "Unknown element under <provider>: " + parser.getName() + " at "
                        + mArchiveSourcePath + " " + parser.getPositionDescription());
                XmlUtils.skipCurrentTag(parser);
                continue;
            } else {
                outError[0] = "Bad element under <provider>: " + parser.getName();
                return false;
            }
        }
    }
    return true;
}

From source file:android.content.pm.PackageParser.java

/**
 * Parse the manifest of a <em>base APK</em>.
 * <p>// www. ja  v  a  2  s . c  o m
 * When adding new features, carefully consider if they should also be
 * supported by split APKs.
 */
private Package parseBaseApk(Resources res, XmlResourceParser parser, int flags, String[] outError)
        throws XmlPullParserException, IOException {
    final boolean trustedOverlay = (flags & PARSE_TRUSTED_OVERLAY) != 0;

    AttributeSet attrs = parser;

    mParseInstrumentationArgs = null;
    mParseActivityArgs = null;
    mParseServiceArgs = null;
    mParseProviderArgs = null;

    final String pkgName;
    final String splitName;
    try {
        Pair<String, String> packageSplit = parsePackageSplitNames(parser, attrs, flags);
        pkgName = packageSplit.first;
        splitName = packageSplit.second;
    } catch (PackageParserException e) {
        mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
        return null;
    }

    int type;

    if (!TextUtils.isEmpty(splitName)) {
        outError[0] = "Expected base APK, but found split " + splitName;
        mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
        return null;
    }

    final Package pkg = new Package(pkgName);
    boolean foundApp = false;

    TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifest);
    pkg.mVersionCode = pkg.applicationInfo.versionCode = sa
            .getInteger(com.android.internal.R.styleable.AndroidManifest_versionCode, 0);
    pkg.baseRevisionCode = sa.getInteger(com.android.internal.R.styleable.AndroidManifest_revisionCode, 0);
    pkg.mVersionName = sa
            .getNonConfigurationString(com.android.internal.R.styleable.AndroidManifest_versionName, 0);
    if (pkg.mVersionName != null) {
        pkg.mVersionName = pkg.mVersionName.intern();
    }
    String str = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifest_sharedUserId, 0);
    if (str != null && str.length() > 0) {
        String nameError = validateName(str, true, false);
        if (nameError != null && !"android".equals(pkgName)) {
            outError[0] = "<manifest> specifies bad sharedUserId name \"" + str + "\": " + nameError;
            mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID;
            return null;
        }
        pkg.mSharedUserId = str.intern();
        pkg.mSharedUserLabel = sa
                .getResourceId(com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0);
    }

    pkg.installLocation = sa.getInteger(com.android.internal.R.styleable.AndroidManifest_installLocation,
            PARSE_DEFAULT_INSTALL_LOCATION);
    pkg.applicationInfo.installLocation = pkg.installLocation;

    pkg.coreApp = attrs.getAttributeBooleanValue(null, "coreApp", false);

    sa.recycle();

    /* Set the global "forward lock" flag */
    if ((flags & PARSE_FORWARD_LOCK) != 0) {
        pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_FORWARD_LOCK;
    }

    /* Set the global "on SD card" flag */
    if ((flags & PARSE_EXTERNAL_STORAGE) != 0) {
        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
    }

    // Resource boolean are -1, so 1 means we don't know the value.
    int supportsSmallScreens = 1;
    int supportsNormalScreens = 1;
    int supportsLargeScreens = 1;
    int supportsXLargeScreens = 1;
    int resizeable = 1;
    int anyDensity = 1;

    int outerDepth = parser.getDepth();
    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
            && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
        if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
            continue;
        }

        String tagName = parser.getName();
        if (tagName.equals("application")) {
            if (foundApp) {
                if (RIGID_PARSER) {
                    outError[0] = "<manifest> has more than one <application>";
                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                    return null;
                } else {
                    Slog.w(TAG, "<manifest> has more than one <application>");
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                }
            }

            foundApp = true;
            if (!parseBaseApplication(pkg, res, parser, attrs, flags, outError)) {
                return null;
            }
        } else if (tagName.equals("overlay")) {
            pkg.mTrustedOverlay = trustedOverlay;

            sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestResourceOverlay);
            pkg.mOverlayTarget = sa
                    .getString(com.android.internal.R.styleable.AndroidManifestResourceOverlay_targetPackage);
            pkg.mOverlayPriority = sa
                    .getInt(com.android.internal.R.styleable.AndroidManifestResourceOverlay_priority, -1);
            sa.recycle();

            if (pkg.mOverlayTarget == null) {
                outError[0] = "<overlay> does not specify a target package";
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return null;
            }
            if (pkg.mOverlayPriority < 0 || pkg.mOverlayPriority > 9999) {
                outError[0] = "<overlay> priority must be between 0 and 9999";
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return null;
            }
            XmlUtils.skipCurrentTag(parser);

        } else if (tagName.equals("key-sets")) {
            if (!parseKeySets(pkg, res, parser, attrs, outError)) {
                return null;
            }
        } else if (tagName.equals("permission-group")) {
            if (parsePermissionGroup(pkg, flags, res, parser, attrs, outError) == null) {
                return null;
            }
        } else if (tagName.equals("permission")) {
            if (parsePermission(pkg, res, parser, attrs, outError) == null) {
                return null;
            }
        } else if (tagName.equals("permission-tree")) {
            if (parsePermissionTree(pkg, res, parser, attrs, outError) == null) {
                return null;
            }
        } else if (tagName.equals("uses-permission")) {
            if (!parseUsesPermission(pkg, res, parser, attrs)) {
                return null;
            }
        } else if (tagName.equals("uses-permission-sdk-m") || tagName.equals("uses-permission-sdk-23")) {
            if (!parseUsesPermission(pkg, res, parser, attrs)) {
                return null;
            }
        } else if (tagName.equals("uses-configuration")) {
            ConfigurationInfo cPref = new ConfigurationInfo();
            sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestUsesConfiguration);
            cPref.reqTouchScreen = sa.getInt(
                    com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqTouchScreen,
                    Configuration.TOUCHSCREEN_UNDEFINED);
            cPref.reqKeyboardType = sa.getInt(
                    com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqKeyboardType,
                    Configuration.KEYBOARD_UNDEFINED);
            if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqHardKeyboard,
                    false)) {
                cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
            }
            cPref.reqNavigation = sa.getInt(
                    com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqNavigation,
                    Configuration.NAVIGATION_UNDEFINED);
            if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqFiveWayNav,
                    false)) {
                cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
            }
            sa.recycle();
            pkg.configPreferences = ArrayUtils.add(pkg.configPreferences, cPref);

            XmlUtils.skipCurrentTag(parser);

        } else if (tagName.equals("uses-feature")) {
            FeatureInfo fi = parseUsesFeature(res, attrs);
            pkg.reqFeatures = ArrayUtils.add(pkg.reqFeatures, fi);

            if (fi.name == null) {
                ConfigurationInfo cPref = new ConfigurationInfo();
                cPref.reqGlEsVersion = fi.reqGlEsVersion;
                pkg.configPreferences = ArrayUtils.add(pkg.configPreferences, cPref);
            }

            XmlUtils.skipCurrentTag(parser);

        } else if (tagName.equals("feature-group")) {
            FeatureGroupInfo group = new FeatureGroupInfo();
            ArrayList<FeatureInfo> features = null;
            final int innerDepth = parser.getDepth();
            while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                    && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
                if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                    continue;
                }

                final String innerTagName = parser.getName();
                if (innerTagName.equals("uses-feature")) {
                    FeatureInfo featureInfo = parseUsesFeature(res, attrs);
                    // FeatureGroups are stricter and mandate that
                    // any <uses-feature> declared are mandatory.
                    featureInfo.flags |= FeatureInfo.FLAG_REQUIRED;
                    features = ArrayUtils.add(features, featureInfo);
                } else {
                    Slog.w(TAG, "Unknown element under <feature-group>: " + innerTagName + " at "
                            + mArchiveSourcePath + " " + parser.getPositionDescription());
                }
                XmlUtils.skipCurrentTag(parser);
            }

            if (features != null) {
                group.features = new FeatureInfo[features.size()];
                group.features = features.toArray(group.features);
            }
            pkg.featureGroups = ArrayUtils.add(pkg.featureGroups, group);

        } else if (tagName.equals("uses-sdk")) {
            if (SDK_VERSION > 0) {
                sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestUsesSdk);

                int minVers = 0;
                String minCode = null;
                int targetVers = 0;
                String targetCode = null;

                TypedValue val = sa
                        .peekValue(com.android.internal.R.styleable.AndroidManifestUsesSdk_minSdkVersion);
                if (val != null) {
                    if (val.type == TypedValue.TYPE_STRING && val.string != null) {
                        targetCode = minCode = val.string.toString();
                    } else {
                        // If it's not a string, it's an integer.
                        targetVers = minVers = val.data;
                    }
                }

                val = sa.peekValue(com.android.internal.R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
                if (val != null) {
                    if (val.type == TypedValue.TYPE_STRING && val.string != null) {
                        targetCode = minCode = val.string.toString();
                    } else {
                        // If it's not a string, it's an integer.
                        targetVers = val.data;
                    }
                }

                sa.recycle();

                if (minCode != null) {
                    boolean allowedCodename = false;
                    for (String codename : SDK_CODENAMES) {
                        if (minCode.equals(codename)) {
                            allowedCodename = true;
                            break;
                        }
                    }
                    if (!allowedCodename) {
                        if (SDK_CODENAMES.length > 0) {
                            outError[0] = "Requires development platform " + minCode
                                    + " (current platform is any of " + Arrays.toString(SDK_CODENAMES) + ")";
                        } else {
                            outError[0] = "Requires development platform " + minCode
                                    + " but this is a release platform.";
                        }
                        mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
                        return null;
                    }
                } else if (minVers > SDK_VERSION) {
                    outError[0] = "Requires newer sdk version #" + minVers + " (current version is #"
                            + SDK_VERSION + ")";
                    mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
                    return null;
                }

                if (targetCode != null) {
                    boolean allowedCodename = false;
                    for (String codename : SDK_CODENAMES) {
                        if (targetCode.equals(codename)) {
                            allowedCodename = true;
                            break;
                        }
                    }
                    if (!allowedCodename) {
                        if (SDK_CODENAMES.length > 0) {
                            outError[0] = "Requires development platform " + targetCode
                                    + " (current platform is any of " + Arrays.toString(SDK_CODENAMES) + ")";
                        } else {
                            outError[0] = "Requires development platform " + targetCode
                                    + " but this is a release platform.";
                        }
                        mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
                        return null;
                    }
                    // If the code matches, it definitely targets this SDK.
                    pkg.applicationInfo.targetSdkVersion = android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
                } else {
                    pkg.applicationInfo.targetSdkVersion = targetVers;
                }
            }

            XmlUtils.skipCurrentTag(parser);

        } else if (tagName.equals("supports-screens")) {
            sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestSupportsScreens);

            pkg.applicationInfo.requiresSmallestWidthDp = sa.getInteger(
                    com.android.internal.R.styleable.AndroidManifestSupportsScreens_requiresSmallestWidthDp, 0);
            pkg.applicationInfo.compatibleWidthLimitDp = sa.getInteger(
                    com.android.internal.R.styleable.AndroidManifestSupportsScreens_compatibleWidthLimitDp, 0);
            pkg.applicationInfo.largestWidthLimitDp = sa.getInteger(
                    com.android.internal.R.styleable.AndroidManifestSupportsScreens_largestWidthLimitDp, 0);

            // This is a trick to get a boolean and still able to detect
            // if a value was actually set.
            supportsSmallScreens = sa.getInteger(
                    com.android.internal.R.styleable.AndroidManifestSupportsScreens_smallScreens,
                    supportsSmallScreens);
            supportsNormalScreens = sa.getInteger(
                    com.android.internal.R.styleable.AndroidManifestSupportsScreens_normalScreens,
                    supportsNormalScreens);
            supportsLargeScreens = sa.getInteger(
                    com.android.internal.R.styleable.AndroidManifestSupportsScreens_largeScreens,
                    supportsLargeScreens);
            supportsXLargeScreens = sa.getInteger(
                    com.android.internal.R.styleable.AndroidManifestSupportsScreens_xlargeScreens,
                    supportsXLargeScreens);
            resizeable = sa.getInteger(
                    com.android.internal.R.styleable.AndroidManifestSupportsScreens_resizeable, resizeable);
            anyDensity = sa.getInteger(
                    com.android.internal.R.styleable.AndroidManifestSupportsScreens_anyDensity, anyDensity);

            sa.recycle();

            XmlUtils.skipCurrentTag(parser);

        } else if (tagName.equals("protected-broadcast")) {
            sa = res.obtainAttributes(attrs,
                    com.android.internal.R.styleable.AndroidManifestProtectedBroadcast);

            // Note: don't allow this value to be a reference to a resource
            // that may change.
            String name = sa.getNonResourceString(
                    com.android.internal.R.styleable.AndroidManifestProtectedBroadcast_name);

            sa.recycle();

            if (name != null && (flags & PARSE_IS_SYSTEM) != 0) {
                if (pkg.protectedBroadcasts == null) {
                    pkg.protectedBroadcasts = new ArrayList<String>();
                }
                if (!pkg.protectedBroadcasts.contains(name)) {
                    pkg.protectedBroadcasts.add(name.intern());
                }
            }

            XmlUtils.skipCurrentTag(parser);

        } else if (tagName.equals("instrumentation")) {
            if (parseInstrumentation(pkg, res, parser, attrs, outError) == null) {
                return null;
            }

        } else if (tagName.equals("original-package")) {
            sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestOriginalPackage);

            String orig = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestOriginalPackage_name, 0);
            if (!pkg.packageName.equals(orig)) {
                if (pkg.mOriginalPackages == null) {
                    pkg.mOriginalPackages = new ArrayList<String>();
                    pkg.mRealPackage = pkg.packageName;
                }
                pkg.mOriginalPackages.add(orig);
            }

            sa.recycle();

            XmlUtils.skipCurrentTag(parser);

        } else if (tagName.equals("adopt-permissions")) {
            sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestOriginalPackage);

            String name = sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestOriginalPackage_name, 0);

            sa.recycle();

            if (name != null) {
                if (pkg.mAdoptPermissions == null) {
                    pkg.mAdoptPermissions = new ArrayList<String>();
                }
                pkg.mAdoptPermissions.add(name);
            }

            XmlUtils.skipCurrentTag(parser);

        } else if (tagName.equals("uses-gl-texture")) {
            // Just skip this tag
            XmlUtils.skipCurrentTag(parser);
            continue;

        } else if (tagName.equals("compatible-screens")) {
            // Just skip this tag
            XmlUtils.skipCurrentTag(parser);
            continue;
        } else if (tagName.equals("supports-input")) {
            XmlUtils.skipCurrentTag(parser);
            continue;

        } else if (tagName.equals("eat-comment")) {
            // Just skip this tag
            XmlUtils.skipCurrentTag(parser);
            continue;

        } else if (RIGID_PARSER) {
            outError[0] = "Bad element under <manifest>: " + parser.getName();
            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
            return null;

        } else {
            Slog.w(TAG, "Unknown element under <manifest>: " + parser.getName() + " at " + mArchiveSourcePath
                    + " " + parser.getPositionDescription());
            XmlUtils.skipCurrentTag(parser);
            continue;
        }
    }

    if (!foundApp && pkg.instrumentation.size() == 0) {
        outError[0] = "<manifest> does not contain an <application> or <instrumentation>";
        mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY;
    }

    final int NP = PackageParser.NEW_PERMISSIONS.length;
    StringBuilder implicitPerms = null;
    for (int ip = 0; ip < NP; ip++) {
        final PackageParser.NewPermissionInfo npi = PackageParser.NEW_PERMISSIONS[ip];
        if (pkg.applicationInfo.targetSdkVersion >= npi.sdkVersion) {
            break;
        }
        if (!pkg.requestedPermissions.contains(npi.name)) {
            if (implicitPerms == null) {
                implicitPerms = new StringBuilder(128);
                implicitPerms.append(pkg.packageName);
                implicitPerms.append(": compat added ");
            } else {
                implicitPerms.append(' ');
            }
            implicitPerms.append(npi.name);
            pkg.requestedPermissions.add(npi.name);
        }
    }
    if (implicitPerms != null) {
        Slog.i(TAG, implicitPerms.toString());
    }

    final int NS = PackageParser.SPLIT_PERMISSIONS.length;
    for (int is = 0; is < NS; is++) {
        final PackageParser.SplitPermissionInfo spi = PackageParser.SPLIT_PERMISSIONS[is];
        if (pkg.applicationInfo.targetSdkVersion >= spi.targetSdk
                || !pkg.requestedPermissions.contains(spi.rootPerm)) {
            continue;
        }
        for (int in = 0; in < spi.newPerms.length; in++) {
            final String perm = spi.newPerms[in];
            if (!pkg.requestedPermissions.contains(perm)) {
                pkg.requestedPermissions.add(perm);
            }
        }
    }

    if (supportsSmallScreens < 0 || (supportsSmallScreens > 0
            && pkg.applicationInfo.targetSdkVersion >= android.os.Build.VERSION_CODES.DONUT)) {
        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
    }
    if (supportsNormalScreens != 0) {
        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS;
    }
    if (supportsLargeScreens < 0 || (supportsLargeScreens > 0
            && pkg.applicationInfo.targetSdkVersion >= android.os.Build.VERSION_CODES.DONUT)) {
        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
    }
    if (supportsXLargeScreens < 0 || (supportsXLargeScreens > 0
            && pkg.applicationInfo.targetSdkVersion >= android.os.Build.VERSION_CODES.GINGERBREAD)) {
        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS;
    }
    if (resizeable < 0 || (resizeable > 0
            && pkg.applicationInfo.targetSdkVersion >= android.os.Build.VERSION_CODES.DONUT)) {
        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS;
    }
    if (anyDensity < 0 || (anyDensity > 0
            && pkg.applicationInfo.targetSdkVersion >= android.os.Build.VERSION_CODES.DONUT)) {
        pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
    }

    return pkg;
}

From source file:android.content.pm.PackageParser.java

private boolean parseKeySets(Package owner, Resources res, XmlPullParser parser, AttributeSet attrs,
        String[] outError) throws XmlPullParserException, IOException {
    // we've encountered the 'key-sets' tag
    // all the keys and keysets that we want must be defined here
    // so we're going to iterate over the parser and pull out the things we want
    int outerDepth = parser.getDepth();
    int currentKeySetDepth = -1;
    int type;//ww w. j  a va  2s . c  o m
    String currentKeySet = null;
    ArrayMap<String, PublicKey> publicKeys = new ArrayMap<String, PublicKey>();
    ArraySet<String> upgradeKeySets = new ArraySet<String>();
    ArrayMap<String, ArraySet<String>> definedKeySets = new ArrayMap<String, ArraySet<String>>();
    ArraySet<String> improperKeySets = new ArraySet<String>();
    while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
            && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
        if (type == XmlPullParser.END_TAG) {
            if (parser.getDepth() == currentKeySetDepth) {
                currentKeySet = null;
                currentKeySetDepth = -1;
            }
            continue;
        }
        String tagName = parser.getName();
        if (tagName.equals("key-set")) {
            if (currentKeySet != null) {
                outError[0] = "Improperly nested 'key-set' tag at " + parser.getPositionDescription();
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }
            final TypedArray sa = res.obtainAttributes(attrs,
                    com.android.internal.R.styleable.AndroidManifestKeySet);
            final String keysetName = sa
                    .getNonResourceString(com.android.internal.R.styleable.AndroidManifestKeySet_name);
            definedKeySets.put(keysetName, new ArraySet<String>());
            currentKeySet = keysetName;
            currentKeySetDepth = parser.getDepth();
            sa.recycle();
        } else if (tagName.equals("public-key")) {
            if (currentKeySet == null) {
                outError[0] = "Improperly nested 'key-set' tag at " + parser.getPositionDescription();
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                return false;
            }
            final TypedArray sa = res.obtainAttributes(attrs,
                    com.android.internal.R.styleable.AndroidManifestPublicKey);
            final String publicKeyName = sa
                    .getNonResourceString(com.android.internal.R.styleable.AndroidManifestPublicKey_name);
            final String encodedKey = sa
                    .getNonResourceString(com.android.internal.R.styleable.AndroidManifestPublicKey_value);
            if (encodedKey == null && publicKeys.get(publicKeyName) == null) {
                outError[0] = "'public-key' " + publicKeyName + " must define a public-key value"
                        + " on first use at " + parser.getPositionDescription();
                mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                sa.recycle();
                return false;
            } else if (encodedKey != null) {
                PublicKey currentKey = parsePublicKey(encodedKey);
                if (currentKey == null) {
                    Slog.w(TAG,
                            "No recognized valid key in 'public-key' tag at " + parser.getPositionDescription()
                                    + " key-set " + currentKeySet
                                    + " will not be added to the package's defined key-sets.");
                    sa.recycle();
                    improperKeySets.add(currentKeySet);
                    XmlUtils.skipCurrentTag(parser);
                    continue;
                }
                if (publicKeys.get(publicKeyName) == null || publicKeys.get(publicKeyName).equals(currentKey)) {

                    /* public-key first definition, or matches old definition */
                    publicKeys.put(publicKeyName, currentKey);
                } else {
                    outError[0] = "Value of 'public-key' " + publicKeyName
                            + " conflicts with previously defined value at " + parser.getPositionDescription();
                    mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
                    sa.recycle();
                    return false;
                }
            }
            definedKeySets.get(currentKeySet).add(publicKeyName);
            sa.recycle();
            XmlUtils.skipCurrentTag(parser);
        } else if (tagName.equals("upgrade-key-set")) {
            final TypedArray sa = res.obtainAttributes(attrs,
                    com.android.internal.R.styleable.AndroidManifestUpgradeKeySet);
            String name = sa
                    .getNonResourceString(com.android.internal.R.styleable.AndroidManifestUpgradeKeySet_name);
            upgradeKeySets.add(name);
            sa.recycle();
            XmlUtils.skipCurrentTag(parser);
        } else if (RIGID_PARSER) {
            outError[0] = "Bad element under <key-sets>: " + parser.getName() + " at " + mArchiveSourcePath
                    + " " + parser.getPositionDescription();
            mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
            return false;
        } else {
            Slog.w(TAG, "Unknown element under <key-sets>: " + parser.getName() + " at " + mArchiveSourcePath
                    + " " + parser.getPositionDescription());
            XmlUtils.skipCurrentTag(parser);
            continue;
        }
    }
    Set<String> publicKeyNames = publicKeys.keySet();
    if (publicKeyNames.removeAll(definedKeySets.keySet())) {
        outError[0] = "Package" + owner.packageName + " AndroidManifext.xml "
                + "'key-set' and 'public-key' names must be distinct.";
        mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
        return false;
    }
    owner.mKeySetMapping = new ArrayMap<String, ArraySet<PublicKey>>();
    for (ArrayMap.Entry<String, ArraySet<String>> e : definedKeySets.entrySet()) {
        final String keySetName = e.getKey();
        if (e.getValue().size() == 0) {
            Slog.w(TAG,
                    "Package" + owner.packageName + " AndroidManifext.xml " + "'key-set' " + keySetName
                            + " has no valid associated 'public-key'."
                            + " Not including in package's defined key-sets.");
            continue;
        } else if (improperKeySets.contains(keySetName)) {
            Slog.w(TAG,
                    "Package" + owner.packageName + " AndroidManifext.xml " + "'key-set' " + keySetName
                            + " contained improper 'public-key'"
                            + " tags. Not including in package's defined key-sets.");
            continue;
        }
        owner.mKeySetMapping.put(keySetName, new ArraySet<PublicKey>());
        for (String s : e.getValue()) {
            owner.mKeySetMapping.get(keySetName).add(publicKeys.get(s));
        }
    }
    if (owner.mKeySetMapping.keySet().containsAll(upgradeKeySets)) {
        owner.mUpgradeKeySets = upgradeKeySets;
    } else {
        outError[0] = "Package" + owner.packageName + " AndroidManifext.xml "
                + "does not define all 'upgrade-key-set's .";
        mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
        return false;
    }
    return true;
}