Loading core/java/android/content/pm/parsing/ParsingPackageUtils.java +93 −15 Original line number Diff line number Diff line Loading @@ -1080,14 +1080,57 @@ public class ParsingPackageUtils { } } final String requiredFeature = sa.getNonConfigurationString( R.styleable.AndroidManifestUsesPermission_requiredFeature, 0); final ArraySet<String> requiredFeatures = new ArraySet<>(); String feature = sa.getNonConfigurationString( com.android.internal.R.styleable.AndroidManifestUsesPermission_requiredFeature, 0); if (feature != null) { requiredFeatures.add(feature); } final String requiredNotfeature = sa.getNonConfigurationString( R.styleable.AndroidManifestUsesPermission_requiredNotFeature, final ArraySet<String> requiredNotFeatures = new ArraySet<>(); feature = sa.getNonConfigurationString( com.android.internal.R.styleable .AndroidManifestUsesPermission_requiredNotFeature, 0); if (feature != null) { requiredNotFeatures.add(feature); } XmlUtils.skipCurrentTag(parser); final 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; } final ParseResult<?> result; switch (parser.getName()) { case "required-feature": result = parseRequiredFeature(input, res, parser); if (result.isSuccess()) { requiredFeatures.add((String) result.getResult()); } break; case "required-not-feature": result = parseRequiredNotFeature(input, res, parser); if (result.isSuccess()) { requiredNotFeatures.add((String) result.getResult()); } break; default: result = ParsingUtils.unknownTag("<uses-permission>", pkg, parser, input); break; } if (result.isError()) { return input.error(result); } } // Can only succeed from here on out ParseResult<ParsingPackage> success = input.success(pkg); Loading @@ -1100,18 +1143,23 @@ public class ParsingPackageUtils { return success; } // Only allow requesting this permission if the platform supports the given feature. if (requiredFeature != null && mCallback != null && !mCallback.hasFeature( requiredFeature)) { if (mCallback != null) { // Only allow requesting this permission if the platform supports all of the // "required-feature"s. for (int i = requiredFeatures.size() - 1; i >= 0; i--) { if (!mCallback.hasFeature(requiredFeatures.valueAt(i))) { return success; } } // Only allow requesting this permission if the platform doesn't support the given // feature. if (requiredNotfeature != null && mCallback != null && mCallback.hasFeature(requiredNotfeature)) { // Only allow requesting this permission if the platform does not supports any of // the "required-not-feature"s. for (int i = requiredNotFeatures.size() - 1; i >= 0; i--) { if (mCallback.hasFeature(requiredNotFeatures.valueAt(i))) { return success; } } } if (!pkg.getRequestedPermissions().contains(name)) { pkg.addRequestedPermission(name.intern()); Loading @@ -1127,6 +1175,36 @@ public class ParsingPackageUtils { } } private ParseResult<String> parseRequiredFeature(ParseInput input, Resources res, AttributeSet attrs) { final TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestRequiredFeature); try { final String featureName = sa.getString( R.styleable.AndroidManifestRequiredFeature_name); return TextUtils.isEmpty(featureName) ? input.error("Feature name is missing from <required-feature> tag.") : input.success(featureName); } finally { sa.recycle(); } } private ParseResult<String> parseRequiredNotFeature(ParseInput input, Resources res, AttributeSet attrs) { final TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestRequiredNotFeature); try { final String featureName = sa.getString( R.styleable.AndroidManifestRequiredNotFeature_name); return TextUtils.isEmpty(featureName) ? input.error("Feature name is missing from <required-not-feature> tag.") : input.success(featureName); } finally { sa.recycle(); } } private static ParseResult<ParsingPackage> parseUsesConfiguration(ParseInput input, ParsingPackage pkg, Resources res, XmlResourceParser parser) { ConfigurationInfo cPref = new ConfigurationInfo(); Loading core/res/res/values/attrs_manifest.xml +16 −0 Original line number Diff line number Diff line Loading @@ -2016,6 +2016,22 @@ <attr name="requiredNotFeature" format="string" /> </declare-styleable> <!-- <code>required-feature</code> and <code>required-not-feature</code> elements inside <code>uses-permission<code/> can be used to request the permission based on the fact whether the system supports or does not support certain features. If multiple <code>required-feature</code> and/or <code>required-not-feature</code> elements are present, the permission will be “requested” only if the system supports all of the listed "required-features" and does not support any of the "required-not-features". --> <declare-styleable name="AndroidManifestRequiredFeature"> <!-- The name of the feature. --> <attr name="name" /> </declare-styleable> <declare-styleable name="AndroidManifestRequiredNotFeature"> <!-- The name of the feature. --> <attr name="name" /> </declare-styleable> <!-- The <code>uses-configuration</code> tag specifies a specific hardware configuration value used by the application. For example an application might specify that it requires Loading tools/aapt2/dump/DumpManifest.cpp +120 −77 Original line number Diff line number Diff line Loading @@ -1063,17 +1063,23 @@ class UsesPermission : public ManifestExtractor::Element { public: UsesPermission() = default; std::string name; std::string requiredFeature; std::string requiredNotFeature; std::vector<std::string> requiredFeatures; std::vector<std::string> requiredNotFeatures; int32_t required = true; int32_t maxSdkVersion = -1; void Extract(xml::Element* element) override { name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); requiredFeature = GetAttributeStringDefault( FindAttribute(element, REQUIRED_FEATURE_ATTR), ""); requiredNotFeature = GetAttributeStringDefault( FindAttribute(element, REQUIRED_NOT_FEATURE_ATTR), ""); std::string feature = GetAttributeStringDefault(FindAttribute(element, REQUIRED_FEATURE_ATTR), ""); if (!feature.empty()) { requiredFeatures.push_back(feature); } feature = GetAttributeStringDefault(FindAttribute(element, REQUIRED_NOT_FEATURE_ATTR), ""); if (!feature.empty()) { requiredNotFeatures.push_back(feature); } required = GetAttributeIntegerDefault(FindAttribute(element, REQUIRED_ATTR), 1); maxSdkVersion = GetAttributeIntegerDefault( FindAttribute(element, MAX_SDK_VERSION_ATTR), -1); Loading @@ -1090,13 +1096,13 @@ class UsesPermission : public ManifestExtractor::Element { if (maxSdkVersion >= 0) { printer->Print(StringPrintf(" maxSdkVersion='%d'", maxSdkVersion)); } if (!requiredFeature.empty()) { printer->Print(StringPrintf(" requiredFeature='%s'", requiredFeature.data())); printer->Print("\n"); for (const std::string& requiredFeature : requiredFeatures) { printer->Print(StringPrintf(" required-feature='%s'\n", requiredFeature.data())); } if (!requiredNotFeature.empty()) { printer->Print(StringPrintf(" requiredNotFeature='%s'", requiredNotFeature.data())); for (const std::string& requiredNotFeature : requiredNotFeatures) { printer->Print(StringPrintf(" required-not-feature='%s'\n", requiredNotFeature.data())); } printer->Print("\n"); if (required == 0) { printer->Print(StringPrintf("optional-permission: name='%s'", name.data())); if (maxSdkVersion >= 0) { Loading @@ -1116,6 +1122,38 @@ class UsesPermission : public ManifestExtractor::Element { } }; /** Represents <required-feature> elements. **/ class RequiredFeature : public ManifestExtractor::Element { public: RequiredFeature() = default; std::string name; void Extract(xml::Element* element) override { name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); auto parent_stack = extractor()->parent_stack(); if (!name.empty() && ElementCast<UsesPermission>(parent_stack[0])) { UsesPermission* uses_permission = ElementCast<UsesPermission>(parent_stack[0]); uses_permission->requiredFeatures.push_back(name); } } }; /** Represents <required-not-feature> elements. **/ class RequiredNotFeature : public ManifestExtractor::Element { public: RequiredNotFeature() = default; std::string name; void Extract(xml::Element* element) override { name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); auto parent_stack = extractor()->parent_stack(); if (!name.empty() && ElementCast<UsesPermission>(parent_stack[0])) { UsesPermission* uses_permission = ElementCast<UsesPermission>(parent_stack[0]); uses_permission->requiredNotFeatures.push_back(name); } } }; /** Represents <uses-permission-sdk-23> elements. **/ class UsesPermissionSdk23 : public ManifestExtractor::Element { public: Loading Loading @@ -1845,7 +1883,8 @@ bool ManifestExtractor::Dump(text::Printer* printer, IDiagnostics* diag) { for (xml::Element* child : element->GetChildElements()) { if (child->name == "uses-permission" || child->name == "uses-permission-sdk-23" || child->name == "permission") { auto permission_element = ManifestExtractor::Element::Inflate(this, child); // Inflate the element and its descendants auto permission_element = Visit(child); manifest->AddChild(permission_element); } } Loading Loading @@ -2239,6 +2278,7 @@ T* ElementCast(ManifestExtractor::Element* element) { const std::unordered_map<std::string, bool> kTagCheck = { {"action", std::is_base_of<Action, T>::value}, {"activity", std::is_base_of<Activity, T>::value}, {"additional-certificate", std::is_base_of<AdditionalCertificate, T>::value}, {"application", std::is_base_of<Application, T>::value}, {"category", std::is_base_of<Category, T>::value}, {"compatible-screens", std::is_base_of<CompatibleScreens, T>::value}, Loading @@ -2253,22 +2293,23 @@ T* ElementCast(ManifestExtractor::Element* element) { {"permission", std::is_base_of<Permission, T>::value}, {"provider", std::is_base_of<Provider, T>::value}, {"receiver", std::is_base_of<Receiver, T>::value}, {"required-feature", std::is_base_of<RequiredFeature, T>::value}, {"required-not-feature", std::is_base_of<RequiredNotFeature, T>::value}, {"screen", std::is_base_of<Screen, T>::value}, {"service", std::is_base_of<Service, T>::value}, {"static-library", std::is_base_of<StaticLibrary, T>::value}, {"supports-gl-texture", std::is_base_of<SupportsGlTexture, T>::value}, {"supports-input", std::is_base_of<SupportsInput, T>::value}, {"supports-screens", std::is_base_of<SupportsScreen, T>::value}, {"uses-configuration", std::is_base_of<UsesConfiguarion, T>::value}, {"uses-feature", std::is_base_of<UsesFeature, T>::value}, {"uses-permission", std::is_base_of<UsesPermission, T>::value}, {"uses-permission-sdk-23", std::is_base_of<UsesPermissionSdk23, T>::value}, {"uses-library", std::is_base_of<UsesLibrary, T>::value}, {"uses-native-library", std::is_base_of<UsesNativeLibrary, T>::value}, {"uses-package", std::is_base_of<UsesPackage, T>::value}, {"static-library", std::is_base_of<StaticLibrary, T>::value}, {"uses-static-library", std::is_base_of<UsesStaticLibrary, T>::value}, {"additional-certificate", std::is_base_of<AdditionalCertificate, T>::value}, {"uses-permission", std::is_base_of<UsesPermission, T>::value}, {"uses-permission-sdk-23", std::is_base_of<UsesPermissionSdk23, T>::value}, {"uses-sdk", std::is_base_of<UsesSdkBadging, T>::value}, {"uses-native-library", std::is_base_of<UsesNativeLibrary, T>::value}, {"uses-static-library", std::is_base_of<UsesStaticLibrary, T>::value}, }; auto check = kTagCheck.find(element->tag()); Loading @@ -2290,6 +2331,7 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Element::Inflate( kTagCheck = { {"action", &CreateType<Action>}, {"activity", &CreateType<Activity>}, {"additional-certificate", &CreateType<AdditionalCertificate>}, {"application", &CreateType<Application>}, {"category", &CreateType<Category>}, {"compatible-screens", &CreateType<CompatibleScreens>}, Loading @@ -2304,22 +2346,23 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Element::Inflate( {"permission", &CreateType<Permission>}, {"provider", &CreateType<Provider>}, {"receiver", &CreateType<Receiver>}, {"required-feature", &CreateType<RequiredFeature>}, {"required-not-feature", &CreateType<RequiredNotFeature>}, {"screen", &CreateType<Screen>}, {"service", &CreateType<Service>}, {"static-library", &CreateType<StaticLibrary>}, {"supports-gl-texture", &CreateType<SupportsGlTexture>}, {"supports-input", &CreateType<SupportsInput>}, {"supports-screens", &CreateType<SupportsScreen>}, {"uses-configuration", &CreateType<UsesConfiguarion>}, {"uses-feature", &CreateType<UsesFeature>}, {"uses-permission", &CreateType<UsesPermission>}, {"uses-permission-sdk-23", &CreateType<UsesPermissionSdk23>}, {"uses-library", &CreateType<UsesLibrary>}, {"static-library", &CreateType<StaticLibrary>}, {"uses-static-library", &CreateType<UsesStaticLibrary>}, {"uses-native-library", &CreateType<UsesNativeLibrary>}, {"uses-package", &CreateType<UsesPackage>}, {"additional-certificate", &CreateType<AdditionalCertificate>}, {"uses-permission", &CreateType<UsesPermission>}, {"uses-permission-sdk-23", &CreateType<UsesPermissionSdk23>}, {"uses-sdk", &CreateType<UsesSdkBadging>}, {"uses-native-library", &CreateType<UsesNativeLibrary>}, {"uses-static-library", &CreateType<UsesStaticLibrary>}, }; // Attempt to map the xml tag to a element inflater Loading tools/aapt2/link/ManifestFixer.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -393,6 +393,8 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, manifest_action["protected-broadcast"]; manifest_action["adopt-permissions"]; manifest_action["uses-permission"]; manifest_action["uses-permission"]["required-feature"].Action(RequiredNameIsNotEmpty); manifest_action["uses-permission"]["required-not-feature"].Action(RequiredNameIsNotEmpty); manifest_action["uses-permission-sdk-23"]; manifest_action["permission"]; manifest_action["permission"]["meta-data"] = meta_data_action; Loading Loading
core/java/android/content/pm/parsing/ParsingPackageUtils.java +93 −15 Original line number Diff line number Diff line Loading @@ -1080,14 +1080,57 @@ public class ParsingPackageUtils { } } final String requiredFeature = sa.getNonConfigurationString( R.styleable.AndroidManifestUsesPermission_requiredFeature, 0); final ArraySet<String> requiredFeatures = new ArraySet<>(); String feature = sa.getNonConfigurationString( com.android.internal.R.styleable.AndroidManifestUsesPermission_requiredFeature, 0); if (feature != null) { requiredFeatures.add(feature); } final String requiredNotfeature = sa.getNonConfigurationString( R.styleable.AndroidManifestUsesPermission_requiredNotFeature, final ArraySet<String> requiredNotFeatures = new ArraySet<>(); feature = sa.getNonConfigurationString( com.android.internal.R.styleable .AndroidManifestUsesPermission_requiredNotFeature, 0); if (feature != null) { requiredNotFeatures.add(feature); } XmlUtils.skipCurrentTag(parser); final 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; } final ParseResult<?> result; switch (parser.getName()) { case "required-feature": result = parseRequiredFeature(input, res, parser); if (result.isSuccess()) { requiredFeatures.add((String) result.getResult()); } break; case "required-not-feature": result = parseRequiredNotFeature(input, res, parser); if (result.isSuccess()) { requiredNotFeatures.add((String) result.getResult()); } break; default: result = ParsingUtils.unknownTag("<uses-permission>", pkg, parser, input); break; } if (result.isError()) { return input.error(result); } } // Can only succeed from here on out ParseResult<ParsingPackage> success = input.success(pkg); Loading @@ -1100,18 +1143,23 @@ public class ParsingPackageUtils { return success; } // Only allow requesting this permission if the platform supports the given feature. if (requiredFeature != null && mCallback != null && !mCallback.hasFeature( requiredFeature)) { if (mCallback != null) { // Only allow requesting this permission if the platform supports all of the // "required-feature"s. for (int i = requiredFeatures.size() - 1; i >= 0; i--) { if (!mCallback.hasFeature(requiredFeatures.valueAt(i))) { return success; } } // Only allow requesting this permission if the platform doesn't support the given // feature. if (requiredNotfeature != null && mCallback != null && mCallback.hasFeature(requiredNotfeature)) { // Only allow requesting this permission if the platform does not supports any of // the "required-not-feature"s. for (int i = requiredNotFeatures.size() - 1; i >= 0; i--) { if (mCallback.hasFeature(requiredNotFeatures.valueAt(i))) { return success; } } } if (!pkg.getRequestedPermissions().contains(name)) { pkg.addRequestedPermission(name.intern()); Loading @@ -1127,6 +1175,36 @@ public class ParsingPackageUtils { } } private ParseResult<String> parseRequiredFeature(ParseInput input, Resources res, AttributeSet attrs) { final TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestRequiredFeature); try { final String featureName = sa.getString( R.styleable.AndroidManifestRequiredFeature_name); return TextUtils.isEmpty(featureName) ? input.error("Feature name is missing from <required-feature> tag.") : input.success(featureName); } finally { sa.recycle(); } } private ParseResult<String> parseRequiredNotFeature(ParseInput input, Resources res, AttributeSet attrs) { final TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.AndroidManifestRequiredNotFeature); try { final String featureName = sa.getString( R.styleable.AndroidManifestRequiredNotFeature_name); return TextUtils.isEmpty(featureName) ? input.error("Feature name is missing from <required-not-feature> tag.") : input.success(featureName); } finally { sa.recycle(); } } private static ParseResult<ParsingPackage> parseUsesConfiguration(ParseInput input, ParsingPackage pkg, Resources res, XmlResourceParser parser) { ConfigurationInfo cPref = new ConfigurationInfo(); Loading
core/res/res/values/attrs_manifest.xml +16 −0 Original line number Diff line number Diff line Loading @@ -2016,6 +2016,22 @@ <attr name="requiredNotFeature" format="string" /> </declare-styleable> <!-- <code>required-feature</code> and <code>required-not-feature</code> elements inside <code>uses-permission<code/> can be used to request the permission based on the fact whether the system supports or does not support certain features. If multiple <code>required-feature</code> and/or <code>required-not-feature</code> elements are present, the permission will be “requested” only if the system supports all of the listed "required-features" and does not support any of the "required-not-features". --> <declare-styleable name="AndroidManifestRequiredFeature"> <!-- The name of the feature. --> <attr name="name" /> </declare-styleable> <declare-styleable name="AndroidManifestRequiredNotFeature"> <!-- The name of the feature. --> <attr name="name" /> </declare-styleable> <!-- The <code>uses-configuration</code> tag specifies a specific hardware configuration value used by the application. For example an application might specify that it requires Loading
tools/aapt2/dump/DumpManifest.cpp +120 −77 Original line number Diff line number Diff line Loading @@ -1063,17 +1063,23 @@ class UsesPermission : public ManifestExtractor::Element { public: UsesPermission() = default; std::string name; std::string requiredFeature; std::string requiredNotFeature; std::vector<std::string> requiredFeatures; std::vector<std::string> requiredNotFeatures; int32_t required = true; int32_t maxSdkVersion = -1; void Extract(xml::Element* element) override { name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); requiredFeature = GetAttributeStringDefault( FindAttribute(element, REQUIRED_FEATURE_ATTR), ""); requiredNotFeature = GetAttributeStringDefault( FindAttribute(element, REQUIRED_NOT_FEATURE_ATTR), ""); std::string feature = GetAttributeStringDefault(FindAttribute(element, REQUIRED_FEATURE_ATTR), ""); if (!feature.empty()) { requiredFeatures.push_back(feature); } feature = GetAttributeStringDefault(FindAttribute(element, REQUIRED_NOT_FEATURE_ATTR), ""); if (!feature.empty()) { requiredNotFeatures.push_back(feature); } required = GetAttributeIntegerDefault(FindAttribute(element, REQUIRED_ATTR), 1); maxSdkVersion = GetAttributeIntegerDefault( FindAttribute(element, MAX_SDK_VERSION_ATTR), -1); Loading @@ -1090,13 +1096,13 @@ class UsesPermission : public ManifestExtractor::Element { if (maxSdkVersion >= 0) { printer->Print(StringPrintf(" maxSdkVersion='%d'", maxSdkVersion)); } if (!requiredFeature.empty()) { printer->Print(StringPrintf(" requiredFeature='%s'", requiredFeature.data())); printer->Print("\n"); for (const std::string& requiredFeature : requiredFeatures) { printer->Print(StringPrintf(" required-feature='%s'\n", requiredFeature.data())); } if (!requiredNotFeature.empty()) { printer->Print(StringPrintf(" requiredNotFeature='%s'", requiredNotFeature.data())); for (const std::string& requiredNotFeature : requiredNotFeatures) { printer->Print(StringPrintf(" required-not-feature='%s'\n", requiredNotFeature.data())); } printer->Print("\n"); if (required == 0) { printer->Print(StringPrintf("optional-permission: name='%s'", name.data())); if (maxSdkVersion >= 0) { Loading @@ -1116,6 +1122,38 @@ class UsesPermission : public ManifestExtractor::Element { } }; /** Represents <required-feature> elements. **/ class RequiredFeature : public ManifestExtractor::Element { public: RequiredFeature() = default; std::string name; void Extract(xml::Element* element) override { name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); auto parent_stack = extractor()->parent_stack(); if (!name.empty() && ElementCast<UsesPermission>(parent_stack[0])) { UsesPermission* uses_permission = ElementCast<UsesPermission>(parent_stack[0]); uses_permission->requiredFeatures.push_back(name); } } }; /** Represents <required-not-feature> elements. **/ class RequiredNotFeature : public ManifestExtractor::Element { public: RequiredNotFeature() = default; std::string name; void Extract(xml::Element* element) override { name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), ""); auto parent_stack = extractor()->parent_stack(); if (!name.empty() && ElementCast<UsesPermission>(parent_stack[0])) { UsesPermission* uses_permission = ElementCast<UsesPermission>(parent_stack[0]); uses_permission->requiredNotFeatures.push_back(name); } } }; /** Represents <uses-permission-sdk-23> elements. **/ class UsesPermissionSdk23 : public ManifestExtractor::Element { public: Loading Loading @@ -1845,7 +1883,8 @@ bool ManifestExtractor::Dump(text::Printer* printer, IDiagnostics* diag) { for (xml::Element* child : element->GetChildElements()) { if (child->name == "uses-permission" || child->name == "uses-permission-sdk-23" || child->name == "permission") { auto permission_element = ManifestExtractor::Element::Inflate(this, child); // Inflate the element and its descendants auto permission_element = Visit(child); manifest->AddChild(permission_element); } } Loading Loading @@ -2239,6 +2278,7 @@ T* ElementCast(ManifestExtractor::Element* element) { const std::unordered_map<std::string, bool> kTagCheck = { {"action", std::is_base_of<Action, T>::value}, {"activity", std::is_base_of<Activity, T>::value}, {"additional-certificate", std::is_base_of<AdditionalCertificate, T>::value}, {"application", std::is_base_of<Application, T>::value}, {"category", std::is_base_of<Category, T>::value}, {"compatible-screens", std::is_base_of<CompatibleScreens, T>::value}, Loading @@ -2253,22 +2293,23 @@ T* ElementCast(ManifestExtractor::Element* element) { {"permission", std::is_base_of<Permission, T>::value}, {"provider", std::is_base_of<Provider, T>::value}, {"receiver", std::is_base_of<Receiver, T>::value}, {"required-feature", std::is_base_of<RequiredFeature, T>::value}, {"required-not-feature", std::is_base_of<RequiredNotFeature, T>::value}, {"screen", std::is_base_of<Screen, T>::value}, {"service", std::is_base_of<Service, T>::value}, {"static-library", std::is_base_of<StaticLibrary, T>::value}, {"supports-gl-texture", std::is_base_of<SupportsGlTexture, T>::value}, {"supports-input", std::is_base_of<SupportsInput, T>::value}, {"supports-screens", std::is_base_of<SupportsScreen, T>::value}, {"uses-configuration", std::is_base_of<UsesConfiguarion, T>::value}, {"uses-feature", std::is_base_of<UsesFeature, T>::value}, {"uses-permission", std::is_base_of<UsesPermission, T>::value}, {"uses-permission-sdk-23", std::is_base_of<UsesPermissionSdk23, T>::value}, {"uses-library", std::is_base_of<UsesLibrary, T>::value}, {"uses-native-library", std::is_base_of<UsesNativeLibrary, T>::value}, {"uses-package", std::is_base_of<UsesPackage, T>::value}, {"static-library", std::is_base_of<StaticLibrary, T>::value}, {"uses-static-library", std::is_base_of<UsesStaticLibrary, T>::value}, {"additional-certificate", std::is_base_of<AdditionalCertificate, T>::value}, {"uses-permission", std::is_base_of<UsesPermission, T>::value}, {"uses-permission-sdk-23", std::is_base_of<UsesPermissionSdk23, T>::value}, {"uses-sdk", std::is_base_of<UsesSdkBadging, T>::value}, {"uses-native-library", std::is_base_of<UsesNativeLibrary, T>::value}, {"uses-static-library", std::is_base_of<UsesStaticLibrary, T>::value}, }; auto check = kTagCheck.find(element->tag()); Loading @@ -2290,6 +2331,7 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Element::Inflate( kTagCheck = { {"action", &CreateType<Action>}, {"activity", &CreateType<Activity>}, {"additional-certificate", &CreateType<AdditionalCertificate>}, {"application", &CreateType<Application>}, {"category", &CreateType<Category>}, {"compatible-screens", &CreateType<CompatibleScreens>}, Loading @@ -2304,22 +2346,23 @@ std::unique_ptr<ManifestExtractor::Element> ManifestExtractor::Element::Inflate( {"permission", &CreateType<Permission>}, {"provider", &CreateType<Provider>}, {"receiver", &CreateType<Receiver>}, {"required-feature", &CreateType<RequiredFeature>}, {"required-not-feature", &CreateType<RequiredNotFeature>}, {"screen", &CreateType<Screen>}, {"service", &CreateType<Service>}, {"static-library", &CreateType<StaticLibrary>}, {"supports-gl-texture", &CreateType<SupportsGlTexture>}, {"supports-input", &CreateType<SupportsInput>}, {"supports-screens", &CreateType<SupportsScreen>}, {"uses-configuration", &CreateType<UsesConfiguarion>}, {"uses-feature", &CreateType<UsesFeature>}, {"uses-permission", &CreateType<UsesPermission>}, {"uses-permission-sdk-23", &CreateType<UsesPermissionSdk23>}, {"uses-library", &CreateType<UsesLibrary>}, {"static-library", &CreateType<StaticLibrary>}, {"uses-static-library", &CreateType<UsesStaticLibrary>}, {"uses-native-library", &CreateType<UsesNativeLibrary>}, {"uses-package", &CreateType<UsesPackage>}, {"additional-certificate", &CreateType<AdditionalCertificate>}, {"uses-permission", &CreateType<UsesPermission>}, {"uses-permission-sdk-23", &CreateType<UsesPermissionSdk23>}, {"uses-sdk", &CreateType<UsesSdkBadging>}, {"uses-native-library", &CreateType<UsesNativeLibrary>}, {"uses-static-library", &CreateType<UsesStaticLibrary>}, }; // Attempt to map the xml tag to a element inflater Loading
tools/aapt2/link/ManifestFixer.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -393,6 +393,8 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor, manifest_action["protected-broadcast"]; manifest_action["adopt-permissions"]; manifest_action["uses-permission"]; manifest_action["uses-permission"]["required-feature"].Action(RequiredNameIsNotEmpty); manifest_action["uses-permission"]["required-not-feature"].Action(RequiredNameIsNotEmpty); manifest_action["uses-permission-sdk-23"]; manifest_action["permission"]; manifest_action["permission"]["meta-data"] = meta_data_action; Loading