Example usage for android.content.res TypedArray peekValue

List of usage examples for android.content.res TypedArray peekValue

Introduction

In this page you can find the example usage for android.content.res TypedArray peekValue.

Prototype

public TypedValue peekValue(@StyleableRes int index) 

Source Link

Document

Retrieve the raw TypedValue for the attribute at index and return a temporary object holding its data.

Usage

From source file:com.android.incallui.widget.multiwaveview.GlowPadView.java

private ArrayList<TargetDrawable> loadDrawableArray(int resourceId) {
    Resources res = getContext().getResources();
    TypedArray array = res.obtainTypedArray(resourceId);
    final int count = array.length();
    ArrayList<TargetDrawable> drawables = new ArrayList<TargetDrawable>(count);
    for (int i = 0; i < count; i++) {
        TypedValue value = array.peekValue(i);
        TargetDrawable target = new TargetDrawable(res, value != null ? value.resourceId : 0, 3);
        drawables.add(target);/*from ww w.ja  va2 s.  c  o  m*/
    }
    array.recycle();
    return drawables;
}

From source file:com.klinker.deskclock.widget.multiwaveview.GlowPadView.java

public GlowPadView(Context context, AttributeSet attrs) {
    super(context, attrs);
    Resources res = context.getResources();

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GlowPadView);
    mInnerRadius = a.getDimension(R.styleable.GlowPadView_innerRadius, mInnerRadius);
    mOuterRadius = a.getDimension(R.styleable.GlowPadView_outerRadius, mOuterRadius);
    mSnapMargin = a.getDimension(R.styleable.GlowPadView_snapMargin, mSnapMargin);
    mVibrationDuration = a.getInt(R.styleable.GlowPadView_vibrationDuration, mVibrationDuration);
    mFeedbackCount = a.getInt(R.styleable.GlowPadView_feedbackCount, mFeedbackCount);
    TypedValue handle = a.peekValue(R.styleable.GlowPadView_handleDrawable);
    mHandleDrawable = new TargetDrawable(res, handle != null ? handle.resourceId : 0, 2);
    mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE);
    mOuterRing = new TargetDrawable(res, getResourceId(a, R.styleable.GlowPadView_outerRingDrawable), 1);

    mAlwaysTrackFinger = a.getBoolean(R.styleable.GlowPadView_alwaysTrackFinger, false);

    int pointId = getResourceId(a, R.styleable.GlowPadView_pointDrawable);
    Drawable pointDrawable = pointId != 0 ? res.getDrawable(pointId) : null;
    mGlowRadius = a.getDimension(R.styleable.GlowPadView_glowRadius, 0.0f);

    TypedValue outValue = new TypedValue();

    // Read array of target drawables
    if (a.getValue(R.styleable.GlowPadView_targetDrawables, outValue)) {
        internalSetTargetResources(outValue.resourceId);
    }//from   w w  w.  ja  v a2  s.  c  om
    if (mTargetDrawables == null || mTargetDrawables.size() == 0) {
        throw new IllegalStateException("Must specify at least one target drawable");
    }

    // Read array of target descriptions
    if (a.getValue(R.styleable.GlowPadView_targetDescriptions, outValue)) {
        final int resourceId = outValue.resourceId;
        if (resourceId == 0) {
            throw new IllegalStateException("Must specify target descriptions");
        }
        setTargetDescriptionsResourceId(resourceId);
    }

    // Read array of direction descriptions
    if (a.getValue(R.styleable.GlowPadView_directionDescriptions, outValue)) {
        final int resourceId = outValue.resourceId;
        if (resourceId == 0) {
            throw new IllegalStateException("Must specify direction descriptions");
        }
        setDirectionDescriptionsResourceId(resourceId);
    }

    a.recycle();

    // Use gravity attribute from LinearLayout
    //a = context.obtainStyledAttributes(attrs, R.styleable.LinearLayout);
    mGravity = a.getInt(R.styleable.GlowPadView_android_gravity, Gravity.TOP);
    a.recycle();

    setVibrateEnabled(mVibrationDuration > 0);

    assignDefaultsIfNeeded();

    mPointCloud = new PointCloud(pointDrawable);
    mPointCloud.makePointCloud(mInnerRadius, mOuterRadius);
    mPointCloud.glowManager.setRadius(mGlowRadius);
}

From source file:com.android.incallui.widget.multiwaveview.GlowPadView.java

public GlowPadView(Context context, AttributeSet attrs) {
    super(context, attrs);
    Resources res = context.getResources();

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GlowPadView);
    mInnerRadius = a.getDimension(R.styleable.GlowPadView_innerRadius, mInnerRadius);
    mOuterRadius = a.getDimension(R.styleable.GlowPadView_outerRadius, mOuterRadius);
    mSnapMargin = a.getDimension(R.styleable.GlowPadView_snapMargin, mSnapMargin);
    mVibrationDuration = a.getInt(R.styleable.GlowPadView_vibrationDuration, mVibrationDuration);
    mFeedbackCount = a.getInt(R.styleable.GlowPadView_feedbackCount, mFeedbackCount);
    mAllowScaling = a.getBoolean(R.styleable.GlowPadView_allowScaling, false);
    TypedValue handle = a.peekValue(R.styleable.GlowPadView_handleDrawable);
    setHandleDrawable(handle != null ? handle.resourceId : R.drawable.ic_incall_audio_handle);
    mOuterRing = new TargetDrawable(res, getResourceId(a, R.styleable.GlowPadView_outerRingDrawable), 1);

    mAlwaysTrackFinger = a.getBoolean(R.styleable.GlowPadView_alwaysTrackFinger, false);

    int pointId = getResourceId(a, R.styleable.GlowPadView_pointDrawable);
    Drawable pointDrawable = pointId != 0 ? res.getDrawable(pointId) : null;
    mGlowRadius = a.getDimension(R.styleable.GlowPadView_glowRadius, 0.0f);

    TypedValue outValue = new TypedValue();

    // Read array of target drawables
    if (a.getValue(R.styleable.GlowPadView_targetDrawables, outValue)) {
        internalSetTargetResources(outValue.resourceId);
    }//from w  w w  .ja  va 2 s.  com
    if (mTargetDrawables == null || mTargetDrawables.size() == 0) {
        throw new IllegalStateException("Must specify at least one target drawable");
    }

    // Read array of target descriptions
    if (a.getValue(R.styleable.GlowPadView_targetDescriptions, outValue)) {
        final int resourceId = outValue.resourceId;
        if (resourceId == 0) {
            throw new IllegalStateException("Must specify target descriptions");
        }
        setTargetDescriptionsResourceId(resourceId);
    }

    // Read array of direction descriptions
    if (a.getValue(R.styleable.GlowPadView_directionDescriptions, outValue)) {
        final int resourceId = outValue.resourceId;
        if (resourceId == 0) {
            throw new IllegalStateException("Must specify direction descriptions");
        }
        setDirectionDescriptionsResourceId(resourceId);
    }

    // Use gravity attribute from LinearLayout
    //a = context.obtainStyledAttributes(attrs, R.styleable.LinearLayout);
    mGravity = a.getInt(R.styleable.GlowPadView_android_gravity, Gravity.TOP);
    a.recycle();

    setVibrateEnabled(mVibrationDuration > 0);

    assignDefaultsIfNeeded();

    mPointCloud = new PointCloud(pointDrawable);
    mPointCloud.makePointCloud(mInnerRadius, mOuterRadius);
    mPointCloud.glowManager.setRadius(mGlowRadius);

    mExploreByTouchHelper = new GlowpadExploreByTouchHelper(this);
    ViewCompat.setAccessibilityDelegate(this, mExploreByTouchHelper);
}

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

private boolean parseUsesPermission(Package pkg, Resources res, XmlResourceParser parser, AttributeSet attrs)
        throws XmlPullParserException, IOException {
    TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestUsesPermission);

    // 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.AndroidManifestUsesPermission_name);

    int maxSdkVersion = 0;
    TypedValue val = sa.peekValue(com.android.internal.R.styleable.AndroidManifestUsesPermission_maxSdkVersion);
    if (val != null) {
        if (val.type >= TypedValue.TYPE_FIRST_INT && val.type <= TypedValue.TYPE_LAST_INT) {
            maxSdkVersion = val.data;
        }/*w  w w.j  a v  a2 s .  co  m*/
    }

    sa.recycle();

    if ((maxSdkVersion == 0) || (maxSdkVersion >= Build.VERSION.RESOURCES_SDK_INT)) {
        if (name != null) {
            int index = pkg.requestedPermissions.indexOf(name);
            if (index == -1) {
                pkg.requestedPermissions.add(name.intern());
            } else {
                Slog.w(TAG, "Ignoring duplicate uses-permissions/uses-permissions-sdk-m: " + name
                        + " in package: " + pkg.packageName + " at: " + parser.getPositionDescription());
            }
        }
    }

    XmlUtils.skipCurrentTag(parser);
    return true;
}

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  ww w . j  a  v  a 2  s . 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 Bundle parseMetaData(Resources res, XmlPullParser parser, AttributeSet attrs, Bundle data,
        String[] outError) throws XmlPullParserException, IOException {

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

    if (data == null) {
        data = new Bundle();
    }/* www .  j  a  va  2 s.c  o m*/

    String name = sa.getNonConfigurationString(com.android.internal.R.styleable.AndroidManifestMetaData_name,
            0);
    if (name == null) {
        outError[0] = "<meta-data> requires an android:name attribute";
        sa.recycle();
        return null;
    }

    name = name.intern();

    TypedValue v = sa.peekValue(com.android.internal.R.styleable.AndroidManifestMetaData_resource);
    if (v != null && v.resourceId != 0) {
        //Slog.i(TAG, "Meta data ref " + name + ": " + v);
        data.putInt(name, v.resourceId);
    } else {
        v = sa.peekValue(com.android.internal.R.styleable.AndroidManifestMetaData_value);
        //Slog.i(TAG, "Meta data " + name + ": " + v);
        if (v != null) {
            if (v.type == TypedValue.TYPE_STRING) {
                CharSequence cs = v.coerceToString();
                data.putString(name, cs != null ? cs.toString().intern() : null);
            } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) {
                data.putBoolean(name, v.data != 0);
            } else if (v.type >= TypedValue.TYPE_FIRST_INT && v.type <= TypedValue.TYPE_LAST_INT) {
                data.putInt(name, v.data);
            } else if (v.type == TypedValue.TYPE_FLOAT) {
                data.putFloat(name, v.getFloat());
            } else {
                if (!RIGID_PARSER) {
                    Slog.w(TAG,
                            "<meta-data> only supports string, integer, float, color, boolean, and resource reference types: "
                                    + parser.getName() + " at " + mArchiveSourcePath + " "
                                    + parser.getPositionDescription());
                } else {
                    outError[0] = "<meta-data> only supports string, integer, float, color, boolean, and resource reference types";
                    data = null;
                }
            }
        } else {
            outError[0] = "<meta-data> requires an android:value or android:resource attribute";
            data = null;
        }
    }

    sa.recycle();

    XmlUtils.skipCurrentTag(parser);

    return data;
}

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

private boolean parsePackageItemInfo(Package owner, PackageItemInfo outInfo, String[] outError, String tag,
        TypedArray sa, int nameRes, int labelRes, int iconRes, int logoRes, int bannerRes) {
    String name = sa.getNonConfigurationString(nameRes, 0);
    if (name == null) {
        outError[0] = tag + " does not specify android:name";
        return false;
    }/*from ww  w.  j ava2s .c  o  m*/

    outInfo.name = buildClassName(owner.applicationInfo.packageName, name, outError);
    if (outInfo.name == null) {
        return false;
    }

    int iconVal = sa.getResourceId(iconRes, 0);
    if (iconVal != 0) {
        outInfo.icon = iconVal;
        outInfo.nonLocalizedLabel = null;
    }

    int logoVal = sa.getResourceId(logoRes, 0);
    if (logoVal != 0) {
        outInfo.logo = logoVal;
    }

    int bannerVal = sa.getResourceId(bannerRes, 0);
    if (bannerVal != 0) {
        outInfo.banner = bannerVal;
    }

    TypedValue v = sa.peekValue(labelRes);
    if (v != null && (outInfo.labelRes = v.resourceId) == 0) {
        outInfo.nonLocalizedLabel = v.coerceToString();
    }

    outInfo.packageName = owner.packageName;

    return true;
}

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 w w  w  .  j  a va 2s .c  om*/
 * 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

/**
 * Parse the manifest of a <em>base APK</em>.
 * <p>//from  www.ja v a  2s . 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;
}