Extend DumpManifest unit to export badging data into proto.
Bug: b/228950123
Test: Dump_test.cpp
Change-Id: I3c228767b435d0e31f1eec1f34daeec1065628d0
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index 64a9441..e36112d 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -17,8 +17,10 @@
#include "DumpManifest.h"
#include <algorithm>
+#include <array>
#include <memory>
#include <set>
+#include <string_view>
#include <vector>
#include "LoadedApk.h"
@@ -114,10 +116,101 @@
return el->FindAttribute(package, name);
}
+class Architectures {
+ public:
+ std::set<std::string> architectures;
+ std::set<std::string> alt_architectures;
+
+ void Print(text::Printer* printer) {
+ if (!architectures.empty()) {
+ printer->Print("native-code:");
+ for (auto& arch : architectures) {
+ printer->Print(StringPrintf(" '%s'", arch.data()));
+ }
+ printer->Print("\n");
+ }
+ if (!alt_architectures.empty()) {
+ printer->Print("alt-native-code:");
+ for (auto& arch : alt_architectures) {
+ printer->Print(StringPrintf(" '%s'", arch.data()));
+ }
+ printer->Print("\n");
+ }
+ }
+
+ void ToProto(pb::Badging* out_badging) {
+ auto out_architectures = out_badging->mutable_architectures();
+ for (auto& arch : architectures) {
+ out_architectures->add_architectures(arch);
+ }
+ for (auto& arch : alt_architectures) {
+ out_architectures->add_alt_architectures(arch);
+ }
+ }
+};
+
+const static std::array<std::string_view, 14> printable_components{"app-widget",
+ "device-admin",
+ "ime",
+ "wallpaper",
+ "accessibility",
+ "print-service",
+ "payment",
+ "search",
+ "document-provider",
+ "launcher",
+ "notification-listener",
+ "dream",
+ "camera",
+ "camera-secure"};
+
+class Components {
+ public:
+ std::set<std::string, std::less<>> discovered_components;
+ bool other_activities = false;
+ bool other_receivers = false;
+ bool other_services = false;
+
+ void Print(text::Printer* printer) {
+ for (auto& component : printable_components) {
+ if (discovered_components.find(component) != discovered_components.end()) {
+ printer->Print(StringPrintf("provides-component:'%s'\n", component.data()));
+ }
+ }
+ // Print presence of main activity
+ if (discovered_components.find("main") != discovered_components.end()) {
+ printer->Print("main\n");
+ }
+
+ if (other_activities) {
+ printer->Print("other-activities\n");
+ }
+ if (other_receivers) {
+ printer->Print("other-receivers\n");
+ }
+ if (other_services) {
+ printer->Print("other-services\n");
+ }
+ }
+
+ void ToProto(pb::Badging* out_badging) {
+ auto out_components = out_badging->mutable_components();
+ for (auto& component : printable_components) {
+ auto discovered = discovered_components.find(component);
+ if (discovered != discovered_components.end()) {
+ out_components->add_provided_components(*discovered);
+ }
+ }
+ out_components->set_main(discovered_components.find("main") != discovered_components.end());
+ out_components->set_other_activities(other_activities);
+ out_components->set_other_receivers(other_receivers);
+ out_components->set_other_services(other_services);
+ }
+};
+
class CommonFeatureGroup;
-class Architectures;
-class SupportsScreen;
class FeatureGroup;
+class SupportsScreen;
class ManifestExtractor {
public:
@@ -133,7 +226,12 @@
static std::unique_ptr<Element> Inflate(ManifestExtractor* extractor, xml::Element* el);
/** Writes out the extracted contents of the element. */
- virtual void Print(text::Printer* printer) { }
+ virtual void Print(text::Printer* printer) {
+ }
+
+ /** Saves extracted information into Badging proto. */
+ virtual void ToProto(pb::Badging* out_badging) {
+ }
/** Adds an element to the list of children of the element. */
void AddChild(std::unique_ptr<Element>& child) { children_.push_back(std::move(child)); }
@@ -345,6 +443,7 @@
bool Extract(IDiagnostics* diag);
bool Dump(text::Printer* printer);
+ bool DumpProto(pb::Badging* out_badging);
/** Recursively visit the xml element tree and return a processed badging element tree. */
std::unique_ptr<Element> Visit(xml::Element* element);
@@ -402,12 +501,9 @@
std::unique_ptr<ManifestExtractor::Element> root_element_;
std::vector<std::unique_ptr<ManifestExtractor::Element>> implied_permissions_;
- std::set<std::string> components_;
std::vector<FeatureGroup*> feature_groups_;
- bool other_activities_ = false;
- bool other_receivers_ = false;
- bool other_services_ = false;
- std::unique_ptr<Architectures> architectures_ = util::make_unique<Architectures>();
+ Components components_;
+ Architectures architectures_;
const SupportsScreen* supports_screen_;
};
@@ -480,6 +576,45 @@
installLocation = GetAttributeInteger(FindAttribute(manifest, INSTALL_LOCATION_ATTR));
}
+ void ToProto(pb::Badging* out_badging) override {
+ auto out_package = out_badging->mutable_package();
+ out_package->set_package(package);
+ out_package->set_version_code(versionCode);
+ out_package->set_version_name(versionName);
+ if (compilesdkVersion) {
+ out_package->set_compile_sdk_version(*compilesdkVersion);
+ }
+ if (compilesdkVersionCodename) {
+ out_package->set_compile_sdk_version_codename(*compilesdkVersionCodename);
+ }
+ if (platformVersionName) {
+ out_package->set_platform_version_name(*platformVersionName);
+ } else if (platformVersionNameInt) {
+ out_package->set_platform_version_name(std::to_string(*platformVersionNameInt));
+ }
+ if (platformVersionCode) {
+ out_package->set_platform_version_code(*platformVersionCode);
+ } else if (platformVersionCodeInt) {
+ out_package->set_platform_version_code(std::to_string(*platformVersionCodeInt));
+ }
+
+ if (installLocation) {
+ switch (*installLocation) {
+ case 0:
+ out_package->set_install_location(pb::PackageInfo_InstallLocation_AUTO);
+ break;
+ case 1:
+ out_package->set_install_location(pb::PackageInfo_InstallLocation_INTERNAL_ONLY);
+ break;
+ case 2:
+ out_package->set_install_location(pb::PackageInfo_InstallLocation_PREFER_EXTERNAL);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
void Print(text::Printer* printer) override {
if (only_package_name) {
printer->Println(StringPrintf("package: %s", package.data()));
@@ -624,6 +759,27 @@
printer->Print("application-debuggable\n");
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ auto application = out_badging->mutable_application();
+ application->set_label(android::ResTable::normalizeForOutput(label.data()));
+ application->set_icon(icon);
+ application->set_banner(banner);
+ application->set_test_only(test_only != 0);
+ application->set_game(is_game != 0);
+ application->set_debuggable(debuggable != 0);
+
+ auto out_locale_labels = application->mutable_locale_labels();
+ for (auto& p : locale_labels) {
+ if (!p.first.empty()) {
+ (*out_locale_labels)[p.first] = p.second;
+ }
+ }
+ auto out_density_icons = application->mutable_density_icons();
+ for (auto& p : density_icons) {
+ (*out_density_icons)[p.first] = p.second;
+ }
+ }
};
/** Represents <uses-sdk> elements. **/
@@ -673,6 +829,23 @@
printer->Print(StringPrintf("targetSdkVersion:'%s'\n", target_sdk_name->data()));
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ auto out_sdks = out_badging->mutable_uses_sdk();
+ if (min_sdk) {
+ out_sdks->set_min_sdk_version(*min_sdk);
+ } else if (min_sdk_name) {
+ out_sdks->set_min_sdk_version_name(*min_sdk_name);
+ }
+ if (max_sdk) {
+ out_sdks->set_max_sdk_version(*max_sdk);
+ }
+ if (target_sdk) {
+ out_sdks->set_target_sdk_version(*target_sdk);
+ } else if (target_sdk_name) {
+ out_sdks->set_target_sdk_version_name(*target_sdk_name);
+ }
+ }
};
/** Represents <uses-configuration> elements. **/
@@ -717,6 +890,15 @@
}
printer->Print("\n");
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ auto out_configuration = out_badging->mutable_uses_configuration();
+ out_configuration->set_req_touch_screen(req_touch_screen);
+ out_configuration->set_req_keyboard_type(req_keyboard_type);
+ out_configuration->set_req_hard_keyboard(req_hard_keyboard);
+ out_configuration->set_req_navigation(req_navigation);
+ out_configuration->set_req_five_way_nav(req_five_way_nav);
+ }
};
/** Represents <supports-screen> elements. **/
@@ -760,53 +942,23 @@
}
void PrintScreens(text::Printer* printer, int32_t target_sdk) const {
- int32_t small_screen_temp = small_screen;
- int32_t normal_screen_temp = normal_screen;
- int32_t large_screen_temp = large_screen;
- int32_t xlarge_screen_temp = xlarge_screen;
- int32_t any_density_temp = any_density;
-
- // Determine default values for any unspecified screen sizes,
- // based on the target SDK of the package. As of 4 (donut)
- // the screen size support was introduced, so all default to
- // enabled.
- if (small_screen_temp > 0) {
- small_screen_temp = target_sdk >= SDK_DONUT ? -1 : 0;
- }
- if (normal_screen_temp > 0) {
- normal_screen_temp = -1;
- }
- if (large_screen_temp > 0) {
- large_screen_temp = target_sdk >= SDK_DONUT ? -1 : 0;
- }
- if (xlarge_screen_temp > 0) {
- // Introduced in Gingerbread.
- xlarge_screen_temp = target_sdk >= SDK_GINGERBREAD ? -1 : 0;
- }
- if (any_density_temp > 0) {
- any_density_temp = (target_sdk >= SDK_DONUT || requires_smallest_width_dp > 0 ||
- compatible_width_limit_dp > 0)
- ? -1
- : 0;
- }
-
// Print the formatted screen info
printer->Print("supports-screens:");
- if (small_screen_temp != 0) {
+ if (IsSmallScreenSupported(target_sdk)) {
printer->Print(" 'small'");
}
- if (normal_screen_temp != 0) {
+ if (normal_screen != 0) {
printer->Print(" 'normal'");
}
- if (large_screen_temp != 0) {
+ if (IsLargeScreenSupported(target_sdk)) {
printer->Print(" 'large'");
}
- if (xlarge_screen_temp != 0) {
+ if (IsXLargeScreenSupported(target_sdk)) {
printer->Print(" 'xlarge'");
}
printer->Print("\n");
printer->Print(StringPrintf("supports-any-density: '%s'\n",
- (any_density_temp ) ? "true" : "false"));
+ (IsAnyDensitySupported(target_sdk)) ? "true" : "false"));
if (requires_smallest_width_dp > 0) {
printer->Print(StringPrintf("requires-smallest-width:'%d'\n", requires_smallest_width_dp));
}
@@ -817,6 +969,60 @@
printer->Print(StringPrintf("largest-width-limit:'%d'\n", largest_width_limit_dp));
}
}
+
+ void ToProtoScreens(pb::Badging* out_badging, int32_t target_sdk) const {
+ auto supports_screen = out_badging->mutable_supports_screen();
+ if (IsSmallScreenSupported(target_sdk)) {
+ supports_screen->add_screens(pb::SupportsScreen_ScreenType_SMALL);
+ }
+ if (normal_screen != 0) {
+ supports_screen->add_screens(pb::SupportsScreen_ScreenType_NORMAL);
+ }
+ if (IsLargeScreenSupported(target_sdk)) {
+ supports_screen->add_screens(pb::SupportsScreen_ScreenType_LARGE);
+ }
+ if (IsXLargeScreenSupported(target_sdk)) {
+ supports_screen->add_screens(pb::SupportsScreen_ScreenType_XLARGE);
+ }
+ supports_screen->set_supports_any_densities(IsAnyDensitySupported(target_sdk));
+ supports_screen->set_requires_smallest_width_dp(requires_smallest_width_dp);
+ supports_screen->set_compatible_width_limit_dp(compatible_width_limit_dp);
+ supports_screen->set_largest_width_limit_dp(largest_width_limit_dp);
+ }
+
+ private:
+ // Determine default values for any unspecified screen sizes,
+ // based on the target SDK of the package. As of 4 (donut)
+ // the screen size support was introduced, so all default to
+ // enabled.
+ bool IsSmallScreenSupported(int32_t target_sdk) const {
+ if (small_screen > 0) {
+ return target_sdk >= SDK_DONUT;
+ }
+ return small_screen != 0;
+ }
+
+ bool IsLargeScreenSupported(int32_t target_sdk) const {
+ if (large_screen > 0) {
+ return target_sdk >= SDK_DONUT;
+ }
+ return large_screen != 0;
+ }
+
+ bool IsXLargeScreenSupported(int32_t target_sdk) const {
+ if (xlarge_screen > 0) {
+ return target_sdk >= SDK_GINGERBREAD;
+ }
+ return xlarge_screen != 0;
+ }
+
+ bool IsAnyDensitySupported(int32_t target_sdk) const {
+ if (any_density > 0) {
+ return target_sdk >= SDK_DONUT || requires_smallest_width_dp > 0 ||
+ compatible_width_limit_dp > 0;
+ }
+ return any_density != 0;
+ }
};
/** Represents <feature-group> elements. **/
@@ -847,6 +1053,18 @@
}
}
+ virtual void GroupToProto(pb::Badging* out_badging) {
+ auto feature_group = out_badging->add_feature_groups();
+ feature_group->set_label(label);
+ feature_group->set_open_gles_version(open_gles_version);
+ for (auto& feature : features_) {
+ auto out_feature = feature_group->add_features();
+ out_feature->set_name(feature.first);
+ out_feature->set_required(feature.second.required);
+ out_feature->set_version(feature.second.version);
+ }
+ }
+
/** Adds a feature to the feature group. */
void AddFeature(const std::string& name, bool required = true, int32_t version = -1) {
features_.insert(std::make_pair(name, Feature{ required, version }));
@@ -936,6 +1154,23 @@
}
}
+ virtual void GroupToProto(pb::Badging* out_badging) override {
+ FeatureGroup::GroupToProto(out_badging);
+ auto feature_group =
+ out_badging->mutable_feature_groups(out_badging->feature_groups_size() - 1);
+ for (auto& feature : implied_features_) {
+ if (features_.find(feature.first) == features_.end()) {
+ auto out_feature = feature_group->add_features();
+ out_feature->set_name(feature.first);
+ auto implied_data = out_feature->mutable_implied_data();
+ implied_data->set_from_sdk_23_permission(feature.second.implied_from_sdk_k23);
+ for (auto& reason : feature.second.reasons) {
+ implied_data->add_reasons(reason);
+ }
+ }
+ }
+ }
+
/** Returns true if the feature group has the given feature. */
bool HasFeature(const std::string& name) override {
return FeatureGroup::HasFeature(name)
@@ -1165,6 +1400,27 @@
printer->Print(StringPrintf(" reason='%s'\n", impliedReason.data()));
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ if (!name.empty()) {
+ auto permission = out_badging->add_uses_permissions();
+ permission->set_name(name);
+ if (maxSdkVersion > 0) {
+ permission->set_max_sdk_version(maxSdkVersion);
+ }
+ if ((usesPermissionFlags & kNeverForLocation) != 0) {
+ permission->mutable_permission_flags()->set_never_for_location(true);
+ }
+ for (auto& requiredFeature : requiredFeatures) {
+ permission->add_required_features(requiredFeature);
+ }
+ for (auto& requiredNotFeature : requiredNotFeatures) {
+ permission->add_required_not_features(requiredNotFeature);
+ }
+ permission->set_required(required != 0);
+ permission->set_implied(implied);
+ }
+ }
};
/** Represents <required-feature> elements. **/
@@ -1225,6 +1481,17 @@
printer->Print("\n");
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ if (name) {
+ auto permission = out_badging->add_uses_permissions();
+ permission->set_sdk23_and_above(true);
+ permission->set_name(*name);
+ if (maxSdkVersion) {
+ permission->set_max_sdk_version(*maxSdkVersion);
+ }
+ }
+ }
};
/** Represents <permission> elements. These elements are only printing when dumping permissions. **/
@@ -1242,6 +1509,12 @@
printer->Print(StringPrintf("permission: %s\n", name.data()));
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ if (!name.empty()) {
+ out_badging->add_permissions()->set_name(name);
+ }
+ }
};
/** Represents <activity> elements. **/
@@ -1322,6 +1595,22 @@
icon.data(), banner.data()));
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ if (has_main_action && has_launcher_category) {
+ auto activity = out_badging->mutable_launchable_activity();
+ activity->set_name(name);
+ activity->set_label(android::ResTable::normalizeForOutput(label.data()));
+ activity->set_icon(icon);
+ }
+ if (has_leanback_launcher_category) {
+ auto activity = out_badging->mutable_leanback_launchable_activity();
+ activity->set_name(name);
+ activity->set_label(android::ResTable::normalizeForOutput(label.data()));
+ activity->set_icon(icon);
+ activity->set_banner(banner);
+ }
+ }
};
/** Represents <intent-filter> elements. */
@@ -1422,6 +1711,14 @@
(required == 0) ? "-not-required" : "", name.data()));
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ if (!name.empty()) {
+ auto uses_library = out_badging->add_uses_libraries();
+ uses_library->set_name(name);
+ uses_library->set_required(required != 0);
+ }
+ }
};
/** Represents <static-library> elements. **/
@@ -1446,6 +1743,13 @@
"static-library: name='%s' version='%d' versionMajor='%d'\n",
name.data(), version, versionMajor));
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ auto static_library = out_badging->mutable_static_library();
+ static_library->set_name(name);
+ static_library->set_version(version);
+ static_library->set_version_major(versionMajor);
+ }
};
/** Represents <uses-static-library> elements. **/
@@ -1486,6 +1790,16 @@
}
printer->Print("\n");
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ auto uses_static_library = out_badging->add_uses_static_libraries();
+ uses_static_library->set_name(name);
+ uses_static_library->set_version(version);
+ uses_static_library->set_version_major(versionMajor);
+ for (auto& cert : certDigests) {
+ uses_static_library->add_certificates(cert);
+ }
+ }
};
/** Represents <sdk-library> elements. **/
@@ -1507,6 +1821,12 @@
printer->Print(
StringPrintf("sdk-library: name='%s' versionMajor='%d'\n", name.data(), versionMajor));
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ auto sdk_library = out_badging->mutable_sdk_library();
+ sdk_library->set_name(name);
+ sdk_library->set_version_major(versionMajor);
+ }
};
/** Represents <uses-sdk-library> elements. **/
@@ -1544,6 +1864,15 @@
}
printer->Print("\n");
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ auto uses_sdk_library = out_badging->add_uses_sdk_libraries();
+ uses_sdk_library->set_name(name);
+ uses_sdk_library->set_version_major(versionMajor);
+ for (auto& cert : certDigests) {
+ uses_sdk_library->add_certificates(cert);
+ }
+ }
};
/** Represents <uses-native-library> elements. **/
@@ -1567,6 +1896,14 @@
(required == 0) ? "-not-required" : "", name.data()));
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ if (!name.empty()) {
+ auto uses_native_library = out_badging->add_uses_native_libraries();
+ uses_native_library->set_name(name);
+ uses_native_library->set_required(required != 0);
+ }
+ }
};
/**
@@ -1607,6 +1944,24 @@
printer->Print("\n");
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ if (!name.empty()) {
+ auto metadata = out_badging->add_metadata();
+ metadata->set_name(name);
+ if (!value.empty()) {
+ metadata->set_value_string(value);
+ } else if (value_int) {
+ metadata->set_value_int(*value_int);
+ } else {
+ if (!resource.empty()) {
+ metadata->set_resource_string(resource);
+ } else if (resource_int) {
+ metadata->set_resource_int(*resource_int);
+ }
+ }
+ }
+ }
};
/**
@@ -1736,6 +2091,13 @@
printer->Print("\n");
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ auto supports_input = out_badging->mutable_supports_input();
+ for (auto& input : inputs) {
+ supports_input->add_inputs(input);
+ }
+ }
};
/** Represents <input-type> elements. **/
@@ -1769,6 +2131,12 @@
printer->Print(StringPrintf("original-package:'%s'\n", name->data()));
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ if (name) {
+ out_badging->mutable_package()->set_original_package(*name);
+ }
+ }
};
@@ -1807,6 +2175,21 @@
}
printer->Print("\n");
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ auto overlay = out_badging->mutable_overlay();
+ if (target_package) {
+ overlay->set_target_package(*target_package);
+ }
+ overlay->set_priority(priority);
+ overlay->set_static_(is_static);
+ if (required_property_name) {
+ overlay->set_required_property_name(*required_property_name);
+ }
+ if (required_property_value) {
+ overlay->set_required_property_value(*required_property_value);
+ }
+ }
};
/** * Represents <package-verifier> elements. **/
@@ -1827,6 +2210,14 @@
name->data(), public_key->data()));
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ auto package_verifier = out_badging->mutable_package_verifier();
+ if (name && public_key) {
+ package_verifier->set_name(*name);
+ package_verifier->set_public_key(*public_key);
+ }
+ }
};
/** Represents <uses-package> elements. **/
@@ -1875,6 +2266,21 @@
}
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ if (name) {
+ auto uses_package = out_badging->add_uses_packages();
+ uses_package->set_name(*name);
+ if (packageType) {
+ uses_package->set_package_type(*packageType);
+ uses_package->set_version(version);
+ uses_package->set_version_major(versionMajor);
+ for (auto& cert : certDigests) {
+ uses_package->add_certificates(cert);
+ }
+ }
+ }
+ }
};
/** Represents <additional-certificate> elements. **/
@@ -1907,6 +2313,14 @@
size = GetAttributeInteger(FindAttribute(element, SCREEN_SIZE_ATTR));
density = GetAttributeInteger(FindAttribute(element, SCREEN_DENSITY_ATTR));
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ if (size && density) {
+ auto screen = out_badging->mutable_compatible_screens()->add_screens();
+ screen->set_density(*density);
+ screen->set_size(*size);
+ }
+ }
};
/**
@@ -1952,6 +2366,12 @@
printer->Print(StringPrintf("supports-gl-texture:'%s'\n", name->data()));
}
}
+
+ void ToProto(pb::Badging* out_badging) override {
+ if (name) {
+ out_badging->mutable_supports_gl_texture()->add_name(*name);
+ }
+ }
};
/** Represents <property> elements. **/
@@ -1987,27 +2407,22 @@
}
printer->Print("\n");
}
-};
-class Architectures {
- public:
- std::set<std::string> architectures;
- std::set<std::string> alt_architectures;
-
- void Print(text::Printer* printer) {
- if (!architectures.empty()) {
- printer->Print("native-code:");
- for (auto& arch : architectures) {
- printer->Print(StringPrintf(" '%s'", arch.data()));
+ void ToProto(pb::Badging* out_badging) override {
+ if (!name.empty()) {
+ auto property = out_badging->add_properties();
+ property->set_name(name);
+ if (!value.empty()) {
+ property->set_value_string(value);
+ } else if (value_int) {
+ property->set_value_int(*value_int);
+ } else {
+ if (!resource.empty()) {
+ property->set_resource_string(resource);
+ } else if (resource_int) {
+ property->set_resource_int(*resource_int);
+ }
}
- printer->Print("\n");
- }
- if (!alt_architectures.empty()) {
- printer->Print("alt-native-code:");
- for (auto& arch : alt_architectures) {
- printer->Print(StringPrintf(" '%s'", arch.data()));
- }
- printer->Print("\n");
}
}
};
@@ -2020,6 +2435,14 @@
}
}
+/** Recursively serializes extracted badging elements to proto. */
+static void ToProto(ManifestExtractor::Element* el, pb::Badging* out_badging) {
+ el->ToProto(out_badging);
+ for (auto& child : el->children()) {
+ ToProto(child.get(), out_badging);
+ }
+}
+
bool ManifestExtractor::Extract(IDiagnostics* diag) {
// Load the manifest
doc_ = apk_->LoadXml("AndroidManifest.xml", diag);
@@ -2198,7 +2621,7 @@
if (ElementCast<Action>(el)) {
auto action = ElementCast<Action>(el);
if (!action->component.empty()) {
- components_.insert(action->component);
+ components_.discovered_components.insert(action->component);
return;
}
}
@@ -2206,7 +2629,7 @@
if (ElementCast<Category>(el)) {
auto category = ElementCast<Category>(el);
if (!category->component.empty()) {
- components_.insert(category->component);
+ components_.discovered_components.insert(category->component);
return;
}
}
@@ -2256,7 +2679,7 @@
if (child->name == "aid-group") {
auto category = FindAttribute(child, CATEGORY_ATTR);
if (category && category->value == "payment") {
- this->components_.insert("payment");
+ this->components_.discovered_components.insert("payment");
return;
}
}
@@ -2272,7 +2695,7 @@
FindElement(root_element_.get(), [&](ManifestExtractor::Element* el) -> bool {
if (auto activity = ElementCast<Activity>(el)) {
if (!activity->has_component_) {
- other_activities_ = true;
+ components_.other_activities = true;
return true;
}
}
@@ -2282,7 +2705,7 @@
FindElement(root_element_.get(), [&](ManifestExtractor::Element* el) -> bool {
if (auto receiver = ElementCast<Receiver>(el)) {
if (!receiver->has_component) {
- other_receivers_ = true;
+ components_.other_receivers = true;
return true;
}
}
@@ -2292,7 +2715,7 @@
FindElement(root_element_.get(), [&](ManifestExtractor::Element* el) -> bool {
if (auto service = ElementCast<Service>(el)) {
if (!service->has_component) {
- other_services_ = true;
+ components_.other_services = true;
return true;
}
}
@@ -2358,16 +2781,16 @@
}
if (arch != architectures_from_apk.end()) {
- architectures_->architectures.insert(*arch);
+ architectures_.architectures.insert(*arch);
architectures_from_apk.erase(arch);
output_alt_native_code = true;
}
}
for (auto& arch : architectures_from_apk) {
if (output_alt_native_code) {
- architectures_->alt_architectures.insert(arch);
+ architectures_.alt_architectures.insert(arch);
} else {
- architectures_->architectures.insert(arch);
+ architectures_.architectures.insert(arch);
}
}
return true;
@@ -2385,43 +2808,7 @@
for (auto& feature_group : feature_groups_) {
feature_group->PrintGroup(printer);
}
- // Print the components types if they are present
- auto& components = components_;
- auto PrintComponent = [&components, &printer](const std::string& component) -> void {
- if (components.find(component) != components.end()) {
- printer->Print(StringPrintf("provides-component:'%s'\n", component.data()));
- }
- };
-
- PrintComponent("app-widget");
- PrintComponent("device-admin");
- PrintComponent("ime");
- PrintComponent("wallpaper");
- PrintComponent("accessibility");
- PrintComponent("print-service");
- PrintComponent("payment");
- PrintComponent("search");
- PrintComponent("document-provider");
- PrintComponent("launcher");
- PrintComponent("notification-listener");
- PrintComponent("dream");
- PrintComponent("camera");
- PrintComponent("camera-secure");
-
- // Print presence of main activity
- if (components.find("main") != components.end()) {
- printer->Print("main\n");
- }
-
- if (other_activities_) {
- printer->Print("other-activities\n");
- }
- if (other_receivers_) {
- printer->Print("other-receivers\n");
- }
- if (other_services_) {
- printer->Print("other-services\n");
- }
+ components_.Print(printer);
supports_screen_->PrintScreens(printer, target_sdk_);
// Print all the unique locales of the apk
@@ -2442,7 +2829,31 @@
}
printer->Print("\n");
- architectures_->Print(printer);
+ architectures_.Print(printer);
+ return true;
+}
+
+bool ManifestExtractor::DumpProto(pb::Badging* out_badging) {
+ ToProto(root_element_.get(), out_badging);
+ for (auto& implied_permission : implied_permissions_) {
+ implied_permission->ToProto(out_badging);
+ }
+ for (auto& feature_group : feature_groups_) {
+ feature_group->GroupToProto(out_badging);
+ }
+ components_.ToProto(out_badging);
+ supports_screen_->ToProtoScreens(out_badging, target_sdk_);
+
+ for (auto& config : locales_) {
+ if (!config.first.empty()) {
+ out_badging->add_locales(config.first);
+ }
+ }
+ for (auto& config : densities_) {
+ out_badging->add_densities(config.first);
+ }
+
+ architectures_.ToProto(out_badging);
return true;
}
@@ -2581,14 +2992,23 @@
return element;
}
-
int DumpManifest(LoadedApk* apk, DumpManifestOptions& options, text::Printer* printer,
IDiagnostics* diag) {
ManifestExtractor extractor(apk, options);
if (!extractor.Extract(diag)) {
- return 0;
+ return 1;
}
return extractor.Dump(printer) ? 0 : 1;
}
+int DumpBadgingProto(LoadedApk* apk, pb::Badging* out_badging, IDiagnostics* diag) {
+ DumpManifestOptions options{/* include_meta_data= */ true,
+ /* only_permissions= */ false};
+ ManifestExtractor extractor(apk, options);
+ if (!extractor.Extract(diag)) {
+ return 1;
+ }
+ return extractor.DumpProto(out_badging) ? 0 : 1;
+}
+
} // namespace aapt