Added --debug-mode flag to AAPT2
Bug: 74968793
Test: Tested for correct debuggable attribute presense with and without
flag
Change-Id: I0148d1caba62db8cf258926f1d9e87a849aa283f
(cherry picked from commit 444f9bb6a18ff34b69cba504c8658b7013eaa53a)
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 0839f6f..e14fc95 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -2159,7 +2159,11 @@
"Syntax: path/to/output.apk:<config>[,<config>[...]].\n"
"On Windows, use a semicolon ';' separator instead.",
&split_args)
- .OptionalSwitch("-v", "Enables verbose logging.", &verbose);
+ .OptionalSwitch("-v", "Enables verbose logging.", &verbose)
+ .OptionalSwitch("--debug-mode",
+ "Inserts android:debuggable=\"true\" in to the application node of the\n"
+ "manifest, making the application debuggable even on production devices.",
+ &options.manifest_fixer_options.debug_mode);
if (!flags.Parse("aapt2 link", args, &std::cerr)) {
return 1;
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 713db5b..165702c 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -354,6 +354,14 @@
uses_static_library_action.Action(RequiredAndroidAttribute("version"));
uses_static_library_action.Action(RequiredAndroidAttribute("certDigest"));
+ if (options_.debug_mode) {
+ application_action.Action([&](xml::Element* el) -> bool {
+ xml::Attribute *attr = el->FindOrCreateAttribute(xml::kSchemaAndroid, "debuggable");
+ attr->value = "true";
+ return true;
+ });
+ }
+
application_action["meta-data"] = meta_data_action;
application_action["activity"] = component_action;
diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h
index 0caa52e..7d6fad2 100644
--- a/tools/aapt2/link/ManifestFixer.h
+++ b/tools/aapt2/link/ManifestFixer.h
@@ -58,10 +58,13 @@
// 'android:compileSdkVersionCodename' in the <manifest> tag.
Maybe<std::string> compile_sdk_version_codename;
- // Wether validation errors should be treated only as warnings. If this is 'true', then an
+ // Whether validation errors should be treated only as warnings. If this is 'true', then an
// incorrect node will not result in an error, but only as a warning, and the parsing will
// continue.
bool warn_validation = false;
+
+ // Whether to inject the android:debuggable="true" flag into the manifest
+ bool debug_mode = false;
};
// Verifies that the manifest is correctly formed and inserts defaults where specified with
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index ed98d71..8db9374 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -416,6 +416,68 @@
EXPECT_THAT(Verify(input), IsNull());
}
+TEST_F(ManifestFixerTest, ApplicationInjectDebuggable) {
+ ManifestFixerOptions options;
+ options.debug_mode = true;
+
+ std::string no_d = R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <application>
+ </application>
+ </manifest>)";
+
+ std::string false_d = R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <application android:debuggable="false">
+ </application>
+ </manifest>)";
+
+ std::string true_d = R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android">
+ <application android:debuggable="true">
+ </application>
+ </manifest>)";
+
+ // Inject the debuggable attribute when the attribute is not present and the
+ // flag is present
+ std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(no_d, options);
+ EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
+ {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
+
+ // Set the debuggable flag to true if the attribute is false and the flag is
+ // present
+ manifest = VerifyWithOptions(false_d, options);
+ EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
+ {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
+
+ // Keep debuggable flag true if the attribute is true and the flag is present
+ manifest = VerifyWithOptions(true_d, options);
+ EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
+ {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
+
+ // Do not inject the debuggable attribute when the attribute is not present
+ // and the flag is not present
+ manifest = Verify(no_d);
+ EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
+ {}, "application", xml::kSchemaAndroid, "debuggable", "true"), IsNull());
+
+ // Do not set the debuggable flag to true if the attribute is false and the
+ // flag is not present
+ manifest = Verify(false_d);
+ EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
+ {}, "application", xml::kSchemaAndroid, "debuggable", "true"), IsNull());
+
+ // Keep debuggable flag true if the attribute is true and the flag is not
+ // present
+ manifest = Verify(true_d);
+ EXPECT_THAT(manifest->root.get()->FindChildWithAttribute(
+ {}, "application", xml::kSchemaAndroid, "debuggable", "true"), NotNull());
+}
+
+
TEST_F(ManifestFixerTest, IgnoreNamespacedElements) {
std::string input = R"EOF(
<manifest xmlns:android="http://schemas.android.com/apk/res/android"