Imported unit tests for ManifestMerger from AOSP.
Summary:
Since ManifestMerger already has unit tests in AOSP for most of its functionality we'll
just import them. We'll extend these unit tests to test new functionality that
we add in a followup diff.
Test Plan: Run unit tests.
diff --git a/lib/BUCK b/lib/BUCK
index 62c3557..d960f9b 100644
--- a/lib/BUCK
+++ b/lib/BUCK
@@ -143,6 +143,7 @@
visibility = [
'//src/com/facebook/buck/junit:junit',
'//test/...',
+ '//third-party/java/aosp/...',
],
)
diff --git a/src/com/facebook/buck/android/BUCK b/src/com/facebook/buck/android/BUCK
index e8461d7..2338d5c 100644
--- a/src/com/facebook/buck/android/BUCK
+++ b/src/com/facebook/buck/android/BUCK
@@ -94,7 +94,7 @@
'//src/com/facebook/buck/util:io',
'//src/com/facebook/buck/util:util',
'//src/com/facebook/buck/zip:steps',
- '//third-party/java/aosp/src/com/android:aosp',
+ '//third-party/java/aosp:aosp',
],
visibility = ['PUBLIC'],
)
@@ -142,7 +142,7 @@
'//src/com/facebook/buck/util/environment:environment',
'//src/com/facebook/buck/zip:steps',
'//src/com/facebook/buck/zip:stream',
- '//third-party/java/aosp/src/com/android:aosp',
+ '//third-party/java/aosp:aosp',
],
visibility = ['PUBLIC'],
)
diff --git a/third-party/java/aosp/BUCK b/third-party/java/aosp/BUCK
new file mode 100644
index 0000000..38d63b2
--- /dev/null
+++ b/third-party/java/aosp/BUCK
@@ -0,0 +1,32 @@
+java_library(
+ name = 'aosp',
+ srcs = glob(['src/**/*.java']),
+ visibility = [
+ 'PUBLIC',
+ ],
+)
+
+TEST_SRC = ['tests/src/**/*Test.java'];
+
+java_library(
+ name = 'testutils',
+ srcs = glob(['tests/src/**/*.java'], excludes = TEST_SRC),
+ deps = [
+ ':aosp',
+ '//lib:junit',
+ ],
+)
+
+java_test(
+ name = 'tests',
+ srcs = glob(TEST_SRC),
+ resources = glob(['tests/src/com/android/manifmerger/data/*']),
+ deps = [
+ ':aosp',
+ ':testutils',
+ '//lib:junit',
+ ],
+ source_under_test = [
+ ':aosp',
+ ],
+)
diff --git a/third-party/java/aosp/aosp.iml b/third-party/java/aosp/aosp.iml
index d5c0743..bc160c3 100644
--- a/third-party/java/aosp/aosp.iml
+++ b/third-party/java/aosp/aosp.iml
@@ -4,9 +4,19 @@
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/tests/src" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="module-library" scope="TEST">
+ <library>
+ <CLASSES>
+ <root url="jar://$APPLICATION_HOME_DIR$/lib/junit.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+ </orderEntry>
</component>
</module>
diff --git a/third-party/java/aosp/src/com/android/BUCK b/third-party/java/aosp/src/com/android/BUCK
deleted file mode 100644
index 6304e69..0000000
--- a/third-party/java/aosp/src/com/android/BUCK
+++ /dev/null
@@ -1,7 +0,0 @@
-java_library(
- name = 'aosp',
- srcs = glob(['**/*.java']),
- visibility = [
- 'PUBLIC',
- ],
-)
diff --git a/third-party/java/aosp/src/com/android/manifmerger/XmlUtils.java b/third-party/java/aosp/src/com/android/manifmerger/XmlUtils.java
index 0a3b08e..42fb074 100755
--- a/third-party/java/aosp/src/com/android/manifmerger/XmlUtils.java
+++ b/third-party/java/aosp/src/com/android/manifmerger/XmlUtils.java
@@ -487,7 +487,7 @@
@Override
public int compare(Attr a1, Attr a2) {
String s1 = a1 == null ? "" : a1.getNodeName(); //$NON-NLS-1$
- String s2 = a2 == null ? "" : a2.getNodeValue(); //$NON-NLS-1$
+ String s2 = a2 == null ? "" : a2.getNodeName(); //$NON-NLS-1$
int prio1 = s1.equals("name") ? 0 : 1; //$NON-NLS-1$
int prio2 = s2.equals("name") ? 0 : 1; //$NON-NLS-1$
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/ManifestMergerTest.java b/third-party/java/aosp/tests/src/com/android/manifmerger/ManifestMergerTest.java
new file mode 100755
index 0000000..47f46c4
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/ManifestMergerTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.manifmerger;
+
+
+/**
+ * Unit tests for {@link ManifestMerger}.
+ */
+public class ManifestMergerTest extends ManifestMergerTestCase {
+
+ /*
+ * Wait, I hear you, where are the tests?
+ *
+ * processTestFiles() uses loadTestData(), which infers the data filename
+ * from the caller method name.
+ * E.g. the method "test00_noop" will use the data file named "data/00_noop.xml".
+ *
+ * We could simplify this even further by simply iterating on the data
+ * files and getting rid of the test methods; however there's some value in
+ * having tests break on a method name that easily points to the data file.
+ */
+
+ public void test00_noop() throws Exception {
+ processTestFiles();
+ }
+
+ public void test01_ignore_app_attr() throws Exception {
+ processTestFiles();
+ }
+
+ public void test02_ignore_instrumentation() throws Exception {
+ processTestFiles();
+ }
+
+ public void test10_activity_merge() throws Exception {
+ processTestFiles();
+ }
+
+ public void test11_activity_dup() throws Exception {
+ processTestFiles();
+ }
+
+ public void test12_alias_dup() throws Exception {
+ processTestFiles();
+ }
+
+ public void test13_service_dup() throws Exception {
+ processTestFiles();
+ }
+
+ public void test14_receiver_dup() throws Exception {
+ processTestFiles();
+ }
+
+ public void test15_provider_dup() throws Exception {
+ processTestFiles();
+ }
+
+ public void test16_fqcn_merge() throws Exception {
+ processTestFiles();
+ }
+
+ public void test17_fqcn_conflict() throws Exception {
+ processTestFiles();
+ }
+
+ public void test20_uses_lib_merge() throws Exception {
+ processTestFiles();
+ }
+
+ public void test21_uses_lib_errors() throws Exception {
+ processTestFiles();
+ }
+
+ public void test25_permission_merge() throws Exception {
+ processTestFiles();
+ }
+
+ public void test26_permission_dup() throws Exception {
+ processTestFiles();
+ }
+
+ public void test28_uses_perm_merge() throws Exception {
+ processTestFiles();
+ }
+
+ public void test30_uses_sdk_ok() throws Exception {
+ processTestFiles();
+ }
+
+ public void test32_uses_sdk_minsdk_ok() throws Exception {
+ processTestFiles();
+ }
+
+ public void test33_uses_sdk_minsdk_conflict() throws Exception {
+ processTestFiles();
+ }
+
+ public void test36_uses_sdk_targetsdk_warning() throws Exception {
+ processTestFiles();
+ }
+
+ public void test40_uses_feat_merge() throws Exception {
+ processTestFiles();
+ }
+
+ public void test41_uses_feat_errors() throws Exception {
+ processTestFiles();
+ }
+
+ public void test45_uses_feat_gles_once() throws Exception {
+ processTestFiles();
+ }
+
+ public void test47_uses_feat_gles_conflict() throws Exception {
+ processTestFiles();
+ }
+
+ public void test50_uses_conf_warning() throws Exception {
+ processTestFiles();
+ }
+
+ public void test52_support_screens_warning() throws Exception {
+ processTestFiles();
+ }
+
+ public void test54_compat_screens_warning() throws Exception {
+ processTestFiles();
+ }
+
+ public void test56_support_gltext_warning() throws Exception {
+ processTestFiles();
+ }
+}
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/ManifestMergerTestCase.java b/third-party/java/aosp/tests/src/com/android/manifmerger/ManifestMergerTestCase.java
new file mode 100755
index 0000000..e152c06
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/ManifestMergerTestCase.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.manifmerger;
+
+import com.android.common.annotations.NonNull;
+import com.android.manifmerger.IMergerLog.FileAndLine;
+
+import org.w3c.dom.Document;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/**
+ * Some utilities to reduce repetitions in the {@link ManifestMergerTest}s.
+ * <p/>
+ * See {@link #loadTestData(String)} for an explanation of the data file format.
+ */
+abstract class ManifestMergerTestCase extends TestCase {
+
+ /**
+ * Delimiter that indicates the test must fail.
+ * An XML output and errors are still generated and checked.
+ */
+ private static final String DELIM_FAILS = "fails";
+ /**
+ * Delimiter that starts a library XML content.
+ * The delimiter name must be in the form {@code @libSomeName} and it will be
+ * used as the base for the test file name. Using separate lib names is encouraged
+ * since it makes the error output easier to read.
+ */
+ private static final String DELIM_LIB = "lib";
+ /**
+ * Delimiter that starts the main manifest XML content.
+ */
+ private static final String DELIM_MAIN = "main";
+ /**
+ * Delimiter that starts the resulting XML content, whatever is generated by the merge.
+ */
+ private static final String DELIM_RESULT = "result";
+ /**
+ * Delimiter that starts the SdkLog output.
+ * The logger prints each entry on its lines, prefixed with E for errors,
+ * W for warnings and P for regular printfs.
+ */
+ private static final String DELIM_ERRORS = "errors";
+
+ static class TestFiles {
+ private final File mMain;
+ private final File[] mLibs;
+ private final File mActualResult;
+ private final String mExpectedResult;
+ private final String mExpectedErrors;
+ private final boolean mShouldFail;
+
+ /**
+ * Files used by a given test case.
+ */
+ public TestFiles(
+ boolean shouldFail,
+ @NonNull File main,
+ @NonNull File[] libs,
+ @NonNull File actualResult,
+ @NonNull String expectedResult,
+ @NonNull String expectedErrors) {
+ mShouldFail = shouldFail;
+ mMain = main;
+ mLibs = libs;
+ mActualResult = actualResult;
+ mExpectedResult = expectedResult;
+ mExpectedErrors = expectedErrors;
+ }
+
+ public boolean getShouldFail() {
+ return mShouldFail;
+ }
+
+ @NonNull
+ public File getMain() {
+ return mMain;
+ }
+
+ @NonNull
+ public File[] getLibs() {
+ return mLibs;
+ }
+
+ @NonNull
+ public File getActualResult() {
+ return mActualResult;
+ }
+
+ @NonNull
+ public String getExpectedResult() {
+ return mExpectedResult;
+ }
+
+ public String getExpectedErrors() {
+ return mExpectedErrors;
+ }
+
+ // Try to delete any temp file potentially created.
+ public void cleanup() {
+ if (mMain != null && mMain.isFile()) {
+ mMain.delete();
+ }
+
+ if (mActualResult != null && mActualResult.isFile()) {
+ mActualResult.delete();
+ }
+
+ for (File f : mLibs) {
+ if (f != null && f.isFile()) {
+ f.delete();
+ }
+ }
+ }
+ }
+
+ /**
+ * Calls {@link #loadTestData(String)} by
+ * inferring the data filename from the caller's method name.
+ * <p/>
+ * The caller method name must be composed of "test" + the leaf filename.
+ * Extensions ".xml" or ".txt" are implied.
+ * <p/>
+ * E.g. to use the data file "12_foo.xml", simply call this from a method
+ * named "test12_foo".
+ *
+ * @return A new {@link TestFiles} instance. Never null.
+ * @throws Exception when things go wrong.
+ * @see #loadTestData(String)
+ */
+ @NonNull
+ TestFiles loadTestData() throws Exception {
+ StackTraceElement[] stack = Thread.currentThread().getStackTrace();
+ for (int i = 0, n = stack.length; i < n; i++) {
+ StackTraceElement caller = stack[i];
+ String name = caller.getMethodName();
+ if (name.startsWith("test")) {
+ return loadTestData(name.substring(4));
+ }
+ }
+
+ throw new IllegalArgumentException("No caller method found which name started with 'test'");
+ }
+
+ /**
+ * Loads test data for a given test case.
+ * The input (main + libs) are stored in temp files.
+ * A new destination temp file is created to store the actual result output.
+ * The expected result is actually kept in a string.
+ * <p/>
+ * Data File Syntax:
+ * <ul>
+ * <li> Lines starting with # are ignored (anywhere, as long as # is the first char).
+ * <li> Lines before the first {@code @delimiter} are ignored.
+ * <li> Empty lines just after the {@code @delimiter}
+ * and before the first < XML line are ignored.
+ * <li> Valid delimiters are {@code @main} for the XML of the main app manifest.
+ * <li> Following delimiters are {@code @libXYZ}, read in the order of definition.
+ * The name can be anything as long as it starts with "{@code @lib}".
+ * </ul>
+ *
+ * @param filename The test data filename. If no extension is provided, this will
+ * try with .xml or .txt. Must not be null.
+ * @return A new {@link TestFiles} instance. Must not be null.
+ * @throws Exception when things fail to load properly.
+ */
+ @NonNull
+ TestFiles loadTestData(@NonNull String filename) throws Exception {
+
+ String resName = "data" + File.separator + filename;
+ InputStream is = null;
+ BufferedReader reader = null;
+ BufferedWriter writer = null;
+
+ try {
+ is = this.getClass().getResourceAsStream(resName);
+ if (is == null && !filename.endsWith(".xml")) {
+ String resName2 = resName + ".xml";
+ is = this.getClass().getResourceAsStream(resName2);
+ if (is != null) {
+ filename = resName2;
+ }
+ }
+ if (is == null && !filename.endsWith(".txt")) {
+ String resName3 = resName + ".txt";
+ is = this.getClass().getResourceAsStream(resName3);
+ if (is != null) {
+ filename = resName3;
+ }
+ }
+ assertNotNull("Test data file not found for " + filename, is);
+
+ reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+
+ // Get the temporary directory to use. Just create a temp file, extracts its
+ // directory and remove the file.
+ File tempFile = File.createTempFile(this.getClass().getSimpleName(), ".tmp");
+ File tempDir = tempFile.getParentFile();
+ if (!tempFile.delete()) {
+ tempFile.deleteOnExit();
+ }
+
+ String line = null;
+ String delimiter = null;
+ boolean skipEmpty = true;
+
+ boolean shouldFail = false;
+ StringBuilder expectedResult = new StringBuilder();
+ StringBuilder expectedErrors = new StringBuilder();
+ File mainFile = null;
+ File actualResultFile = null;
+ List<File> libFiles = new ArrayList<File>();
+ int tempIndex = 0;
+
+ while ((line = reader.readLine()) != null) {
+ if (skipEmpty && line.trim().length() == 0) {
+ continue;
+ }
+ if (line.length() > 0 && line.charAt(0) == '#') {
+ continue;
+ }
+ if (line.length() > 0 && line.charAt(0) == '@') {
+ delimiter = line.substring(1);
+ assertTrue(
+ "Unknown delimiter @" + delimiter + " in " + filename,
+ delimiter.startsWith(DELIM_LIB) ||
+ delimiter.equals(DELIM_MAIN) ||
+ delimiter.equals(DELIM_RESULT) ||
+ delimiter.equals(DELIM_ERRORS) ||
+ delimiter.equals(DELIM_FAILS));
+
+ skipEmpty = true;
+
+ if (writer != null) {
+ try {
+ writer.close();
+ } catch (IOException ignore) {
+ }
+ writer = null;
+ }
+
+ if (delimiter.equals(DELIM_FAILS)) {
+ shouldFail = true;
+
+ } else if (!delimiter.equals(DELIM_ERRORS)) {
+ tempFile = new File(tempDir, String.format("%1$s%2$d_%3$s.xml",
+ this.getClass().getSimpleName(),
+ tempIndex++,
+ delimiter.replaceAll("[^a-zA-Z0-9_-]", "")
+ ));
+ tempFile.deleteOnExit();
+
+ if (delimiter.startsWith(DELIM_LIB)) {
+ libFiles.add(tempFile);
+
+ } else if (delimiter.equals(DELIM_MAIN)) {
+ mainFile = tempFile;
+
+ } else if (delimiter.equals(DELIM_RESULT)) {
+ actualResultFile = tempFile;
+
+ } else {
+ fail("Unexpected data file delimiter @" + delimiter +
+ " in " + filename);
+ }
+
+ if (!delimiter.equals(DELIM_RESULT)) {
+ writer = new BufferedWriter(new FileWriter(tempFile));
+ }
+ }
+
+ continue;
+ }
+ if (delimiter != null &&
+ skipEmpty &&
+ line.length() > 0 &&
+ line.charAt(0) != '#' &&
+ line.charAt(0) != '@') {
+ skipEmpty = false;
+ }
+ if (writer != null) {
+ writer.write(line);
+ writer.write('\n');
+ } else if (DELIM_RESULT.equals(delimiter)) {
+ expectedResult.append(line).append('\n');
+ } else if (DELIM_ERRORS.equals(delimiter)) {
+ expectedErrors.append(line).append('\n');
+ }
+ }
+
+ assertNotNull("Missing @" + DELIM_MAIN + " in " + filename, mainFile);
+ assertNotNull("Missing @" + DELIM_RESULT + " in " + filename, actualResultFile);
+
+ assert mainFile != null;
+ assert actualResultFile != null;
+
+ return new TestFiles(
+ shouldFail,
+ mainFile,
+ libFiles.toArray(new File[libFiles.size()]),
+ actualResultFile,
+ expectedResult.toString(),
+ expectedErrors.toString());
+
+ } catch (UnsupportedEncodingException e) {
+ // BufferedReader failed to decode UTF-8, O'RLY?
+ throw e;
+
+ } finally {
+ if (writer != null) {
+ try {
+ writer.close();
+ } catch (IOException ignore) {
+ }
+ }
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException ignore) {
+ }
+ }
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+ }
+
+ /**
+ * Loads the data test files using {@link #loadTestData()} and then
+ * invokes {@link #processTestFiles(TestFiles)} to test them.
+ *
+ * @see #loadTestData()
+ * @see #processTestFiles(TestFiles)
+ */
+ void processTestFiles() throws Exception {
+ processTestFiles(loadTestData());
+ }
+
+ /**
+ * Processes the data from the given {@link TestFiles} by
+ * invoking {@link ManifestMerger#process(File, File, File[])}:
+ * the given library files are applied consecutively to the main XML
+ * document and the output is generated.
+ * <p/>
+ * Then the expected and actual outputs are loaded into a DOM,
+ * dumped again to a String using an XML transform and compared.
+ * This makes sure only the structure is checked and that any
+ * formatting is ignored in the comparison.
+ *
+ * @param testFiles The test files to process. Must not be null.
+ * @throws Exception when this go wrong.
+ */
+ void processTestFiles(TestFiles testFiles) throws Exception {
+ MockLog log = new MockLog();
+ IMergerLog mergerLog = MergerLog.wrapSdkLog(log);
+ ManifestMerger merger = new ManifestMerger(mergerLog, new ICallback() {
+ @Override
+ public int queryCodenameApiLevel(@NonNull String codename) {
+ if ("ApiCodename1".equals(codename)) {
+ return 1;
+ } else if ("ApiCodename10".equals(codename)) {
+ return 10;
+ }
+ return ICallback.UNKNOWN_CODENAME;
+ }
+ });
+ boolean processOK = merger.process(testFiles.getActualResult(),
+ testFiles.getMain(),
+ testFiles.getLibs());
+
+ String expectedErrors = testFiles.getExpectedErrors().trim();
+ StringBuilder actualErrors = new StringBuilder();
+ for (String s : log.getMessages()) {
+ actualErrors.append(s);
+ if (!s.endsWith("\n")) {
+ actualErrors.append('\n');
+ }
+ }
+ assertEquals("Error generated during merging",
+ expectedErrors, actualErrors.toString().trim());
+
+ if (testFiles.getShouldFail()) {
+ assertFalse("Merge process() returned true, expected false", processOK);
+ } else {
+ assertTrue("Merge process() returned false, expected true", processOK);
+ }
+
+ // Test result XML. There should always be one created
+ // since the process action does not stop on errors.
+ log.clear();
+ Document document = XmlUtils.parseDocument(testFiles.getActualResult(), mergerLog);
+ assertNotNull(document);
+ assert document != null; // for Eclipse null analysis
+ String actual = XmlUtils.printXmlString(document, mergerLog);
+ assertEquals("Error parsing actual result XML", "[]", log.toString());
+ log.clear();
+ document = XmlUtils.parseDocument(
+ testFiles.getExpectedResult(),
+ mergerLog,
+ new FileAndLine("<expected-result>", 0));
+ assertNotNull(document);
+ assert document != null;
+ String expected = XmlUtils.printXmlString(document, mergerLog);
+ assertEquals("Error parsing expected result XML", "[]", log.toString());
+ assertEquals("Error comparing expected to actual result", expected, actual);
+
+ testFiles.cleanup();
+ }
+
+}
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/MockLog.java b/third-party/java/aosp/tests/src/com/android/manifmerger/MockLog.java
new file mode 100644
index 0000000..cfb5de6
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/MockLog.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.manifmerger;
+
+import com.android.common.annotations.NonNull;
+import com.android.common.utils.ILogger;
+
+import java.util.ArrayList;
+import java.util.Formatter;
+import java.util.List;
+
+/**
+ * An instance of {@link ILogger} that captures all messages to an internal list.
+ * Messages can be retrieved later using {@link #toString()}.
+ * Useful for unit-tests.
+ */
+public class MockLog implements ILogger {
+ private ArrayList<String> mMessages = new ArrayList<String>();
+
+ private void add(String code, String format, Object... args) {
+ Formatter formatter = new Formatter();
+ mMessages.add(formatter.format(code + format, args).toString());
+ formatter.close();
+ }
+
+ @Override
+ public void warning(@NonNull String format, Object... args) {
+ add("W ", format, args);
+ }
+
+ @Override
+ public void info(@NonNull String format, Object... args) {
+ add("P ", format, args);
+ }
+
+ @Override
+ public void verbose(@NonNull String format, Object... args) {
+ add("V ", format, args);
+ }
+
+ @Override
+ public void error(Throwable t, String format, Object... args) {
+ if (t != null) {
+ add("T", "%s", t.toString());
+ }
+ add("E ", format, args);
+ }
+
+ @Override
+ public String toString() {
+ return mMessages.toString();
+ }
+
+ @NonNull
+ public List<String> getMessages() {
+ return mMessages;
+ }
+
+ public void clear() {
+ mMessages.clear();
+ }
+}
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/00_noop.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/00_noop.xml
new file mode 100755
index 0000000..2160f69
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/00_noop.xml
@@ -0,0 +1,229 @@
+#
+# Syntax:
+# - Lines starting with # are ignored (anywhere, as long as # is the first char).
+# - Lines before the first @delimiter are ignored.
+# - Empty lines just after the @delimiter and before the first < XML line are ignored.
+# - Valid delimiters are @main for the XML of the main app manifest.
+# - Following delimiters are @libXYZ, read in the order of definition. The name can be
+# anything as long as it starts with "@lib".
+# - Last delimiter should be @result.
+#
+
+@main
+
+<!--
+ This is a canonical manifest that has some uses-permissions,
+ the usual uses-sdk and supports-screens, an app with an activity,
+ customer receiver & service and a widget.
+-->
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <!-- Typical analytics permissions. -->
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <!-- Touchscreen feature, optional to make sure we can run on devices with no touch screen. -->
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- Receiver -->
+ <receiver
+ android:name="com.example.AppReceiver"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+
+ <!-- Broadcast Receiver for a widget. -->
+ <receiver
+ android:label="@string/widget_name"
+ android:icon="@drawable/widget_icon"
+ android:name="com.example.WidgetReceiver" >
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ </intent-filter>
+ <meta-data
+ android:name="android.appwidget.provider"
+ android:resource="@xml/widget_provider"
+ />
+ </receiver>
+
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService" />
+
+ <!-- Activity to configure widget -->
+ <activity
+ android:icon="@drawable/widget_icon"
+ android:label="Configure Widget"
+ android:name="com.example.WidgetConfigurationUI"
+ android:theme="@style/Theme.WidgetConfigurationUI" >
+ <intent-filter >
+ <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
+ </intent-filter>
+ </activity>
+
+ <!-- Provider extracted from ApiDemos -->
+ <provider android:name=".app.LoaderThrottle$SimpleProvider"
+ android:authorities="com.example.android.apis.app.LoaderThrottle"
+ android:enabled="@bool/atLeastHoneycomb" />
+
+ </application>
+
+</manifest>
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+</manifest>
+
+
+@lib2
+
+# An empty library is not supported. It must be a valid XML file.
+<manifest/>
+
+@result
+
+<!--
+ This is a canonical manifest that has some uses-permissions,
+ the usual uses-sdk and supports-screens, an app with an activity,
+ customer receiver & service and a widget.
+-->
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <!-- Typical analytics permissions. -->
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <!-- Touchscreen feature, optional to make sure we can run on devices with no touch screen. -->
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- Receiver -->
+ <receiver
+ android:name="com.example.AppReceiver"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+
+ <!-- Broadcast Receiver for a widget. -->
+ <receiver
+ android:label="@string/widget_name"
+ android:icon="@drawable/widget_icon"
+ android:name="com.example.WidgetReceiver" >
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ </intent-filter>
+ <meta-data
+ android:name="android.appwidget.provider"
+ android:resource="@xml/widget_provider"
+ />
+ </receiver>
+
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService" />
+
+ <!-- Activity to configure widget -->
+ <activity
+ android:icon="@drawable/widget_icon"
+ android:label="Configure Widget"
+ android:name="com.example.WidgetConfigurationUI"
+ android:theme="@style/Theme.WidgetConfigurationUI" >
+ <intent-filter >
+ <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
+ </intent-filter>
+ </activity>
+
+ <!-- Provider extracted from ApiDemos -->
+ <provider
+ android:name="com.example.app1.app.LoaderThrottle$SimpleProvider"
+ android:authorities="com.example.android.apis.app.LoaderThrottle"
+ android:enabled="@bool/atLeastHoneycomb" />
+
+ </application>
+
+</manifest>
+
+
+@errors
+
+W [ManifestMergerTest2_lib2.xml:1] Missing 'package' attribute in manifest.
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/01_ignore_app_attr.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/01_ignore_app_attr.xml
new file mode 100755
index 0000000..b939dd7
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/01_ignore_app_attr.xml
@@ -0,0 +1,69 @@
+#
+# Test:
+# - Attributes from the application element in a library are ignored (except name)
+# - Comments from nodes ignored in libraries are not merged either.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- Source comments are preserved as-is. -->
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+ </application>
+
+</manifest>
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- The attributes from <application> in a library are not merged nor checked
+ except for 'name' and 'backupAgent' which must match.
+ This comment is ignored. -->
+ <application
+ android:label="@string/lib_name"
+ android:icon="@drawable/lib_icon"
+ android:name="com.example.TheApp" >
+ </application>
+
+</manifest>
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- Source comments are preserved as-is. -->
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+ </application>
+
+</manifest>
+
+@errors
+
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/02_ignore_instrumentation.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/02_ignore_instrumentation.xml
new file mode 100755
index 0000000..ed0dbbc
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/02_ignore_instrumentation.xml
@@ -0,0 +1,62 @@
+#
+# Test:
+# - Instrumentation element from libraries are not merged in main manifest.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+ </application>
+
+</manifest>
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- Instrumentation is not merged from libraries. -->
+ <instrumentation
+ android:targetPackage="com.example.app1"
+ android:name="android.test.InstrumentationTestRunner" />
+
+</manifest>
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+ </application>
+
+</manifest>
+
+@errors
+
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/10_activity_merge.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/10_activity_merge.xml
new file mode 100755
index 0000000..59c5c42
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/10_activity_merge.xml
@@ -0,0 +1,378 @@
+#
+# Test:
+# - Activities from libraries are merged in the main manifest.
+# - Acts on activity / activity-alias / service / receiver / provider.
+# - Elements are merged as-is with the first comment element preceding them.
+# - Whitespace preceding the merged elements is transfered over too.
+#
+# Note:
+# - New elements are always merged at the end of the application element.
+# - It's an error if an element with the same @name attribute is defined
+# or merged more than once unless the definition is *exactly* the same,
+# the "same" being defined by the exact XML elements, whitespace excluded.
+#
+# This tests that a normal merge is done as expected.
+# There's a warning because one of the activities from lib2 is already defined
+# in the main but it's purely identical so it's not an error.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <!-- Typical analytics permissions. -->
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <!-- Touchscreen feature, optional to make sure we can run on devices with no touch screen. -->
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- Receiver -->
+ <receiver
+ android:name="com.example.AppReceiver"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+
+ <!-- This is exactly the same as in lib2_activity -->
+ <activity
+ android:name="com.example.LibActivity"
+ android:label="@string/lib_activity_name"
+ android:icon="@drawable/lib_activity_icon"
+ android:theme="@style/Lib.Theme">
+
+ <!-- When comparing duplicate elements, whitespace and comments are ignored. -->
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+
+ </activity>
+
+ <!-- end of the main manifest's application element. Note that the
+ merger will insert at the end of this comment, in the specific
+ order activity, activity-alias, service, receiver and provider. -->
+
+ </application>
+
+</manifest>
+
+
+@lib1_widget
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <application android:label="@string/lib_name" >
+
+ <!-- Broadcast Receiver for a widget. -->
+ <receiver
+ android:label="@string/widget_name"
+ android:icon="@drawable/widget_icon"
+ android:name="com.example.WidgetReceiver" >
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ </intent-filter>
+ <meta-data
+ android:name="android.appwidget.provider"
+ android:resource="@xml/widget_provider"
+ />
+ </receiver>
+
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService" />
+
+ <!-- Activity to configure widget -->
+ <activity
+ android:icon="@drawable/widget_icon"
+ android:label="Configure Widget"
+ android:name="com.example.WidgetConfigurationUI"
+ android:theme="@style/Theme.WidgetConfigurationUI" >
+ <intent-filter >
+ <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+
+
+@lib2_activity
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <application android:label="@string/lib_name" >
+
+ <!-- This won't be merged because there's already an identical definition in the main. -->
+ <activity
+ android:name="com.example.LibActivity"
+ android:label="@string/lib_activity_name"
+ android:icon="@drawable/lib_activity_icon"
+ android:theme="@style/Lib.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- Provider extracted from ApiDemos -->
+ <provider android:name=".app.LoaderThrottle$SimpleProvider"
+ android:authorities="com.example.android.apis.app.LoaderThrottle"
+ android:enabled="@bool/atLeastHoneycomb" />
+
+ <!-- This one does not conflict with the main -->
+ <activity
+ android:name="com.example.LibActivity2"
+ android:label="@string/lib_activity_name"
+ android:icon="@drawable/lib_activity_icon"
+ android:theme="@style/Lib.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@lib3_alias
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib3">
+
+ <!-- This comment is ignored. -->
+
+ <application android:label="@string/lib_name" >
+
+ <!-- The first comment just before the element
+ is carried over as-is.
+ -->
+ <!-- Formatting is preserved. -->
+ <!-- All consecutive comments are taken together. -->
+
+ <activity-alias
+ android:name="com.example.alias.MyActivity"
+ android:targetActivity="com.example.MainActivity"
+ android:label="@string/alias_name"
+ android:icon="@drawable/alias_icon"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
+
+ <!-- This is a dup of the 2nd activity in lib2 -->
+ <activity
+ android:name="com.example.LibActivity2"
+ android:label="@string/lib_activity_name"
+ android:icon="@drawable/lib_activity_icon"
+ android:theme="@style/Lib.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <!-- Typical analytics permissions. -->
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <!-- Touchscreen feature, optional to make sure we can run on devices with no touch screen. -->
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- Receiver -->
+ <receiver
+ android:name="com.example.AppReceiver"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+
+ <!-- This is exactly the same as in lib2_activity -->
+ <activity
+ android:name="com.example.LibActivity"
+ android:label="@string/lib_activity_name"
+ android:icon="@drawable/lib_activity_icon"
+ android:theme="@style/Lib.Theme">
+
+ <!-- When comparing duplicate elements, whitespace and comments are ignored. -->
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+
+ </activity>
+
+ <!-- end of the main manifest's application element. Note that the
+ merger will insert at the end of this comment, in the specific
+ order activity, activity-alias, service, receiver and provider. -->
+
+# from @lib1_widget
+ <!-- Activity to configure widget -->
+ <activity
+ android:icon="@drawable/widget_icon"
+ android:label="Configure Widget"
+ android:name="com.example.WidgetConfigurationUI"
+ android:theme="@style/Theme.WidgetConfigurationUI" >
+ <intent-filter >
+ <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
+ </intent-filter>
+ </activity>
+
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService" />
+
+ <!-- Broadcast Receiver for a widget. -->
+ <receiver
+ android:label="@string/widget_name"
+ android:icon="@drawable/widget_icon"
+ android:name="com.example.WidgetReceiver" >
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ </intent-filter>
+ <meta-data
+ android:name="android.appwidget.provider"
+ android:resource="@xml/widget_provider"
+ />
+ </receiver>
+
+# from @lib2_activity
+ <!-- This one does not conflict with the main -->
+ <activity
+ android:name="com.example.LibActivity2"
+ android:label="@string/lib_activity_name"
+ android:icon="@drawable/lib_activity_icon"
+ android:theme="@style/Lib.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- Provider extracted from ApiDemos -->
+ <provider android:name="com.example.lib2.app.LoaderThrottle$SimpleProvider"
+ android:authorities="com.example.android.apis.app.LoaderThrottle"
+ android:enabled="@bool/atLeastHoneycomb" />
+
+# from @lib3_alias
+ <!-- The first comment just before the element
+ is carried over as-is.
+ -->
+ <!-- Formatting is preserved. -->
+ <!-- All consecutive comments are taken together. -->
+
+ <activity-alias
+ android:name="com.example.alias.MyActivity"
+ android:targetActivity="com.example.MainActivity"
+ android:label="@string/alias_name"
+ android:icon="@drawable/alias_icon"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
+
+ </application>
+
+</manifest>
+
+@errors
+
+P [ManifestMergerTest0_main.xml:31, ManifestMergerTest2_lib2_activity.xml:6] Skipping identical /manifest/application/activity[@name=com.example.LibActivity] element.
+P [ManifestMergerTest0_main.xml, ManifestMergerTest3_lib3_alias.xml:19] Skipping identical /manifest/application/activity[@name=com.example.LibActivity2] element.
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/11_activity_dup.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/11_activity_dup.xml
new file mode 100755
index 0000000..5ba6688
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/11_activity_dup.xml
@@ -0,0 +1,387 @@
+#
+# Test:
+# - Activities from libraries are merged in the main manifest.
+# - Acts on activity / activity-alias / service / receiver / provider.
+# - Elements are merged as-is with the first comment element preceding them.
+# - Whitespace preceding the merged elements is transfered over too.
+#
+# Note:
+# - New elements are always merged at the end of the application element.
+# - It's an error if an element with the same @name attribute is defined
+# or merged more than once unless the definition is *exactly* the same,
+# the "same" being defined by the exact XML elements, whitespace excluded.
+#
+# This tests that an error is generated because the libraries define
+# activities which are already in the main, with slightly different XML content:
+# number and *order* of elements must match, attributes must match.
+#
+
+@fails
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <!-- Typical analytics permissions. -->
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <!-- Touchscreen feature, optional to make sure we can run on devices with no touch screen. -->
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- Receiver -->
+ <receiver
+ android:name="com.example.AppReceiver"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+
+
+ <!-- Conflict with lib1 -->
+ <activity
+ android:icon="@drawable/widget_icon"
+ android:label="Configure Widget"
+ android:name="com.example.WidgetConfigurationUI"
+ android:theme="@style/Theme.WidgetConfigurationUI" >
+ <!-- missing the intent-filter -->
+ </activity>
+
+
+ <!-- Conflict with lib2 -->
+ <activity
+ android:name="com.example.LibActivity"
+ android:label="@string/lib_activity_name"
+ android:icon="@drawable/lib_activity_icon">
+ <!-- missing attribute android:theme="@style/Lib.Theme" -->
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@lib1_widget
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <application android:label="@string/lib_name" >
+
+ <!-- Broadcast Receiver for a widget. -->
+ <receiver
+ android:label="@string/widget_name"
+ android:icon="@drawable/widget_icon"
+ android:name="com.example.WidgetReceiver" >
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ </intent-filter>
+ <meta-data
+ android:name="android.appwidget.provider"
+ android:resource="@xml/widget_provider"
+ />
+ </receiver>
+
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService" />
+
+ <!-- Activity to configure widget -->
+ <activity
+ android:icon="@drawable/widget_icon"
+ android:label="Configure Widget"
+ android:name="com.example.WidgetConfigurationUI"
+ android:theme="@style/Theme.WidgetConfigurationUI" >
+ <intent-filter >
+ <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+
+
+@lib2_activity
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <application android:label="@string/lib_name" >
+
+ <!-- This won't be merged because there's already an identical definition in the main. -->
+ <activity
+ android:name="com.example.LibActivity"
+ android:label="@string/lib_activity_name"
+ android:icon="@drawable/lib_activity_icon"
+ android:theme="@style/Lib.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- Provider extracted from ApiDemos -->
+ <provider android:name=".app.LoaderThrottle$SimpleProvider"
+ android:authorities="com.example.android.apis.app.LoaderThrottle"
+ android:enabled="@bool/atLeastHoneycomb" />
+
+ <!-- This one does not conflict with the main -->
+ <activity
+ android:name="com.example.LibActivity2"
+ android:label="@string/lib_activity_name"
+ android:icon="@drawable/lib_activity_icon"
+ android:theme="@style/Lib.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@lib3_alias
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib3">
+
+ <!-- This comment is ignored. -->
+
+ <application android:label="@string/lib_name" >
+
+ <!-- The first comment just before the element
+ is carried over as-is.
+ -->
+ <!-- Formatting is preserved. -->
+ <!-- All consecutive comments are taken together. -->
+
+ <activity-alias
+ android:name="com.example.alias.MyActivity"
+ android:targetActivity="com.example.MainActivity"
+ android:label="@string/alias_name"
+ android:icon="@drawable/alias_icon"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
+
+ <!-- This will conflict with the 2nd one from lib2 -->
+ <activity
+ android:name="com.example.LibActivity2"
+ android:label="@string/lib_activity_name"
+ android:icon="@drawable/lib_activity_icon"
+ android:theme="@style/Lib.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ <category android:name="android.intent.category.MOARCATZPLZ" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <!-- Typical analytics permissions. -->
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <!-- Touchscreen feature, optional to make sure we can run on devices with no touch screen. -->
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <!-- Receiver -->
+ <receiver
+ android:name="com.example.AppReceiver"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+
+
+ <!-- Conflict with lib1 -->
+ <activity
+ android:icon="@drawable/widget_icon"
+ android:label="Configure Widget"
+ android:name="com.example.WidgetConfigurationUI"
+ android:theme="@style/Theme.WidgetConfigurationUI" >
+ <!-- missing the intent-filter -->
+ </activity>
+
+
+ <!-- Conflict with lib2 -->
+ <activity
+ android:name="com.example.LibActivity"
+ android:label="@string/lib_activity_name"
+ android:icon="@drawable/lib_activity_icon">
+ <!-- missing attribute android:theme="@style/Lib.Theme" -->
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+# from @lib1_widget
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService" />
+
+ <!-- Broadcast Receiver for a widget. -->
+ <receiver
+ android:label="@string/widget_name"
+ android:icon="@drawable/widget_icon"
+ android:name="com.example.WidgetReceiver" >
+ <intent-filter>
+ <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+ </intent-filter>
+ <meta-data
+ android:name="android.appwidget.provider"
+ android:resource="@xml/widget_provider"
+ />
+ </receiver>
+
+# from @lib2_activity
+ <!-- This one does not conflict with the main -->
+ <activity android:icon="@drawable/lib_activity_icon" android:label="@string/lib_activity_name" android:name="com.example.LibActivity2" android:theme="@style/Lib.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.LAUNCHER"/>
+ </intent-filter>
+ </activity>
+
+ <!-- Provider extracted from ApiDemos -->
+ <provider android:name="com.example.lib2.app.LoaderThrottle$SimpleProvider"
+ android:authorities="com.example.android.apis.app.LoaderThrottle"
+ android:enabled="@bool/atLeastHoneycomb" />
+
+# from @lib3_alias
+ <!-- The first comment just before the element
+ is carried over as-is.
+ -->
+ <!-- Formatting is preserved. -->
+ <!-- All consecutive comments are taken together. -->
+
+ <activity-alias
+ android:name="com.example.alias.MyActivity"
+ android:targetActivity="com.example.MainActivity"
+ android:label="@string/alias_name"
+ android:icon="@drawable/alias_icon"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
+
+ </application>
+
+</manifest>
+
+@errors
+
+E [ManifestMergerTest0_main.xml:32, ManifestMergerTest1_lib1_widget.xml:16] Trying to merge incompatible /manifest/application/activity[@name=com.example.WidgetConfigurationUI] element:
+ <activity android:name=com.example.WidgetConfigurationUI>
+-- <intent-filter>
+++ (end reached)
+E [ManifestMergerTest0_main.xml:38, ManifestMergerTest2_lib2_activity.xml:6] Trying to merge incompatible /manifest/application/activity[@name=com.example.LibActivity] element:
+ <activity android:name=com.example.LibActivity>
+ @android:icon = @drawable/lib_activity_icon
+ @android:label = @string/lib_activity_name
+ @android:name = com.example.LibActivity
+-- @android:theme = @style/Lib.Theme
+E [ManifestMergerTest0_main.xml, ManifestMergerTest3_lib3_alias.xml:19] Trying to merge incompatible /manifest/application/activity[@name=com.example.LibActivity2] element:
+ <activity android:name=com.example.LibActivity2>
+ <intent-filter>
+ <action android:name=android.intent.action.MAIN>
+ <category android:name=android.intent.category.LAUNCHER>
+-- <category android:name=android.intent.category.MOARCATZPLZ>
+++ (end reached)
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/12_alias_dup.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/12_alias_dup.xml
new file mode 100755
index 0000000..696965f
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/12_alias_dup.xml
@@ -0,0 +1,205 @@
+#
+# Test:
+# - Activities from libraries are merged in the main manifest.
+# - Acts on activity / activity-alias / service / receiver / provider.
+# - Elements are merged as-is with the first comment element preceding them.
+# - Whitespace preceding the merged elements is transfered over too.
+#
+# Note:
+# - New elements are always merged at the end of the application element.
+# - It's an error if an element with the same @name attribute is defined
+# or merged more than once unless the definition is *exactly* the same,
+# the "same" being defined by the exact XML elements, whitespace excluded.
+#
+# This tests that an error is generated because the libraries define
+# aliases which are already defined differently.
+#
+
+@fails
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity-alias
+ android:name="com.example.alias.MyActivity1"
+ android:targetActivity="com.example.MainActivity1"
+ android:label="@string/alias_name1"
+ android:icon="@drawable/alias_icon1"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
+
+ <activity-alias
+ android:name="com.example.alias.MyActivity2"
+ android:targetActivity="com.example.MainActivity2"
+ android:label="@string/alias_name2"
+ android:icon="@drawable/alias_icon2"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
+
+ </application>
+
+</manifest>
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <application android:label="@string/lib_name1" >
+
+ <!-- Same as 1 in main -->
+ <activity-alias
+ android:name="com.example.alias.MyActivity1"
+ android:targetActivity="com.example.MainActivity1"
+ android:label="@string/alias_name1"
+ android:icon="@drawable/alias_icon1"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
+
+ <!-- Differs from 2 in main -->
+ <activity-alias
+ android:name="com.example.alias.MyActivity2"
+ android:targetActivity="com.example.MainActivity2">
+ </activity-alias>
+
+ <!-- A new one defined by lib1 -->
+ <activity-alias
+ android:name="com.example.alias.MyActivity3"
+ android:targetActivity="com.example.MainActivity3"
+ android:label="@string/alias_name3"
+ android:icon="@drawable/alias_icon3"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
+
+ </application>
+
+</manifest>
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <application android:label="@string/lib_name2" >
+
+ <!-- Conflicts with 3 from lib1 -->
+ <activity-alias
+ android:name="com.example.alias.MyActivity3"
+ android:label="@string/alias_name3"
+ android:icon="@drawable/alias_icon3">
+ <intent-filter>
+ <category android:name="android.intent.category.LAUNCHER2" />
+ </intent-filter>
+ </activity-alias>
+ </application>
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity-alias
+ android:name="com.example.alias.MyActivity1"
+ android:targetActivity="com.example.MainActivity1"
+ android:label="@string/alias_name1"
+ android:icon="@drawable/alias_icon1"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
+
+ <activity-alias
+ android:name="com.example.alias.MyActivity2"
+ android:targetActivity="com.example.MainActivity2"
+ android:label="@string/alias_name2"
+ android:icon="@drawable/alias_icon2"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
+
+ <!-- A new one defined by lib1 -->
+ <activity-alias
+ android:name="com.example.alias.MyActivity3"
+ android:targetActivity="com.example.MainActivity3"
+ android:label="@string/alias_name3"
+ android:icon="@drawable/alias_icon3"
+ >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity-alias>
+
+ </application>
+
+</manifest>
+
+@errors
+
+P [ManifestMergerTest0_main.xml:6, ManifestMergerTest1_lib1.xml:6] Skipping identical /manifest/application/activity-alias[@name=com.example.alias.MyActivity1] element.
+E [ManifestMergerTest0_main.xml:13, ManifestMergerTest1_lib1.xml:14] Trying to merge incompatible /manifest/application/activity-alias[@name=com.example.alias.MyActivity2] element:
+ <activity-alias android:name=com.example.alias.MyActivity2>
+++ @android:icon = @drawable/alias_icon2
+++ @android:label = @string/alias_name2
+ @android:name = com.example.alias.MyActivity2
+ @android:targetActivity = com.example.MainActivity2
+E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:6] Trying to merge incompatible /manifest/application/activity-alias[@name=com.example.alias.MyActivity3] element:
+ <activity-alias android:name=com.example.alias.MyActivity3>
+ @android:icon = @drawable/alias_icon3
+ @android:label = @string/alias_name3
+ @android:name = com.example.alias.MyActivity3
+++ @android:targetActivity = com.example.MainActivity3
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/13_service_dup.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/13_service_dup.xml
new file mode 100755
index 0000000..36d7e24
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/13_service_dup.xml
@@ -0,0 +1,155 @@
+#
+# Test:
+# - Activities from libraries are merged in the main manifest.
+# - Acts on activity / activity-alias / service / receiver / provider.
+# - Elements are merged as-is with the first comment element preceding them.
+# - Whitespace preceding the merged elements is transfered over too.
+#
+# Note:
+# - New elements are always merged at the end of the application element.
+# - It's an error if an element with the same @name attribute is defined
+# or merged more than once unless the definition is *exactly* the same,
+# the "same" being defined by the exact XML elements, whitespace excluded.
+#
+# This tests that an error is generated because the libraries define
+# services which are already defined differently.
+#
+
+@fails
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService1" />
+
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService2" />
+
+ </application>
+
+</manifest>
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <application android:label="@string/lib_name1" >
+
+ <!-- Same as 1 in main -->
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService1" />
+
+ <!-- Differs from 2 in main -->
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService2" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </service>
+
+ <!-- A new one defined by lib1 -->
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService3" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </service>
+
+ </application>
+
+</manifest>
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <application android:label="@string/lib_name2" >
+
+ <!-- Conflicts with 3 from lib1 -->
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService3" />
+
+ </application>
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService1" />
+
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService2" />
+
+ <!-- A new one defined by lib1 -->
+ <service
+ android:icon="@drawable/app_icon"
+ android:name="com.example.AppService3" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </service>
+
+ </application>
+
+</manifest>
+
+@errors
+
+P [ManifestMergerTest0_main.xml:6, ManifestMergerTest1_lib1.xml:6] Skipping identical /manifest/application/service[@name=com.example.AppService1] element.
+E [ManifestMergerTest0_main.xml:8, ManifestMergerTest1_lib1.xml:9] Trying to merge incompatible /manifest/application/service[@name=com.example.AppService2] element:
+ <service android:name=com.example.AppService2>
+-- <intent-filter>
+++ (end reached)
+E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:6] Trying to merge incompatible /manifest/application/service[@name=com.example.AppService3] element:
+ <service android:name=com.example.AppService3>
+-- (end reached)
+++ <intent-filter>
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/14_receiver_dup.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/14_receiver_dup.xml
new file mode 100755
index 0000000..a2547af
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/14_receiver_dup.xml
@@ -0,0 +1,176 @@
+#
+# Test:
+# - Activities from libraries are merged in the main manifest.
+# - Acts on activity / activity-alias / service / receiver / provider.
+# - Elements are merged as-is with the first comment element preceding them.
+# - Whitespace preceding the merged elements is transfered over too.
+#
+# Note:
+# - New elements are always merged at the end of the application element.
+# - It's an error if an element with the same @name attribute is defined
+# or merged more than once unless the definition is *exactly* the same,
+# the "same" being defined by the exact XML elements, whitespace excluded.
+#
+# This tests that an error is generated because the libraries define
+# receivers which are already defined differently.
+#
+
+@fails
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <receiver
+ android:name="com.example.AppReceiver1"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+
+ <receiver
+ android:name="com.example.AppReceiver2"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+
+ </application>
+
+</manifest>
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <application android:label="@string/lib_name1" >
+
+ <!-- Same as 1 in main -->
+ <receiver
+ android:name="com.example.AppReceiver1"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+
+ <!-- Differs from 2 in main -->
+ <receiver
+ android:name="com.example.AppReceiver2" />
+
+ <!-- A new one defined by lib1 -->
+ <receiver
+ android:name="com.example.AppReceiver3"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM1" />
+ <action android:name="com.example.action.ACTION_CUSTOM2" />
+ <action android:name="com.example.action.ACTION_CUSTOM3" />
+ </intent-filter>
+ </receiver>
+
+ </application>
+
+</manifest>
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <application android:label="@string/lib_name2" >
+
+ <!-- Conflicts with 3 from lib1 -->
+ <receiver
+ android:name="com.example.AppReceiver3"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+ </application>
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <receiver
+ android:name="com.example.AppReceiver1"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+
+ <receiver
+ android:name="com.example.AppReceiver2"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM" />
+ </intent-filter>
+ </receiver>
+
+ <!-- A new one defined by lib1 -->
+ <receiver
+ android:name="com.example.AppReceiver3"
+ android:icon="@drawable/app_icon">
+ <intent-filter>
+ <action android:name="com.example.action.ACTION_CUSTOM1" />
+ <action android:name="com.example.action.ACTION_CUSTOM2" />
+ <action android:name="com.example.action.ACTION_CUSTOM3" />
+ </intent-filter>
+ </receiver>
+
+ </application>
+
+</manifest>
+
+@errors
+
+P [ManifestMergerTest0_main.xml:6, ManifestMergerTest1_lib1.xml:6] Skipping identical /manifest/application/receiver[@name=com.example.AppReceiver1] element.
+E [ManifestMergerTest0_main.xml:12, ManifestMergerTest1_lib1.xml:13] Trying to merge incompatible /manifest/application/receiver[@name=com.example.AppReceiver2] element:
+ <receiver android:name=com.example.AppReceiver2>
+++ @android:icon = @drawable/app_icon
+ @android:name = com.example.AppReceiver2
+E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:6] Trying to merge incompatible /manifest/application/receiver[@name=com.example.AppReceiver3] element:
+ <receiver android:name=com.example.AppReceiver3>
+ <intent-filter>
+ <action android:name=com.example.action.ACTION_CUSTOM>
+-- @android:name = com.example.action.ACTION_CUSTOM
+++ @android:name = com.example.action.ACTION_CUSTOM1
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/15_provider_dup.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/15_provider_dup.xml
new file mode 100755
index 0000000..7938c1e
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/15_provider_dup.xml
@@ -0,0 +1,145 @@
+#
+# Test:
+# - Activities from libraries are merged in the main manifest.
+# - Acts on activity / activity-alias / service / receiver / provider.
+# - Elements are merged as-is with the first comment element preceding them.
+# - Whitespace preceding the merged elements is transfered over too.
+#
+# Note:
+# - New elements are always merged at the end of the application element.
+# - It's an error if an element with the same @name attribute is defined
+# or merged more than once unless the definition is *exactly* the same,
+# the "same" being defined by the exact XML elements, whitespace excluded.
+#
+# This tests that an error is generated because the libraries define
+# providers which are already defined differently.
+#
+
+@fails
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <provider
+ android:name="com.example.Provider1"
+ android:authorities="com.example.android.apis.app.thingy1"
+ android:enabled="@bool/someConditionalValue" />
+
+ <provider
+ android:name="com.example.Provider2" />
+
+ </application>
+
+</manifest>
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <application android:label="@string/lib_name1" >
+
+ <!-- Same as MyActivity1 in main -->
+ <provider
+ android:name="com.example.Provider1"
+ android:authorities="com.example.android.apis.app.thingy1"
+ android:enabled="@bool/someConditionalValue" />
+
+ <!-- Differs from MyActivity2 in main -->
+ <provider
+ android:name="com.example.Provider2"
+ android:authorities="com.example.android.apis.app.thingy2"
+ android:enabled="@bool/someConditionalValue2" />
+
+ <!-- A new one defined by lib1 -->
+ <provider
+ android:name="com.example.Provider3"
+ android:authorities="com.example.android.apis.app.thingy3"
+ android:enabled="@bool/someConditionalValue" />
+
+ </application>
+
+</manifest>
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <application android:label="@string/lib_name2" >
+
+ <!-- Conflicts with 3 from lib1 -->
+ <provider
+ android:name="com.example.Provider3"
+ android:authorities="com.example.android.apis.app.thingy3" />
+ </application>
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <provider
+ android:name="com.example.Provider1"
+ android:authorities="com.example.android.apis.app.thingy1"
+ android:enabled="@bool/someConditionalValue" />
+
+ <provider
+ android:name="com.example.Provider2" />
+
+ <!-- A new one defined by lib1 -->
+ <provider
+ android:name="com.example.Provider3"
+ android:authorities="com.example.android.apis.app.thingy3"
+ android:enabled="@bool/someConditionalValue" />
+
+ </application>
+
+</manifest>
+
+@errors
+
+P [ManifestMergerTest0_main.xml:6, ManifestMergerTest1_lib1.xml:6] Skipping identical /manifest/application/provider[@name=com.example.Provider1] element.
+E [ManifestMergerTest0_main.xml:8, ManifestMergerTest1_lib1.xml:9] Trying to merge incompatible /manifest/application/provider[@name=com.example.Provider2] element:
+ <provider android:name=com.example.Provider2>
+-- @android:authorities = com.example.android.apis.app.thingy2
+-- @android:enabled = @bool/someConditionalValue2
+ @android:name = com.example.Provider2
+E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:6] Trying to merge incompatible /manifest/application/provider[@name=com.example.Provider3] element:
+ <provider android:name=com.example.Provider3>
+ @android:authorities = com.example.android.apis.app.thingy3
+++ @android:enabled = @bool/someConditionalValue
+ @android:name = com.example.Provider3
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/16_fqcn_merge.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/16_fqcn_merge.xml
new file mode 100755
index 0000000..8414a3c
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/16_fqcn_merge.xml
@@ -0,0 +1,129 @@
+#
+# Test how FQCN class names are expanded and handled:
+# - A library application can be merged doesn't have an app class name.
+# - A library application can be merged if it has the same class name as the app.
+# - A partial class name is expanded using the package name in a library or app.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <application
+ android:name="TheApp"
+ android:backupAgent=".MyBackupAgent" >
+ <activity android:name=".MainActivity" />
+ <receiver android:name="AppReceiver" />
+ <activity android:name="com.example.lib2.LibActivity" />
+ </application>
+</manifest>
+
+
+@lib1_widget
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <application android:name="com.example.app1.TheApp" >
+ <activity android:name=".WidgetLibrary" />
+ <receiver android:name=".WidgetReceiver" />
+ <service android:name="AppService" />
+ <activity android:name="com.example.lib1.WidgetConfigurationUI" />
+ </application>
+</manifest>
+
+
+@lib2_activity
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <application>
+ <!-- This won't be merged because there's already an identical definition in the main. -->
+ <activity android:name="LibActivity" />
+
+ <!-- Provider extracted from ApiDemos -->
+ <provider android:name=".app.LoaderThrottle$SimpleProvider" />
+
+ <!-- This one does not conflict with the main -->
+ <activity android:name="com.example.lib2.LibActivity2" />
+
+ </application>
+</manifest>
+
+
+@lib3_alias
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib3" >
+ <!-- This manifest has a 'package' attribute and FQCNs get resolved. -->
+
+ <application
+ android:name="com.example.app1.TheApp"
+ android:backupAgent="com.example.app1.MyBackupAgent">
+ <activity-alias android:name="com.example.lib3.MyActivity"
+ android:targetActivity="com.example.app1.MainActivity" />
+
+ <!-- This is a dup of the 2nd activity in lib2 -->
+ <activity android:name="com.example.lib2.LibActivity2" />
+
+ <!-- These class name should be expanded. -->
+ <activity android:name=".LibActivity3" />
+ <service android:name=".LibService3" />
+ <receiver android:name=".LibReceiver3" />
+ <provider android:name=".LibProvider3" />
+
+ </application>
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <application
+ android:name="com.example.app1.TheApp"
+ android:backupAgent="com.example.app1.MyBackupAgent" >
+ <activity android:name="com.example.app1.MainActivity" />
+ <receiver android:name="com.example.app1.AppReceiver" />
+ <activity android:name="com.example.lib2.LibActivity" />
+# from @lib1_widget
+ <activity android:name="com.example.lib1.WidgetLibrary" />
+ <activity android:name="com.example.lib1.WidgetConfigurationUI" />
+ <service android:name="com.example.lib1.AppService" />
+ <receiver android:name="com.example.lib1.WidgetReceiver" />
+
+# from @lib2_activity
+ <!-- This one does not conflict with the main -->
+ <activity android:name="com.example.lib2.LibActivity2" />
+
+ <!-- Provider extracted from ApiDemos -->
+ <provider android:name="com.example.lib2.app.LoaderThrottle$SimpleProvider" />
+
+# from @lib3_alias
+ <!-- These class name should be expanded. -->
+ <activity android:name="com.example.lib3.LibActivity3" />
+ <activity-alias android:name="com.example.lib3.MyActivity"
+ android:targetActivity="com.example.app1.MainActivity" />
+ <service android:name="com.example.lib3.LibService3" />
+ <receiver android:name="com.example.lib3.LibReceiver3" />
+ <provider android:name="com.example.lib3.LibProvider3" />
+ </application>
+</manifest>
+
+@errors
+
+P [ManifestMergerTest0_main.xml:6, ManifestMergerTest2_lib2_activity.xml:5] Skipping identical /manifest/application/activity[@name=com.example.lib2.LibActivity] element.
+P [ManifestMergerTest0_main.xml, ManifestMergerTest3_lib3_alias.xml:8] Skipping identical /manifest/application/activity[@name=com.example.lib2.LibActivity2] element.
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/17_fqcn_conflict.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/17_fqcn_conflict.xml
new file mode 100755
index 0000000..7b95027
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/17_fqcn_conflict.xml
@@ -0,0 +1,118 @@
+#
+# Test how FQCN class names are expanded and handled:
+# - A library application can be merged doesn't have an app class name.
+# - A library application can be merged if it has the same class name as the app.
+# - A partial class name is expanded using the package name in a library or app.
+#
+# All tests fail with just warnings, no solid errors.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <application
+ android:name="TheApp"
+ android:backupAgent=".MyBackupAgent" >
+ <activity android:name=".MainActivity" />
+ <receiver android:name="AppReceiver" />
+ <activity android:name="com.example.lib2.LibActivity" />
+ </application>
+</manifest>
+
+
+@lib1_widget
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- App name is different, will not merge. -->
+ <application android:name="TheApp" >
+ <activity android:name=".WidgetLibrary1" />
+ </application>
+</manifest>
+
+
+@lib2_widget
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- App name is good, but backupAgent is mentioned and is different, will not merge. -->
+ <application
+ android:name="com.example.app1.TheApp"
+ android:backupAgent=".MyBackupAgent" >
+ <activity android:name=".WidgetLibrary2" />
+ <activity android:name=".LibActivity" />
+ </application>
+</manifest>
+
+
+@lib3_widget
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib3">
+
+ <application android:name="com.example.app1.TheApp">
+ <activity android:name=".WidgetLibrary3" />
+ </application>
+
+</manifest>
+
+
+@lib4_not_package
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+ <!-- It's an error for the manifest to lack a 'package' attribute. -->
+
+ <application>
+ <!-- These class name can't be expanded due to the lack of 'package' attribute. -->
+ <activity android:name=".LibActivity4" />
+ <service android:name=".LibService4" />
+ <receiver android:name=".LibReceiver4" />
+ <provider android:name=".LibProvider4" />
+
+ </application>
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <application
+ android:name="com.example.app1.TheApp"
+ android:backupAgent="com.example.app1.MyBackupAgent" >
+ <activity android:name="com.example.app1.MainActivity" />
+ <receiver android:name="com.example.app1.AppReceiver" />
+ <activity android:name="com.example.lib2.LibActivity" />
+ <activity android:name="com.example.lib1.WidgetLibrary1" />
+ <activity android:name="com.example.lib2.WidgetLibrary2" />
+ <activity android:name="com.example.lib3.WidgetLibrary3" />
+# from @lib4_alias
+ <!-- These class name can't be expanded due to the lack of 'package' attribute. -->
+ <activity android:name=".LibActivity4" />
+ <service android:name=".LibService4" />
+ <receiver android:name=".LibReceiver4" />
+ <provider android:name=".LibProvider4" />
+ </application>
+</manifest>
+
+@errors
+
+W [ManifestMergerTest0_main.xml:3, ManifestMergerTest1_lib1_widget.xml:4] Main manifest has <application android:name='com.example.app1.TheApp'> but library uses name='com.example.lib1.TheApp'.
+W [ManifestMergerTest0_main.xml:3, ManifestMergerTest2_lib2_widget.xml:4] Main manifest has <application android:backupAgent='com.example.app1.MyBackupAgent'> but library uses backupAgent='com.example.lib2.MyBackupAgent'.
+P [ManifestMergerTest0_main.xml:6, ManifestMergerTest2_lib2_widget.xml:6] Skipping identical /manifest/application/activity[@name=com.example.lib2.LibActivity] element.
+W [ManifestMergerTest4_lib4_not_package.xml:1] Missing 'package' attribute in manifest.
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/20_uses_lib_merge.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/20_uses_lib_merge.xml
new file mode 100755
index 0000000..a5eecce
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/20_uses_lib_merge.xml
@@ -0,0 +1,176 @@
+#
+# Test merge of uses-library:
+# - Merge is OK if destination already has one with the same @name.
+# - required defaults to "true"
+# - when merging, a required=true (explicit or implicit) overwrites a required=false.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <!-- A library that is implicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary0_DefaultTrue" />
+
+ <!-- A library that is implicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary1_DefaultTrue" />
+
+ <!-- A library that is explicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary2_RequiredTrue"
+ android:required="true" />
+
+ <!-- A library that is explicitly marked as required=false -->
+ <uses-library
+ android:name="com.example.SomeLibrary3_RequiredFalse"
+ android:required="false" />
+
+ <!-- A library that is explicitly marked as required=false -->
+ <uses-library
+ android:name="com.example.SomeLibrary4_RequiredFalse"
+ android:required="false" />
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <application android:label="@string/lib_name1" >
+
+ <!-- Same as 1 from main, marking it as required=false -->
+ <uses-library
+ android:name="com.example.SomeLibrary1_DefaultTrue"
+ android:required="false" />
+
+ <!-- Same as 3 from main -->
+ <uses-library
+ android:name="com.example.SomeLibrary3_RequiredFalse"
+ android:required="false" />
+
+ <!-- Same as 4 from main -->
+ <uses-library
+ android:name="com.example.SomeLibrary4_RequiredFalse"
+ android:required="false" />
+
+ <!-- Add a new lib that is implicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary5_RequiredTrue"
+ android:required="true" />
+
+ <!-- Add a new lib that is implicitly marked as required=false -->
+ <uses-library
+ android:name="com.example.SomeLibrary6_RequiredFalse"
+ android:required="false" />
+
+ </application>
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <application android:label="@string/lib_name1" >
+
+ <!-- Overrides 3, changing it from required=false to true -->
+ <uses-library
+ android:name="com.example.SomeLibrary3_RequiredFalse"
+ android:required="true" />
+
+ <!-- Same as 4 from main -->
+ <uses-library
+ android:name="com.example.SomeLibrary4_RequiredFalse"
+ android:required="false" />
+
+ <!-- Overrides 6, but implicitly declaring required=True -->
+ <uses-library
+ android:name="com.example.SomeLibrary6_RequiredFalse" />
+
+ </application>
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <!-- A library that is implicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary0_DefaultTrue" />
+
+ <!-- A library that is implicitly marked as required=true -->
+# required=false from lib1 is ignored, it stays at the default
+ <uses-library
+ android:name="com.example.SomeLibrary1_DefaultTrue" />
+
+ <!-- A library that is explicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary2_RequiredTrue"
+ android:required="true" />
+
+ <!-- A library that is explicitly marked as required=false -->
+# lib1 keeps it required=false but lib2 makes it switch to required=true
+ <uses-library
+ android:name="com.example.SomeLibrary3_RequiredFalse"
+ android:required="true" />
+
+ <!-- A library that is explicitly marked as required=false -->
+ <uses-library
+ android:name="com.example.SomeLibrary4_RequiredFalse"
+ android:required="false" />
+
+# new from lib1
+ <!-- Add a new lib that is implicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary5_RequiredTrue"
+ android:required="true" />
+
+# new from lib1, but lib2 makes it switch to required=true
+ <!-- Add a new lib that is implicitly marked as required=false -->
+ <uses-library
+ android:name="com.example.SomeLibrary6_RequiredFalse"
+ android:required="true" />
+
+ </application>
+
+</manifest>
+
+
+@errors
+
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/21_uses_lib_errors.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/21_uses_lib_errors.xml
new file mode 100755
index 0000000..65f0fb6
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/21_uses_lib_errors.xml
@@ -0,0 +1,202 @@
+#
+# Test merge of uses-library:
+# - Merge is OK if destination already has one with the same @name.
+# - required defaults to "true"
+# - when merging, a required=true (explicit or implicit) overwrites a required=false.
+#
+
+@fails
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <!-- A library that is implicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary0_DefaultTrue" />
+
+ <!-- A library that is implicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary1_DefaultTrue" />
+
+ <!-- A library that is explicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary2_RequiredTrue"
+ android:required="booh!" />
+
+ <!-- A library that is explicitly marked as required=false -->
+ <uses-library
+ android:name="com.example.SomeLibrary3_RequiredFalse"
+ android:required="false" />
+
+ <!-- A library that is explicitly marked as required=false. Duplicated. -->
+ <uses-library
+ android:name="com.example.SomeLibrary3_RequiredFalse"
+ android:required="false" />
+
+ <!-- A library that is explicitly marked as required=false -->
+ <uses-library
+ android:name="com.example.SomeLibrary4_RequiredFalse"
+ android:required="false" />
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <application android:label="@string/lib_name1" >
+
+ <!-- Error: android:name attribute is missing. -->
+ <uses-library />
+ <uses-library android:required="false" />
+ <uses-library android:required="true" />
+
+ <!-- Same as 2 from main. Warning/ignore because dest required isn't true/false. -->
+ <uses-library
+ android:name="com.example.SomeLibrary2_RequiredTrue"
+ android:required="true" />
+
+ <!-- Same as 3 from main. Warning because destination as a duplicate. -->
+ <uses-library
+ android:name="com.example.SomeLibrary3_RequiredFalse"
+ android:required="false" />
+
+ <!-- Same as 4 from main. Warning because required isn't true or false. -->
+ <uses-library
+ android:name="com.example.SomeLibrary4_RequiredFalse"
+ android:required="foo" />
+
+ <!-- Add a new lib that is implicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary5_RequiredTrue"
+ android:required="true" />
+
+ <!-- Add a new lib that is implicitly marked as required=false -->
+ <uses-library
+ android:name="com.example.SomeLibrary6_RequiredFalse"
+ android:required="false" />
+
+ </application>
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <application android:label="@string/lib_name1" >
+
+ <!-- Overrides 3, changing it from required=false to true -->
+ <uses-library
+ android:name="com.example.SomeLibrary3_RequiredFalse"
+ android:required="true" />
+
+ <!-- Same as 4 from main -->
+ <uses-library
+ android:name="com.example.SomeLibrary4_RequiredFalse"
+ android:required="false" />
+
+ <!-- Overrides 6, but implicitly declaring required=True -->
+ <uses-library
+ android:name="com.example.SomeLibrary6_RequiredFalse" />
+
+ </application>
+</manifest>
+
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <!-- A library that is implicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary0_DefaultTrue" />
+
+ <!-- A library that is implicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary1_DefaultTrue" />
+
+ <!-- A library that is explicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary2_RequiredTrue"
+ android:required="booh!" />
+
+ <!-- A library that is explicitly marked as required=false -->
+# lib1 keeps it required=false but lib2 makes it switch to required=true
+ <uses-library
+ android:name="com.example.SomeLibrary3_RequiredFalse"
+ android:required="true" />
+
+ <!-- A library that is explicitly marked as required=false. Duplicated. -->
+ <uses-library
+ android:name="com.example.SomeLibrary3_RequiredFalse"
+ android:required="true" />
+
+ <!-- A library that is explicitly marked as required=false -->
+ <uses-library
+ android:name="com.example.SomeLibrary4_RequiredFalse"
+ android:required="false" />
+
+# new from lib1
+ <!-- Add a new lib that is implicitly marked as required=true -->
+ <uses-library
+ android:name="com.example.SomeLibrary5_RequiredTrue"
+ android:required="true" />
+
+# new from lib1, but lib2 makes it switch to required=true
+ <!-- Add a new lib that is implicitly marked as required=false -->
+ <uses-library
+ android:name="com.example.SomeLibrary6_RequiredFalse"
+ android:required="true" />
+
+ </application>
+
+</manifest>
+
+
+@errors
+
+E [ManifestMergerTest1_lib1.xml:6] Undefined 'name' attribute in /manifest/application/uses-library.
+E [ManifestMergerTest1_lib1.xml:7] Undefined 'name' attribute in /manifest/application/uses-library.
+E [ManifestMergerTest1_lib1.xml:8] Undefined 'name' attribute in /manifest/application/uses-library.
+W [ManifestMergerTest0_main.xml:12] Invalid attribute 'required' in /manifest/application/uses-library[@name=com.example.SomeLibrary2_RequiredTrue] element:
+Expected 'true' or 'false' but found 'booh!'.
+W [ManifestMergerTest0_main.xml:15] Manifest has more than one /manifest/application/uses-library[@name=com.example.SomeLibrary3_RequiredFalse] element.
+W [ManifestMergerTest1_lib1.xml:17] Invalid attribute 'required' in /manifest/application/uses-library[@name=com.example.SomeLibrary4_RequiredFalse] element:
+Expected 'true' or 'false' but found 'foo'.
+W [ManifestMergerTest0_main.xml:15] Manifest has more than one /manifest/application/uses-library[@name=com.example.SomeLibrary3_RequiredFalse] element.
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/25_permission_merge.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/25_permission_merge.xml
new file mode 100755
index 0000000..07208ad
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/25_permission_merge.xml
@@ -0,0 +1,259 @@
+#
+# Text permission, permission-group and permission-tree:
+# - Libraries can add any of these elements as long as they don't conflict
+# with the destination: either the element must not be at all in the destination
+# (as identified by the name) or it must match exactly.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <permission
+ android:description="Insert boring description here"
+ android:icon="@drawable/robot"
+ android:label="Danger, Will Robinson!"
+ android:name="com.example.DangerWillRobinson"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="dangerous" />
+
+ <permission
+ android:name="com.example.WhatWereYouThinking"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="signatureOrSystem" />
+
+ <permission-group
+ android:description="Nobody expects..."
+ android:icon="@drawable/ignored_icon"
+ android:label="the Spanish Inquisition"
+ android:name="com.example.MasterControlPermission" />
+
+ <permission-tree
+ android:label="This is not a label"
+ android:name="com.example.PermTree" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- Same permissions as main manifest -->
+ <permission
+ android:description="Insert boring description here"
+ android:icon="@drawable/robot"
+ android:label="Danger, Will Robinson!"
+ android:name="com.example.DangerWillRobinson"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="dangerous" />
+ <permission-group
+ android:description="Nobody expects..."
+ android:icon="@drawable/ignored_icon"
+ android:label="the Spanish Inquisition"
+ android:name="com.example.MasterControlPermission" />
+ <permission-tree
+ android:label="This is not a label"
+ android:name="com.example.PermTree" />
+
+ <!-- Added by lib1. -->
+ <permission
+ android:name="com.example.Permission1"
+ android:permissionGroup="com.example.Permission1"
+ android:protectionLevel="normal" />
+
+ <permission-group
+ android:description="This is getting"
+ android:label="too silly"
+ android:name="com.example.EnoughWithTheQuotes" />
+
+ <permission-tree
+ android:name="com.example.PermTree1" />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- Redefine one permission from main manifest -->
+ <permission
+ android:description="Insert boring description here"
+ android:icon="@drawable/robot"
+ android:label="Danger, Will Robinson!"
+ android:name="com.example.DangerWillRobinson"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="dangerous" />
+ <!-- And one from lib1. -->
+ <permission
+ android:name="com.example.Permission1"
+ android:permissionGroup="com.example.Permission1"
+ android:protectionLevel="normal" />
+ <permission-tree
+ android:name="com.example.PermTree1" />
+
+ <!-- Added by lib2. -->
+ <permission
+ android:name="com.example.SensiblePermission2"
+ android:permissionGroup="com.example.SensibleGroup2"
+ android:protectionLevel="normal" />
+
+ <permission-group
+ android:name="com.example.SensibleGroup2" />
+
+ <permission-tree
+ android:name="com.example.PermTree2" />
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <permission
+ android:description="Insert boring description here"
+ android:icon="@drawable/robot"
+ android:label="Danger, Will Robinson!"
+ android:name="com.example.DangerWillRobinson"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="dangerous" />
+
+ <permission
+ android:name="com.example.WhatWereYouThinking"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="signatureOrSystem" />
+
+ <permission-group
+ android:description="Nobody expects..."
+ android:icon="@drawable/ignored_icon"
+ android:label="the Spanish Inquisition"
+ android:name="com.example.MasterControlPermission" />
+
+ <permission-tree
+ android:label="This is not a label"
+ android:name="com.example.PermTree" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+# Added by lib1
+ <!-- Added by lib1. -->
+ <permission
+ android:name="com.example.Permission1"
+ android:permissionGroup="com.example.Permission1"
+ android:protectionLevel="normal" />
+
+ <permission-group
+ android:description="This is getting"
+ android:label="too silly"
+ android:name="com.example.EnoughWithTheQuotes" />
+
+ <permission-tree
+ android:name="com.example.PermTree1" />
+
+# Added by lib2
+ <!-- Added by lib2. -->
+ <permission
+ android:name="com.example.SensiblePermission2"
+ android:permissionGroup="com.example.SensibleGroup2"
+ android:protectionLevel="normal" />
+
+ <permission-group
+ android:name="com.example.SensibleGroup2" />
+
+ <permission-tree
+ android:name="com.example.PermTree2" />
+
+</manifest>
+
+
+@errors
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/26_permission_dup.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/26_permission_dup.xml
new file mode 100755
index 0000000..3862249
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/26_permission_dup.xml
@@ -0,0 +1,307 @@
+#
+# Text permission, permission-group and permission-tree:
+# - Libraries can add any of these elements as long as they don't conflict
+# with the destination: either the element must not be at all in the destination
+# (as identified by the name) or it must match exactly.
+#
+# This one tests that duplicate definitions that are strictly equal generate errors
+# with some (hopefully useful) diff.
+#
+
+@fails
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <permission
+ android:description="Insert boring description here"
+ android:icon="@drawable/robot"
+ android:label="Danger, Will Robinson!"
+ android:name="com.example.DangerWillRobinson"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="dangerous" />
+
+ <permission
+ android:name="com.example.WhatWereYouThinking"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="signatureOrSystem" />
+
+ <permission-group
+ android:description="Nobody expects..."
+ android:icon="@drawable/ignored_icon"
+ android:label="the Spanish Inquisition"
+ android:name="com.example.MasterControlPermission" />
+
+ <permission-tree
+ android:label="This is not a label"
+ android:name="com.example.PermTree" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- Similar permissions as main manifest, but with slight conflicts -->
+ <permission
+ android:description="Different description here"
+ android:icon="@drawable/not_the_same_icon"
+ android:label="Danger, Will Robinson!"
+ android:name="com.example.DangerWillRobinson"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="dangerous" />
+ <!-- missing icon: --><permission-group
+ android:description="Nobody expects..."
+ android:label="the Spanish Inquisition"
+ android:name="com.example.MasterControlPermission" />
+ <permission-tree
+ android:label="This is not the same label"
+ android:name="com.example.PermTree" />
+
+ <!-- different protectionLevel --><permission
+ android:name="com.example.WhatWereYouThinking"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="normal" />
+
+ <!-- Added by lib1. -->
+ <permission
+ android:name="com.example.Permission1"
+ android:permissionGroup="com.example.Permission1"
+ android:protectionLevel="normal" />
+
+ <permission-group
+ android:description="This is getting"
+ android:label="too silly"
+ android:name="com.example.EnoughWithTheQuotes" />
+
+ <permission-tree
+ android:name="com.example.PermTree1" />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- Redefine one permission from main manifest -->
+ <permission
+ android:description="Insert boring description here"
+ android:icon="@drawable/robot"
+ android:label="Danger, Will Robinson!"
+ android:name="com.example.DangerWillRobinson"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="dangerous" />
+ <!-- And one from lib1, with a slight variation. -->
+ <permission
+ android:name="com.example.Permission1"
+ android:permissionGroup="com.example.Permission1"
+ android:protectionLevel="system" />
+ <permission-tree
+ android:description="Extra description"
+ android:name="com.example.PermTree1" />
+
+ <!-- Added by lib2. -->
+ <permission
+ android:name="com.example.SensiblePermission2"
+ android:permissionGroup="com.example.SensibleGroup2"
+ android:protectionLevel="normal" />
+
+ <permission-group
+ android:name="com.example.SensibleGroup2" />
+
+ <permission-tree
+ android:name="com.example.PermTree2" />
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <permission
+ android:description="Insert boring description here"
+ android:icon="@drawable/robot"
+ android:label="Danger, Will Robinson!"
+ android:name="com.example.DangerWillRobinson"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="dangerous" />
+
+ <permission
+ android:name="com.example.WhatWereYouThinking"
+ android:permissionGroup="com.example.MasterControlPermission"
+ android:protectionLevel="signatureOrSystem" />
+
+ <permission-group
+ android:description="Nobody expects..."
+ android:icon="@drawable/ignored_icon"
+ android:label="the Spanish Inquisition"
+ android:name="com.example.MasterControlPermission" />
+
+ <permission-tree
+ android:label="This is not a label"
+ android:name="com.example.PermTree" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+# Added by lib1
+ <!-- Added by lib1. -->
+ <permission
+ android:name="com.example.Permission1"
+ android:permissionGroup="com.example.Permission1"
+ android:protectionLevel="normal" />
+
+ <permission-group
+ android:description="This is getting"
+ android:label="too silly"
+ android:name="com.example.EnoughWithTheQuotes" />
+
+ <permission-tree
+ android:name="com.example.PermTree1" />
+
+# Added by lib2
+ <!-- Added by lib2. -->
+ <permission
+ android:name="com.example.SensiblePermission2"
+ android:permissionGroup="com.example.SensibleGroup2"
+ android:protectionLevel="normal" />
+
+ <permission-group
+ android:name="com.example.SensibleGroup2" />
+
+ <permission-tree
+ android:name="com.example.PermTree2" />
+
+</manifest>
+
+
+@errors
+
+E [ManifestMergerTest0_main.xml:12, ManifestMergerTest1_lib1.xml:4] Trying to merge incompatible /manifest/permission[@name=com.example.DangerWillRobinson] element:
+ <permission android:name=com.example.DangerWillRobinson>
+-- @android:description = Different description here
+++ @android:description = Insert boring description here
+-- @android:icon = @drawable/not_the_same_icon
+++ @android:icon = @drawable/robot
+ @android:label = Danger, Will Robinson!
+ @android:name = com.example.DangerWillRobinson
+ @android:permissionGroup = com.example.MasterControlPermission
+ @android:protectionLevel = dangerous
+E [ManifestMergerTest0_main.xml:14, ManifestMergerTest1_lib1.xml:8] Trying to merge incompatible /manifest/permission[@name=com.example.WhatWereYouThinking] element:
+ <permission android:name=com.example.WhatWereYouThinking>
+ @android:name = com.example.WhatWereYouThinking
+ @android:permissionGroup = com.example.MasterControlPermission
+-- @android:protectionLevel = normal
+++ @android:protectionLevel = signatureOrSystem
+E [ManifestMergerTest0_main.xml:16, ManifestMergerTest1_lib1.xml:5] Trying to merge incompatible /manifest/permission-group[@name=com.example.MasterControlPermission] element:
+ <permission-group android:name=com.example.MasterControlPermission>
+ @android:description = Nobody expects...
+++ @android:icon = @drawable/ignored_icon
+ @android:label = the Spanish Inquisition
+ @android:name = com.example.MasterControlPermission
+E [ManifestMergerTest0_main.xml:18, ManifestMergerTest1_lib1.xml:6] Trying to merge incompatible /manifest/permission-tree[@name=com.example.PermTree] element:
+ <permission-tree android:name=com.example.PermTree>
+++ @android:label = This is not a label
+-- @android:label = This is not the same label
+ @android:name = com.example.PermTree
+E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:6] Trying to merge incompatible /manifest/permission[@name=com.example.Permission1] element:
+ <permission android:name=com.example.Permission1>
+ @android:name = com.example.Permission1
+ @android:permissionGroup = com.example.Permission1
+++ @android:protectionLevel = normal
+-- @android:protectionLevel = system
+E [ManifestMergerTest0_main.xml, ManifestMergerTest2_lib2.xml:7] Trying to merge incompatible /manifest/permission-tree[@name=com.example.PermTree1] element:
+ <permission-tree android:name=com.example.PermTree1>
+-- @android:description = Extra description
+ @android:name = com.example.PermTree1
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/28_uses_perm_merge.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/28_uses_perm_merge.xml
new file mode 100755
index 0000000..ecc644a
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/28_uses_perm_merge.xml
@@ -0,0 +1,156 @@
+#
+# Text uses-permission:
+# - Libraries can add any of these elements as long as they don't conflict
+# with the destination: either the element must not be at all in the destination
+# (as identified by the name) or it must match exactly.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- Same permissions as main manifest -->
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <!-- Library 1 wants to know what you're running. -->
+ <uses-permission android:name="android.permission.GET_TASKS" />
+
+ <!-- Are you calling me? -->
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- Redefine one permission from main manifest -->
+ <uses-permission android:name="android.permission.INTERNET" />
+ <!-- And one from lib1. -->
+ <uses-permission android:name="android.permission.GET_TASKS" />
+
+ <!-- Lib2 wants to know it all. -->
+ <uses-permission android:name="android.permission.READ_LOGS"/>
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+# Added by lib1
+ <!-- Library 1 wants to know what you're running. -->
+ <uses-permission android:name="android.permission.GET_TASKS" />
+
+ <!-- Are you calling me? -->
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+
+# Added by lib2
+ <!-- Lib2 wants to know it all. -->
+ <uses-permission android:name="android.permission.READ_LOGS"/>
+
+</manifest>
+
+
+@errors
+
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/30_uses_sdk_ok.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/30_uses_sdk_ok.xml
new file mode 100755
index 0000000..bcee4ce
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/30_uses_sdk_ok.xml
@@ -0,0 +1,86 @@
+#
+# Test uses-sdk: add a uses-sdk from an app that doesn't define one.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk
+ android:minSdkVersion="11"
+ android:targetSdkVersion="14"
+ />
+
+ <application />
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- This app requires cupcake. -->
+ <uses-sdk android:minSdkVersion="3" />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- This only defines a max-sdk, and we purposely ignore this attribute.
+ It doesn't get merged and doesn't generate a conflict either.
+ -->
+ <uses-sdk
+ android:maxSdkVersion="5"
+ />
+
+</manifest>
+
+
+@lib3
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib3">
+
+ <!-- Lib3 redefines the same requirements as lib1.
+ -->
+ <uses-sdk
+ android:minSdkVersion="3"
+ android:targetSdkVersion="11"
+ />
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk
+ android:minSdkVersion="11"
+ android:targetSdkVersion="14"
+ />
+
+ <application />
+
+</manifest>
+
+
+@errors
+
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/32_uses_sdk_minsdk_ok.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/32_uses_sdk_minsdk_ok.xml
new file mode 100755
index 0000000..b94efe8
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/32_uses_sdk_minsdk_ok.xml
@@ -0,0 +1,70 @@
+#
+# Test uses-sdk: it's ok for a library to have a smaller minSdkVersion than the main manifest.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="14" />
+
+ <application />
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- it's ok for a library to have a smaller minSdkVersion than the main manifest. -->
+ <uses-sdk android:minSdkVersion="4" />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <uses-sdk android:minSdkVersion="10" />
+
+</manifest>
+
+
+@lib3
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib3">
+
+ <uses-sdk android:minSdkVersion="11" />
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="14" />
+
+ <application />
+
+</manifest>
+
+
+@errors
+
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/33_uses_sdk_minsdk_conflict.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/33_uses_sdk_minsdk_conflict.xml
new file mode 100755
index 0000000..8edbedb
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/33_uses_sdk_minsdk_conflict.xml
@@ -0,0 +1,148 @@
+#
+# Test uses-sdk: it's an error for a library to require a minSdkVersion higher than the
+# one defined in the main manifest.
+#
+# Also a uses-sdk with a lack of minSdkVersion is equivalent to using version=1.
+#
+
+@fails
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- This is the same as writing android:minSdkVersion="1" -->
+ <uses-sdk android:targetSdkVersion="14" />
+
+ <application />
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- The app can cope with API 1 but this library can only cope with API 4. -->
+ <uses-sdk android:minSdkVersion="4" />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <uses-sdk android:minSdkVersion="10" />
+
+</manifest>
+
+
+@lib3
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib3">
+
+ <uses-sdk android:minSdkVersion="11" />
+
+</manifest>
+
+
+@lib4_parsingError
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib4">
+
+ <!-- Parsing errors -->
+ <uses-sdk android:minSdkVersion="abcd" />
+
+</manifest>
+
+
+@lib5_parsingError
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib5">
+
+ <!-- Parsing errors -->
+ <uses-sdk android:minSdkVersion="123456789123456789" />
+
+</manifest>
+
+
+@lib6_parsingError
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib6">
+
+ <!-- Parsing errors -->
+ <uses-sdk android:minSdkVersion="0xFFFFFFFFFFFFFFFF" />
+
+</manifest>
+
+
+@lib7_parsingError
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib7">
+
+ <!-- Parsing errors -->
+ <uses-sdk android:minSdkVersion="InvalidMinSdk" android:targetSdkVersion="InvalidTargetSdk" />
+
+</manifest>
+
+
+@lib8_parsingCodename
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib8">
+
+ <!-- Test code names -->
+ <uses-sdk android:minSdkVersion="ApiCodename1" android:targetSdkVersion="ApiCodename10" />
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- This is the same as writing android:minSdkVersion="1" -->
+ <uses-sdk android:targetSdkVersion="14" />
+
+ <application />
+
+</manifest>
+
+
+@errors
+
+E [ManifestMergerTest0_main.xml:4, ManifestMergerTest1_lib1.xml:4] Main manifest has <uses-sdk android:minSdkVersion='1'> but library uses minSdkVersion='4'
+Note: main manifest lacks a <uses-sdk android:minSdkVersion> declaration, which defaults to value 1.
+E [ManifestMergerTest0_main.xml:4, ManifestMergerTest2_lib2.xml:3] Main manifest has <uses-sdk android:minSdkVersion='1'> but library uses minSdkVersion='10'
+Note: main manifest lacks a <uses-sdk android:minSdkVersion> declaration, which defaults to value 1.
+E [ManifestMergerTest0_main.xml:4, ManifestMergerTest3_lib3.xml:3] Main manifest has <uses-sdk android:minSdkVersion='1'> but library uses minSdkVersion='11'
+Note: main manifest lacks a <uses-sdk android:minSdkVersion> declaration, which defaults to value 1.
+E [ManifestMergerTest4_lib4_parsingError.xml:4] Failed to parse <uses-sdk minSdkVersion='abcd'>: must be an integer number or codename.
+E [ManifestMergerTest5_lib5_parsingError.xml:4] Failed to parse <uses-sdk minSdkVersion='123456789123456789'>: must be an integer number or codename.
+E [ManifestMergerTest6_lib6_parsingError.xml:4] Failed to parse <uses-sdk minSdkVersion='0xFFFFFFFFFFFFFFFF'>: must be an integer number or codename.
+E [ManifestMergerTest7_lib7_parsingError.xml:4] Failed to parse <uses-sdk minSdkVersion='InvalidMinSdk'>: must be an integer number or codename.
+E [ManifestMergerTest7_lib7_parsingError.xml:4] Failed to parse <uses-sdk targetSdkVersion='InvalidTargetSdk'>: must be an integer number or codename.
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/36_uses_sdk_targetsdk_warning.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/36_uses_sdk_targetsdk_warning.xml
new file mode 100755
index 0000000..df8b717
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/36_uses_sdk_targetsdk_warning.xml
@@ -0,0 +1,77 @@
+#
+# Test uses-sdk: there's a warning if the main manifest defines a targetSdkVersion that
+# is smaller than what the libraries target.
+#
+
+@fails
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- This app requires cupcake and targets at least 10. -->
+ <uses-sdk
+ android:minSdkVersion="3"
+ android:targetSdkVersion="ApiCodename10"
+ />
+
+ <application />
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- This lib requires cupcake and targets 11 which is > 10 so it's a warning. -->
+ <uses-sdk
+ android:minSdkVersion="3"
+ android:targetSdkVersion="11"
+ />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- This is not an error nor a warning. -->
+ <uses-sdk
+ android:minSdkVersion="3"
+ android:targetSdkVersion="4"
+ />
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- This app requires cupcake and targets at least 10. -->
+ <uses-sdk
+ android:minSdkVersion="3"
+ android:targetSdkVersion="ApiCodename10"
+ />
+
+ <application />
+
+</manifest>
+
+
+@errors
+
+W [ManifestMergerTest0_main.xml:4, ManifestMergerTest1_lib1.xml:4] Main manifest has <uses-sdk android:targetSdkVersion='10'> but library uses targetSdkVersion='11'
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/40_uses_feat_merge.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/40_uses_feat_merge.xml
new file mode 100755
index 0000000..d14dcaa
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/40_uses_feat_merge.xml
@@ -0,0 +1,178 @@
+#
+# Test merge of uses-feature:
+# - Merge is OK if destination already has one with the same @name.
+# - required defaults to "true"
+# - when merging, a required=true (explicit or implicit) overwrites a required=false.
+#
+# Note: uses-feature with android:glEsVersion is dealt with in another test case.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- A feature that is implicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature0_DefaultTrue" />
+
+ <!-- A feature that is implicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature1_DefaultTrue" />
+
+ <!-- A feature that is explicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature2_RequiredTrue"
+ android:required="true" />
+
+ <!-- A feature that is explicitly marked as required=false -->
+ <uses-feature
+ android:name="com.example.SomeFeature3_RequiredFalse"
+ android:required="false" />
+
+ <!-- A feature that is explicitly marked as required=false -->
+ <uses-feature
+ android:name="com.example.SomeFeature4_RequiredFalse"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- Same as 1 from main, marking it as required=false -->
+ <uses-feature
+ android:name="com.example.SomeFeature1_DefaultTrue"
+ android:required="false" />
+
+ <!-- Same as 3 from main -->
+ <uses-feature
+ android:name="com.example.SomeFeature3_RequiredFalse"
+ android:required="false" />
+
+ <!-- Same as 4 from main -->
+ <uses-feature
+ android:name="com.example.SomeFeature4_RequiredFalse"
+ android:required="false" />
+
+ <!-- Add a new feature that is implicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature5_RequiredTrue"
+ android:required="true" />
+
+ <!-- Add a new feature that is implicitly marked as required=false -->
+ <uses-feature
+ android:name="com.example.SomeFeature6_RequiredFalse"
+ android:required="false" />
+
+ <application android:label="@string/lib_name1" >
+
+ </application>
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- Overrides 3, changing it from required=false to true -->
+ <uses-feature
+ android:name="com.example.SomeFeature3_RequiredFalse"
+ android:required="true" />
+
+ <!-- Same as 4 from main -->
+ <uses-feature
+ android:name="com.example.SomeFeature4_RequiredFalse"
+ android:required="false" />
+
+ <!-- Overrides 6, but implicitly declaring required=True -->
+ <uses-feature
+ android:name="com.example.SomeFeature6_RequiredFalse" />
+
+ <application android:label="@string/lib_name2" >
+
+ </application>
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- A feature that is implicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature0_DefaultTrue" />
+
+ <!-- A feature that is implicitly marked as required=true -->
+# required=false from lib1 is ignored, it stays at the default
+ <uses-feature
+ android:name="com.example.SomeFeature1_DefaultTrue" />
+
+ <!-- A feature that is explicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature2_RequiredTrue"
+ android:required="true" />
+
+ <!-- A feature that is explicitly marked as required=false -->
+# lib1 keeps it required=false but lib2 makes it switch to required=true
+ <uses-feature
+ android:name="com.example.SomeFeature3_RequiredFalse"
+ android:required="true" />
+
+ <!-- A feature that is explicitly marked as required=false -->
+ <uses-feature
+ android:name="com.example.SomeFeature4_RequiredFalse"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ </application>
+
+# new from lib1
+ <!-- Add a new feature that is implicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature5_RequiredTrue"
+ android:required="true" />
+
+# new from lib1, but lib2 makes it switch to required=true
+ <!-- Add a new feature that is implicitly marked as required=false -->
+ <uses-feature
+ android:name="com.example.SomeFeature6_RequiredFalse"
+ android:required="true" />
+
+</manifest>
+
+
+@errors
+
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/41_uses_feat_errors.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/41_uses_feat_errors.xml
new file mode 100755
index 0000000..b86f74a
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/41_uses_feat_errors.xml
@@ -0,0 +1,205 @@
+#
+# Test merge of uses-feature:
+# - Merge is OK if destination already has one with the same @name.
+# - required defaults to "true"
+# - when merging, a required=true (explicit or implicit) overwrites a required=false.
+#
+# Note: uses-feature with android:glEsVersion is dealt with in another test case.
+#
+
+@fails
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- A feature that is implicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature0_DefaultTrue" />
+
+ <!-- A feature that is implicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature1_DefaultTrue" />
+
+ <!-- A feature that is explicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature2_RequiredTrue"
+ android:required="booh!" />
+
+ <!-- A feature that is explicitly marked as required=false -->
+ <uses-feature
+ android:name="com.example.SomeFeature3_RequiredFalse"
+ android:required="false" />
+
+ <!-- A feature that is explicitly marked as required=false. Duplicated. -->
+ <uses-feature
+ android:name="com.example.SomeFeature3_RequiredFalse"
+ android:required="false" />
+
+ <!-- A feature that is explicitly marked as required=false -->
+ <uses-feature
+ android:name="com.example.SomeFeature4_RequiredFalse"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- Error: android:name attribute is missing. -->
+ <uses-feature />
+ <uses-feature android:required="false" />
+ <uses-feature android:required="true" />
+
+ <!-- Same as 2 from main. Warning/ignore because dest required isn't true/false. -->
+ <uses-feature
+ android:name="com.example.SomeFeature2_RequiredTrue"
+ android:required="true" />
+
+ <!-- Same as 3 from main. Warning because destination as a duplicate. -->
+ <uses-feature
+ android:name="com.example.SomeFeature3_RequiredFalse"
+ android:required="false" />
+
+ <!-- Same as 4 from main. Warning because required isn't true or false. -->
+ <uses-feature
+ android:name="com.example.SomeFeature4_RequiredFalse"
+ android:required="foo" />
+
+ <!-- Add a new feature that is implicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature5_RequiredTrue"
+ android:required="true" />
+
+ <!-- Add a new feature that is implicitly marked as required=false -->
+ <uses-feature
+ android:name="com.example.SomeFeature6_RequiredFalse"
+ android:required="false" />
+
+ <application android:label="@string/lib_name1" >
+
+ </application>
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- Overrides 3, changing it from required=false to true -->
+ <uses-feature
+ android:name="com.example.SomeFeature3_RequiredFalse"
+ android:required="true" />
+
+ <!-- Same as 4 from main -->
+ <uses-feature
+ android:name="com.example.SomeFeature4_RequiredFalse"
+ android:required="false" />
+
+ <!-- Overrides 6, but implicitly declaring required=True -->
+ <uses-feature
+ android:name="com.example.SomeFeature6_RequiredFalse" />
+
+ <application android:label="@string/lib_name2" >
+
+ </application>
+</manifest>
+
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <!-- A feature that is implicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature0_DefaultTrue" />
+
+ <!-- A feature that is implicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature1_DefaultTrue" />
+
+ <!-- A feature that is explicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature2_RequiredTrue"
+ android:required="booh!" />
+
+ <!-- A feature that is explicitly marked as required=false -->
+# lib1 keeps it required=false but lib2 makes it switch to required=true
+ <uses-feature
+ android:name="com.example.SomeFeature3_RequiredFalse"
+ android:required="true" />
+
+ <!-- A feature that is explicitly marked as required=false. Duplicated. -->
+# in case of duplicated name, they are all modified.
+ <uses-feature
+ android:name="com.example.SomeFeature3_RequiredFalse"
+ android:required="true" />
+
+ <!-- A feature that is explicitly marked as required=false -->
+ <uses-feature
+ android:name="com.example.SomeFeature4_RequiredFalse"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ </application>
+
+# new from lib1
+ <!-- Add a new feature that is implicitly marked as required=true -->
+ <uses-feature
+ android:name="com.example.SomeFeature5_RequiredTrue"
+ android:required="true" />
+
+# new from lib1, but lib2 makes it switch to required=true
+ <!-- Add a new feature that is implicitly marked as required=false -->
+ <uses-feature
+ android:name="com.example.SomeFeature6_RequiredFalse"
+ android:required="true" />
+
+</manifest>
+
+
+@errors
+
+E [ManifestMergerTest1_lib1.xml:4] Undefined 'name' attribute in /manifest/uses-feature.
+E [ManifestMergerTest1_lib1.xml:5] Undefined 'name' attribute in /manifest/uses-feature.
+E [ManifestMergerTest1_lib1.xml:6] Undefined 'name' attribute in /manifest/uses-feature.
+W [ManifestMergerTest0_main.xml:10] Invalid attribute 'required' in /manifest/uses-feature[@name=com.example.SomeFeature2_RequiredTrue] element:
+Expected 'true' or 'false' but found 'booh!'.
+W [ManifestMergerTest0_main.xml:13] Manifest has more than one /manifest/uses-feature[@name=com.example.SomeFeature3_RequiredFalse] element.
+W [ManifestMergerTest1_lib1.xml:15] Invalid attribute 'required' in /manifest/uses-feature[@name=com.example.SomeFeature4_RequiredFalse] element:
+Expected 'true' or 'false' but found 'foo'.
+W [ManifestMergerTest0_main.xml:13] Manifest has more than one /manifest/uses-feature[@name=com.example.SomeFeature3_RequiredFalse] element.
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/45_uses_feat_gles_once.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/45_uses_feat_gles_once.xml
new file mode 100755
index 0000000..57937a6
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/45_uses_feat_gles_once.xml
@@ -0,0 +1,126 @@
+#
+# Test merge of uses-feature with android:glEsVersion:
+# - Error if defined in lib+dest with dest < lib.
+# - Never automatically change dest.
+# - Default implied value is 1.0 (0x00010000).
+#
+# This tests a case that works. Also checks that glEsVersion attributes are stripped
+# when merging uses-feature with the name attribute.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-feature
+ android:name="com.example.SomeFeature0" />
+ <uses-feature
+ android:name="com.example.SomeFeature1"
+ android:required="false" />
+ <uses-feature android:glEsVersion="0x00020001" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- Add a new feature with a glEsVersion of 2.1 -->
+ <uses-feature
+ android:name="com.example.SomeFeature5"
+ android:required="false"
+ android:glEsVersion="0x00020001"
+ />
+
+ <!-- Add a glEsVersion of 2.0, which will be ignored -->
+ <uses-feature
+ android:glEsVersion="0x00020000"
+ />
+
+ <application android:label="@string/lib_name1" />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- Add a new feature with a glEsVersion of 1.1 which will be ignored -->
+ <uses-feature
+ android:name="com.example.SomeFeature6"
+ android:required="false"
+ android:glEsVersion="0x00020001"
+ />
+
+ <!-- Add a glEsVersion of 1.0, which will be ignored -->
+ <uses-feature android:glEsVersion="0x00010000" />
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-feature
+ android:name="com.example.SomeFeature0" />
+ <uses-feature
+ android:name="com.example.SomeFeature1"
+ android:required="false" />
+ <uses-feature android:glEsVersion="0x00020001" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ </application>
+
+ <!-- Add a new feature with a glEsVersion of 2.1 -->
+# lib1 adds this new node. Note how the glEsVersion=2.1 is stripped out.
+ <uses-feature
+ android:name="com.example.SomeFeature5"
+ android:required="false"
+ />
+
+ <!-- Add a new feature with a glEsVersion of 1.1 which will be ignored -->
+# lib2 adds this new node. Note how the glEsVersion=2.0 is stripped out.
+ <uses-feature
+ android:name="com.example.SomeFeature6"
+ android:required="false"
+ />
+
+</manifest>
+
+
+@errors
+
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/47_uses_feat_gles_conflict.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/47_uses_feat_gles_conflict.xml
new file mode 100755
index 0000000..936d009
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/47_uses_feat_gles_conflict.xml
@@ -0,0 +1,162 @@
+#
+# Test merge of uses-feature with android:glEsVersion:
+# - Error if defined in lib+dest with dest < lib.
+# - Never automatically change dest.
+# - Default implied value is 1.0 (0x00010000).
+#
+# This tests a case that doesn't works because the main manifest doesn't declare
+# the value and thus defaults to 1.0, so libraries with higher requirements will
+# conflict.
+#
+
+@fails
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-feature
+ android:name="com.example.SomeFeature0" />
+ <uses-feature
+ android:name="com.example.SomeFeature1"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- Add a new feature with a glEsVersion of 2.1 -->
+ <uses-feature
+ android:name="com.example.SomeFeature5"
+ android:required="false"
+ android:glEsVersion="0x00020001"
+ />
+
+ <!-- Add a glEsVersion of 2.0, which will be ignored -->
+ <uses-feature
+ android:glEsVersion="0x00020000"
+ />
+
+ <application android:label="@string/lib_name1" />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- Add a new feature with a glEsVersion of 1.1 which will be ignored -->
+ <uses-feature
+ android:name="com.example.SomeFeature6"
+ android:required="false"
+ android:glEsVersion="0x00020001"
+ />
+
+ <!-- Add a glEsVersion of 1.0, which will be ignored -->
+ <uses-feature
+ android:glEsVersion="0x00010000"
+ />
+
+ <!-- Test some invalid values. -->
+
+ <!-- 0 isn't a valid value and generates a warning stating it's ignored. -->
+ <uses-feature
+ android:glEsVersion="0"
+ />
+
+ <!-- 0.0xFFFF is 0.99... and generates a warning stating it's ignored.
+ The real minimal value is 1.0, not 0.99... -->
+ <uses-feature
+ android:glEsVersion="0x0000FFFF"
+ />
+
+ <!-- 0xFFFF.xFFFF is not invalid. It does correspond to 65535.9999847412109375
+ which is unlikely to be valid anyway. It's not ignored and should parse just fine.
+ -->
+ <uses-feature
+ android:glEsVersion="0xFFFFFFFF"
+ />
+
+ <!-- This value shouldn't parse correctly with a Long and will generate a parsing error.
+ -->
+ <uses-feature
+ android:glEsVersion="0xFFFFFFFFFFFFFFFF"
+ />
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-feature
+ android:name="com.example.SomeFeature0" />
+ <uses-feature
+ android:name="com.example.SomeFeature1"
+ android:required="false" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ </application>
+
+ <!-- Add a new feature with a glEsVersion of 2.1 -->
+# lib1 adds this new node. Note how the glEsVersion=2.1 is stripped out.
+ <uses-feature
+ android:name="com.example.SomeFeature5"
+ android:required="false"
+ />
+
+ <!-- Add a new feature with a glEsVersion of 1.1 which will be ignored -->
+# lib2 adds this new node. Note how the glEsVersion=2.0 is stripped out.
+ <uses-feature
+ android:name="com.example.SomeFeature6"
+ android:required="false"
+ />
+
+</manifest>
+
+
+@errors
+
+W [ManifestMergerTest0_main.xml:1, ManifestMergerTest1_lib1.xml:4] Main manifest has <uses-feature android:glEsVersion='0x00010000'> but library uses glEsVersion='0x00020001'
+Note: main manifest lacks a <uses-feature android:glEsVersion> declaration, and thus defaults to glEsVersion=0x00010000.
+W [ManifestMergerTest2_lib2.xml:12] Ignoring <uses-feature android:glEsVersion='0'> because it's smaller than 1.0.
+W [ManifestMergerTest2_lib2.xml:15] Ignoring <uses-feature android:glEsVersion='0x0000FFFF'> because it's smaller than 1.0.
+E [ManifestMergerTest2_lib2.xml:21] Failed to parse <uses-feature android:glEsVersion='0xFFFFFFFFFFFFFFFF'>: must be an integer in the form 0x00020001.
+W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:18] Main manifest has <uses-feature android:glEsVersion='0x00010000'> but library uses glEsVersion='0xffffffff'
+Note: main manifest lacks a <uses-feature android:glEsVersion> declaration, and thus defaults to glEsVersion=0x00010000.
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/50_uses_conf_warning.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/50_uses_conf_warning.xml
new file mode 100755
index 0000000..b1cb3f9
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/50_uses_conf_warning.xml
@@ -0,0 +1,162 @@
+#
+# Test uses-configuration:
+# - it's OK if a library defines one or multiple times an element already in the application.
+# - it's a warning if the library defines an element not in the application.
+# - this does not actually merge anything. The XML is not changed at all.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-configuration
+ android:reqFiveWayNav="true"
+ android:reqHardKeyboard="false"
+ android:reqKeyboardType="undefined"
+ android:reqNavigation="nonav"
+ android:reqTouchScreen="stylus"
+ />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <supports-gl-texture android:name="some.gl.texture1" />
+ <supports-gl-texture android:name="some.gl.texture2" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- this is the same uses-conf than in the main. -->
+ <uses-configuration
+ android:reqFiveWayNav="true"
+ android:reqHardKeyboard="false"
+ android:reqKeyboardType="undefined"
+ android:reqNavigation="nonav"
+ android:reqTouchScreen="stylus"
+ />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- this is the not same uses-conf than in the main. -->
+ <uses-configuration
+ android:reqFiveWayNav="false"
+ android:reqNavigation="trackball"
+ android:reqTouchScreen="finger" />
+
+</manifest>
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-configuration
+ android:reqFiveWayNav="true"
+ android:reqHardKeyboard="false"
+ android:reqKeyboardType="undefined"
+ android:reqNavigation="nonav"
+ android:reqTouchScreen="stylus"
+ />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <supports-gl-texture android:name="some.gl.texture1" />
+ <supports-gl-texture android:name="some.gl.texture2" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@errors
+
+W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:4] /manifest/uses-configuration defined in library, missing from main manifest:
+<uses-configuration>
+ @android:reqFiveWayNav = false
+ @android:reqNavigation = trackball
+ @android:reqTouchScreen = finger
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/52_support_screens_warning.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/52_support_screens_warning.xml
new file mode 100755
index 0000000..363fb2b
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/52_support_screens_warning.xml
@@ -0,0 +1,162 @@
+#
+# Test supports-screens:
+# - it's OK if a library defines one or multiple times an element already in the application.
+# - it's a warning if the library defines an element not in the application.
+# - this does not actually merge anything. The XML is not changed at all.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-configuration
+ android:reqFiveWayNav="true"
+ android:reqHardKeyboard="false"
+ android:reqKeyboardType="undefined"
+ android:reqNavigation="nonav"
+ android:reqTouchScreen="stylus"
+ />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <supports-gl-texture android:name="some.gl.texture1" />
+ <supports-gl-texture android:name="some.gl.texture2" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- this is the same supports-screens than in the main. -->
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- this is the not same supports-screens than in the main. -->
+ <supports-screens
+ android:smallScreens="false"
+ android:resizeable="false"
+ />
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-configuration
+ android:reqFiveWayNav="true"
+ android:reqHardKeyboard="false"
+ android:reqKeyboardType="undefined"
+ android:reqNavigation="nonav"
+ android:reqTouchScreen="stylus"
+ />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <supports-gl-texture android:name="some.gl.texture1" />
+ <supports-gl-texture android:name="some.gl.texture2" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@errors
+
+W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:4] /manifest/supports-screens defined in library, missing from main manifest:
+<supports-screens>
+ @android:resizeable = false
+ @android:smallScreens = false
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/54_compat_screens_warning.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/54_compat_screens_warning.xml
new file mode 100755
index 0000000..1e1c2d2
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/54_compat_screens_warning.xml
@@ -0,0 +1,204 @@
+#
+# Test compatible-screens:
+# - it's OK if a library defines one or multiple times an element already in the application.
+# - it's a warning if the library defines an element not in the application.
+# - this does not actually merge anything. The XML is not changed at all.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-configuration
+ android:reqFiveWayNav="true"
+ android:reqHardKeyboard="false"
+ android:reqKeyboardType="undefined"
+ android:reqNavigation="nonav"
+ android:reqTouchScreen="stylus"
+ />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <supports-gl-texture android:name="some.gl.texture1" />
+ <supports-gl-texture android:name="some.gl.texture2" />
+
+ <compatible-screens>
+ <screen android:screenSize="small" android:screenDensity="ldpi" />
+ <screen android:screenSize="normal" android:screenDensity="xhdpi" />
+ </compatible-screens>
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- this is the same compatible-screens than in the main. -->
+ <compatible-screens>
+ <screen android:screenSize="small" android:screenDensity="ldpi" />
+ <screen android:screenSize="normal" android:screenDensity="xhdpi" />
+ </compatible-screens>
+
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- this is the not same compatible-screens than in the main. -->
+ <compatible-screens>
+ <screen android:screenSize="small" android:screenDensity="ldpi" />
+ <screen android:screenSize="normal" android:screenDensity="mdpi" />
+ </compatible-screens>
+
+ <compatible-screens>
+ <screen android:screenSize="small" android:screenDensity="ldpi" />
+ </compatible-screens>
+
+ <compatible-screens>
+ <screen android:screenSize="normal" android:screenDensity="ldpi" />
+ <screen android:screenSize="normal" android:screenDensity="mdpi" />
+ <screen android:screenSize="normal" android:screenDensity="hdpi" />
+ <screen android:screenSize="normal" android:screenDensity="xhdpi" />
+ </compatible-screens>
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-configuration
+ android:reqFiveWayNav="true"
+ android:reqHardKeyboard="false"
+ android:reqKeyboardType="undefined"
+ android:reqNavigation="nonav"
+ android:reqTouchScreen="stylus"
+ />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <supports-gl-texture android:name="some.gl.texture1" />
+ <supports-gl-texture android:name="some.gl.texture2" />
+
+ <compatible-screens>
+ <screen android:screenSize="small" android:screenDensity="ldpi" />
+ <screen android:screenSize="normal" android:screenDensity="xhdpi" />
+ </compatible-screens>
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@errors
+
+W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:4] /manifest/compatible-screens defined in library, missing from main manifest:
+<compatible-screens>
+ <screen>
+ @android:screenDensity = ldpi
+ @android:screenSize = small
+ <screen>
+ @android:screenDensity = mdpi
+ @android:screenSize = normal
+W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:9] /manifest/compatible-screens defined in library, missing from main manifest:
+<compatible-screens>
+ <screen>
+ @android:screenDensity = ldpi
+ @android:screenSize = small
+W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:13] /manifest/compatible-screens defined in library, missing from main manifest:
+<compatible-screens>
+ <screen>
+ @android:screenDensity = ldpi
+ @android:screenSize = normal
+ <screen>
+ @android:screenDensity = mdpi
+ @android:screenSize = normal
+ <screen>
+ @android:screenDensity = hdpi
+ @android:screenSize = normal
+ <screen>
+ @android:screenDensity = xhdpi
+ @android:screenSize = normal
diff --git a/third-party/java/aosp/tests/src/com/android/manifmerger/data/56_support_gltext_warning.xml b/third-party/java/aosp/tests/src/com/android/manifmerger/data/56_support_gltext_warning.xml
new file mode 100755
index 0000000..494fd2e
--- /dev/null
+++ b/third-party/java/aosp/tests/src/com/android/manifmerger/data/56_support_gltext_warning.xml
@@ -0,0 +1,152 @@
+#
+# Test supports-gl-texture:
+# - it's OK if a library defines one or multiple times an element already in the application.
+# - it's a warning if the library defines an element not in the application.
+# - this does not actually merge anything. The XML is not changed at all.
+#
+
+@main
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-configuration
+ android:reqFiveWayNav="true"
+ android:reqHardKeyboard="false"
+ android:reqKeyboardType="undefined"
+ android:reqNavigation="nonav"
+ android:reqTouchScreen="stylus"
+ />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <supports-gl-texture android:name="some.gl.texture1" />
+ <supports-gl-texture android:name="some.gl.texture2" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@lib1
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib1">
+
+ <!-- this is the same supports-gl-texture than in the main. -->
+ <supports-gl-texture android:name="some.gl.texture1" />
+
+</manifest>
+
+
+@lib2
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.lib2">
+
+ <!-- this is the not same supports-gl-texture than in the main. -->
+ <supports-gl-texture android:name="some.gl.texture3" />
+
+</manifest>
+
+
+@result
+
+<manifest
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.example.app1"
+ android:versionCode="100"
+ android:versionName="1.0.0">
+
+ <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
+
+ <supports-screens
+ android:largeScreens="true"
+ android:smallScreens="true"
+ android:normalScreens="true"
+ android:resizeable="true"
+ android:xlargeScreens="true"
+ />
+
+ <uses-configuration
+ android:reqFiveWayNav="true"
+ android:reqHardKeyboard="false"
+ android:reqKeyboardType="undefined"
+ android:reqNavigation="nonav"
+ android:reqTouchScreen="stylus"
+ />
+
+ <uses-feature
+ android:name="android.hardware.touchscreen"
+ android:required="false" />
+
+ <supports-gl-texture android:name="some.gl.texture1" />
+ <supports-gl-texture android:name="some.gl.texture2" />
+
+ <application
+ android:label="@string/app_name"
+ android:icon="@drawable/app_icon"
+ android:backupAgent="com.example.app.BackupAgentClass"
+ android:restoreAnyVersion="true"
+ android:allowBackup="true"
+ android:killAfterRestore="true"
+ android:name="com.example.TheApp" >
+
+ <activity
+ android:name="com.example.MainActivity"
+ android:label="@string/activity_name"
+ android:icon="@drawable/activity_icon"
+ android:theme="@style/Some.Theme">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
+
+
+@errors
+
+W [ManifestMergerTest0_main.xml:1, ManifestMergerTest2_lib2.xml:4] /manifest/supports-gl-texture defined in library, missing from main manifest:
+<supports-gl-texture>
+ @android:name = some.gl.texture3