aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaphael Moll <ralf@android.com>2013-01-04 11:24:13 -0800
committerRaphael Moll <ralf@android.com>2013-01-08 13:59:33 -0800
commitd09956e1e7375d5a6ddd6d2d8c61c96376333d5f (patch)
treedfed5d7f754235fb95e2e717cfce053177902afa
parentb6049e3c93e27b943832ec300a6d9b04f4f6d474 (diff)
downloadsdk-d09956e1e7375d5a6ddd6d2d8c61c96376333d5f.zip
sdk-d09956e1e7375d5a6ddd6d2d8c61c96376333d5f.tar.gz
sdk-d09956e1e7375d5a6ddd6d2d8c61c96376333d5f.tar.bz2
SDK: Remove sources for jobb & manifmerge. They are in tools/base now.
Change-Id: I1092079acad333deda47d4c8a092279879fadea6
-rw-r--r--jobb/etc/Android.mk21
-rwxr-xr-xjobb/etc/jobb68
-rwxr-xr-xjobb/etc/jobb.bat51
-rw-r--r--jobb/etc/manifest.txt2
-rw-r--r--jobb/src/Twofish/Twofish_Algorithm.java835
-rw-r--r--jobb/src/Twofish/Twofish_Properties.java197
-rw-r--r--jobb/src/com/android/jobb/Base64.java276
-rw-r--r--jobb/src/com/android/jobb/Encoder.java33
-rw-r--r--jobb/src/com/android/jobb/EncryptedBlockFile.java379
-rw-r--r--jobb/src/com/android/jobb/Main.java607
-rw-r--r--jobb/src/com/android/jobb/ObbFile.java231
-rw-r--r--jobb/src/com/android/jobb/PBKDF.java55
-rw-r--r--manifmerger/etc/Android.mk10
-rw-r--r--manifmerger/etc/manifest.txt2
-rwxr-xr-xmanifmerger/etc/manifmerger87
-rwxr-xr-xmanifmerger/src/main/java/com/android/manifmerger/ArgvParser.java116
-rwxr-xr-xmanifmerger/src/main/java/com/android/manifmerger/ICallback.java37
-rwxr-xr-xmanifmerger/src/main/java/com/android/manifmerger/IMergerLog.java164
-rw-r--r--manifmerger/src/main/java/com/android/manifmerger/Main.java92
-rwxr-xr-xmanifmerger/src/main/java/com/android/manifmerger/ManifestMerger.java1577
-rwxr-xr-xmanifmerger/src/main/java/com/android/manifmerger/MergerLog.java151
-rwxr-xr-xmanifmerger/src/main/java/com/android/manifmerger/MergerXmlUtils.java915
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/ManifestMergerTest.java200
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/ManifestMergerTestCase.java494
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/00_noop.xml229
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/01_ignore_app_attr.xml69
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/02_ignore_instrumentation.xml62
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/03_inject_attributes.xml53
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/04_inject_attributes.xml63
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/10_activity_merge.xml378
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/11_activity_dup.xml406
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/12_alias_dup.xml211
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/13_service_dup.xml167
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/14_receiver_dup.xml186
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/15_provider_dup.xml153
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/16_fqcn_merge.xml129
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/17_fqcn_conflict.xml120
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/20_uses_lib_merge.xml176
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/21_uses_lib_errors.xml202
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/25_permission_merge.xml259
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/26_permission_dup.xml314
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/28_uses_perm_merge.xml156
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/30_uses_sdk_ok.xml86
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/32_uses_sdk_minsdk_ok.xml70
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/33_uses_sdk_minsdk_conflict.xml148
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/36_uses_sdk_targetsdk_warning.xml77
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/40_uses_feat_merge.xml178
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/41_uses_feat_errors.xml205
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/45_uses_feat_gles_once.xml126
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/47_uses_feat_gles_conflict.xml162
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/50_uses_conf_warning.xml162
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/52_support_screens_warning.xml162
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/54_compat_screens_warning.xml204
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/56_support_gltext_warning.xml151
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/60_merge_order.xml318
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/65_override_app.xml197
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/66_remove_app.xml53
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/67_override_activities.xml159
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/68_override_uses.xml206
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/69_remove_uses.xml178
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/70_expand_fqcns.xml93
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/71_extract_package_prefix.xml99
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/75_app_metadata_merge.xml100
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/76_app_metadata_ignore.xml103
-rwxr-xr-xmanifmerger/src/test/java/com/android/manifmerger/data/77_app_metadata_conflict.xml131
65 files changed, 0 insertions, 13301 deletions
diff --git a/jobb/etc/Android.mk b/jobb/etc/Android.mk
deleted file mode 100644
index 3030e87..0000000
--- a/jobb/etc/Android.mk
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2010 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := jobb
-LOCAL_MODULE_TAGS := debug
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/jobb/etc/jobb b/jobb/etc/jobb
deleted file mode 100755
index c782141..0000000
--- a/jobb/etc/jobb
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/sh
-# Copyright 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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=jobb.jar
-frameworkdir="$progdir"
-libdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/tools/lib
- libdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/framework
- libdir=`dirname "$progdir"`/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- echo `basename "$prog"`": can't find $jarfile"
- exit 1
-fi
-
-javaCmd="java"
-
-if [ `uname` = "Linux" ]; then
- export GDK_NATIVE_WINDOWS=true
-fi
-
-jarpath="$frameworkdir/$jarfile:$frameworkdir/fat32lib.jar"
-
-exec "$javaCmd" \
- $os_opts \
- -classpath "$jarpath" \
- com.android.jobb.Main "$@"
-
diff --git a/jobb/etc/jobb.bat b/jobb/etc/jobb.bat
deleted file mode 100755
index a5043c1..0000000
--- a/jobb/etc/jobb.bat
+++ /dev/null
@@ -1,51 +0,0 @@
-@echo off
-rem Copyright (C) 2008 The Android Open Source Project
-rem
-rem Licensed under the Apache License, Version 2.0 (the "License");
-rem you may not use this file except in compliance with the License.
-rem You may obtain a copy of the License at
-rem
-rem http://www.apache.org/licenses/LICENSE-2.0
-rem
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-
-rem don't modify the caller's environment
-setlocal
-
-rem Set up prog to be the path of this script, including following symlinks,
-rem and set up progdir to be the fully-qualified pathname of its directory.
-set prog=%~f0
-
-rem Change current directory and drive to where the script is, to avoid
-rem issues with directories containing whitespaces.
-cd /d %~dp0
-
-rem Get the CWD as a full path with short names only (without spaces)
-for %%i in ("%cd%") do set prog_dir=%%~fsi
-
-rem Check we have a valid Java.exe in the path.
-set java_exe=
-call lib\find_java.bat
-if not defined java_exe goto :EOF
-
-set jarfile=jobb.jar
-set frameworkdir=
-set libdir=
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
- set frameworkdir=lib\
-
-if exist %frameworkdir%%jarfile% goto JarFileOk
- set frameworkdir=..\framework\
-
-:JarFileOk
-
-set jarpath=%frameworkdir%%jarfile%;%frameworkdir%libfat32.jar
-
-call %java_exe% %java_debug% -classpath "%jarpath%" com.android.jobb.Main %*
-
-
diff --git a/jobb/etc/manifest.txt b/jobb/etc/manifest.txt
deleted file mode 100644
index 305cd61..0000000
--- a/jobb/etc/manifest.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Main-Class: com.android.jobb.Main
-Class-Path: fat32lib.jar
diff --git a/jobb/src/Twofish/Twofish_Algorithm.java b/jobb/src/Twofish/Twofish_Algorithm.java
deleted file mode 100644
index 330d68e..0000000
--- a/jobb/src/Twofish/Twofish_Algorithm.java
+++ /dev/null
@@ -1,835 +0,0 @@
-// $Id: $
-//
-// $Log: $
-// Revision 1.0 1998/03/24 raif
-// + start of history.
-//
-// $Endlog$
-/*
- * Copyright (c) 1997, 1998 Systemics Ltd on behalf of
- * the Cryptix Development Team. All rights reserved.
- */
-package Twofish;
-
-import java.io.PrintWriter;
-import java.security.InvalidKeyException;
-
-//...........................................................................
-/**
- * Twofish is an AES candidate algorithm. It is a balanced 128-bit Feistel
- * cipher, consisting of 16 rounds. In each round, a 64-bit S-box value is
- * computed from 64 bits of the block, and this value is xored into the other
- * half of the block. The two half-blocks are then exchanged, and the next
- * round begins. Before the first round, all input bits are xored with key-
- * dependent "whitening" subkeys, and after the final round the output bits
- * are xored with other key-dependent whitening subkeys; these subkeys are
- * not used anywhere else in the algorithm.<p>
- *
- * Twofish was submitted by Bruce Schneier, Doug Whiting, John Kelsey, Chris
- * Hall and David Wagner.<p>
- *
- * Reference:<ol>
- * <li>TWOFISH2.C -- Optimized C API calls for TWOFISH AES submission,
- * Version 1.00, April 1998, by Doug Whiting.</ol><p>
- *
- * <b>Copyright</b> &copy; 1998
- * <a href="http://www.systemics.com/">Systemics Ltd</a> on behalf of the
- * <a href="http://www.systemics.com/docs/cryptix/">Cryptix Development Team</a>.
- * <br>All rights reserved.<p>
- *
- * <b>$Revision: $</b>
- * @author Raif S. Naffah
- */
-public final class Twofish_Algorithm // implicit no-argument constructor
-{
-// Debugging methods and variables
-//...........................................................................
-
- static final String NAME = "Twofish_Algorithm";
- static final boolean IN = true, OUT = false;
-
- static final boolean DEBUG = Twofish_Properties.GLOBAL_DEBUG;
- static final int debuglevel = DEBUG ? Twofish_Properties.getLevel(NAME) : 0;
- static final PrintWriter err = DEBUG ? Twofish_Properties.getOutput() : null;
-
- static final boolean TRACE = Twofish_Properties.isTraceable(NAME);
-
- static void debug (String s) { err.println(">>> "+NAME+": "+s); }
- static void trace (boolean in, String s) {
- if (TRACE) err.println((in?"==> ":"<== ")+NAME+"."+s);
- }
- static void trace (String s) { if (TRACE) err.println("<=> "+NAME+"."+s); }
-
-
-// Constants and variables
-//...........................................................................
-
- static final int BLOCK_SIZE = 16; // bytes in a data-block
- private static final int ROUNDS = 16;
- private static final int MAX_ROUNDS = 16; // max # rounds (for allocating subkeys)
-
- /* Subkey array indices */
- private static final int INPUT_WHITEN = 0;
- private static final int OUTPUT_WHITEN = INPUT_WHITEN + BLOCK_SIZE/4;
- private static final int ROUND_SUBKEYS = OUTPUT_WHITEN + BLOCK_SIZE/4; // 2*(# rounds)
-
- private static final int TOTAL_SUBKEYS = ROUND_SUBKEYS + 2*MAX_ROUNDS;
-
- private static final int SK_STEP = 0x02020202;
- private static final int SK_BUMP = 0x01010101;
- private static final int SK_ROTL = 9;
-
- /** Fixed 8x8 permutation S-boxes */
- private static final byte[][] P = new byte[][] {
- { // p0
- (byte) 0xA9, (byte) 0x67, (byte) 0xB3, (byte) 0xE8,
- (byte) 0x04, (byte) 0xFD, (byte) 0xA3, (byte) 0x76,
- (byte) 0x9A, (byte) 0x92, (byte) 0x80, (byte) 0x78,
- (byte) 0xE4, (byte) 0xDD, (byte) 0xD1, (byte) 0x38,
- (byte) 0x0D, (byte) 0xC6, (byte) 0x35, (byte) 0x98,
- (byte) 0x18, (byte) 0xF7, (byte) 0xEC, (byte) 0x6C,
- (byte) 0x43, (byte) 0x75, (byte) 0x37, (byte) 0x26,
- (byte) 0xFA, (byte) 0x13, (byte) 0x94, (byte) 0x48,
- (byte) 0xF2, (byte) 0xD0, (byte) 0x8B, (byte) 0x30,
- (byte) 0x84, (byte) 0x54, (byte) 0xDF, (byte) 0x23,
- (byte) 0x19, (byte) 0x5B, (byte) 0x3D, (byte) 0x59,
- (byte) 0xF3, (byte) 0xAE, (byte) 0xA2, (byte) 0x82,
- (byte) 0x63, (byte) 0x01, (byte) 0x83, (byte) 0x2E,
- (byte) 0xD9, (byte) 0x51, (byte) 0x9B, (byte) 0x7C,
- (byte) 0xA6, (byte) 0xEB, (byte) 0xA5, (byte) 0xBE,
- (byte) 0x16, (byte) 0x0C, (byte) 0xE3, (byte) 0x61,
- (byte) 0xC0, (byte) 0x8C, (byte) 0x3A, (byte) 0xF5,
- (byte) 0x73, (byte) 0x2C, (byte) 0x25, (byte) 0x0B,
- (byte) 0xBB, (byte) 0x4E, (byte) 0x89, (byte) 0x6B,
- (byte) 0x53, (byte) 0x6A, (byte) 0xB4, (byte) 0xF1,
- (byte) 0xE1, (byte) 0xE6, (byte) 0xBD, (byte) 0x45,
- (byte) 0xE2, (byte) 0xF4, (byte) 0xB6, (byte) 0x66,
- (byte) 0xCC, (byte) 0x95, (byte) 0x03, (byte) 0x56,
- (byte) 0xD4, (byte) 0x1C, (byte) 0x1E, (byte) 0xD7,
- (byte) 0xFB, (byte) 0xC3, (byte) 0x8E, (byte) 0xB5,
- (byte) 0xE9, (byte) 0xCF, (byte) 0xBF, (byte) 0xBA,
- (byte) 0xEA, (byte) 0x77, (byte) 0x39, (byte) 0xAF,
- (byte) 0x33, (byte) 0xC9, (byte) 0x62, (byte) 0x71,
- (byte) 0x81, (byte) 0x79, (byte) 0x09, (byte) 0xAD,
- (byte) 0x24, (byte) 0xCD, (byte) 0xF9, (byte) 0xD8,
- (byte) 0xE5, (byte) 0xC5, (byte) 0xB9, (byte) 0x4D,
- (byte) 0x44, (byte) 0x08, (byte) 0x86, (byte) 0xE7,
- (byte) 0xA1, (byte) 0x1D, (byte) 0xAA, (byte) 0xED,
- (byte) 0x06, (byte) 0x70, (byte) 0xB2, (byte) 0xD2,
- (byte) 0x41, (byte) 0x7B, (byte) 0xA0, (byte) 0x11,
- (byte) 0x31, (byte) 0xC2, (byte) 0x27, (byte) 0x90,
- (byte) 0x20, (byte) 0xF6, (byte) 0x60, (byte) 0xFF,
- (byte) 0x96, (byte) 0x5C, (byte) 0xB1, (byte) 0xAB,
- (byte) 0x9E, (byte) 0x9C, (byte) 0x52, (byte) 0x1B,
- (byte) 0x5F, (byte) 0x93, (byte) 0x0A, (byte) 0xEF,
- (byte) 0x91, (byte) 0x85, (byte) 0x49, (byte) 0xEE,
- (byte) 0x2D, (byte) 0x4F, (byte) 0x8F, (byte) 0x3B,
- (byte) 0x47, (byte) 0x87, (byte) 0x6D, (byte) 0x46,
- (byte) 0xD6, (byte) 0x3E, (byte) 0x69, (byte) 0x64,
- (byte) 0x2A, (byte) 0xCE, (byte) 0xCB, (byte) 0x2F,
- (byte) 0xFC, (byte) 0x97, (byte) 0x05, (byte) 0x7A,
- (byte) 0xAC, (byte) 0x7F, (byte) 0xD5, (byte) 0x1A,
- (byte) 0x4B, (byte) 0x0E, (byte) 0xA7, (byte) 0x5A,
- (byte) 0x28, (byte) 0x14, (byte) 0x3F, (byte) 0x29,
- (byte) 0x88, (byte) 0x3C, (byte) 0x4C, (byte) 0x02,
- (byte) 0xB8, (byte) 0xDA, (byte) 0xB0, (byte) 0x17,
- (byte) 0x55, (byte) 0x1F, (byte) 0x8A, (byte) 0x7D,
- (byte) 0x57, (byte) 0xC7, (byte) 0x8D, (byte) 0x74,
- (byte) 0xB7, (byte) 0xC4, (byte) 0x9F, (byte) 0x72,
- (byte) 0x7E, (byte) 0x15, (byte) 0x22, (byte) 0x12,
- (byte) 0x58, (byte) 0x07, (byte) 0x99, (byte) 0x34,
- (byte) 0x6E, (byte) 0x50, (byte) 0xDE, (byte) 0x68,
- (byte) 0x65, (byte) 0xBC, (byte) 0xDB, (byte) 0xF8,
- (byte) 0xC8, (byte) 0xA8, (byte) 0x2B, (byte) 0x40,
- (byte) 0xDC, (byte) 0xFE, (byte) 0x32, (byte) 0xA4,
- (byte) 0xCA, (byte) 0x10, (byte) 0x21, (byte) 0xF0,
- (byte) 0xD3, (byte) 0x5D, (byte) 0x0F, (byte) 0x00,
- (byte) 0x6F, (byte) 0x9D, (byte) 0x36, (byte) 0x42,
- (byte) 0x4A, (byte) 0x5E, (byte) 0xC1, (byte) 0xE0
- },
- { // p1
- (byte) 0x75, (byte) 0xF3, (byte) 0xC6, (byte) 0xF4,
- (byte) 0xDB, (byte) 0x7B, (byte) 0xFB, (byte) 0xC8,
- (byte) 0x4A, (byte) 0xD3, (byte) 0xE6, (byte) 0x6B,
- (byte) 0x45, (byte) 0x7D, (byte) 0xE8, (byte) 0x4B,
- (byte) 0xD6, (byte) 0x32, (byte) 0xD8, (byte) 0xFD,
- (byte) 0x37, (byte) 0x71, (byte) 0xF1, (byte) 0xE1,
- (byte) 0x30, (byte) 0x0F, (byte) 0xF8, (byte) 0x1B,
- (byte) 0x87, (byte) 0xFA, (byte) 0x06, (byte) 0x3F,
- (byte) 0x5E, (byte) 0xBA, (byte) 0xAE, (byte) 0x5B,
- (byte) 0x8A, (byte) 0x00, (byte) 0xBC, (byte) 0x9D,
- (byte) 0x6D, (byte) 0xC1, (byte) 0xB1, (byte) 0x0E,
- (byte) 0x80, (byte) 0x5D, (byte) 0xD2, (byte) 0xD5,
- (byte) 0xA0, (byte) 0x84, (byte) 0x07, (byte) 0x14,
- (byte) 0xB5, (byte) 0x90, (byte) 0x2C, (byte) 0xA3,
- (byte) 0xB2, (byte) 0x73, (byte) 0x4C, (byte) 0x54,
- (byte) 0x92, (byte) 0x74, (byte) 0x36, (byte) 0x51,
- (byte) 0x38, (byte) 0xB0, (byte) 0xBD, (byte) 0x5A,
- (byte) 0xFC, (byte) 0x60, (byte) 0x62, (byte) 0x96,
- (byte) 0x6C, (byte) 0x42, (byte) 0xF7, (byte) 0x10,
- (byte) 0x7C, (byte) 0x28, (byte) 0x27, (byte) 0x8C,
- (byte) 0x13, (byte) 0x95, (byte) 0x9C, (byte) 0xC7,
- (byte) 0x24, (byte) 0x46, (byte) 0x3B, (byte) 0x70,
- (byte) 0xCA, (byte) 0xE3, (byte) 0x85, (byte) 0xCB,
- (byte) 0x11, (byte) 0xD0, (byte) 0x93, (byte) 0xB8,
- (byte) 0xA6, (byte) 0x83, (byte) 0x20, (byte) 0xFF,
- (byte) 0x9F, (byte) 0x77, (byte) 0xC3, (byte) 0xCC,
- (byte) 0x03, (byte) 0x6F, (byte) 0x08, (byte) 0xBF,
- (byte) 0x40, (byte) 0xE7, (byte) 0x2B, (byte) 0xE2,
- (byte) 0x79, (byte) 0x0C, (byte) 0xAA, (byte) 0x82,
- (byte) 0x41, (byte) 0x3A, (byte) 0xEA, (byte) 0xB9,
- (byte) 0xE4, (byte) 0x9A, (byte) 0xA4, (byte) 0x97,
- (byte) 0x7E, (byte) 0xDA, (byte) 0x7A, (byte) 0x17,
- (byte) 0x66, (byte) 0x94, (byte) 0xA1, (byte) 0x1D,
- (byte) 0x3D, (byte) 0xF0, (byte) 0xDE, (byte) 0xB3,
- (byte) 0x0B, (byte) 0x72, (byte) 0xA7, (byte) 0x1C,
- (byte) 0xEF, (byte) 0xD1, (byte) 0x53, (byte) 0x3E,
- (byte) 0x8F, (byte) 0x33, (byte) 0x26, (byte) 0x5F,
- (byte) 0xEC, (byte) 0x76, (byte) 0x2A, (byte) 0x49,
- (byte) 0x81, (byte) 0x88, (byte) 0xEE, (byte) 0x21,
- (byte) 0xC4, (byte) 0x1A, (byte) 0xEB, (byte) 0xD9,
- (byte) 0xC5, (byte) 0x39, (byte) 0x99, (byte) 0xCD,
- (byte) 0xAD, (byte) 0x31, (byte) 0x8B, (byte) 0x01,
- (byte) 0x18, (byte) 0x23, (byte) 0xDD, (byte) 0x1F,
- (byte) 0x4E, (byte) 0x2D, (byte) 0xF9, (byte) 0x48,
- (byte) 0x4F, (byte) 0xF2, (byte) 0x65, (byte) 0x8E,
- (byte) 0x78, (byte) 0x5C, (byte) 0x58, (byte) 0x19,
- (byte) 0x8D, (byte) 0xE5, (byte) 0x98, (byte) 0x57,
- (byte) 0x67, (byte) 0x7F, (byte) 0x05, (byte) 0x64,
- (byte) 0xAF, (byte) 0x63, (byte) 0xB6, (byte) 0xFE,
- (byte) 0xF5, (byte) 0xB7, (byte) 0x3C, (byte) 0xA5,
- (byte) 0xCE, (byte) 0xE9, (byte) 0x68, (byte) 0x44,
- (byte) 0xE0, (byte) 0x4D, (byte) 0x43, (byte) 0x69,
- (byte) 0x29, (byte) 0x2E, (byte) 0xAC, (byte) 0x15,
- (byte) 0x59, (byte) 0xA8, (byte) 0x0A, (byte) 0x9E,
- (byte) 0x6E, (byte) 0x47, (byte) 0xDF, (byte) 0x34,
- (byte) 0x35, (byte) 0x6A, (byte) 0xCF, (byte) 0xDC,
- (byte) 0x22, (byte) 0xC9, (byte) 0xC0, (byte) 0x9B,
- (byte) 0x89, (byte) 0xD4, (byte) 0xED, (byte) 0xAB,
- (byte) 0x12, (byte) 0xA2, (byte) 0x0D, (byte) 0x52,
- (byte) 0xBB, (byte) 0x02, (byte) 0x2F, (byte) 0xA9,
- (byte) 0xD7, (byte) 0x61, (byte) 0x1E, (byte) 0xB4,
- (byte) 0x50, (byte) 0x04, (byte) 0xF6, (byte) 0xC2,
- (byte) 0x16, (byte) 0x25, (byte) 0x86, (byte) 0x56,
- (byte) 0x55, (byte) 0x09, (byte) 0xBE, (byte) 0x91
- }
- };
-
- /**
- * Define the fixed p0/p1 permutations used in keyed S-box lookup.
- * By changing the following constant definitions, the S-boxes will
- * automatically get changed in the Twofish engine.
- */
- private static final int P_00 = 1;
- private static final int P_01 = 0;
- private static final int P_02 = 0;
- private static final int P_03 = P_01 ^ 1;
- private static final int P_04 = 1;
-
- private static final int P_10 = 0;
- private static final int P_11 = 0;
- private static final int P_12 = 1;
- private static final int P_13 = P_11 ^ 1;
- private static final int P_14 = 0;
-
- private static final int P_20 = 1;
- private static final int P_21 = 1;
- private static final int P_22 = 0;
- private static final int P_23 = P_21 ^ 1;
- private static final int P_24 = 0;
-
- private static final int P_30 = 0;
- private static final int P_31 = 1;
- private static final int P_32 = 1;
- private static final int P_33 = P_31 ^ 1;
- private static final int P_34 = 1;
-
- /** Primitive polynomial for GF(256) */
- private static final int GF256_FDBK = 0x169;
- private static final int GF256_FDBK_2 = 0x169 / 2;
- private static final int GF256_FDBK_4 = 0x169 / 4;
-
- /** MDS matrix */
- private static final int[][] MDS = new int[4][256]; // blank final
-
- private static final int RS_GF_FDBK = 0x14D; // field generator
-
- /** data for hexadecimal visualisation. */
- private static final char[] HEX_DIGITS = {
- '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
- };
-
-
-// Static code - to intialise the MDS matrix
-//...........................................................................
-
- static {
- long time = System.currentTimeMillis();
-
-if (DEBUG && debuglevel > 6) {
-System.out.println("Algorithm Name: "+Twofish_Properties.FULL_NAME);
-System.out.println("Electronic Codebook (ECB) Mode");
-System.out.println();
-}
- //
- // precompute the MDS matrix
- //
- int[] m1 = new int[2];
- int[] mX = new int[2];
- int[] mY = new int[2];
- int i, j;
- for (i = 0; i < 256; i++) {
- j = P[0][i] & 0xFF; // compute all the matrix elements
- m1[0] = j;
- mX[0] = Mx_X( j ) & 0xFF;
- mY[0] = Mx_Y( j ) & 0xFF;
-
- j = P[1][i] & 0xFF;
- m1[1] = j;
- mX[1] = Mx_X( j ) & 0xFF;
- mY[1] = Mx_Y( j ) & 0xFF;
-
- MDS[0][i] = m1[P_00] << 0 | // fill matrix w/ above elements
- mX[P_00] << 8 |
- mY[P_00] << 16 |
- mY[P_00] << 24;
- MDS[1][i] = mY[P_10] << 0 |
- mY[P_10] << 8 |
- mX[P_10] << 16 |
- m1[P_10] << 24;
- MDS[2][i] = mX[P_20] << 0 |
- mY[P_20] << 8 |
- m1[P_20] << 16 |
- mY[P_20] << 24;
- MDS[3][i] = mX[P_30] << 0 |
- m1[P_30] << 8 |
- mY[P_30] << 16 |
- mX[P_30] << 24;
- }
-
- time = System.currentTimeMillis() - time;
-
-if (DEBUG && debuglevel > 8) {
-System.out.println("==========");
-System.out.println();
-System.out.println("Static Data");
-System.out.println();
-System.out.println("MDS[0][]:"); for(i=0;i<64;i++) { for(j=0;j<4;j++) System.out.print("0x"+intToString(MDS[0][i*4+j])+", "); System.out.println();}
-System.out.println();
-System.out.println("MDS[1][]:"); for(i=0;i<64;i++) { for(j=0;j<4;j++) System.out.print("0x"+intToString(MDS[1][i*4+j])+", "); System.out.println();}
-System.out.println();
-System.out.println("MDS[2][]:"); for(i=0;i<64;i++) { for(j=0;j<4;j++) System.out.print("0x"+intToString(MDS[2][i*4+j])+", "); System.out.println();}
-System.out.println();
-System.out.println("MDS[3][]:"); for(i=0;i<64;i++) { for(j=0;j<4;j++) System.out.print("0x"+intToString(MDS[3][i*4+j])+", "); System.out.println();}
-System.out.println();
-System.out.println("Total initialization time: "+time+" ms.");
-System.out.println();
-}
- }
-
- private static final int LFSR1( int x ) {
- return (x >> 1) ^
- ((x & 0x01) != 0 ? GF256_FDBK_2 : 0);
- }
-
- private static final int LFSR2( int x ) {
- return (x >> 2) ^
- ((x & 0x02) != 0 ? GF256_FDBK_2 : 0) ^
- ((x & 0x01) != 0 ? GF256_FDBK_4 : 0);
- }
-
- private static final int Mx_1( int x ) { return x; }
- private static final int Mx_X( int x ) { return x ^ LFSR2(x); } // 5B
- private static final int Mx_Y( int x ) { return x ^ LFSR1(x) ^ LFSR2(x); } // EF
-
-
-// Basic API methods
-//...........................................................................
-
- /**
- * Expand a user-supplied key material into a session key.
- *
- * @param key The 64/128/192/256-bit user-key to use.
- * @return This cipher's round keys.
- * @exception InvalidKeyException If the key is invalid.
- */
- public static synchronized Object makeKey (byte[] k)
- throws InvalidKeyException {
-if (DEBUG) trace(IN, "makeKey("+k+")");
- if (k == null)
- throw new InvalidKeyException("Empty key");
- int length = k.length;
- if (!(length == 8 || length == 16 || length == 24 || length == 32))
- throw new InvalidKeyException("Incorrect key length");
-
-if (DEBUG && debuglevel > 7) {
-System.out.println("Intermediate Session Key Values");
-System.out.println();
-System.out.println("Raw="+toString(k));
-System.out.println();
-}
- int k64Cnt = length / 8;
- int subkeyCnt = ROUND_SUBKEYS + 2*ROUNDS;
- int[] k32e = new int[4]; // even 32-bit entities
- int[] k32o = new int[4]; // odd 32-bit entities
- int[] sBoxKey = new int[4];
- //
- // split user key material into even and odd 32-bit entities and
- // compute S-box keys using (12, 8) Reed-Solomon code over GF(256)
- //
- int i, j, offset = 0;
- for (i = 0, j = k64Cnt-1; i < 4 && offset < length; i++, j--) {
- k32e[i] = (k[offset++] & 0xFF) |
- (k[offset++] & 0xFF) << 8 |
- (k[offset++] & 0xFF) << 16 |
- (k[offset++] & 0xFF) << 24;
- k32o[i] = (k[offset++] & 0xFF) |
- (k[offset++] & 0xFF) << 8 |
- (k[offset++] & 0xFF) << 16 |
- (k[offset++] & 0xFF) << 24;
- sBoxKey[j] = RS_MDS_Encode( k32e[i], k32o[i] ); // reverse order
- }
- // compute the round decryption subkeys for PHT. these same subkeys
- // will be used in encryption but will be applied in reverse order.
- int q, A, B;
- int[] subKeys = new int[subkeyCnt];
- for (i = q = 0; i < subkeyCnt/2; i++, q += SK_STEP) {
- A = F32( k64Cnt, q , k32e ); // A uses even key entities
- B = F32( k64Cnt, q+SK_BUMP, k32o ); // B uses odd key entities
- B = B << 8 | B >>> 24;
- A += B;
- subKeys[2*i ] = A; // combine with a PHT
- A += B;
- subKeys[2*i + 1] = A << SK_ROTL | A >>> (32-SK_ROTL);
- }
- //
- // fully expand the table for speed
- //
- int k0 = sBoxKey[0];
- int k1 = sBoxKey[1];
- int k2 = sBoxKey[2];
- int k3 = sBoxKey[3];
- int b0, b1, b2, b3;
- int[] sBox = new int[4 * 256];
- for (i = 0; i < 256; i++) {
- b0 = b1 = b2 = b3 = i;
- switch (k64Cnt & 3) {
- case 1:
- sBox[ 2*i ] = MDS[0][(P[P_01][b0] & 0xFF) ^ b0(k0)];
- sBox[ 2*i+1] = MDS[1][(P[P_11][b1] & 0xFF) ^ b1(k0)];
- sBox[0x200+2*i ] = MDS[2][(P[P_21][b2] & 0xFF) ^ b2(k0)];
- sBox[0x200+2*i+1] = MDS[3][(P[P_31][b3] & 0xFF) ^ b3(k0)];
- break;
- case 0: // same as 4
- b0 = (P[P_04][b0] & 0xFF) ^ b0(k3);
- b1 = (P[P_14][b1] & 0xFF) ^ b1(k3);
- b2 = (P[P_24][b2] & 0xFF) ^ b2(k3);
- b3 = (P[P_34][b3] & 0xFF) ^ b3(k3);
- case 3:
- b0 = (P[P_03][b0] & 0xFF) ^ b0(k2);
- b1 = (P[P_13][b1] & 0xFF) ^ b1(k2);
- b2 = (P[P_23][b2] & 0xFF) ^ b2(k2);
- b3 = (P[P_33][b3] & 0xFF) ^ b3(k2);
- case 2: // 128-bit keys
- sBox[ 2*i ] = MDS[0][(P[P_01][(P[P_02][b0] & 0xFF) ^ b0(k1)] & 0xFF) ^ b0(k0)];
- sBox[ 2*i+1] = MDS[1][(P[P_11][(P[P_12][b1] & 0xFF) ^ b1(k1)] & 0xFF) ^ b1(k0)];
- sBox[0x200+2*i ] = MDS[2][(P[P_21][(P[P_22][b2] & 0xFF) ^ b2(k1)] & 0xFF) ^ b2(k0)];
- sBox[0x200+2*i+1] = MDS[3][(P[P_31][(P[P_32][b3] & 0xFF) ^ b3(k1)] & 0xFF) ^ b3(k0)];
- }
- }
-
- Object sessionKey = new Object[] { sBox, subKeys };
-
-if (DEBUG && debuglevel > 7) {
-System.out.println("S-box[]:");
-for(i=0;i<64;i++) { for(j=0;j<4;j++) System.out.print("0x"+intToString(sBox[i*4+j])+", "); System.out.println();}
-System.out.println();
-for(i=0;i<64;i++) { for(j=0;j<4;j++) System.out.print("0x"+intToString(sBox[256+i*4+j])+", "); System.out.println();}
-System.out.println();
-for(i=0;i<64;i++) { for(j=0;j<4;j++) System.out.print("0x"+intToString(sBox[512+i*4+j])+", "); System.out.println();}
-System.out.println();
-for(i=0;i<64;i++) { for(j=0;j<4;j++) System.out.print("0x"+intToString(sBox[768+i*4+j])+", "); System.out.println();}
-System.out.println();
-System.out.println("User (odd, even) keys --> S-Box keys:");
-for(i=0;i<k64Cnt;i++) { System.out.println("0x"+intToString(k32o[i])+" 0x"+intToString(k32e[i])+" --> 0x"+intToString(sBoxKey[k64Cnt-1-i])); }
-System.out.println();
-System.out.println("Round keys:");
-for(i=0;i<ROUND_SUBKEYS + 2*ROUNDS;i+=2) { System.out.println("0x"+intToString(subKeys[i])+" 0x"+intToString(subKeys[i+1])); }
-System.out.println();
-
-}
-if (DEBUG) trace(OUT, "makeKey()");
- return sessionKey;
- }
-
- /**
- * Encrypt exactly one block of plaintext.
- *
- * @param in The plaintext.
- * @param inOffset Index of in from which to start considering data.
- * @param sessionKey The session key to use for encryption.
- * @return The ciphertext generated from a plaintext using the session key.
- */
- public static byte[]
- blockEncrypt (byte[] in, int inOffset, Object sessionKey) {
-if (DEBUG) trace(IN, "blockEncrypt("+in+", "+inOffset+", "+sessionKey+")");
- Object[] sk = (Object[]) sessionKey; // extract S-box and session key
- int[] sBox = (int[]) sk[0];
- int[] sKey = (int[]) sk[1];
-
-if (DEBUG && debuglevel > 6) System.out.println("PT="+toString(in, inOffset, BLOCK_SIZE));
-
- int x0 = (in[inOffset++] & 0xFF) |
- (in[inOffset++] & 0xFF) << 8 |
- (in[inOffset++] & 0xFF) << 16 |
- (in[inOffset++] & 0xFF) << 24;
- int x1 = (in[inOffset++] & 0xFF) |
- (in[inOffset++] & 0xFF) << 8 |
- (in[inOffset++] & 0xFF) << 16 |
- (in[inOffset++] & 0xFF) << 24;
- int x2 = (in[inOffset++] & 0xFF) |
- (in[inOffset++] & 0xFF) << 8 |
- (in[inOffset++] & 0xFF) << 16 |
- (in[inOffset++] & 0xFF) << 24;
- int x3 = (in[inOffset++] & 0xFF) |
- (in[inOffset++] & 0xFF) << 8 |
- (in[inOffset++] & 0xFF) << 16 |
- (in[inOffset++] & 0xFF) << 24;
-
- x0 ^= sKey[INPUT_WHITEN ];
- x1 ^= sKey[INPUT_WHITEN + 1];
- x2 ^= sKey[INPUT_WHITEN + 2];
- x3 ^= sKey[INPUT_WHITEN + 3];
-if (DEBUG && debuglevel > 6) System.out.println("PTw="+intToString(x0)+intToString(x1)+intToString(x2)+intToString(x3));
-
- int t0, t1;
- int k = ROUND_SUBKEYS;
- for (int R = 0; R < ROUNDS; R += 2) {
- t0 = Fe32( sBox, x0, 0 );
- t1 = Fe32( sBox, x1, 3 );
- x2 ^= t0 + t1 + sKey[k++];
- x2 = x2 >>> 1 | x2 << 31;
- x3 = x3 << 1 | x3 >>> 31;
- x3 ^= t0 + 2*t1 + sKey[k++];
-if (DEBUG && debuglevel > 6) System.out.println("CT"+(R)+"="+intToString(x0)+intToString(x1)+intToString(x2)+intToString(x3));
-
- t0 = Fe32( sBox, x2, 0 );
- t1 = Fe32( sBox, x3, 3 );
- x0 ^= t0 + t1 + sKey[k++];
- x0 = x0 >>> 1 | x0 << 31;
- x1 = x1 << 1 | x1 >>> 31;
- x1 ^= t0 + 2*t1 + sKey[k++];
-if (DEBUG && debuglevel > 6) System.out.println("CT"+(R+1)+"="+intToString(x0)+intToString(x1)+intToString(x2)+intToString(x3));
- }
- x2 ^= sKey[OUTPUT_WHITEN ];
- x3 ^= sKey[OUTPUT_WHITEN + 1];
- x0 ^= sKey[OUTPUT_WHITEN + 2];
- x1 ^= sKey[OUTPUT_WHITEN + 3];
-if (DEBUG && debuglevel > 6) System.out.println("CTw="+intToString(x0)+intToString(x1)+intToString(x2)+intToString(x3));
-
- byte[] result = new byte[] {
- (byte) x2, (byte)(x2 >>> 8), (byte)(x2 >>> 16), (byte)(x2 >>> 24),
- (byte) x3, (byte)(x3 >>> 8), (byte)(x3 >>> 16), (byte)(x3 >>> 24),
- (byte) x0, (byte)(x0 >>> 8), (byte)(x0 >>> 16), (byte)(x0 >>> 24),
- (byte) x1, (byte)(x1 >>> 8), (byte)(x1 >>> 16), (byte)(x1 >>> 24),
- };
-
-if (DEBUG && debuglevel > 6) {
-System.out.println("CT="+toString(result));
-System.out.println();
-}
-if (DEBUG) trace(OUT, "blockEncrypt()");
- return result;
- }
-
- /**
- * Decrypt exactly one block of ciphertext.
- *
- * @param in The ciphertext.
- * @param inOffset Index of in from which to start considering data.
- * @param sessionKey The session key to use for decryption.
- * @return The plaintext generated from a ciphertext using the session key.
- */
- public static byte[]
- blockDecrypt (byte[] in, int inOffset, Object sessionKey) {
-if (DEBUG) trace(IN, "blockDecrypt("+in+", "+inOffset+", "+sessionKey+")");
- Object[] sk = (Object[]) sessionKey; // extract S-box and session key
- int[] sBox = (int[]) sk[0];
- int[] sKey = (int[]) sk[1];
-
-if (DEBUG && debuglevel > 6) System.out.println("CT="+toString(in, inOffset, BLOCK_SIZE));
-
- int x2 = (in[inOffset++] & 0xFF) |
- (in[inOffset++] & 0xFF) << 8 |
- (in[inOffset++] & 0xFF) << 16 |
- (in[inOffset++] & 0xFF) << 24;
- int x3 = (in[inOffset++] & 0xFF) |
- (in[inOffset++] & 0xFF) << 8 |
- (in[inOffset++] & 0xFF) << 16 |
- (in[inOffset++] & 0xFF) << 24;
- int x0 = (in[inOffset++] & 0xFF) |
- (in[inOffset++] & 0xFF) << 8 |
- (in[inOffset++] & 0xFF) << 16 |
- (in[inOffset++] & 0xFF) << 24;
- int x1 = (in[inOffset++] & 0xFF) |
- (in[inOffset++] & 0xFF) << 8 |
- (in[inOffset++] & 0xFF) << 16 |
- (in[inOffset++] & 0xFF) << 24;
-
- x2 ^= sKey[OUTPUT_WHITEN ];
- x3 ^= sKey[OUTPUT_WHITEN + 1];
- x0 ^= sKey[OUTPUT_WHITEN + 2];
- x1 ^= sKey[OUTPUT_WHITEN + 3];
-if (DEBUG && debuglevel > 6) System.out.println("CTw="+intToString(x2)+intToString(x3)+intToString(x0)+intToString(x1));
-
- int k = ROUND_SUBKEYS + 2*ROUNDS - 1;
- int t0, t1;
- for (int R = 0; R < ROUNDS; R += 2) {
- t0 = Fe32( sBox, x2, 0 );
- t1 = Fe32( sBox, x3, 3 );
- x1 ^= t0 + 2*t1 + sKey[k--];
- x1 = x1 >>> 1 | x1 << 31;
- x0 = x0 << 1 | x0 >>> 31;
- x0 ^= t0 + t1 + sKey[k--];
-if (DEBUG && debuglevel > 6) System.out.println("PT"+(ROUNDS-R)+"="+intToString(x2)+intToString(x3)+intToString(x0)+intToString(x1));
-
- t0 = Fe32( sBox, x0, 0 );
- t1 = Fe32( sBox, x1, 3 );
- x3 ^= t0 + 2*t1 + sKey[k--];
- x3 = x3 >>> 1 | x3 << 31;
- x2 = x2 << 1 | x2 >>> 31;
- x2 ^= t0 + t1 + sKey[k--];
-if (DEBUG && debuglevel > 6) System.out.println("PT"+(ROUNDS-R-1)+"="+intToString(x2)+intToString(x3)+intToString(x0)+intToString(x1));
- }
- x0 ^= sKey[INPUT_WHITEN ];
- x1 ^= sKey[INPUT_WHITEN + 1];
- x2 ^= sKey[INPUT_WHITEN + 2];
- x3 ^= sKey[INPUT_WHITEN + 3];
-if (DEBUG && debuglevel > 6) System.out.println("PTw="+intToString(x2)+intToString(x3)+intToString(x0)+intToString(x1));
-
- byte[] result = new byte[] {
- (byte) x0, (byte)(x0 >>> 8), (byte)(x0 >>> 16), (byte)(x0 >>> 24),
- (byte) x1, (byte)(x1 >>> 8), (byte)(x1 >>> 16), (byte)(x1 >>> 24),
- (byte) x2, (byte)(x2 >>> 8), (byte)(x2 >>> 16), (byte)(x2 >>> 24),
- (byte) x3, (byte)(x3 >>> 8), (byte)(x3 >>> 16), (byte)(x3 >>> 24),
- };
-
-if (DEBUG && debuglevel > 6) {
-System.out.println("PT="+toString(result));
-System.out.println();
-}
-if (DEBUG) trace(OUT, "blockDecrypt()");
- return result;
- }
-
- /** A basic symmetric encryption/decryption test. */
- public static boolean self_test() { return self_test(BLOCK_SIZE); }
-
-
-// own methods
-//...........................................................................
-
- private static final int b0( int x ) { return x & 0xFF; }
- private static final int b1( int x ) { return (x >>> 8) & 0xFF; }
- private static final int b2( int x ) { return (x >>> 16) & 0xFF; }
- private static final int b3( int x ) { return (x >>> 24) & 0xFF; }
-
- /**
- * Use (12, 8) Reed-Solomon code over GF(256) to produce a key S-box
- * 32-bit entity from two key material 32-bit entities.
- *
- * @param k0 1st 32-bit entity.
- * @param k1 2nd 32-bit entity.
- * @return Remainder polynomial generated using RS code
- */
- private static final int RS_MDS_Encode( int k0, int k1) {
- int r = k1;
- for (int i = 0; i < 4; i++) // shift 1 byte at a time
- r = RS_rem( r );
- r ^= k0;
- for (int i = 0; i < 4; i++)
- r = RS_rem( r );
- return r;
- }
-
- /*
- * Reed-Solomon code parameters: (12, 8) reversible code:<p>
- * <pre>
- * g(x) = x**4 + (a + 1/a) x**3 + a x**2 + (a + 1/a) x + 1
- * </pre>
- * where a = primitive root of field generator 0x14D
- */
- private static final int RS_rem( int x ) {
- int b = (x >>> 24) & 0xFF;
- int g2 = ((b << 1) ^ ( (b & 0x80) != 0 ? RS_GF_FDBK : 0 )) & 0xFF;
- int g3 = (b >>> 1) ^ ( (b & 0x01) != 0 ? (RS_GF_FDBK >>> 1) : 0 ) ^ g2 ;
- int result = (x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b;
- return result;
- }
-
- private static final int F32( int k64Cnt, int x, int[] k32 ) {
- int b0 = b0(x);
- int b1 = b1(x);
- int b2 = b2(x);
- int b3 = b3(x);
- int k0 = k32[0];
- int k1 = k32[1];
- int k2 = k32[2];
- int k3 = k32[3];
-
- int result = 0;
- switch (k64Cnt & 3) {
- case 1:
- result =
- MDS[0][(P[P_01][b0] & 0xFF) ^ b0(k0)] ^
- MDS[1][(P[P_11][b1] & 0xFF) ^ b1(k0)] ^
- MDS[2][(P[P_21][b2] & 0xFF) ^ b2(k0)] ^
- MDS[3][(P[P_31][b3] & 0xFF) ^ b3(k0)];
- break;
- case 0: // same as 4
- b0 = (P[P_04][b0] & 0xFF) ^ b0(k3);
- b1 = (P[P_14][b1] & 0xFF) ^ b1(k3);
- b2 = (P[P_24][b2] & 0xFF) ^ b2(k3);
- b3 = (P[P_34][b3] & 0xFF) ^ b3(k3);
- case 3:
- b0 = (P[P_03][b0] & 0xFF) ^ b0(k2);
- b1 = (P[P_13][b1] & 0xFF) ^ b1(k2);
- b2 = (P[P_23][b2] & 0xFF) ^ b2(k2);
- b3 = (P[P_33][b3] & 0xFF) ^ b3(k2);
- case 2: // 128-bit keys (optimize for this case)
- result =
- MDS[0][(P[P_01][(P[P_02][b0] & 0xFF) ^ b0(k1)] & 0xFF) ^ b0(k0)] ^
- MDS[1][(P[P_11][(P[P_12][b1] & 0xFF) ^ b1(k1)] & 0xFF) ^ b1(k0)] ^
- MDS[2][(P[P_21][(P[P_22][b2] & 0xFF) ^ b2(k1)] & 0xFF) ^ b2(k0)] ^
- MDS[3][(P[P_31][(P[P_32][b3] & 0xFF) ^ b3(k1)] & 0xFF) ^ b3(k0)];
- break;
- }
- return result;
- }
-
- private static final int Fe32( int[] sBox, int x, int R ) {
- return sBox[ 2*_b(x, R ) ] ^
- sBox[ 2*_b(x, R+1) + 1] ^
- sBox[0x200 + 2*_b(x, R+2) ] ^
- sBox[0x200 + 2*_b(x, R+3) + 1];
- }
-
- private static final int _b( int x, int N) {
- int result = 0;
- switch (N%4) {
- case 0: result = b0(x); break;
- case 1: result = b1(x); break;
- case 2: result = b2(x); break;
- case 3: result = b3(x); break;
- }
- return result;
- }
-
- /** @return The length in bytes of the Algorithm input block. */
- public static int blockSize() { return BLOCK_SIZE; }
-
- /** A basic symmetric encryption/decryption test for a given key size. */
- private static boolean self_test (int keysize) {
-if (DEBUG) trace(IN, "self_test("+keysize+")");
- boolean ok = false;
- try {
- byte[] kb = new byte[keysize];
- byte[] pt = new byte[BLOCK_SIZE];
- int i;
-
- for (i = 0; i < keysize; i++)
- kb[i] = (byte) i;
- for (i = 0; i < BLOCK_SIZE; i++)
- pt[i] = (byte) i;
-
-if (DEBUG && debuglevel > 6) {
-System.out.println("==========");
-System.out.println();
-System.out.println("KEYSIZE="+(8*keysize));
-System.out.println("KEY="+toString(kb));
-System.out.println();
-}
- Object key = makeKey(kb);
-
-if (DEBUG && debuglevel > 6) {
-System.out.println("Intermediate Ciphertext Values (Encryption)");
-System.out.println();
-}
- byte[] ct = blockEncrypt(pt, 0, key);
-
-if (DEBUG && debuglevel > 6) {
-System.out.println("Intermediate Plaintext Values (Decryption)");
-System.out.println();
-}
- byte[] cpt = blockDecrypt(ct, 0, key);
-
- ok = areEqual(pt, cpt);
- if (!ok)
- throw new RuntimeException("Symmetric operation failed");
- } catch (Exception x) {
-if (DEBUG && debuglevel > 0) {
- debug("Exception encountered during self-test: " + x.getMessage());
- x.printStackTrace();
-}
- }
-if (DEBUG && debuglevel > 0) debug("Self-test OK? " + ok);
-if (DEBUG) trace(OUT, "self_test()");
- return ok;
- }
-
-
-// utility static methods (from cryptix.util.core ArrayUtil and Hex classes)
-//...........................................................................
-
- /** @return True iff the arrays have identical contents. */
- private static boolean areEqual (byte[] a, byte[] b) {
- int aLength = a.length;
- if (aLength != b.length)
- return false;
- for (int i = 0; i < aLength; i++)
- if (a[i] != b[i])
- return false;
- return true;
- }
-
- /**
- * Returns a string of 8 hexadecimal digits (most significant
- * digit first) corresponding to the integer <i>n</i>, which is
- * treated as unsigned.
- */
- private static String intToString (int n) {
- char[] buf = new char[8];
- for (int i = 7; i >= 0; i--) {
- buf[i] = HEX_DIGITS[n & 0x0F];
- n >>>= 4;
- }
- return new String(buf);
- }
-
- /**
- * Returns a string of hexadecimal digits from a byte array. Each
- * byte is converted to 2 hex symbols.
- */
- private static String toString (byte[] ba) {
- return toString(ba, 0, ba.length);
- }
- private static String toString (byte[] ba, int offset, int length) {
- char[] buf = new char[length * 2];
- for (int i = offset, j = 0, k; i < offset+length; ) {
- k = ba[i++];
- buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
- buf[j++] = HEX_DIGITS[ k & 0x0F];
- }
- return new String(buf);
- }
-
-
-// main(): use to generate the Intermediate Values KAT
-//...........................................................................
-
- public static void main (String[] args) {
- self_test(16);
- self_test(24);
- self_test(32);
- }
-} \ No newline at end of file
diff --git a/jobb/src/Twofish/Twofish_Properties.java b/jobb/src/Twofish/Twofish_Properties.java
deleted file mode 100644
index 2098c8f..0000000
--- a/jobb/src/Twofish/Twofish_Properties.java
+++ /dev/null
@@ -1,197 +0,0 @@
-// $Id: $
-//
-// $Log: $
-// Revision 1.0 1998/03/24 raif
-// + start of history.
-//
-// $Endlog$
-/*
- * Copyright (c) 1997, 1998 Systemics Ltd on behalf of
- * the Cryptix Development Team. All rights reserved.
- */
-package Twofish;
-
-import java.io.InputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.util.Enumeration;
-import java.util.Properties;
-
-/**
- * This class acts as a central repository for an algorithm specific
- * properties. It reads an (algorithm).properties file containing algorithm-
- * specific properties. When using the AES-Kit, this (algorithm).properties
- * file is located in the (algorithm).jar file produced by the "jarit" batch/
- * script command.<p>
- *
- * <b>Copyright</b> &copy; 1997, 1998
- * <a href="http://www.systemics.com/">Systemics Ltd</a> on behalf of the
- * <a href="http://www.systemics.com/docs/cryptix/">Cryptix Development Team</a>.
- * <br>All rights reserved.<p>
- *
- * <b>$Revision: $</b>
- * @author David Hopwood
- * @author Jill Baker
- * @author Raif S. Naffah
- */
-public class Twofish_Properties // implicit no-argument constructor
-{
-// Constants and variables with relevant static code
-//...........................................................................
-
- static final boolean GLOBAL_DEBUG = false;
-
- static final String ALGORITHM = "Twofish";
- static final double VERSION = 0.2;
- static final String FULL_NAME = ALGORITHM + " ver. " + VERSION;
- static final String NAME = "Twofish_Properties";
-
- static final Properties properties = new Properties();
-
- /** Default properties in case .properties file was not found. */
- private static final String[][] DEFAULT_PROPERTIES = {
- {"Trace.Twofish_Algorithm", "true"},
- {"Debug.Level.*", "1"},
- {"Debug.Level.Twofish_Algorithm", "9"},
- };
-
- static {
-if (GLOBAL_DEBUG) System.err.println(">>> " + NAME + ": Looking for " + ALGORITHM + " properties");
- String it = ALGORITHM + ".properties";
- InputStream is = Twofish_Properties.class.getResourceAsStream(it);
- boolean ok = is != null;
- if (ok)
- try {
- properties.load(is);
- is.close();
-if (GLOBAL_DEBUG) System.err.println(">>> " + NAME + ": Properties file loaded OK...");
- } catch (Exception x) {
- ok = false;
- }
- if (!ok) {
-if (GLOBAL_DEBUG) System.err.println(">>> " + NAME + ": WARNING: Unable to load \"" + it + "\" from CLASSPATH.");
-if (GLOBAL_DEBUG) System.err.println(">>> " + NAME + ": Will use default values instead...");
- int n = DEFAULT_PROPERTIES.length;
- for (int i = 0; i < n; i++)
- properties.put(
- DEFAULT_PROPERTIES[i][0], DEFAULT_PROPERTIES[i][1]);
-if (GLOBAL_DEBUG) System.err.println(">>> " + NAME + ": Default properties now set...");
- }
- }
-
-
-// Properties methods (excluding load and save, which are deliberately not
-// supported).
-//...........................................................................
-
- /** Get the value of a property for this algorithm. */
- public static String getProperty (String key) {
- return properties.getProperty(key);
- }
-
- /**
- * Get the value of a property for this algorithm, or return
- * <i>value</i> if the property was not set.
- */
- public static String getProperty (String key, String value) {
- return properties.getProperty(key, value);
- }
-
- /** List algorithm properties to the PrintStream <i>out</i>. */
- public static void list (PrintStream out) {
- list(new PrintWriter(out, true));
- }
-
- /** List algorithm properties to the PrintWriter <i>out</i>. */
- public static void list (PrintWriter out) {
- out.println("#");
- out.println("# ----- Begin "+ALGORITHM+" properties -----");
- out.println("#");
- String key, value;
- Enumeration en = properties.propertyNames();
- while (en.hasMoreElements()) {
- key = (String) en.nextElement();
- value = getProperty(key);
- out.println(key + " = " + value);
- }
- out.println("#");
- out.println("# ----- End "+ALGORITHM+" properties -----");
- }
-
-// public synchronized void load(InputStream in) throws IOException {}
-
- public static Enumeration propertyNames() {
- return properties.propertyNames();
- }
-
-// public void save (OutputStream os, String comment) {}
-
-
-// Developer support: Tracing and debugging enquiry methods (package-private)
-//...........................................................................
-
- /**
- * Return true if tracing is requested for a given class.<p>
- *
- * User indicates this by setting the tracing <code>boolean</code>
- * property for <i>label</i> in the <code>(algorithm).properties</code>
- * file. The property's key is "<code>Trace.<i>label</i></code>".<p>
- *
- * @param label The name of a class.
- * @return True iff a boolean true value is set for a property with
- * the key <code>Trace.<i>label</i></code>.
- */
- static boolean isTraceable (String label) {
- String s = getProperty("Trace." + label);
- if (s == null)
- return false;
- return new Boolean(s).booleanValue();
- }
-
- /**
- * Return the debug level for a given class.<p>
- *
- * User indicates this by setting the numeric property with key
- * "<code>Debug.Level.<i>label</i></code>".<p>
- *
- * If this property is not set, "<code>Debug.Level.*</code>" is looked up
- * next. If neither property is set, or if the first property found is
- * not a valid decimal integer, then this method returns 0.
- *
- * @param label The name of a class.
- * @return The required debugging level for the designated class.
- */
- static int getLevel (String label) {
- String s = getProperty("Debug.Level." + label);
- if (s == null) {
- s = getProperty("Debug.Level.*");
- if (s == null)
- return 0;
- }
- try {
- return Integer.parseInt(s);
- } catch (NumberFormatException e) {
- return 0;
- }
- }
-
- /**
- * Return the PrintWriter to which tracing and debugging output is to
- * be sent.<p>
- *
- * User indicates this by setting the property with key <code>Output</code>
- * to the literal <code>out</code> or <code>err</code>.<p>
- *
- * By default or if the set value is not allowed, <code>System.err</code>
- * will be used.
- */
- static PrintWriter getOutput() {
- PrintWriter pw;
- String name = getProperty("Output");
- if (name != null && name.equals("out"))
- pw = new PrintWriter(System.out, true);
- else
- pw = new PrintWriter(System.err, true);
- return pw;
- }
-} \ No newline at end of file
diff --git a/jobb/src/com/android/jobb/Base64.java b/jobb/src/com/android/jobb/Base64.java
deleted file mode 100644
index 7301763..0000000
--- a/jobb/src/com/android/jobb/Base64.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
-Copyright (c) 2000 The Legion Of The Bouncy Castle
-(http://www.bouncycastle.org)
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation
-the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-*/
-package com.android.jobb;
-
-public class Base64
-{
- private static final byte[] encodingTable =
- {
- (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G',
- (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N',
- (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U',
- (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z',
- (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g',
- (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n',
- (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u',
- (byte)'v',
- (byte)'w', (byte)'x', (byte)'y', (byte)'z',
- (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6',
- (byte)'7', (byte)'8', (byte)'9',
- (byte)'+', (byte)'/'
- };
-
- /**
- * encode the input data producing a base 64 encoded byte array.
- *
- * @return a byte array containing the base 64 encoded data.
- */
- public static byte[] encode(
- byte[] data)
- {
- byte[] bytes;
-
- int modulus = data.length % 3;
- if (modulus == 0)
- {
- bytes = new byte[4 * data.length / 3];
- }
- else
- {
- bytes = new byte[4 * ((data.length / 3) + 1)];
- }
-
- int dataLength = (data.length - modulus);
- int a1, a2, a3;
- for (int i = 0, j = 0; i < dataLength; i += 3, j += 4)
- {
- a1 = data[i] & 0xff;
- a2 = data[i + 1] & 0xff;
- a3 = data[i + 2] & 0xff;
-
- bytes[j] = encodingTable[(a1 >>> 2) & 0x3f];
- bytes[j + 1] = encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f];
- bytes[j + 2] = encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f];
- bytes[j + 3] = encodingTable[a3 & 0x3f];
- }
-
- /*
- * process the tail end.
- */
- int b1, b2, b3;
- int d1, d2;
-
- switch (modulus)
- {
- case 0: /* nothing left to do */
- break;
- case 1:
- d1 = data[data.length - 1] & 0xff;
- b1 = (d1 >>> 2) & 0x3f;
- b2 = (d1 << 4) & 0x3f;
-
- bytes[bytes.length - 4] = encodingTable[b1];
- bytes[bytes.length - 3] = encodingTable[b2];
- bytes[bytes.length - 2] = (byte)'=';
- bytes[bytes.length - 1] = (byte)'=';
- break;
- case 2:
- d1 = data[data.length - 2] & 0xff;
- d2 = data[data.length - 1] & 0xff;
-
- b1 = (d1 >>> 2) & 0x3f;
- b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f;
- b3 = (d2 << 2) & 0x3f;
-
- bytes[bytes.length - 4] = encodingTable[b1];
- bytes[bytes.length - 3] = encodingTable[b2];
- bytes[bytes.length - 2] = encodingTable[b3];
- bytes[bytes.length - 1] = (byte)'=';
- break;
- }
-
- return bytes;
- }
-
- /*
- * set up the decoding table.
- */
- private static final byte[] decodingTable;
-
- static
- {
- decodingTable = new byte[128];
-
- for (int i = 'A'; i <= 'Z'; i++)
- {
- decodingTable[i] = (byte)(i - 'A');
- }
-
- for (int i = 'a'; i <= 'z'; i++)
- {
- decodingTable[i] = (byte)(i - 'a' + 26);
- }
-
- for (int i = '0'; i <= '9'; i++)
- {
- decodingTable[i] = (byte)(i - '0' + 52);
- }
-
- decodingTable['+'] = 62;
- decodingTable['/'] = 63;
- }
-
- /**
- * decode the base 64 encoded input data.
- *
- * @return a byte array representing the decoded data.
- */
- public static byte[] decode(
- byte[] data)
- {
- byte[] bytes;
- byte b1, b2, b3, b4;
-
- if (data[data.length - 2] == '=')
- {
- bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
- }
- else if (data[data.length - 1] == '=')
- {
- bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
- }
- else
- {
- bytes = new byte[((data.length / 4) * 3)];
- }
-
- for (int i = 0, j = 0; i < data.length - 4; i += 4, j += 3)
- {
- b1 = decodingTable[data[i]];
- b2 = decodingTable[data[i + 1]];
- b3 = decodingTable[data[i + 2]];
- b4 = decodingTable[data[i + 3]];
-
- bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
- bytes[j + 2] = (byte)((b3 << 6) | b4);
- }
-
- if (data[data.length - 2] == '=')
- {
- b1 = decodingTable[data[data.length - 4]];
- b2 = decodingTable[data[data.length - 3]];
-
- bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
- }
- else if (data[data.length - 1] == '=')
- {
- b1 = decodingTable[data[data.length - 4]];
- b2 = decodingTable[data[data.length - 3]];
- b3 = decodingTable[data[data.length - 2]];
-
- bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
- }
- else
- {
- b1 = decodingTable[data[data.length - 4]];
- b2 = decodingTable[data[data.length - 3]];
- b3 = decodingTable[data[data.length - 2]];
- b4 = decodingTable[data[data.length - 1]];
-
- bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
- bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
- }
-
- return bytes;
- }
-
- /**
- * decode the base 64 encoded String data.
- *
- * @return a byte array representing the decoded data.
- */
- public static byte[] decode(
- String data)
- {
- byte[] bytes;
- byte b1, b2, b3, b4;
-
- if (data.charAt(data.length() - 2) == '=')
- {
- bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
- }
- else if (data.charAt(data.length() - 1) == '=')
- {
- bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
- }
- else
- {
- bytes = new byte[((data.length() / 4) * 3)];
- }
-
- for (int i = 0, j = 0; i < data.length() - 4; i += 4, j += 3)
- {
- b1 = decodingTable[data.charAt(i)];
- b2 = decodingTable[data.charAt(i + 1)];
- b3 = decodingTable[data.charAt(i + 2)];
- b4 = decodingTable[data.charAt(i + 3)];
-
- bytes[j] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[j + 1] = (byte)((b2 << 4) | (b3 >> 2));
- bytes[j + 2] = (byte)((b3 << 6) | b4);
- }
-
- if (data.charAt(data.length() - 2) == '=')
- {
- b1 = decodingTable[data.charAt(data.length() - 4)];
- b2 = decodingTable[data.charAt(data.length() - 3)];
-
- bytes[bytes.length - 1] = (byte)((b1 << 2) | (b2 >> 4));
- }
- else if (data.charAt(data.length() - 1) == '=')
- {
- b1 = decodingTable[data.charAt(data.length() - 4)];
- b2 = decodingTable[data.charAt(data.length() - 3)];
- b3 = decodingTable[data.charAt(data.length() - 2)];
-
- bytes[bytes.length - 2] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 1] = (byte)((b2 << 4) | (b3 >> 2));
- }
- else
- {
- b1 = decodingTable[data.charAt(data.length() - 4)];
- b2 = decodingTable[data.charAt(data.length() - 3)];
- b3 = decodingTable[data.charAt(data.length() - 2)];
- b4 = decodingTable[data.charAt(data.length() - 1)];
-
- bytes[bytes.length - 3] = (byte)((b1 << 2) | (b2 >> 4));
- bytes[bytes.length - 2] = (byte)((b2 << 4) | (b3 >> 2));
- bytes[bytes.length - 1] = (byte)((b3 << 6) | b4);
- }
-
- return bytes;
- }
-}
diff --git a/jobb/src/com/android/jobb/Encoder.java b/jobb/src/com/android/jobb/Encoder.java
deleted file mode 100644
index 15c01f4..0000000
--- a/jobb/src/com/android/jobb/Encoder.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2012 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.jobb;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * Encode and decode byte arrays (typically from binary to 7-bit ASCII
- * encodings).
- */
-public interface Encoder
-{
- int encode(byte[] data, int off, int length, OutputStream out) throws IOException;
-
- int decode(byte[] data, int off, int length, OutputStream out) throws IOException;
-
- int decode(String data, OutputStream out) throws IOException;
-}
diff --git a/jobb/src/com/android/jobb/EncryptedBlockFile.java b/jobb/src/com/android/jobb/EncryptedBlockFile.java
deleted file mode 100644
index deb75c4..0000000
--- a/jobb/src/com/android/jobb/EncryptedBlockFile.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright (C) 2012 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.jobb;
-
-import Twofish.Twofish_Algorithm;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.nio.channels.ReadableByteChannel;
-import java.nio.channels.WritableByteChannel;
-import java.security.InvalidKeyException;
-import java.util.Arrays;
-
-public class EncryptedBlockFile extends RandomAccessFile {
-
- private final class EncryptedBlockFileChannel extends FileChannel {
- final FileChannel mFC;
-
- protected EncryptedBlockFileChannel(FileChannel wrappedFC) {
- super();
- mFC = wrappedFC;
- }
-
- @Override
- public void force(boolean metaData) throws IOException {
- mFC.force(metaData);
- }
-
- @Override
- public FileLock lock(long position, long size, boolean shared) throws IOException {
- throw new RuntimeException("Lock not implemented");
- }
-
- @Override
- public MappedByteBuffer map(MapMode mode, long position, long size) throws IOException {
- throw new RuntimeException("MappedByteBuffer not implemented");
- }
-
- @Override
- public long position() throws IOException {
- return mFC.position();
- }
-
- @Override
- public FileChannel position(long newPosition) throws IOException {
- mFC.position(newPosition);
- return this;
- }
-
- @Override
- public int read(ByteBuffer dst) throws IOException {
- long position = position();
- int read = read(dst, position);
- if ( read >= 0 ) {
- position += read;
- position(position);
- }
- return read;
- }
-
- @Override
- public int read(ByteBuffer dest, long position) throws IOException {
- boolean isMisaligned;
- boolean isPartial;
- boolean doubleBuffer;
-
- int toRead = dest.remaining();
- int targetRead = toRead;
- int numSectors = toRead / BYTES_PER_SECTOR;
- if ((position + toRead) > length())
- throw new IOException(
- "reading past end of device");
-
- int alignmentOff;
- int firstSector = (int) position / BYTES_PER_SECTOR;
- if ( 0 != (alignmentOff = (int)(position % BYTES_PER_SECTOR ))) {
- toRead += alignmentOff;
- numSectors = toRead/BYTES_PER_SECTOR;
- isMisaligned = true;
- doubleBuffer = true;
- System.out.println("Alignment off reading from sector: " + firstSector);
- } else {
- isMisaligned = false;
- doubleBuffer = false;
- alignmentOff = 0;
- }
-
- int partialReadSize;
- if ( 0 != (partialReadSize = (int)(toRead % BYTES_PER_SECTOR ))) {
- isPartial = true;
- doubleBuffer = true;
- numSectors = toRead/BYTES_PER_SECTOR + 1;
- System.out.println("Partial read from sector: " + firstSector);
- } else {
- isPartial = false;
- }
-
- ByteBuffer tempDest;
- if ( doubleBuffer ) {
- tempDest = ByteBuffer.allocate(BYTES_PER_SECTOR);
- } else {
- tempDest = null;
- }
- int lastSector = firstSector + numSectors;
- if ( isMisaligned ) {
- // first sector is misaligned. Read and decrypt into temp dest
- readDecryptedSector(firstSector++, tempDest);
- tempDest.position(alignmentOff);
- // special case -- small sector;
- if ( firstSector == lastSector && isPartial ) {
- tempDest.limit(partialReadSize);
- }
- dest.put(tempDest);
- }
- for ( int i = firstSector; i < lastSector; i++ ) {
- if ( firstSector+1 == lastSector && isPartial ) {
- readDecryptedSector(i, tempDest);
- tempDest.rewind();
- tempDest.limit(partialReadSize);
- dest.put(tempDest);
- } else {
- readDecryptedSector(i, dest);
- }
- }
- return targetRead;
- }
-
- @Override
- public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
- throw new RuntimeException("Scattering Channel Read not implemented");
- }
-
- @Override
- public long size() throws IOException {
- return mFC.size();
- }
-
- @Override
- public long transferFrom(ReadableByteChannel src, long position, long count)
- throws IOException {
- throw new RuntimeException("File Channel transfer not implemented");
- }
-
- @Override
- public long transferTo(long position, long count, WritableByteChannel target)
- throws IOException {
- throw new RuntimeException("File Channel transfer to not implemented");
- }
-
- @Override
- public FileChannel truncate(long size) throws IOException {
- mFC.truncate(size);
- return this;
- }
-
- @Override
- public FileLock tryLock(long position, long size, boolean shared) throws IOException {
- return mFC.tryLock(position, size, shared);
- }
-
- @Override
- public int write(ByteBuffer src) throws IOException {
- long position = position();
- int write = write(src, position);
- if ( write >= 0 ) {
- position += write;
- position(position);
- }
- return write;
- }
-
- @Override
- public int write(ByteBuffer src, long position) throws IOException {
- int toWrite = src.remaining();
- int targetWrite = toWrite;
- int firstSector = (int) position / BYTES_PER_SECTOR;
- int numSectors = toWrite / BYTES_PER_SECTOR;
-
- boolean fixAccess = false;
- long readOffset;
- if ( 0 != position % BYTES_PER_SECTOR ) {
- long alignmentOff = (position % BYTES_PER_SECTOR);
- readOffset = position - alignmentOff;
- toWrite += alignmentOff;
- numSectors = toWrite/BYTES_PER_SECTOR;
- fixAccess = true;
- System.out.println("Alignment off writing to sector: " + firstSector);
- } else {
- readOffset = position;
- }
-
- if ( 0 != toWrite % BYTES_PER_SECTOR ) {
- numSectors = toWrite/BYTES_PER_SECTOR + 1;
- fixAccess = true;
- System.out.println("Partial Sector [" + toWrite % BYTES_PER_SECTOR + "] writing to sector: " + firstSector);
- }
-
- if ( fixAccess ) {
- ByteBuffer dest = ByteBuffer.allocate(numSectors * BYTES_PER_SECTOR);
- read(dest, readOffset);
- int bufOffset = (int)(position - readOffset);
- dest.position(bufOffset);
- dest.put(src);
-
- src = dest;
- src.rewind();
- }
-
- int lastSector = firstSector + numSectors;
-
- for ( int i = firstSector; i < lastSector; i++ ) {
- writeEncryptedSector(i, src);
- }
- return targetWrite;
- }
-
- @Override
- public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
- throw new RuntimeException("Scattering Channel Write not implemented");
- }
-
- @Override
- protected void implCloseChannel() throws IOException {
- // TODO Auto-generated method stub
-
- }
-
- /**
- * plain: the initial vector is the 32-bit little-endian version of the
- * sector number, padded with zeros if necessary.
- */
- private void cryptIVPlainGen(int sector, byte[] out) {
- Arrays.fill(out, (byte)0);
- out[0] = (byte)(sector & 0xff);
- out[1] = (byte)(sector >> 8 & 0xff);
- out[2] = (byte)(sector >> 16 & 0xff);
- out[3] = (byte)(sector >>> 24);
- }
-
- private void readDecryptedSector(int sector, ByteBuffer dest) throws IOException {
- ByteBuffer temp = ByteBuffer.allocate(BYTES_PER_SECTOR);
- int toRead = BYTES_PER_SECTOR;
- int devOffset = BYTES_PER_SECTOR*sector;
-
- // number of chained twofish blocks
- int blockSize = Twofish_Algorithm.blockSize();
- byte[] bufLast = new byte[blockSize];
- int numBlocks = toRead / blockSize;
-
- // read unencrypted sector
- while (toRead > 0) {
- final int read = mFC.read(temp, devOffset);
- if (read < 0)
- throw new IOException();
- toRead -= read;
- devOffset += read;
- }
- temp.rewind();
-
- // set initialization vector
- cryptIVPlainGen(sector, bufLast);
-
- byte[] buf = new byte[blockSize];
- for (int i = 0; i < numBlocks; i++) {
- temp.get(buf);
- // decrypt with chained blocks --- xor with the previous encrypted block
- byte[] decryptBuf = Twofish_Algorithm.blockDecrypt(buf, 0, mKey);
- for (int j = 0; j < blockSize; j++) {
- decryptBuf[j] ^= bufLast[j];
- }
- System.arraycopy(buf, 0, bufLast, 0, blockSize);
- dest.put(decryptBuf);
- }
- }
-
- private void writeEncryptedSector(int sector, ByteBuffer src) throws IOException {
- byte[] sectorBuf = new byte[BYTES_PER_SECTOR];
- int toRead = BYTES_PER_SECTOR;
- int devOffset = BYTES_PER_SECTOR*sector;
-
- // number of chained twofish blocks
- int blockSize = Twofish_Algorithm.blockSize();
- byte[] bufLast = new byte[blockSize];
- int numBlocks = toRead / blockSize;
-
- // fetch unencrypted sector
- src.get(sectorBuf);
-
- // set initialization vector
- cryptIVPlainGen(sector, bufLast);
-
- int pos = 0;
- byte[] buf = new byte[blockSize];
- for (int i = 0; i < numBlocks; i++) {
- System.arraycopy(sectorBuf, pos, buf, 0, blockSize);
- // encrypt with chained blocks --- xor with the previous encrypted block
- for (int j = 0; j < blockSize; j++) {
- buf[j] ^= bufLast[j];
- }
- byte[] encryptBuf = Twofish_Algorithm.blockEncrypt(buf, 0, mKey);
- bufLast = encryptBuf;
- int toWrite = blockSize;
- ByteBuffer encryptBuffer = ByteBuffer.wrap(encryptBuf);
- while (toWrite > 0) {
- final int written = mFC.write(encryptBuffer, devOffset);
- if (written < 0)
- throw new IOException();
- toWrite -= written;
- devOffset += written;
- }
- pos += blockSize;
- }
- }
-
-
- }
-
- public EncryptedBlockFileChannel getEncryptedFileChannel() {
- return mEBFC;
- }
-
- /**
- * This will clear the file as well as set the length. It would be easy enough
- * to preserve the blocks, but that is not the intention of this class.
- */
- @Override
- public void setLength(long newLength) throws IOException {
- int numsectors = (int)newLength/BYTES_PER_SECTOR;
- if ( newLength % BYTES_PER_SECTOR != 0 ) {
- throw new IOException("Invalid file size!");
- }
- super.setLength(newLength);
- // write encrypted empty sectors into the block storage
- byte[] byteBuf = new byte[BYTES_PER_SECTOR];
- ByteBuffer buf = ByteBuffer.wrap(byteBuf);
- for ( int i = 0; i < numsectors; i++ ) {
- buf.rewind();
- mEBFC.write(buf);
- }
- }
-
- /**
- * The number of bytes per sector for all {@code FileDisk} instances.
- */
- public final static int BYTES_PER_SECTOR = 512;
-
- private final Object mKey;
- private final EncryptedBlockFileChannel mEBFC;
-
- public EncryptedBlockFile(byte[] key, File file, String mode) throws FileNotFoundException,
- InvalidKeyException {
- super(file, mode);
- mEBFC = new EncryptedBlockFileChannel(getChannel());
- if (!file.exists())
- throw new FileNotFoundException();
-
- mKey = Twofish_Algorithm.makeKey(key);
- }
-}
diff --git a/jobb/src/com/android/jobb/Main.java b/jobb/src/com/android/jobb/Main.java
deleted file mode 100644
index a4ea1fc..0000000
--- a/jobb/src/com/android/jobb/Main.java
+++ /dev/null
@@ -1,607 +0,0 @@
-/*
- * Copyright (C) 2012 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.jobb;
-
-import de.waldheinz.fs.BlockDevice;
-import de.waldheinz.fs.FsDirectory;
-import de.waldheinz.fs.FsDirectoryEntry;
-import de.waldheinz.fs.FsFile;
-import de.waldheinz.fs.fat.BootSector;
-import de.waldheinz.fs.fat.Fat;
-import de.waldheinz.fs.fat.FatFile;
-import de.waldheinz.fs.fat.FatFileSystem;
-import de.waldheinz.fs.fat.FatLfnDirectory;
-import de.waldheinz.fs.fat.FatLfnDirectoryEntry;
-import de.waldheinz.fs.fat.FatType;
-import de.waldheinz.fs.fat.FatUtils;
-import de.waldheinz.fs.fat.SuperFloppyFormatter;
-import de.waldheinz.fs.util.FileDisk;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.channels.ReadableByteChannel;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Iterator;
-import java.util.Stack;
-
-public class Main {
-
- private static final int BLOCK_SIZE = 512; // MUST BE 512
-
- public static void printArgs() {
- System.out.println("Jobb -- Create OBB files for use on Android");
- System.out.println();
- System.out.println(" -d <directory> Use <directory> as input/output for OBB files");
- System.out.println(" -k <key> Use <key> as password to encrypt/decrypt OBB file");
- System.out.println(" -o <filename> Write OBB file out to <filename>");
- System.out.println(" -v Verbose mode");
- System.out.println(" -h Help; this usage screen");
- System.out.println(" -pn <package> Package name for OBB file");
- System.out.println(" -pv <version> Package version for OBB file");
- System.out.println(" -ov Set overlay flag");
- System.out.println(" -dump <file> Parse and dump OBB file");
- System.out.println(" -about Notices about this tool");
- System.out.println();
- System.out.println("Example: Dump the contents of the encrypted OBB file to the directory");
- System.out.println(" jobb -dump myfile.obb -d ./mydirectory -k mypassword");
- System.out.println();
- System.out.println("Example: Create an encrypted OBB file by recursing the directory path");
- System.out.println(" jobb -pn package.name -pv 1 -d ./mydirectory -k mypassword");
- }
-
- static String sDirectory;
- static File sDirectoryFile;
- static boolean sHasOutputDirectory;
- static String sKey;
- static String sOutputFile;
- static boolean sVerboseMode;
- static String sPackageName;
- static int sPackageVersion = -1;
- static byte[] sSalt;
- static boolean sOverlay;
- static int sFlags;
- static String sInputFile;
- static byte[] sFishKey;
-
- private interface FileProcessor {
- void processFile(File f);
-
- void processDirectory(File f);
-
- /**
- * @param dir
- */
- void endDirectory(File dir);
- }
-
- static ByteBuffer sTempBuf = ByteBuffer.allocate(1024*1024);
-
- static public void dumpDirectory(FsDirectory dir, int tabStop, File curDirectory) throws IOException {
- Iterator<FsDirectoryEntry> i = dir.iterator();
- while (i.hasNext()) {
- final FsDirectoryEntry e = i.next();
- if (e.isDirectory()) {
- for (int idx = 0; idx < tabStop; idx++)
- System.out.print(' ');
- if (e.getName().equals(".") || e.getName().equals(".."))
- continue;
- for (int idx = 0; idx < tabStop; idx++)
- System.out.print(" ");
- System.out.println("[" + e + "]");
- dumpDirectory(e.getDirectory(), tabStop + 1, new File(curDirectory, e.getName()));
- } else {
- for ( int idx = 0; idx < tabStop; idx++ ) System.out.print(" ");
- System.out.println( e );
- if ( sHasOutputDirectory ) {
- if ( !curDirectory.exists() ) {
- if ( false == curDirectory.mkdirs() ) {
- throw new IOException("Unable to create directory: " + curDirectory);
- }
- }
- File curFile = new File(curDirectory, e.getName());
- if ( curFile.exists() ) {
- throw new IOException("File exists: " + curFile);
- } else {
- FsFile f = e.getFile();
- FileOutputStream fos = null;
- try {
- fos = new FileOutputStream(curFile);
- FileChannel outputChannel = fos.getChannel();
- int capacity = sTempBuf.capacity();
- long length = f.getLength();
- for ( long pos = 0; pos < length; pos++ ) {
- int readLength = (int)(length-pos > capacity ? capacity : length-pos);
- sTempBuf.rewind();
- sTempBuf.limit(readLength);
- f.read(pos, sTempBuf);
- sTempBuf.rewind();
- while(sTempBuf.remaining() > 0)
- outputChannel.write(sTempBuf);
- pos += readLength;
- }
- } finally {
- if ( null != fos ) fos.close();
- }
- }
- }
- }
- }
- }
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- boolean displayHelp = false;
- boolean isEncrypted = false;
- try {
- for (int i = 0; i < args.length; i++) {
- String curArg = args[i];
- if (curArg.equals("-d")) {
- sDirectory = args[++i];
- sDirectoryFile = new File(sDirectory);
- sHasOutputDirectory = true;
- } else if (curArg.equals("-k")) {
- isEncrypted = true;
- sKey = args[++i];
- } else if (curArg.equals("-o")) {
- sOutputFile = args[++i];
- } else if (curArg.equals("-h")) {
- displayHelp = true;
- } else if (curArg.equals("-v")) {
- sVerboseMode = true;
- } else if (curArg.equals("-pn")) {
- sPackageName = args[++i];
- } else if (curArg.equals("-pv")) {
- sPackageVersion = Integer.parseInt(args[++i]);
- } else if (curArg.equals("-ov")) {
- sFlags |= ObbFile.OBB_OVERLAY;
- } else if (curArg.equals("-dump")) {
- sInputFile = args[++i];
- } else if (curArg.equals("-salt")) {
- // special case --- use same salt
- String saltString = args[++i];
- BigInteger bi = new BigInteger(saltString, 16);
- sSalt = bi.toByteArray();
- if ( sSalt.length != PBKDF.SALT_LEN ) {
- displayHelp = true;
- }
- } else if (curArg.equals("-about")) {
- System.out.println("-------------------------------------------------------------------------------");
- System.out.println("Portions of this code:");
- System.out.println("-------------------------------------------------------------------------------");
- System.out.println("Copyright (c) 2000 The Legion Of The Bouncy Castle");
- System.out.println("(http://www.bouncycastle.org)");
- System.out.println();
- System.out.println("Permission is hereby granted, free of charge, to any person obtaining");
- System.out.println("a copy of this software and associated documentation files (the \"Software\"");
- System.out.println("to deal in the Software without restriction, including without limitation");
- System.out.println("the rights to use, copy, modify, merge, publish, distribute, sublicense");
- System.out.println("and/or sell copies of the Software, and to permit persons to whom the Software");
- System.out.println("is furnished to do so, subject to the following conditions:");
- System.out.println();
- System.out.println("The above copyright notice and this permission notice shall be included in all");
- System.out.println("copies or substantial portions of the Software.");
- System.out.println("-------------------------------------------------------------------------------");
- System.out.println("Twofish is uncopyrighted and license-free, and was created and analyzed by:");
- System.out.println("Bruce Schneier - John Kelsey - Doug Whiting");
- System.out.println("David Wagner - Chris Hall - Niels Ferguson");
- System.out.println("-------------------------------------------------------------------------------");
- System.out.println("Cryptix General License");
- System.out.println();
- System.out.println("Copyright (c) 1995-2005 The Cryptix Foundation Limited.");
- System.out.println("All rights reserved.");
- System.out.println("");
- System.out.println("Redistribution and use in source and binary forms, with or without");
- System.out.println("modification, are permitted provided that the following conditions are");
- System.out.println("met:");
- System.out.println();
- System.out.println(" 1. Redistributions of source code must retain the copyright notice,");
- System.out.println(" this list of conditions and the following disclaimer.");
- System.out.println(" 2. Redistributions in binary form must reproduce the above copyright");
- System.out.println(" notice, this list of conditions and the following disclaimer in");
- System.out.println(" the documentation and/or other materials provided with the");
- System.out.println(" distribution.");
- System.out.println("-------------------------------------------------------------------------------");
- return;
- }
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- displayHelp = true;
- }
- if (null != sInputFile) {
- ObbFile obbFile = new ObbFile();
- obbFile.readFrom(sInputFile);
- System.out.print("Package Name: ");
- System.out.println(obbFile.mPackageName);
- System.out.print("Package Version: ");
- System.out.println(obbFile.mPackageVersion);
- if (0 != (obbFile.mFlags & ObbFile.OBB_SALTED)) {
- System.out.print("SALT: ");
- BigInteger bi = new BigInteger(obbFile.mSalt);
- System.out.println(bi.toString(16));
- System.out.println();
- if ( null == sKey ) {
- System.out.println("Encrypted file. Please add password.");
- return;
- }
- try {
- sFishKey = PBKDF.getKey(sKey,obbFile.mSalt);
- bi = new BigInteger(sFishKey);
- System.out.println(bi.toString(16));
- } catch (InvalidKeyException e) {
- e.printStackTrace();
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- isEncrypted = true;
- } else {
- isEncrypted = false;
- }
- File obbInputFile = new File(sInputFile);
-
- BlockDevice fd;
- try {
- if ( isEncrypted ) {
- EncryptedBlockFile ebf = new EncryptedBlockFile(sFishKey, obbInputFile, "r");
- fd = new FileDisk(ebf, ebf.getEncryptedFileChannel(), true);
- } else {
- fd = new FileDisk(obbInputFile, true);
- }
- final FatFileSystem fatFs = FatFileSystem.read(fd, true);
- final BootSector bs = fatFs.getBootSector();
- final FsDirectory rootDir = fatFs.getRoot();
- if (sVerboseMode) {
- System.out.print("Filesystem Type: ");
- FatType ft = bs.getFatType();
- if (ft == FatType.FAT32) {
- System.out.println("FAT32");
- } else if (ft == FatType.FAT16) {
- System.out.println("FAT16");
- } else if (ft == FatType.FAT12) {
- System.out.println("FAT12");
- } else {
- System.out.println("Unknown");
- }
- System.out.print(" OEM Name: ");
- System.out.println(bs.getOemName());
- System.out.print(" Bytes Per Sector: ");
- System.out.println(bs.getBytesPerSector());
- System.out.print("Sectors per cluster: ");
- System.out.println(bs.getSectorsPerCluster());
- System.out.print(" Reserved Sectors: ");
- System.out.println(bs.getNrReservedSectors());
- System.out.print(" Fats: ");
- System.out.println(bs.getNrFats());
- System.out.print(" Root Dir Entries: ");
- System.out.println(bs.getRootDirEntryCount());
- System.out.print(" Medium Descriptor: ");
- System.out.println(bs.getMediumDescriptor());
- System.out.print(" Sectors: ");
- System.out.println(bs.getSectorCount());
- System.out.print(" Sectors Per Fat: ");
- System.out.println(bs.getSectorsPerFat());
- System.out.print(" Heads: ");
- System.out.println(bs.getNrHeads());
- System.out.print(" Hidden Sectors: ");
- System.out.println(bs.getNrHiddenSectors());
- System.out.print(" Fat Offset: ");
- System.out.println(FatUtils.getFatOffset(bs, 0));
- System.out.println(" RootDir: " + rootDir);
- }
- dumpDirectory(rootDir, 0, sDirectoryFile);
- } catch (IOException e) {
- e.printStackTrace();
- } catch (InvalidKeyException e) {
- e.printStackTrace();
- }
- return;
- }
- boolean printArgs;
- if (displayHelp) {
- printArgs = true;
- } else if ( null == sDirectory ) {
- printArgs = true;
- System.out.println("A directory to be recursed through [-d directory] is required when creating an OBB filesystem.");
- } else if ( null == sOutputFile ) {
- printArgs = true;
- System.out.println("An output filename [-o outputfile] is required when creating an OBB filesystem.");
- } else if ( null == sPackageName ) {
- printArgs = true;
- System.out.println("A package name [-pn package] is required when creating an OBB filesystem.");
- } else if ( -1 == sPackageVersion ) {
- printArgs = true;
- System.out.println("A package version [-pv package] is required when creating an OBB filesystem.");
- } else {
- printArgs = false;
- }
- if (printArgs) {
- printArgs();
- } else {
- if (null != sKey) {
- if ( null == sSalt ) {
- sSalt = PBKDF.getRandomSalt();
- }
- try {
- sFishKey = PBKDF.getKey(sKey, sSalt);
- } catch (Exception e) {
- e.printStackTrace();
- return;
- }
- sFlags |= ObbFile.OBB_SALTED;
- if (sVerboseMode) {
- System.out.println("Crypto: ");
- System.out.print("SALT: ");
- for (byte b : sSalt) {
- int out = b & 0xFF;
- System.out.print(Integer.toHexString(out));
- System.out.print(" ");
- }
- System.out.print("\t");
- System.out.print("KEY: ");
- for (byte b : sFishKey) {
- int out = b & 0xFF;
- System.out.print(Integer.toHexString(out));
- System.out.print(" ");
- }
- System.out.println();
- }
- }
- if (sVerboseMode) {
- System.out.println("Scanning directory: " + sDirectory);
- }
- final File f = new File(sDirectory);
-
- long fileSize = getTotalFileSize(f, 0);
- fileSize = getTotalFileSize(f, BLOCK_SIZE*SuperFloppyFormatter.clusterSizeFromSize(fileSize, BLOCK_SIZE));
- if (sVerboseMode) {
- System.out.println("Total Files: " + fileSize);
- }
- long numSectors = fileSize / BLOCK_SIZE;
- long clusterSize = SuperFloppyFormatter.clusterSizeFromSize(fileSize, BLOCK_SIZE);
- long fatOverhead = 2*numSectors/clusterSize*4;
- fatOverhead += clusterSize*BLOCK_SIZE - fatOverhead % (clusterSize*BLOCK_SIZE);
- fatOverhead += 2*clusterSize; //start at second cluster
- if (sVerboseMode) {
- System.out.println("FAT Overhead: " + fatOverhead);
- }
- long clusterSizeInBytes = clusterSize * BLOCK_SIZE;
- long filesystemSize = (( numSectors ) * BLOCK_SIZE + fatOverhead + clusterSizeInBytes -1 ) / clusterSizeInBytes * clusterSizeInBytes;
- if (sVerboseMode) {
- System.out.println("Filesystem Size: " + filesystemSize);
- }
- File fsFile = new File(sOutputFile);
- if (fsFile.exists())
- fsFile.delete();
- try {
- BlockDevice fd;
- if ( isEncrypted ) {
- try {
- EncryptedBlockFile ebf = new EncryptedBlockFile(sFishKey, fsFile, "rw");
- ebf.setLength(filesystemSize);
- fd = new FileDisk(ebf, ebf.getEncryptedFileChannel(), false);
- } catch (InvalidKeyException e) {
- e.printStackTrace();
- return;
- }
- } else {
- fd = FileDisk.create(fsFile, filesystemSize);
- }
- // fat type set based on device size by SuperFloppyFormatter
- final FatFileSystem fs = SuperFloppyFormatter.get(fd).format();
- final String rootPath = f.getAbsolutePath();
- // add the files into the filesystem
- processAllFiles(f, new FileProcessor() {
- Stack<FatLfnDirectory> mCurDir = new Stack<FatLfnDirectory>();
-
- @Override
- public void processDirectory(File curFile) {
- String directory = curFile.getAbsolutePath().substring(rootPath.length());
- if (sVerboseMode) {
- System.out.println("Processing Directory: " + directory + " at cluster " + fs.getFat().getLastFreeCluster());
- }
- FatLfnDirectory curDir = fs.getRoot();
- if (directory.length() > 0) {
- File tempFile = new File(directory);
- Stack<String> pathStack = new Stack<String>();
- do {
- pathStack.push(tempFile.getName());
- } while (null != (tempFile = tempFile.getParentFile()));
- while (!pathStack.empty()) {
- String name = pathStack.pop();
- if (0 == name.length())
- continue;
- FatLfnDirectoryEntry entry = curDir.getEntry(name);
- if (null != entry) {
- if (!entry.isDirectory()) {
- throw new RuntimeException(
- "File path not FAT compatible - naming conflict!");
- }
- } else {
- try {
- if (sVerboseMode) {
- System.out.println("Adding Directory: " + name);
- }
- entry = curDir.addDirectory(name);
- } catch (IOException e) {
- e.printStackTrace();
- throw new RuntimeException("Error adding directory!");
- }
- }
- try {
- curDir = entry.getDirectory();
- } catch (IOException e) {
- e.printStackTrace();
- throw new RuntimeException("Error getting directory");
- }
- }
- }
- mCurDir.push(curDir);
- }
-
- @Override
- public void processFile(File curFile) {
- FatLfnDirectoryEntry entry;
- FatLfnDirectory curDir = mCurDir.peek();
- try {
- if (sVerboseMode) {
- System.out.println("Adding file: "
- + curFile.getAbsolutePath().substring(rootPath.length())
- + " with length " + curFile.length() + " at cluster " + fs.getFat().getLastFreeCluster());
- }
- entry = curDir.addFile(curFile.getName());
- } catch (IOException e) {
- e.printStackTrace();
- throw new RuntimeException("Error adding file with name: "
- + curFile.getName());
- }
- ReadableByteChannel channel = null;
- try {
- FatFile f = entry.getFile();
- channel = new FileInputStream(curFile).getChannel();
- ByteBuffer buf = ByteBuffer.allocateDirect(1024 * 512);
- int numRead = 0;
- long offset = 0;
- while (true) {
- buf.clear();
- numRead = channel.read(buf);
- if (numRead < 0)
- break;
- buf.rewind();
- buf.limit(numRead);
- f.write(offset, buf);
- offset += numRead;
- }
- f.flush();
- } catch (IOException e) {
- e.printStackTrace();
- throw new RuntimeException("Error getting/writing file with name: "
- + curFile.getName());
- } finally {
- if (null != channel)
- try {
- channel.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- @Override
- public void endDirectory(File dir) {
- mCurDir.pop();
- }
-
- });
- fs.flush();
- fs.close();
- Fat fat = fs.getFat();
- ObbFile ob = new ObbFile();
- ob.setPackageName(sPackageName);
- ob.setPackageVersion(sPackageVersion);
- ob.setFlags(sFlags);
- if (null != sSalt) {
- ob.setSalt(sSalt);
- }
- ob.writeTo(fsFile);
- if (sVerboseMode) {
- System.out.println("Success!");
- System.out.println("" + fs.getTotalSpace() + " bytes total");
- System.out.println("" + fs.getFreeSpace() + " bytes free");
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- public static long getTotalFileSize(File dir, final int clusterSize) {
- final long[] mSize = new long[3];
- final boolean calculateSlop = clusterSize > 0;
- processAllFiles(dir, new FileProcessor() {
- Stack<int[]> mDirLen = new Stack<int[]>();
-
- @Override
- public void processFile(File f) {
- if (sVerboseMode) {
- System.out.println("Adding size for file: " + f.getAbsolutePath());
- }
- long length = f.length();
- if ( calculateSlop && length > 0 ) {
- int[] dirLen = mDirLen.peek();
- long realLength = ((clusterSize-1)+length) / clusterSize*clusterSize;
- long slop = realLength-length;
- length += slop;
- mSize[0] += length;
- mSize[1] += slop;
- dirLen[0] += f.getName().length()/13+3;
- } else {
- mSize[0] += length;
- }
- }
-
- @Override
- public void processDirectory(File f) {
- if ( calculateSlop ) {
- int[] dirLen = new int[1];
- dirLen[0] += f.getName().length()/13+4;
- mDirLen.push(dirLen);
- }
- }
-
- @Override
- public void endDirectory(File dir) {
- if ( calculateSlop ) {
- int[] dirLen = mDirLen.pop();
- long lastDirLen = dirLen[0] * 32;
- if ( lastDirLen != 0 ) {
- long realLength = ((clusterSize-1)+lastDirLen) / clusterSize*clusterSize;
- long slop = realLength-lastDirLen;
- mSize[0] += lastDirLen + slop;
- mSize[1] += slop;
- mSize[2] += lastDirLen;
- }
- }
- }
- });
- System.out.println("Slop: " + mSize[1] + " Directory Overhead: " + mSize[2] );
- return mSize[0];
- }
-
- // Process all files and directories under dir
- public static void processAllFiles(File dir, FileProcessor fp) {
- if (dir.isDirectory()) {
- fp.processDirectory(dir);
- String[] children = dir.list();
- for (int i = 0; i < children.length; i++) {
- processAllFiles(new File(dir, children[i]), fp);
- }
- fp.endDirectory(dir);
- } else {
- fp.processFile(dir);
- }
- }
-}
diff --git a/jobb/src/com/android/jobb/ObbFile.java b/jobb/src/com/android/jobb/ObbFile.java
deleted file mode 100644
index e23785d..0000000
--- a/jobb/src/com/android/jobb/ObbFile.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2012 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.jobb;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.FileChannel;
-
-public class ObbFile {
- public static final int OBB_OVERLAY = (1 << 0);
- public static final int OBB_SALTED = (1 << 1);
-
- static final int kFooterTagSize = 8; /* last two 32-bit integers */
-
- static final int kFooterMinSize = 33; /* 32-bit signature version (4 bytes)
- * 32-bit package version (4 bytes)
- * 32-bit flags (4 bytes)
- * 64-bit salt (8 bytes)
- * 32-bit package name size (4 bytes)
- * >=1-character package name (1 byte)
- * 32-bit footer size (4 bytes)
- * 32-bit footer marker (4 bytes)
- */
-
- static final int kMaxBufSize = 32768; /* Maximum file read buffer */
-
- static final long kSignature = 0x01059983; /* ObbFile signature */
-
- static final int kSigVersion = 1; /* We only know about signature version 1 */
-
- /* offsets in version 1 of the header */
- static final int kPackageVersionOffset = 4;
- static final int kFlagsOffset = 8;
- static final int kSaltOffset = 12;
- static final int kPackageNameLenOffset = 20;
- static final int kPackageNameOffset = 24;
-
- long mPackageVersion = -1, mFlags;
- String mPackageName;
- byte[] mSalt = new byte[8];
-
- public ObbFile() {}
-
- public boolean readFrom(String filename)
- {
- File obbFile = new File(filename);
- return readFrom(obbFile);
- }
-
- public boolean readFrom(File obbFile)
- {
- return parseObbFile(obbFile);
- }
-
- static public long get4LE(ByteBuffer buf) {
- buf.order(ByteOrder.LITTLE_ENDIAN);
- return (buf.getInt() & 0xFFFFFFFFL);
- }
-
- public void setPackageName(String packageName) {
- mPackageName = packageName;
- }
-
- public void setSalt(byte[] salt) {
- if ( salt.length != mSalt.length ) {
- throw new RuntimeException("salt must be " + mSalt.length + " characters in length");
- }
- System.arraycopy(salt, 0, mSalt, 0, mSalt.length);
- }
-
- public void setPackageVersion(long packageVersion) {
- mPackageVersion = packageVersion;
- }
-
- public void setFlags(long flags) {
- mFlags = flags;
- }
-
- public boolean parseObbFile(File obbFile)
- {
- try {
- long fileLength = obbFile.length();
-
- if (fileLength < kFooterMinSize) {
- throw new RuntimeException("file is only " + fileLength + " (less than " + kFooterMinSize + " minimum)");
- }
-
- RandomAccessFile raf = new RandomAccessFile(obbFile, "r");
- raf.seek(fileLength - kFooterTagSize);
- byte[] footer = new byte[kFooterTagSize];
- raf.readFully(footer);
- ByteBuffer footBuf = ByteBuffer.wrap(footer);
- footBuf.position(4);
- long fileSig = get4LE(footBuf);
- if (fileSig != kSignature) {
- throw new RuntimeException("footer didn't match magic string (expected 0x" + Long.toHexString(kSignature) + ";got 0x" +
- Long.toHexString(fileSig)+ ")");
- }
-
- footBuf.rewind();
- long footerSize = get4LE(footBuf);
- if (footerSize > fileLength - kFooterTagSize
- || footerSize > kMaxBufSize) {
- throw new RuntimeException("claimed footer size is too large (0x" + Long.toHexString(footerSize) + "; file size is 0x" +
- Long.toHexString(fileLength)+ ")");
- }
-
- if (footerSize < (kFooterMinSize - kFooterTagSize)) {
- throw new RuntimeException("claimed footer size is too small (0x" + Long.toHexString(footerSize) + "; minimum size is 0x" +
- Long.toHexString(kFooterMinSize - kFooterTagSize));
- }
-
- long fileOffset = fileLength - footerSize - kFooterTagSize;
- raf.seek(fileOffset);
-
- footer = new byte[(int)footerSize];
- raf.readFully(footer);
- footBuf = ByteBuffer.wrap(footer);
-
- long sigVersion = get4LE(footBuf);
- if (sigVersion != kSigVersion) {
- throw new RuntimeException("Unsupported ObbFile version " + sigVersion );
- }
-
- footBuf.position(kPackageVersionOffset);
- mPackageVersion = get4LE(footBuf);
- footBuf.position(kFlagsOffset);
- mFlags = get4LE(footBuf);
-
- footBuf.position(kSaltOffset);
- footBuf.get(mSalt);
- footBuf.position(kPackageNameLenOffset);
- long packageNameLen = get4LE(footBuf);
- if (packageNameLen == 0
- || packageNameLen > (footerSize - kPackageNameOffset)) {
- throw new RuntimeException("bad ObbFile package name length (0x" + Long.toHexString(packageNameLen) +
- "; 0x" + Long.toHexString(footerSize - kPackageNameOffset) + "possible)");
- }
- byte[] packageNameBuf = new byte[(int)packageNameLen];
- footBuf.position(kPackageNameOffset);
- footBuf.get(packageNameBuf);
-
- mPackageName = new String(packageNameBuf);
- return true;
- } catch (IOException e) {
- e.printStackTrace();
- }
- return false;
- }
-
- public boolean writeTo(String fileName)
- {
- File obbFile = new File(fileName);
- return writeTo(obbFile);
- }
-
- public boolean writeTo(File obbFile) {
- if ( !obbFile.exists() )
- return false;
-
- try {
-
- long fileLength = obbFile.length();
- RandomAccessFile raf = new RandomAccessFile(obbFile, "rw");
- raf.seek(fileLength);
-
- if (null == mPackageName || mPackageVersion == -1) {
- throw new RuntimeException("tried to write uninitialized ObbFile data");
- }
-
- FileChannel fc = raf.getChannel();
- ByteBuffer bbInt = ByteBuffer.allocate(4);
- bbInt.order(ByteOrder.LITTLE_ENDIAN);
- bbInt.putInt(kSigVersion);
- bbInt.rewind();
- fc.write(bbInt);
-
- bbInt.rewind();
- bbInt.putInt((int)mPackageVersion);
- bbInt.rewind();
- fc.write(bbInt);
-
- bbInt.rewind();
- bbInt.putInt((int)mFlags);
- bbInt.rewind();
- fc.write(bbInt);
-
- raf.write(mSalt);
-
- bbInt.rewind();
- bbInt.putInt(mPackageName.length());
- bbInt.rewind();
- fc.write(bbInt);
-
- raf.write(mPackageName.getBytes());
-
- bbInt.rewind();
- bbInt.putInt(mPackageName.length()+kPackageNameOffset);
- bbInt.rewind();
- fc.write(bbInt);
-
- bbInt.rewind();
- bbInt.putInt((int)kSignature);
- bbInt.rewind();
- fc.write(bbInt);
-
- raf.close();
- return true;
- } catch (IOException e) {
- e.printStackTrace();
- }
- return false;
- }
-}
diff --git a/jobb/src/com/android/jobb/PBKDF.java b/jobb/src/com/android/jobb/PBKDF.java
deleted file mode 100644
index 4893c00..0000000
--- a/jobb/src/com/android/jobb/PBKDF.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2012 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.jobb;
-
-import java.io.UnsupportedEncodingException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.spec.InvalidKeySpecException;
-
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.interfaces.PBEKey;
-import javax.crypto.spec.PBEKeySpec;
-
-public class PBKDF {
- public static final int SALT_LEN = 8;
- private static final int ROUNDS = 1024;
- private static final int KEY_BITS = 128;
-
- public static byte[] getKey(String password, byte[] saltBytes) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
- PBEKeySpec pwKey = new PBEKeySpec(password.toCharArray(), saltBytes, ROUNDS, KEY_BITS);
- SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
- PBEKey pbeKey;
- try {
- pbeKey = (PBEKey) factory.generateSecret(pwKey);
- byte[] pbkdfKey = pbeKey.getEncoded();
- return pbkdfKey;
- } catch (InvalidKeySpecException e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public static byte[] getRandomSalt() {
- SecureRandom random = new SecureRandom();
- byte[] saltBytes = new byte[SALT_LEN];
- random.nextBytes(saltBytes);
- return saltBytes;
- }
-
-}
diff --git a/manifmerger/etc/Android.mk b/manifmerger/etc/Android.mk
deleted file mode 100644
index 6b180ab..0000000
--- a/manifmerger/etc/Android.mk
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright 2011 The Android Open Source Project
-#
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := manifmerger
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/manifmerger/etc/manifest.txt b/manifmerger/etc/manifest.txt
deleted file mode 100644
index bfc9524..0000000
--- a/manifmerger/etc/manifest.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Main-Class: com.android.manifestmerger.Main
-Class-Path: sdklib.jar
diff --git a/manifmerger/etc/manifmerger b/manifmerger/etc/manifmerger
deleted file mode 100755
index 1e2c2a7..0000000
--- a/manifmerger/etc/manifmerger
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/bin/sh
-# Copyright 2011, 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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-cd "${oldwd}"
-
-jarfile=manifmerger.jar
-frameworkdir="$progdir"
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/tools/lib
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- frameworkdir=`dirname "$progdir"`/framework
-fi
-if [ ! -r "$frameworkdir/$jarfile" ]
-then
- echo `basename "$prog"`": can't find $jarfile"
- exit 1
-fi
-
-
-# Check args.
-if [ debug = "$1" ]; then
- # add this in for debugging
- java_debug=-agentlib:jdwp=transport=dt_socket,server=y,address=8050,suspend=y
- shift 1
-else
- java_debug=
-fi
-
-java_cmd="java"
-
-# Mac OS X needs an additional arg, or you get an "illegal thread" complaint.
-if [ `uname` = "Darwin" ]; then
- os_opts="-XstartOnFirstThread"
-else
- os_opts=
-fi
-
-if [ `uname` = "Linux" ]; then
- export GDK_NATIVE_WINDOWS=true
-fi
-
-if [ "$OSTYPE" = "cygwin" ] ; then
- jarpath=`cygpath -w "$frameworkdir/$jarfile"`
- progdir=`cygpath -w "$progdir"`
-else
- jarpath="$frameworkdir/$jarfile"
-fi
-
-# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
-exec "$java_cmd" \
- -Xmx256M $os_opts $java_debug \
- -Dcom.android.manifmergerdir="$progdir" \
- -classpath "$jarpath" \
- com.android.manifestmerger.Main "$@"
diff --git a/manifmerger/src/main/java/com/android/manifmerger/ArgvParser.java b/manifmerger/src/main/java/com/android/manifmerger/ArgvParser.java
deleted file mode 100755
index 6d22f57..0000000
--- a/manifmerger/src/main/java/com/android/manifmerger/ArgvParser.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2011 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.sdklib.util.CommandLineParser;
-import com.android.utils.ILogger;
-
-import java.util.List;
-
-
-/**
- * Specific command-line flags for the {@link ManifestMerger}.
- */
-class ArgvParser extends CommandLineParser {
-
- /*
- * Steps needed to add a new action:
- * - Each action is defined as a "verb object" followed by parameters.
- * - Either reuse a VERB_ constant or define a new one.
- * - Either reuse an OBJECT_ constant or define a new one.
- * - Add a new entry to mAction with a one-line help summary.
- * - In the constructor, add a define() call for each parameter (either mandatory
- * or optional) for the given action.
- */
-
- public final static String VERB_MERGE = "merge"; //$NON-NLS-1$
- public static final String KEY_OUT = "out"; //$NON-NLS-1$
- public static final String KEY_MAIN = "main"; //$NON-NLS-1$
- public static final String KEY_LIBS = "libs"; //$NON-NLS-1$
-
- /**
- * Action definitions for ManifestMerger command line.
- * <p/>
- * This list serves two purposes: first it is used to know which verb/object
- * actions are acceptable on the command-line; second it provides a summary
- * for each action that is printed in the help.
- * <p/>
- * Each entry is a string array with:
- * <ul>
- * <li> the verb.
- * <li> an object (use #NO_VERB_OBJECT if there's no object).
- * <li> a description.
- * <li> an alternate form for the object (e.g. plural).
- * </ul>
- */
- private final static String[][] ACTIONS = {
-
- { VERB_MERGE, NO_VERB_OBJECT,
- "Merge two or more manifests." },
-
- };
-
- public ArgvParser(ILogger logger) {
- super(logger, ACTIONS);
-
- // The following defines the parameters of the actions defined in mAction.
-
- // --- merge manifest ---
-
- define(Mode.STRING, true,
- VERB_MERGE, NO_VERB_OBJECT, "o", KEY_OUT, //$NON-NLS-1$
- "Output path (where to write the merged manifest). Use - for stdout.", null);
-
- define(Mode.STRING, true,
- VERB_MERGE, NO_VERB_OBJECT, "1", KEY_MAIN, //$NON-NLS-1$
- "Path of the main manifest (what to merge *into*)", null);
-
- define(Mode.STRING_ARRAY, true,
- VERB_MERGE, NO_VERB_OBJECT, "2", KEY_LIBS, //$NON-NLS-1$
- "Paths of library manifests to be merged into the main one.",
- null);
- }
-
- @Override
- public boolean acceptLackOfVerb() {
- return true;
- }
-
- // -- some helpers for generic action flags
-
- /** Helper to retrieve the --out value. */
- public String getParamOut() {
- return (String) getValue(null, null, KEY_OUT);
- }
-
- /** Helper to retrieve the --main value. */
- public String getParamMain() {
- return (String) getValue(null, null, KEY_MAIN);
- }
-
- /**
- * Helper to retrieve the --libs values.
- */
- public String[] getParamLibs() {
- Object v = getValue(null, null, KEY_LIBS);
- if (v instanceof List<?>) {
- List<?> a = (List<?>) v;
- return a.toArray(new String[a.size()]);
- }
- return null;
- }
-}
diff --git a/manifmerger/src/main/java/com/android/manifmerger/ICallback.java b/manifmerger/src/main/java/com/android/manifmerger/ICallback.java
deleted file mode 100755
index 26ae40d..0000000
--- a/manifmerger/src/main/java/com/android/manifmerger/ICallback.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2012 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.annotations.NonNull;
-
-/**
- * Callback used by the ManifestMerger to query the caller.
- */
-public interface ICallback {
-
- public static final int UNKNOWN_CODENAME = 0;
-
- /**
- * Queries the caller to find the API level for a given provisional API codename,
- * as used in the &lt;uses-sdk&gt; {@code minSdkVersion} field.
- *
- * @param codename A non-null codename string.
- * @return The integer API > 0 for the given codename, or {@link #UNKNOWN_CODENAME}.
- */
- public int queryCodenameApiLevel(@NonNull String codename);
-
-}
diff --git a/manifmerger/src/main/java/com/android/manifmerger/IMergerLog.java b/manifmerger/src/main/java/com/android/manifmerger/IMergerLog.java
deleted file mode 100755
index 5402dd4..0000000
--- a/manifmerger/src/main/java/com/android/manifmerger/IMergerLog.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2012 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.annotations.NonNull;
-import com.android.annotations.Nullable;
-
-
-/**
- * Logger interface for the {@link ManifestMerger}.
- */
-public interface IMergerLog {
-
- /** Severity of the error message. */
- public enum Severity {
- /**
- * A very low severity information. This does not stop processing.
- * Clients might want to have a "not verbose" flag to not display this.
- */
- INFO,
- /**
- * A warning. This does not stop processing.
- * */
- WARNING,
- /**
- * A fatal error.
- * The merger does not stop on errors, in an attempt to accumulate as much
- * info as possible to return to the user. However in case even one error
- * is generated the output should not be used, if any.
- */
- ERROR
- }
-
- /**
- * Logs an error that occurred at a specific single manifest.
- *
- * @param severity Whether this is an actual error or a mere warning.
- * @param location A file and line location of where the error was detected.
- * @param message A message string, suitable for {@link String#format(String, Object...)}.
- * @param msgParams The optional parameters for the {@code message} string.
- */
- public abstract void error(
- @NonNull Severity severity,
- @NonNull FileAndLine location,
- @NonNull String message,
- Object...msgParams);
-
- /**
- * Logs a conflict, that is an error that happens when comparing 2 manifests.
- *
- * @param severity Whether this is an actual error or a mere warning.
- * @param location1 A file and line location of where the error was detected.
- * By convention, location1 is generally the main manifest location.
- * @param location2 A file and line location of where the error was detected.
- * By convention, location2 is generally a library location.
- * @param message A message string, suitable for {@link String#format(String, Object...)}.
- * @param msgParams The optional parameters for the {@code message} string.
- */
- public abstract void conflict(
- @NonNull Severity severity,
- @NonNull FileAndLine location1,
- @NonNull FileAndLine location2,
- @NonNull String message,
- Object...msgParams);
-
- /**
- * Information about the file and line number where an error ocurred.
- */
- public static class FileAndLine {
- private final String mFilePath;
- private final int mLine;
-
- /**
- * Constructs a new {@link FileAndLine}.
- *
- * @param filePath The file path. This is typically a file path when the
- * merge is initiated via the {@code process(File...)} interface.
- * When using the {@code process(Document...)} interface, this will be
- * one of the magic constants {@link IMergerLog#LIBRARY} or
- * {@link IMergerLog#MAIN_MANIFEST}. When that fails, null is used.
- * @param line The line number where the error occurred in the XML file.
- * Zero is used when the line number isn't known (e.g. when the error
- * happens at the document level rather than on a specific element.)
- */
- public FileAndLine(@Nullable String filePath, int line) {
- mFilePath = filePath;
- mLine = line;
- }
-
- /**
- * Returns the file path.
- * <p/>
- * This is typically a file path when the merge is initiated via the
- * {@code process(File...)} interface.
- * When using the {@code process(Document...)} interface, this will be
- * one of the magic constants {@link IMergerLog#LIBRARY} or
- * {@link IMergerLog#MAIN_MANIFEST}.
- * When that fails, null is used.
- */
- public @Nullable String getFileName() {
- return mFilePath;
- }
-
- /**
- * Returns the line number where the error occurred in the XML file.
- * Zero is used when the line number isn't known (e.g. when the error
- * happens at the document level rather than on a specific element.)
- */
- public int getLine() {
- return mLine;
- }
-
- /**
- * Displays the information in the form "file:line".
- */
- @Override
- public String toString() {
- String name = mFilePath;
- if (MAIN_MANIFEST.equals(name)) {
- name = "main manifest"; // translatable
- } else if (LIBRARY.equals(name)) {
- name = "library"; // translatable
- } else if (name == null) {
- name = "(Unknown)"; // translatable
- }
- if (mLine <= 0) {
- return name;
- } else {
- return name + ':' + mLine;
- }
- }
- }
-
- /**
- * The reference to the "main manifest" used in {@link FileAndLine} when the
- * path to the main manifest file isn't known. This happens when the
- * {@link ManifestMerger} is called with the {@code process(Document...)}
- * interface.
- */
- public static final String MAIN_MANIFEST = "@main"; //$NON-NLS-1$
-
- /**
- * The reference to "a library" used in {@link FileAndLine} when the
- * path to the library file isn't known. This happens when the
- * {@link ManifestMerger} is called with the {@code process(Document...)}
- * interface.
- */
- public static final String LIBRARY = "@library"; //$NON-NLS-1$
-
-}
diff --git a/manifmerger/src/main/java/com/android/manifmerger/Main.java b/manifmerger/src/main/java/com/android/manifmerger/Main.java
deleted file mode 100644
index 2a6460e..0000000
--- a/manifmerger/src/main/java/com/android/manifmerger/Main.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2011 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.utils.ILogger;
-import com.android.utils.StdLogger;
-
-import java.io.File;
-import java.util.Map;
-
-/**
- * Command-line entry point of the Manifest Merger.
- * The goal of the manifest merger is to merge library manifest into a main application manifest.
- * See {@link ManifestMerger} for the exact merging rules.
- * <p/>
- * The command-line version creates a {@link ManifestMerger}
- * which takes file arguments from the command-line and dumps all errors and warnings on the
- * stdout/stderr console.
- * <p/>
- * Usage: <br/>
- * {@code $ manifmerger merge --main main_manifest.xml --libs lib1.xml lib2.xml --out result.xml}
- * <p/>
- * When used as a library, please call {@link ManifestMerger#process(File, File, File[], Map)}
- * directly.
- */
-public class Main {
-
- /** Logger object. Use this to print normal output, warnings or errors. Never null. */
- private ILogger mSdkLog;
- /** Command line parser. Never null. */
- private ArgvParser mArgvParser;
-
- public static void main(String[] args) {
- new Main().run(args);
- }
-
- /**
- * Runs the sdk manager app
- */
- private void run(String[] args) {
- createLogger();
-
- mArgvParser = new ArgvParser(mSdkLog);
- mArgvParser.parseArgs(args);
-
- // Create a new ManifestMerger and call its process method.
- // It will take care of validating its own arguments.
- ManifestMerger mm = new ManifestMerger(MergerLog.wrapSdkLog(mSdkLog), null);
-
- String[] libPaths = mArgvParser.getParamLibs();
- File[] libFiles = new File[libPaths.length];
- for (int n = libPaths.length - 1; n >= 0; n--) {
- libFiles[n] = new File(libPaths[n]);
- }
-
- boolean ok = mm.process(
- new File(mArgvParser.getParamOut()),
- new File(mArgvParser.getParamMain()),
- libFiles,
- null /*injectAttributes*/
- );
- System.exit(ok ? 0 : 1);
- }
-
- /**
- * Creates the {@link #mSdkLog} object.
- * This logger prints to the attached console.
- */
- private void createLogger() {
- mSdkLog = new StdLogger(StdLogger.Level.VERBOSE);
- }
-
- /** For testing */
- public void setLogger(ILogger logger) {
- mSdkLog = logger;
- }
-
-}
diff --git a/manifmerger/src/main/java/com/android/manifmerger/ManifestMerger.java b/manifmerger/src/main/java/com/android/manifmerger/ManifestMerger.java
deleted file mode 100755
index 2148c98..0000000
--- a/manifmerger/src/main/java/com/android/manifmerger/ManifestMerger.java
+++ /dev/null
@@ -1,1577 +0,0 @@
-/*
- * Copyright (C) 2011 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.SdkConstants;
-import com.android.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.manifmerger.IMergerLog.FileAndLine;
-import com.android.manifmerger.IMergerLog.Severity;
-import com.android.utils.XmlUtils;
-import com.android.xml.AndroidXPathFactory;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-
-/**
- * Merges a library manifest into a main application manifest.
- * <p/>
- * To use, create with {@link ManifestMerger#ManifestMerger(IMergerLog, ICallback)} then
- * call {@link ManifestMerger#process(File, File, File[], Map)}.
- * <p/>
- * <pre> Merge operations:
- * - root manifest: attributes ignored, warn if defined.
- * - application:
- * G- {@code @attributes}: most attributes are ignored in libs
- * except: application:name if defined, it must match.
- * except: application:agentBackup if defined, it must match.
- * (these represent class names and we don't want a lib to assume their app or backup
- * classes are being used when that will never be the case.)
- * C- activity / activity-alias / service / receiver / provider
- * => Merge as-is. Error if exists in the destination (same {@code @name})
- * unless the definitions are exactly the same.
- * New elements are always merged at the end of the application element.
- * => Indicate if there's a dup.
- * D- uses-library
- * => Merge. OK if already exists same {@code @name}.
- * => Merge {@code @required}: true>false.
- * C- meta-data
- * => Merge as-is. Error if exists in the destination (same {@code @name})
- * unless the definitions are exactly the same.
- * New elements are always merged at the end of the application element.
- * => Indicate if there's a dup.
- * A- instrumentation:
- * => Do not merge. ignore the ones from libs.
- * C- permission / permission-group / permission-tree:
- * => Merge as-is. Error if exists in the destination (same {@code @name})
- * unless the definitions are exactly the same.
- * C- uses-permission:
- * => Add. OK if already defined.
- * E- uses-sdk:
- * {@code @minSdkVersion}: error if dest&lt;lib. Never automatically change dest minsdk.
- * Codenames are accepted if we can resolve their API level.
- * {@code @targetSdkVersion}: warning if dest&lt;lib.
- * Never automatically change dest targetsdk.
- * {@code @maxSdkVersion}: obsolete, ignored. Not used in comparisons and not merged.
- * D- uses-feature with {@code @name}:
- * => Merge with same {@code @name}
- * => Merge {@code @required}: true>false.
- * - Do not merge any {@code @glEsVersion} attribute at this point.
- * F- uses-feature with {@code @glEsVersion}:
- * => Error if defined in lib+dest with dest&lt;lib. Never automatically change dest.
- * B- uses-configuration:
- * => There can be many. Error if source defines one that is not an exact match in dest.
- * (e.g. right now app must manually define something that matches exactly each lib)
- * B- supports-screens / compatible-screens:
- * => Do not merge.
- * => Error (warn?) if defined in lib and not strictly the same as in dest.
- * B- supports-gl-texture:
- * => Do not merge. Can have more than one.
- * => Error (warn?) if defined in lib and not present as-is in dest.
- *
- * Strategies:
- * A = Ignore, do not merge (no-op).
- * B = Do not merge but if defined in both must match equally.
- * C = Must not exist in dest or be exactly the same (key is the {@code @name} attribute).
- * D = Add new or merge with same key {@code @name}, adjust {@code @required} true>false.
- * E, F, G = Custom strategies; see above.
- *
- * What happens when merging libraries with conflicting information?
- * Say for example a main manifest has a minSdkVersion of 3, whereas libraries have
- * a minSdkVersion of 4 and 11. We could have 2 point of views:
- * - Play it safe: If we have a library with a minSdkVersion of 11, it means this
- * library code knows it can't work reliably on a lower API level. So the safest end
- * result would be a merged manifest with the highest minSdkVersion of all libraries.
- * - Trust the main manifest: When an app declares a given minSdkVersion, it also expects
- * to run a given range of devices. If we change the final minSdkVersion, the app won't
- * be available on as many devices as the developer might expect. And as a counterpoint
- * to issue 1, the app may be careful and not call the library without checking the
- * necessary features or APIs are available before hand.
- * Both points of views are conflicting. The solution taken here is to be conservative
- * and generate an error rather than merge and change a value that might be surprising.
- * On the other hand this can be problematic and force a developer to keep the main
- * manifest in sync with the libraries ones, in essence reducing the usefulness of the
- * automated merge to pure trivial cases. The idea is to just start this way and enhance
- * or revisit the mechanism later.
- * </pre>
- */
-public class ManifestMerger {
-
- /** Logger object. Never null. */
- private final IMergerLog mLog;
- /** An optional callback that the merger can use to query the calling SDK. */
- private final ICallback mCallback;
- private XPath mXPath;
- private Document mMainDoc;
- /** Option to extract the package prefixes from the merged manifest. */
- private boolean mExtractPackagePrefix;
-
- /** Namespace for Android attributes in an AndroidManifest.xml */
- private static final String NS_URI = SdkConstants.NS_RESOURCES;
- /** Prefix for the Android namespace to use in XPath expressions. */
- private static final String NS_PREFIX = AndroidXPathFactory.DEFAULT_NS_PREFIX;
- /** Namespace used in XML files for Android Tooling attributes */
- private static final String TOOLS_URI = SdkConstants.TOOLS_URI;
- /** The name of the tool:merge attribute, to either override or ignore merges. */
- private static final String MERGE_ATTR = "merge"; //$NON-NLS-1$
- /** tool:merge="override" means to ignore what comes from libraries and only keep the
- * version from the main manifest. No conflict can be generated. */
- private static final String MERGE_OVERRIDE = "override"; //$NON-NLS-1$
- /** tool:merge="remove" means to remove a node and prevent merging -- not only is the
- * node from the libraries not merged, but the element is removed from the main manifest. */
- private static final String MERGE_REMOVE = "remove"; //$NON-NLS-1$
-
- /**
- * Sets of element/attribute that need to be treated as class names.
- * The attribute name must be the local name for the Android namespace.
- * For example "application/name" maps to &lt;application android:name=...&gt;.
- */
- private static final String[] sClassAttributes = {
- "application/name",
- "application/backupAgent",
- "activity/name",
- "activity-alias/name",
- "receiver/name",
- "service/name",
- "provider/name",
- "instrumentation/name"
- };
-
- /**
- * Creates a new {@link ManifestMerger}.
- *
- * @param log A non-null merger log to capture all warnings, errors and their location.
- * @param callback An optional callback that the merger can use to query the calling SDK.
- */
- public ManifestMerger(@NonNull IMergerLog log, @Nullable ICallback callback) {
- mLog = log;
- mCallback = callback;
- }
-
- /**
- * Sets whether the manifest merger should extract package prefixes.
- * <p/>
- * When true, the merged document is revisited and class names attributes
- * are shortened when possible, e.g. the package prefix is removed from the
- * class name if it matches.
- *
- * @param extract If true, extract package prefixes.
- * @return this, for constructor chaining
- */
- public ManifestMerger setExtractPackagePrefix(boolean extract) {
- mExtractPackagePrefix = extract;
- return this;
- }
-
- /**
- * Performs the merge operation.
- * <p/>
- * This does NOT stop on errors, in an attempt to accumulate as much
- * info as possible to return to the user.
- * Unless it failed to read the main manifest, a result file will be
- * created. However if process() returns false, the file should not
- * be used except for debugging purposes.
- *
- * @param outputFile The output path to generate. Can be the same as the main path.
- * @param mainFile The main manifest paths to read. What we merge into.
- * @param libraryFiles The library manifest paths to read. Must not be null.
- * @param injectAttributes A map of attributes to inject in the form [pseudo-xpath] => value.
- * The key is "/manifest/elements...|attribute-ns-uri attribute-local-name",
- * for example "/manifest/uses-sdk|http://schemas.android.com/apk/res/android minSdkVersion".
- * (note the space separator between the attribute URI and its local name.)
- * The elements will be created if they don't exists. Existing attributes will be modified.
- * The replacement is done on the main document <em>before</em> merging.
- * @return True if the merge was completed, false otherwise.
- */
- public boolean process(
- File outputFile,
- File mainFile,
- File[] libraryFiles,
- Map<String, String> injectAttributes) {
- Document mainDoc = MergerXmlUtils.parseDocument(mainFile, mLog);
- if (mainDoc == null) {
- return false;
- }
-
- boolean success = process(mainDoc, libraryFiles, injectAttributes);
-
- if (!MergerXmlUtils.printXmlFile(mainDoc, outputFile, mLog)) {
- success = false;
- }
- return success;
- }
-
- /**
- * Performs the merge operation in-place in the given DOM.
- * <p/>
- * This does NOT stop on errors, in an attempt to accumulate as much
- * info as possible to return to the user.
- * <p/>
- * The method might modify the input XML document in-place for its own processing.
- *
- * @param mainDoc The document to merge into. Will be modified in-place.
- * @param libraryFiles The library manifest paths to read. Must not be null.
- * These will be modified in-place.
- * @param injectAttributes A map of attributes to inject in the form [pseudo-xpath] => value.
- * The key is "/manifest/elements...|attribute-ns-uri attribute-local-name",
- * for example "/manifest/uses-sdk|http://schemas.android.com/apk/res/android minSdkVersion".
- * (note the space separator between the attribute URI and its local name.)
- * The elements will be created if they don't exists. Existing attributes will be modified.
- * The replacement is done on the main document <em>before</em> merging.
- * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
- */
- public boolean process(
- Document mainDoc,
- File[] libraryFiles,
- Map<String, String> injectAttributes) {
-
- boolean success = true;
- mMainDoc = mainDoc;
- MergerXmlUtils.decorateDocument(mainDoc, IMergerLog.MAIN_MANIFEST);
- MergerXmlUtils.injectAttributes(mainDoc, injectAttributes, mLog);
-
- String prefix = XmlUtils.lookupNamespacePrefix(mainDoc, SdkConstants.NS_RESOURCES);
- mXPath = AndroidXPathFactory.newXPath(prefix);
-
- expandFqcns(mainDoc);
- for (File libFile : libraryFiles) {
- Document libDoc = MergerXmlUtils.parseDocument(libFile, mLog);
- if (libDoc == null || !mergeLibDoc(cleanupToolsAttributes(libDoc))) {
- success = false;
- }
- }
-
- cleanupToolsAttributes(mainDoc);
-
- if (mExtractPackagePrefix) {
- extractFqcns(mainDoc);
- }
-
- mXPath = null;
- mMainDoc = null;
- return success;
- }
-
- /**
- * Performs the merge operation in-place in the given DOM.
- * <p/>
- * This does NOT stop on errors, in an attempt to accumulate as much
- * info as possible to return to the user.
- * <p/>
- * The method might modify the input XML documents in-place for its own processing.
- *
- * @param mainDoc The document to merge into. Will be modified in-place.
- * @param libraryDocs The library manifest documents to merge in. Must not be null.
- * These will be modified in-place.
- * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
- */
- public boolean process(@NonNull Document mainDoc, @NonNull Document... libraryDocs) {
-
- boolean success = true;
- mMainDoc = mainDoc;
- MergerXmlUtils.decorateDocument(mainDoc, IMergerLog.MAIN_MANIFEST);
-
- String prefix = XmlUtils.lookupNamespacePrefix(mainDoc, SdkConstants.NS_RESOURCES);
- mXPath = AndroidXPathFactory.newXPath(prefix);
-
- expandFqcns(mainDoc);
- for (Document libDoc : libraryDocs) {
- MergerXmlUtils.decorateDocument(libDoc, IMergerLog.LIBRARY);
- if (!mergeLibDoc(cleanupToolsAttributes(libDoc))) {
- success = false;
- }
- }
-
- cleanupToolsAttributes(mainDoc);
- mXPath = null;
- mMainDoc = null;
- return success;
- }
-
- // --------
-
- /**
- * Merges the given library manifest into the destination manifest.
- * See {@link ManifestMerger} for merge details.
- *
- * @param libDoc The library document to merge from. Must not be null.
- * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
- */
- private boolean mergeLibDoc(Document libDoc) {
-
- boolean err = false;
-
- expandFqcns(libDoc);
-
- // Strategy G (check <application> is compatible)
- err |= !checkApplication(libDoc);
-
- // Strategy B
- err |= !doNotMergeCheckEqual("/manifest/uses-configuration", libDoc); //$NON-NLS-1$
- err |= !doNotMergeCheckEqual("/manifest/supports-screens", libDoc); //$NON-NLS-1$
- err |= !doNotMergeCheckEqual("/manifest/compatible-screens", libDoc); //$NON-NLS-1$
- err |= !doNotMergeCheckEqual("/manifest/supports-gl-texture", libDoc); //$NON-NLS-1$
-
- boolean skipApplication = hasOverrideOrRemoveTag(
- findFirstElement(mMainDoc, "/manifest/application")); //$NON-NLS-1$
-
- // Strategy C
- if (!skipApplication) {
- err |= !mergeNewOrEqual(
- "/manifest/application/activity", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- libDoc,
- true);
- err |= !mergeNewOrEqual(
- "/manifest/application/activity-alias", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- libDoc,
- true);
- err |= !mergeNewOrEqual(
- "/manifest/application/service", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- libDoc,
- true);
- err |= !mergeNewOrEqual(
- "/manifest/application/receiver", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- libDoc,
- true);
- err |= !mergeNewOrEqual(
- "/manifest/application/provider", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- libDoc,
- true);
- }
- err |= !mergeNewOrEqual(
- "/manifest/permission", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- libDoc,
- false);
- err |= !mergeNewOrEqual(
- "/manifest/permission-group", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- libDoc,
- false);
- err |= !mergeNewOrEqual(
- "/manifest/permission-tree", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- libDoc,
- false);
- err |= !mergeNewOrEqual(
- "/manifest/uses-permission", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- libDoc,
- false);
-
- // Strategy D
- if (!skipApplication) {
- err |= !mergeAdjustRequired(
- "/manifest/application/uses-library", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- "required", //$NON-NLS-1$
- libDoc,
- null /*alternateKeyAttr*/);
- err |= !mergeNewOrEqual(
- "/manifest/application/meta-data", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- libDoc,
- true);
- }
- err |= !mergeAdjustRequired(
- "/manifest/uses-feature", //$NON-NLS-1$
- "name", //$NON-NLS-1$
- "required", //$NON-NLS-1$
- libDoc,
- "glEsVersion" /*alternateKeyAttr*/);
-
- // Strategy E
- err |= !checkSdkVersion(libDoc);
-
- // Strategy F
- err |= !checkGlEsVersion(libDoc);
-
- return !err;
- }
-
- /**
- * Expand all possible class names attributes in the given document.
- * <p/>
- * Some manifest attributes represent class names. These can be specified as fully
- * qualified class names or use a short notation consisting of just the terminal
- * class simple name or a dot followed by a partial class name. Unfortunately this
- * makes textual comparison of the attributes impossible. To simplify this, we can
- * modify the document to fully expand all these class names. The list of elements
- * and attributes to process is listed by {@link #sClassAttributes} and the expansion
- * simply consists of appending the manifest' package if defined.
- *
- * @param doc The document in which to expand potential FQCNs.
- */
- private void expandFqcns(Document doc) {
- // Find the package attribute of the manifest.
- String pkg = null;
- Element manifest = findFirstElement(doc, "/manifest");
- if (manifest != null) {
- pkg = manifest.getAttribute("package");
- }
-
- if (pkg == null || pkg.length() == 0) {
- // We can't adjust FQCNs if we don't know the root package name.
- // It's not a proper manifest if this is missing anyway.
- assert manifest != null;
- mLog.error(Severity.WARNING,
- xmlFileAndLine(manifest),
- "Missing 'package' attribute in manifest.");
- return;
- }
-
- for (String elementAttr : sClassAttributes) {
- String[] names = elementAttr.split("/");
- if (names.length != 2) {
- continue;
- }
- String elemName = names[0];
- String attrName = names[1];
- NodeList elements = doc.getElementsByTagName(elemName);
- for (int i = 0; i < elements.getLength(); i++) {
- Node elem = elements.item(i);
- if (elem instanceof Element) {
- Attr attr = ((Element) elem).getAttributeNodeNS(NS_URI, attrName);
- if (attr != null) {
- String value = attr.getNodeValue();
-
- // We know it's a shortened FQCN if it starts with a dot
- // or does not contain any dot.
- if (value != null && value.length() > 0 &&
- (value.indexOf('.') == -1 || value.charAt(0) == '.')) {
- if (value.charAt(0) == '.') {
- value = pkg + value;
- } else {
- value = pkg + '.' + value;
- }
- attr.setNodeValue(value);
- }
- }
- }
- }
- }
- }
-
- /**
- * Extracts the fully qualified class names from the manifest and uses the
- * prefix notation relative to the manifest package. This basically reverses
- * the effects of {@link #expandFqcns(Document)}, though of course it may
- * also remove prefixes which were inlined in the original documents.
- *
- * @param doc the document in which to extract the FQCNs.
- */
- private void extractFqcns(Document doc) {
- // Find the package attribute of the manifest.
- String pkg = null;
- Element manifest = findFirstElement(doc, "/manifest");
- if (manifest != null) {
- pkg = manifest.getAttribute("package");
- }
-
- if (pkg == null || pkg.length() == 0) {
- return;
- }
-
- int pkgLength = pkg.length();
- for (String elementAttr : sClassAttributes) {
- String[] names = elementAttr.split("/");
- if (names.length != 2) {
- continue;
- }
- String elemName = names[0];
- String attrName = names[1];
- NodeList elements = doc.getElementsByTagName(elemName);
- for (int i = 0; i < elements.getLength(); i++) {
- Node elem = elements.item(i);
- if (elem instanceof Element) {
- Attr attr = ((Element) elem).getAttributeNodeNS(NS_URI, attrName);
- if (attr != null) {
- String value = attr.getNodeValue();
-
- // We know it's a shortened FQCN if it starts with a dot
- // or does not contain any dot.
- if (value != null && value.length() > pkgLength &&
- value.startsWith(pkg) && value.charAt(pkgLength) == '.') {
- value = value.substring(pkgLength);
- attr.setNodeValue(value);
- }
- }
- }
- }
- }
- }
-
- /**
- * Checks (but does not merge) the application attributes using the following rules:
- * <pre>
- * - {@code @name}: Ignore if empty. Warning if its expanded FQCN doesn't match the main doc.
- * - {@code @backupAgent}: Ignore if empty. Warning if its expanded FQCN doesn't match main doc.
- * - All other attributes are ignored.
- * </pre>
- * The name and backupAgent represent classes and the merger will warn since if a lib has
- * these defined they will never be used anyway.
- * @param libDoc The library document to merge from. Must not be null.
- * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
- */
- private boolean checkApplication(Document libDoc) {
-
- Element mainApp = findFirstElement(mMainDoc, "/manifest/application"); //$NON-NLS-1$
- Element libApp = findFirstElement(libDoc, "/manifest/application"); //$NON-NLS-1$
-
- // A manifest does not necessarily define an application.
- // If the lib has none, there's nothing to check for.
- if (libApp == null) {
- return true;
- }
- if (hasOverrideOrRemoveTag(mainApp)) {
- // Don't check the <application> element since it is tagged with override or remove.
- return true;
- }
-
- for (String attrName : new String[] { "name", "backupAgent" }) {
- String libValue = getAttributeValue(libApp, attrName);
- if (libValue == null || libValue.length() == 0) {
- // Nothing to do if the attribute is not defined in the lib.
- continue;
- }
- // The main doc does not have to have an application node.
- String mainValue = mainApp == null ? "" : getAttributeValue(mainApp, attrName);
- if (!libValue.equals(mainValue)) {
- assert mainApp != null;
- mLog.conflict(Severity.WARNING,
- xmlFileAndLine(mainApp),
- xmlFileAndLine(libApp),
- mainApp == null ?
- "Library has <application android:%1$s='%3$s'> but main manifest has no application element." :
- "Main manifest has <application android:%1$s='%2$s'> but library uses %1$s='%3$s'.",
- attrName,
- mainValue,
- libValue);
- }
- }
-
- return true;
- }
-
- /**
- * Do not merge anything. Instead it checks that the requested elements from the
- * given library are all present and equal in the destination and prints a warning
- * if it's not the case.
- * <p/>
- * For example if a library supports a given screen configuration, print a
- * warning if the main manifest doesn't indicate the app supports the same configuration.
- * We should not merge it since we don't want to silently give the impression an app
- * supports a configuration just because it uses a library which does.
- * On the other hand we don't want to silently ignore this fact.
- * <p/>
- * TODO there should be a way to silence this warning.
- * The current behavior is certainly arbitrary and needs to be tweaked somehow.
- *
- * @param path The XPath of the elements to merge from the library. Must not be null.
- * @param libDoc The library document to merge from. Must not be null.
- * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
- */
- private boolean doNotMergeCheckEqual(String path, Document libDoc) {
-
- for (Element src : findElements(libDoc, path)) {
-
- boolean found = false;
-
- for (Element dest : findElements(mMainDoc, path)) {
- if (hasOverrideOrRemoveTag(dest)) {
- continue;
- }
- if (compareElements(dest, src, false, null /*diff*/, null /*keyAttr*/)) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- mLog.conflict(Severity.WARNING,
- xmlFileAndLine(mMainDoc),
- xmlFileAndLine(src),
- "%1$s defined in library, missing from main manifest:\n%2$s",
- path,
- MergerXmlUtils.dump(src, false /*nextSiblings*/));
- }
- }
-
- return true;
- }
-
- /**
- * Merges the requested elements from the library in the main document.
- * The key attribute name is used to identify the same elements.
- * Merged elements must either not exist in the destination or be identical.
- * <p/>
- * When merging, append to the end of the application element.
- * Also merges any preceding whitespace and up to one comment just prior to the merged element.
- *
- * @param path The XPath of the elements to merge from the library. Must not be null.
- * @param keyAttr The Android-namespace attribute used as key to identify similar elements.
- * E.g. "name" for "android:name"
- * @param libDoc The library document to merge from. Must not be null.
- * @param warnDups When true, will print a warning when a library definition is already
- * present in the destination and is equal.
- * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
- */
- private boolean mergeNewOrEqual(
- String path,
- String keyAttr,
- Document libDoc,
- boolean warnDups) {
-
- // The parent of XPath /p1/p2/p3 is /p1/p2. To find it, delete the last "/segment"
- int pos = path.lastIndexOf('/');
- assert pos > 1;
- String parentPath = path.substring(0, pos);
- Element parent = findFirstElement(mMainDoc, parentPath);
- assert parent != null;
- if (parent == null) {
- mLog.error(Severity.ERROR,
- xmlFileAndLine(mMainDoc),
- "Could not find element %1$s.",
- parentPath);
- return false;
- }
-
- boolean success = true;
-
- nextSource: for (Element src : findElements(libDoc, path)) {
- String name = getAttributeValue(src, keyAttr);
- if (name.length() == 0) {
- mLog.error(Severity.ERROR,
- xmlFileAndLine(src),
- "Undefined '%1$s' attribute in %2$s.",
- keyAttr, path);
- success = false;
- continue;
- }
-
- // Look for the same item in the destination
- List<Element> dests = findElements(mMainDoc, path, keyAttr, name);
- if (dests.size() > 1) {
- // This should not be happening. We'll just use the first one found in this case.
- mLog.error(Severity.WARNING,
- xmlFileAndLine(dests.get(0)),
- "Manifest has more than one %1$s[@%2$s=%3$s] element.",
- path, keyAttr, name);
- }
- boolean doMerge = true;
- for (Element dest : dests) {
- // Don't try to merge this element since it has tools:merge=override|remove.
- if (hasOverrideOrRemoveTag(dest)) {
- doMerge = false;
- continue;
- }
- // If there's already a similar node in the destination, check it's identical.
- StringBuilder diff = new StringBuilder();
- if (compareElements(dest, src, false, diff, keyAttr)) {
- // Same element. Skip.
- if (warnDups) {
- mLog.conflict(Severity.INFO,
- xmlFileAndLine(dest),
- xmlFileAndLine(src),
- "Skipping identical %1$s[@%2$s=%3$s] element.",
- path, keyAttr, name);
- }
- continue nextSource;
- } else {
- // Print the diff we got from the comparison.
- mLog.conflict(Severity.ERROR,
- xmlFileAndLine(dest),
- xmlFileAndLine(src),
- "Trying to merge incompatible %1$s[@%2$s=%3$s] element:\n%4$s",
- path, keyAttr, name, diff.toString());
- success = false;
- continue nextSource;
- }
- }
-
- if (doMerge) {
- // Ready to merge element src. Select which previous siblings to merge.
- Node start = selectPreviousSiblings(src);
-
- insertAtEndOf(parent, start, src);
- }
- }
-
- return success;
- }
-
- /**
- * Returns the value of the given "android:attribute" in the given element.
- *
- * @param element The non-null element where to extract the attribute.
- * @param attrName The local name of the attribute.
- * It must use the {@link #NS_URI} but no prefix should be specified here.
- * @return The value of the attribute or a non-null empty string if not found.
- */
- private String getAttributeValue(Element element, String attrName) {
- Attr attr = element.getAttributeNodeNS(NS_URI, attrName);
- String value = attr == null ? "" : attr.getNodeValue(); //$NON-NLS-1$
- return value;
- }
-
- /**
- * Merge elements as identified by their key name attribute.
- * The element must have an option boolean "required" attribute which can be either "true" or
- * "false". Default is true if the attribute is missisng. When merging, a "false" is superseded
- * by a "true" (explicit or implicit).
- * <p/>
- * When merging, this does NOT merge any other attributes than {@code keyAttr} and
- * {@code requiredAttr}.
- *
- * @param path The XPath of the elements to merge from the library. Must not be null.
- * @param keyAttr The Android-namespace attribute used as key to identify similar elements.
- * E.g. "name" for "android:name"
- * @param requiredAttr The name of the Android-namespace boolean attribute that must be merged.
- * Typically should be "required".
- * @param libDoc The library document to merge from. Must not be null.
- * @param alternateKeyAttr When non-null, this is an alternate valid key attribute. If the
- * default key attribute is missing, we won't output a warning if the alternate one is
- * present.
- * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
- */
- private boolean mergeAdjustRequired(
- String path,
- String keyAttr,
- String requiredAttr,
- Document libDoc,
- @Nullable String alternateKeyAttr) {
-
- // The parent of XPath /p1/p2/p3 is /p1/p2. To find it, delete the last "/segment"
- int pos = path.lastIndexOf('/');
- assert pos > 1;
- String parentPath = path.substring(0, pos);
- Element parent = findFirstElement(mMainDoc, parentPath);
- assert parent != null;
- if (parent == null) {
- mLog.error(Severity.ERROR,
- xmlFileAndLine(mMainDoc),
- "Could not find element %1$s.",
- parentPath);
- return false;
- }
-
- boolean success = true;
-
- for (Element src : findElements(libDoc, path)) {
- Attr attr = src.getAttributeNodeNS(NS_URI, keyAttr);
- String name = attr == null ? "" : attr.getNodeValue().trim(); //$NON-NLS-1$
- if (name.length() == 0) {
- if (alternateKeyAttr != null) {
- attr = src.getAttributeNodeNS(NS_URI, alternateKeyAttr);
- String s = attr == null ? "" : attr.getNodeValue().trim(); //$NON-NLS-1$
- if (s.length() != 0) {
- // This element lacks the keyAttr but has the alternateKeyAttr. Skip it.
- continue;
- }
- }
-
- mLog.error(Severity.ERROR,
- xmlFileAndLine(src),
- "Undefined '%1$s' attribute in %2$s.",
- keyAttr, path);
- success = false;
- continue;
- }
-
- // Look for the same item in the destination
- List<Element> dests = findElements(mMainDoc, path, keyAttr, name);
- if (dests.size() > 1) {
- // This should not be happening. We'll just use the first one found in this case.
- mLog.error(Severity.WARNING,
- xmlFileAndLine(dests.get(0)),
- "Manifest has more than one %1$s[@%2$s=%3$s] element.",
- path, keyAttr, name);
- }
- if (dests.size() > 0) {
-
- attr = src.getAttributeNodeNS(NS_URI, requiredAttr);
- String value = attr == null ? "true" : attr.getNodeValue(); //$NON-NLS-1$
- if (value == null || !(value.equals("true") || value.equals("false"))) {
- mLog.error(Severity.WARNING,
- xmlFileAndLine(src),
- "Invalid attribute '%1$s' in %2$s[@%3$s=%4$s] element:\nExpected 'true' or 'false' but found '%5$s'.",
- requiredAttr, path, keyAttr, name, value);
- continue;
- }
- boolean boolE = Boolean.parseBoolean(value);
-
- for (Element dest : dests) {
- // Don't try to merge this element since it has tools:merge=override|remove.
- if (hasOverrideOrRemoveTag(dest)) {
- continue;
- }
-
- // Compare the required attributes.
- attr = dest.getAttributeNodeNS(NS_URI, requiredAttr);
- value = attr == null ? "true" : attr.getNodeValue(); //$NON-NLS-1$
- if (value == null || !(value.equals("true") || value.equals("false"))) {
- mLog.error(Severity.WARNING,
- xmlFileAndLine(dest),
- "Invalid attribute '%1$s' in %2$s[@%3$s=%4$s] element:\nExpected 'true' or 'false' but found '%5$s'.",
- requiredAttr, path, keyAttr, name, value);
- continue;
- }
- boolean boolD = Boolean.parseBoolean(value);
-
- if (!boolD && boolE) {
- // Required attributes differ: destination is false and source was true
- // so we need to change the destination to true.
-
- // If attribute was already in the destination, change it in place
- if (attr != null) {
- attr.setNodeValue("true"); //$NON-NLS-1$
- } else {
- // Otherwise, do nothing. The destination doesn't have the
- // required=true attribute, and true is the default value.
- // Consequently not setting is the right thing to do.
-
- // -- code snippet for reference --
- // If we wanted to create a new attribute, we'd use the code
- // below. There's a simpler call to d.setAttributeNS(ns, name, value)
- // but experience shows that it would create a new prefix out of the
- // blue instead of looking it up.
- //
- // Attr a=d.getOwnerDocument().createAttributeNS(NS_URI, requiredAttr);
- // String prefix = d.lookupPrefix(NS_URI);
- // if (prefix != null) {
- // a.setPrefix(prefix);
- // }
- // a.setValue("true"); //$NON-NLS-1$
- // d.setAttributeNodeNS(attr);
- }
- }
- }
- } else {
- // Destination doesn't exist. We simply merge the source element.
- // Select which previous siblings to merge.
- Node start = selectPreviousSiblings(src);
-
- Node node = insertAtEndOf(parent, start, src);
-
- NamedNodeMap attrs = node.getAttributes();
- if (attrs != null) {
- for (int i = 0; i < attrs.getLength(); i++) {
- Node a = attrs.item(i);
- if (a.getNodeType() == Node.ATTRIBUTE_NODE) {
- boolean keep = NS_URI.equals(a.getNamespaceURI());
- if (keep) {
- name = a.getLocalName();
- keep = keyAttr.equals(name) || requiredAttr.equals(name);
- }
- if (!keep) {
- attrs.removeNamedItemNS(NS_URI, name);
- // Restart the loop from index 0 since there's no
- // guarantee on the order of the nodes in the "map".
- // This makes it O(n+2n) at most, where n is [2..3] in
- // a typical case.
- i = -1;
- }
- }
- }
- }
- }
- }
-
- return success;
- }
-
-
-
- /**
- * Checks (but does not merge) uses-feature glEsVersion attribute using the following rules:
- * <pre>
- * - Error if defined in lib+dest with dest&lt;lib.
- * - Never automatically change dest.
- * - Default implied value is 1.0 (0x00010000).
- * </pre>
- *
- * @param libDoc The library document to merge from. Must not be null.
- * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
- */
- private boolean checkGlEsVersion(Document libDoc) {
-
- String parentPath = "/manifest"; //$NON-NLS-1$
- Element parent = findFirstElement(mMainDoc, parentPath);
- assert parent != null;
- if (parent == null) {
- mLog.error(Severity.ERROR,
- xmlFileAndLine(mMainDoc),
- "Could not find element %1$s.",
- parentPath);
- return false;
- }
-
- // Find the max glEsVersion on the destination side
- String path = "/manifest/uses-feature"; //$NON-NLS-1$
- String keyAttr = "glEsVersion"; //$NON-NLS-1$
- long destGlEsVersion = 0x00010000L; // default minimum is 1.0
- Element destNode = null;
- boolean result = true;
- for (Element dest : findElements(mMainDoc, path)) {
- Attr attr = dest.getAttributeNodeNS(NS_URI, keyAttr);
- String value = attr == null ? "" : attr.getNodeValue().trim(); //$NON-NLS-1$
- if (value.length() != 0) {
- try {
- // Note that the value can be an hex number such as 0x00020001 so we
- // need Integer.decode instead of Integer.parseInt.
- // Note: Integer.decode cannot handle "ffffffff", see JDK issue 6624867
- // so we just treat the version as a long and test like this, ignoring
- // the fact that a value of 0xFFFF/.0xFFFF is probably invalid anyway
- // in the context of glEsVersion.
- long version = Long.decode(value);
- if (version >= destGlEsVersion) {
- destGlEsVersion = version;
- destNode = dest;
- } else if (version < 0x00010000) {
- mLog.error(Severity.WARNING,
- xmlFileAndLine(dest),
- "Ignoring <uses-feature android:glEsVersion='%1$s'> because it's smaller than 1.0.",
- value);
- }
- } catch (NumberFormatException e) {
- // Note: NumberFormatException.toString() has no interesting information
- // so we don't output it.
- mLog.error(Severity.ERROR,
- xmlFileAndLine(dest),
- "Failed to parse <uses-feature android:glEsVersion='%1$s'>: must be an integer in the form 0x00020001.",
- value);
- result = false;
- }
- }
- }
-
- // If we found at least one valid with no error, use that, otherwise bail out.
- if (!result && destNode == null) {
- return false;
- }
-
- // Now find the max glEsVersion on the source side.
-
- long srcGlEsVersion = 0x00010000L; // default minimum is 1.0
- Element srcNode = null;
- result = true;
- for (Element src : findElements(libDoc, path)) {
- Attr attr = src.getAttributeNodeNS(NS_URI, keyAttr);
- String value = attr == null ? "" : attr.getNodeValue().trim(); //$NON-NLS-1$
- if (value.length() != 0) {
- try {
- // See comment on Long.decode above.
- long version = Long.decode(value);
- if (version >= srcGlEsVersion) {
- srcGlEsVersion = version;
- srcNode = src;
- } else if (version < 0x00010000) {
- mLog.error(Severity.WARNING,
- xmlFileAndLine(src),
- "Ignoring <uses-feature android:glEsVersion='%1$s'> because it's smaller than 1.0.",
- value);
- }
- } catch (NumberFormatException e) {
- // Note: NumberFormatException.toString() has no interesting information
- // so we don't output it.
- mLog.error(Severity.ERROR,
- xmlFileAndLine(src),
- "Failed to parse <uses-feature android:glEsVersion='%1$s'>: must be an integer in the form 0x00020001.",
- value);
- result = false;
- }
- }
- }
-
- if (srcNode != null && destGlEsVersion < srcGlEsVersion) {
- mLog.conflict(Severity.WARNING,
- xmlFileAndLine(destNode == null ? mMainDoc : destNode),
- xmlFileAndLine(srcNode),
- "Main manifest has <uses-feature android:glEsVersion='0x%1$08x'> but library uses glEsVersion='0x%2$08x'%3$s",
- destGlEsVersion,
- srcGlEsVersion,
- destNode != null ? "" : //$NON-NLS-1$
- "\nNote: main manifest lacks a <uses-feature android:glEsVersion> declaration, and thus defaults to glEsVersion=0x00010000."
- );
- result = false;
- }
-
- return result;
- }
-
- /**
- * Checks (but does not merge) uses-sdk attributes using the following rules:
- * <pre>
- * - {@code @minSdkVersion}: error if dest&lt;lib. Never automatically change dest minsdk.
- * - {@code @targetSdkVersion}: warning if dest&lt;lib. Never automatically change destination.
- * - {@code @maxSdkVersion}: obsolete, ignored. Not used in comparisons and not merged.
- * - The API level can be a codename if we have a callback that can convert it to an integer.
- * </pre>
- * @param libDoc The library document to merge from. Must not be null.
- * @return True on success, false if any error occurred (printed to the {@link IMergerLog}).
- */
- private boolean checkSdkVersion(Document libDoc) {
-
- boolean result = true;
-
- Element destUsesSdk = findFirstElement(mMainDoc, "/manifest/uses-sdk"); //$NON-NLS-1$
-
- if (hasOverrideOrRemoveTag(destUsesSdk)) {
- // Don't try to check this element since it has tools:merge=override|remove.
- return true;
- }
-
- Element srcUsesSdk = findFirstElement(libDoc, "/manifest/uses-sdk"); //$NON-NLS-1$
-
- AtomicInteger destValue = new AtomicInteger(1);
- AtomicInteger srcValue = new AtomicInteger(1);
- AtomicBoolean destImplied = new AtomicBoolean(true);
- AtomicBoolean srcImplied = new AtomicBoolean(true);
-
- // Check minSdkVersion
- int destMinSdk = 1;
- result = extractSdkVersionAttribute(
- libDoc,
- destUsesSdk, srcUsesSdk,
- "min", //$NON-NLS-1$
- destValue, srcValue,
- destImplied, srcImplied);
-
- if (result) {
- // Make it an error for an application to use a library with a greater
- // minSdkVersion. This means the library code may crash unexpectedly.
- // TODO it would be nice to be able to work around this in case the
- // user think s/he knows what s/he's doing.
- // We could define a simple XML comment flag: <!-- @NoMinSdkVersionMergeError -->
-
- destMinSdk = destValue.get();
-
- if (destMinSdk < srcValue.get()) {
- mLog.conflict(Severity.ERROR,
- xmlFileAndLine(destUsesSdk == null ? mMainDoc : destUsesSdk),
- xmlFileAndLine(srcUsesSdk == null ? libDoc : srcUsesSdk),
- "Main manifest has <uses-sdk android:minSdkVersion='%1$d'> but library uses minSdkVersion='%2$d'%3$s",
- destMinSdk,
- srcValue.get(),
- !destImplied.get() ? "" : //$NON-NLS-1$
- "\nNote: main manifest lacks a <uses-sdk android:minSdkVersion> declaration, which defaults to value 1."
- );
- result = false;
- }
- }
-
- // Check targetSdkVersion.
-
- // Note that destValue/srcValue purposely defaults to whatever minSdkVersion was last read
- // since that's their definition when missing.
- destImplied.set(true);
- srcImplied.set(true);
-
- boolean result2 = extractSdkVersionAttribute(
- libDoc,
- destUsesSdk, srcUsesSdk,
- "target", //$NON-NLS-1$
- destValue, srcValue,
- destImplied, srcImplied);
-
- result &= result2;
- if (result2) {
- // Make it a warning for an application to use a library with a greater
- // targetSdkVersion.
-
- int destTargetSdk = destImplied.get() ? destMinSdk : destValue.get();
-
- if (destTargetSdk < srcValue.get()) {
- mLog.conflict(Severity.WARNING,
- xmlFileAndLine(destUsesSdk == null ? mMainDoc : destUsesSdk),
- xmlFileAndLine(srcUsesSdk == null ? libDoc : srcUsesSdk),
- "Main manifest has <uses-sdk android:targetSdkVersion='%1$d'> but library uses targetSdkVersion='%2$d'%3$s",
- destTargetSdk,
- srcValue.get(),
- !destImplied.get() ? "" : //$NON-NLS-1$
- "\nNote: main manifest lacks a <uses-sdk android:targetSdkVersion> declaration, which defaults to value minSdkVersion or 1."
- );
- result = false;
- }
- }
-
- return result;
- }
-
- /**
- * Implementation detail for {@link #checkSdkVersion(Document)}.
- * Note that the various atomic out-variables must be preset to their default before
- * the call.
- * <p/>
- * destValue/srcValue will be filled with the integer value of the field, if present
- * and a correct number, in which case destImplied/destImplied are also set to true.
- * Otherwise the values and the implied variables are left untouched.
- */
- private boolean extractSdkVersionAttribute(
- Document libDoc,
- Element destUsesSdk,
- Element srcUsesSdk,
- String attr,
- AtomicInteger destValue,
- AtomicInteger srcValue,
- AtomicBoolean destImplied,
- AtomicBoolean srcImplied) {
- String s = destUsesSdk == null ? "" //$NON-NLS-1$
- : destUsesSdk.getAttributeNS(NS_URI, attr + "SdkVersion"); //$NON-NLS-1$
-
- boolean result = true;
- assert s != null;
- s = s.trim();
- try {
- if (s.length() > 0) {
- destValue.set(Integer.parseInt(s));
- destImplied.set(false);
- }
- } catch (NumberFormatException e) {
- boolean error = true;
- if (mCallback != null) {
- // Versions can contain codenames such as "JellyBean".
- // We'll accept it only if have a callback that can give us the API level for it.
- int apiLevel = mCallback.queryCodenameApiLevel(s);
- if (apiLevel > ICallback.UNKNOWN_CODENAME) {
- destValue.set(apiLevel);
- destImplied.set(false);
- error = false;
- }
- }
- if (error) {
- // Note: NumberFormatException.toString() has no interesting information
- // so we don't output it.
- mLog.error(Severity.ERROR,
- xmlFileAndLine(destUsesSdk == null ? mMainDoc : destUsesSdk),
- "Failed to parse <uses-sdk %1$sSdkVersion='%2$s'>: must be an integer number or codename.",
- attr,
- s);
- result = false;
- }
- }
-
- s = srcUsesSdk == null ? "" //$NON-NLS-1$
- : srcUsesSdk.getAttributeNS(NS_URI, attr + "SdkVersion"); //$NON-NLS-1$
- assert s != null;
- s = s.trim();
- try {
- if (s.length() > 0) {
- srcValue.set(Integer.parseInt(s));
- srcImplied.set(false);
- }
- } catch (NumberFormatException e) {
- boolean error = true;
- if (mCallback != null) {
- // Versions can contain codenames such as "JellyBean".
- // We'll accept it only if have a callback that can give us the API level for it.
- int apiLevel = mCallback.queryCodenameApiLevel(s);
- if (apiLevel > ICallback.UNKNOWN_CODENAME) {
- srcValue.set(apiLevel);
- srcImplied.set(false);
- error = false;
- }
- }
- if (error) {
- mLog.error(Severity.ERROR,
- xmlFileAndLine(srcUsesSdk == null ? libDoc : srcUsesSdk),
- "Failed to parse <uses-sdk %1$sSdkVersion='%2$s'>: must be an integer number or codename.",
- attr,
- s);
- result = false;
- }
- }
-
- return result;
- }
-
-
- // -----
-
-
- /**
- * Given an element E, select which previous siblings we want to merge.
- * We want to include any whitespace up to the closing of the previous element.
- * We also want to include up preceding comment nodes and their preceding whitespace.
- * <p/>
- * This may returns either {@code end} or a previous sibling. Never returns null.
- */
- @NonNull
- private Node selectPreviousSiblings(Node end) {
-
- Node start = end;
- Node prev = start.getPreviousSibling();
- while (prev != null) {
- short t = prev.getNodeType();
- if (t == Node.TEXT_NODE) {
- String text = prev.getNodeValue();
- if (text == null || text.trim().length() != 0) {
- // Not whitespace, we don't want it.
- break;
- }
- } else if (t == Node.COMMENT_NODE) {
- // It's a comment. We'll take it.
- } else {
- // Not a comment node nor a whitespace text. We don't want it.
- break;
- }
- start = prev;
- prev = start.getPreviousSibling();
- }
-
- return start;
- }
-
- /**
- * Inserts all siblings from {@code start} to {@code end} at the end
- * of the given destination element.
- * <p/>
- * Implementation detail: this clones the source nodes into the destination.
- *
- * @param dest The destination at the end of which to insert. Cannot be null.
- * @param start The first element to insert. Must not be null.
- * @param end The last element to insert (included). Must not be null.
- * Must be a direct "next sibling" of the start node.
- * Can be equal to the start node to insert just that one node.
- * @return The copy of the {@code end} node in the destination document or null
- * if no such copy was created and added to the destination.
- */
- private Node insertAtEndOf(Element dest, Node start, Node end) {
- // Check whether we'll need to adjust URI prefixes
- String destPrefix = XmlUtils.lookupNamespacePrefix(mMainDoc, NS_URI);
- String srcPrefix = XmlUtils.lookupNamespacePrefix(start.getOwnerDocument(), NS_URI);
- boolean needPrefixChange = destPrefix != null && !destPrefix.equals(srcPrefix);
-
- // First let's figure out the insertion point.
- // We want the end of the last 'content' element of the
- // destination element and basically we want to insert right
- // before the last whitespace of the destination element.
- Node target = dest.getLastChild();
- while (target != null) {
- if (target.getNodeType() == Node.TEXT_NODE) {
- String text = target.getNodeValue();
- if (text == null || text.trim().length() != 0) {
- // Not whitespace, insert after.
- break;
- }
- } else {
- // Not text. Insert after
- break;
- }
- target = target.getPreviousSibling();
- }
- if (target != null) {
- target = target.getNextSibling();
- }
-
- // Destination and start..end must not be part of the same document
- // because we try to import below. If they were, it would mess the
- // structure.
- assert dest.getOwnerDocument() == mMainDoc;
- assert dest.getOwnerDocument() != start.getOwnerDocument();
- assert start.getOwnerDocument() == end.getOwnerDocument();
-
- while (start != null) {
- Node node = mMainDoc.importNode(start, true /*deep*/);
- if (needPrefixChange) {
- changePrefix(node, srcPrefix, destPrefix);
- }
- dest.insertBefore(node, target);
-
- if (start == end) {
- return node;
- }
- start = start.getNextSibling();
- }
- return null;
- }
-
- /**
- * Changes the namespace prefix of all nodes, recursively.
- *
- * @param node The node to process, as well as all it's descendants. Can be null.
- * @param srcPrefix The prefix to match.
- * @param destPrefix The new prefix to replace with.
- */
- private void changePrefix(Node node, String srcPrefix, String destPrefix) {
- for (; node != null; node = node.getNextSibling()) {
- if (srcPrefix.equals(node.getPrefix())) {
- node.setPrefix(destPrefix);
- }
- Node child = node.getFirstChild();
- if (child != null) {
- changePrefix(child, srcPrefix, destPrefix);
- }
- }
- }
-
- /**
- * Compares two {@link Element}s recursively.
- * They must be identical with the same structure.
- * Order should not matter.
- * Whitespace and comments are ignored.
- *
- * @param expected The first element to compare.
- * @param actual The second element to compare with.
- * @param nextSiblings If true, will also compare the following siblings.
- * If false, it will just compare the given node.
- * @param diff An optional {@link StringBuilder} where to accumulate a diff output.
- * @param keyAttr An optional key attribute to always add to elements when dumping a diff.
- * @return True if {@code e1} and {@code e2} are equal.
- */
- private boolean compareElements(
- @NonNull Node expected,
- @NonNull Node actual,
- boolean nextSiblings,
- @Nullable StringBuilder diff,
- @Nullable String keyAttr) {
- Map<String, String> nsPrefixE = new HashMap<String, String>();
- Map<String, String> nsPrefixA = new HashMap<String, String>();
- String sE = MergerXmlUtils.printElement(expected, nsPrefixE, ""); //$NON-NLS-1$
- String sA = MergerXmlUtils.printElement(actual, nsPrefixA, ""); //$NON-NLS-1$
- if (sE.equals(sA)) {
- return true;
- } else {
- if (diff != null) {
- MergerXmlUtils.printXmlDiff(diff, sE, sA, nsPrefixE, nsPrefixA, NS_URI + ':' + keyAttr);
- }
- return false;
- }
- }
-
- /**
- * Finds the first element matching the given XPath expression in the given document.
- *
- * @param doc The document where to find the expression.
- * @param path The XPath expression. It must yield an {@link Element} node type.
- * @return The {@link Element} found or null.
- */
- @Nullable
- private Element findFirstElement(
- @NonNull Document doc,
- @NonNull String path) {
- Node result;
- try {
- result = (Node) mXPath.evaluate(path, doc, XPathConstants.NODE);
- if (result instanceof Element) {
- return (Element) result;
- }
-
- if (result != null) {
- mLog.error(Severity.ERROR,
- xmlFileAndLine(doc),
- "Unexpected Node type %s when evaluating %s", //$NON-NLS-1$
- result.getClass().getName(), path);
- }
- } catch (XPathExpressionException e) {
- mLog.error(Severity.ERROR,
- xmlFileAndLine(doc),
- "XPath error on expr %s: %s", //$NON-NLS-1$
- path, e.toString());
- }
- return null;
- }
-
- /**
- * Finds zero or more elements matching the given XPath expression in the given document.
- *
- * @param doc The document where to find the expression.
- * @param path The XPath expression. Only {@link Element}s nodes will be returned.
- * @return A list of {@link Element} found, possibly empty but never null.
- */
- private List<Element> findElements(
- @NonNull Document doc,
- @NonNull String path) {
- return findElements(doc, path, null, null);
- }
-
-
- /**
- * Finds zero or more elements matching the given XPath expression in the given document.
- * <p/>
- * Furthermore, the elements must have an attribute matching the given attribute name
- * and value if provided. (If you don't need to match an attribute, use the other version.)
- * <p/>
- * Note that if you provide {@code attrName} as non-null then the {@code attrValue}
- * must be non-null too. In this case the XPath expression will be modified to add
- * the check by naively appending a "[name='value']" filter.
- *
- * @param doc The document where to find the expression.
- * @param path The XPath expression. Only {@link Element}s nodes will be returned.
- * @param attrName The name of the optional attribute to match. Can be null.
- * @param attrValue The value of the optional attribute to match.
- * Can be null if {@code attrName} is null, otherwise must be non-null.
- * @return A list of {@link Element} found, possibly empty but never null.
- *
- * @see #findElements(Document, String)
- */
- private List<Element> findElements(
- @NonNull Document doc,
- @NonNull String path,
- @Nullable String attrName,
- @Nullable String attrValue) {
- List<Element> elements = new ArrayList<Element>();
-
- if (attrName != null) {
- assert attrValue != null;
- // Generate expression /manifest/application/activity[@android:name='my.fqcn']
- path = String.format("%1$s[@%2$s:%3$s='%4$s']", //$NON-NLS-1$
- path, NS_PREFIX, attrName, attrValue);
- }
-
- try {
- NodeList results = (NodeList) mXPath.evaluate(path, doc, XPathConstants.NODESET);
- if (results != null && results.getLength() > 0) {
- for (int i = 0; i < results.getLength(); i++) {
- Node n = results.item(i);
- assert n instanceof Element;
- if (n instanceof Element) {
- elements.add((Element) n);
- } else {
- mLog.error(Severity.ERROR,
- xmlFileAndLine(doc),
- "Unexpected Node type %s when evaluating %s", //$NON-NLS-1$
- n.getClass().getName(), path);
- }
- }
- }
-
- } catch (XPathExpressionException e) {
- mLog.error(Severity.ERROR,
- xmlFileAndLine(doc),
- "XPath error on expr %s: %s", //$NON-NLS-1$
- path, e.toString());
- }
-
- return elements;
- }
-
- /**
- * Returns a new {@link FileAndLine} structure that identifies
- * the base filename & line number from which the XML node was parsed.
- * <p/>
- * When the line number is unknown (e.g. if a {@link Document} instance is given)
- * then line number 0 will be used.
- *
- * @param node The node or document where the error occurs. Must not be null.
- * @return A new non-null {@link FileAndLine} combining the file name and line number.
- */
- private @NonNull FileAndLine xmlFileAndLine(@NonNull Node node) {
- return MergerXmlUtils.xmlFileAndLine(node);
- }
-
- /**
- * Checks whether the given element has a tools:merge=override or tools:merge=remove attribute.
- * @param node The node to check.
- * @return True if the element has a tools:merge=override or tools:merge=remove attribute.
- */
- private boolean hasOverrideOrRemoveTag(@Nullable Node node) {
- if (node == null || node.getNodeType() != Node.ELEMENT_NODE) {
- return false;
- }
- NamedNodeMap attrs = node.getAttributes();
- Node merge = attrs.getNamedItemNS(TOOLS_URI, MERGE_ATTR);
- String value = merge == null ? null : merge.getNodeValue();
- return MERGE_OVERRIDE.equals(value) || MERGE_REMOVE.equals(value);
- }
-
- /**
- * Cleans up all tools attributes from the given node hierarchy.
- * <p/>
- * If an element is marked with tools:merge=override, this attribute is removed.
- * If an element is marked with tools:merge=remove, the <em>whole</em> element is removed.
- *
- * @param root The root node to parse and edit, recursively.
- */
- private void cleanupToolsAttributes(@Nullable Node root) {
- if (root == null) {
- return;
- }
- NamedNodeMap attrs = root.getAttributes();
- if (attrs != null) {
- for (int i = attrs.getLength() - 1; i >= 0; i--) {
- Node attr = attrs.item(i);
- if (SdkConstants.XMLNS_URI.equals(attr.getNamespaceURI()) &&
- TOOLS_URI.equals(attr.getNodeValue())) {
- attrs.removeNamedItem(attr.getNodeName());
- } else if (TOOLS_URI.equals(attr.getNamespaceURI()) &&
- MERGE_ATTR.equals(attr.getLocalName())) {
- attrs.removeNamedItem(attr.getNodeName());
- }
- }
- assert attrs.getNamedItemNS(TOOLS_URI, MERGE_ATTR) == null;
- }
-
- for (Node child = root.getFirstChild(); child != null; ) {
- if (child.getNodeType() != Node.ELEMENT_NODE) {
- child = child.getNextSibling();
- continue;
- }
- attrs = child.getAttributes();
- Node merge = attrs == null ? null : attrs.getNamedItemNS(TOOLS_URI, MERGE_ATTR);
- String value = merge == null ? null : merge.getNodeValue();
- Node sibling = child.getNextSibling();
- if (MERGE_REMOVE.equals(value)) {
- // Note: save the previous sibling since removing the child will clear its siblings.
- Node prev = child.getPreviousSibling();
- root.removeChild(child);
- // If there's some whitespace just before that element, clean it up too.
- while (prev != null && prev.getNodeType() == Node.TEXT_NODE) {
- if (prev.getNodeValue().trim().length() == 0) {
- Node prevPrev = prev.getPreviousSibling();
- root.removeChild(prev);
- prev = prevPrev;
- } else {
- break;
- }
- }
- } else {
- cleanupToolsAttributes(child);
- }
- child = sibling;
- }
- }
-
- /**
- * @see #cleanupToolsAttributes(Node)
- */
- private Document cleanupToolsAttributes(@NonNull Document doc) {
- cleanupToolsAttributes(doc.getFirstChild());
- return doc;
- }
-}
diff --git a/manifmerger/src/main/java/com/android/manifmerger/MergerLog.java b/manifmerger/src/main/java/com/android/manifmerger/MergerLog.java
deleted file mode 100755
index 446898c..0000000
--- a/manifmerger/src/main/java/com/android/manifmerger/MergerLog.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2012 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.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.utils.ILogger;
-
-
-/**
- * Helper to create {@link IMergerLog} instances with specific purposes.
- */
-public abstract class MergerLog {
-
- /**
- * Create a new instance of a {@link MergerLog} that prints to an {@link ILogger}.
- *
- * @param sdkLog A non-null {@link ILogger}.
- * @return A new IMergerLog.
- */
- public static IMergerLog wrapSdkLog(final @NonNull ILogger sdkLog) {
- return new IMergerLog() {
- @Override
- public void error(
- @NonNull Severity severity,
- @NonNull FileAndLine location,
- @NonNull String message,
- Object...msgParams) {
-
- switch(severity) {
- case INFO:
- sdkLog.info(
- "[%1$s] %2$s", //$NON-NLS-1$
- location,
- String.format(message, msgParams));
- break;
- case WARNING:
- sdkLog.warning(
- "[%1$s] %2$s", //$NON-NLS-1$
- location,
- String.format(message, msgParams));
- break;
- case ERROR:
- sdkLog.error(null /*throwable*/,
- "[%1$s] %2$s", //$NON-NLS-1$
- location,
- String.format(message, msgParams));
- break;
- }
- }
-
- @Override
- public void conflict(@NonNull Severity severity,
- @NonNull FileAndLine location1,
- @NonNull FileAndLine location2,
- @NonNull String message,
- Object...msgParams) {
-
- switch(severity) {
- case INFO:
- sdkLog.info(
- "[%1$s, %2$s] %3$s", //$NON-NLS-1$
- location1,
- location2,
- String.format(message, msgParams));
- break;
- case WARNING:
- sdkLog.warning(
- "[%1$s, %2$s] %3$s", //$NON-NLS-1$
- location1,
- location2,
- String.format(message, msgParams));
- break;
- case ERROR:
- sdkLog.error(null /*throwable*/,
- "[%1$s, %2$s] %3$s", //$NON-NLS-1$
- location1,
- location2,
- String.format(message, msgParams));
- break;
- }
- };
- };
- }
-
- /*
- * Creates a new instance of a {@link MergerLog} that wraps another {@link IMergerLog}
- * and overrides the {@link FileAndLine} locations with the arguments specified.
- * <p/>
- * An example of usage would be merging temporary files yet associating the errors
- * with the original files.
- *
- * @param parentLog A non-null IMergerLog to wrap.
- * @param filePath1 The file path to override in location1 (for errors and conflicts).
- * @param filePath2 An optional file path to override in location2 (for conflicts).
- * @return A new IMergerLog.
- */
- public static IMergerLog mergerLogOverrideLocation(
- final @NonNull IMergerLog parentLog,
- final @Nullable String filePath1,
- final @Nullable String... filePath2) {
- return new IMergerLog() {
- @Override
- public void error(
- @NonNull Severity severity,
- @NonNull FileAndLine location,
- @NonNull String message,
- Object...msgParams) {
-
- if (filePath1 != null) {
- location = new FileAndLine(filePath1, location.getLine());
- }
-
- parentLog.error(severity, location, message, msgParams);
- }
-
- @Override
- public void conflict(@NonNull Severity severity,
- @NonNull FileAndLine location1,
- @NonNull FileAndLine location2,
- @NonNull String message,
- Object...msgParams) {
-
- if (filePath1 != null) {
- location1 = new FileAndLine(filePath1, location1.getLine());
- }
-
- if (filePath2 != null && filePath2.length > 0) {
- location2 = new FileAndLine(filePath2[0], location2.getLine());
- }
-
- parentLog.conflict(severity, location1, location2, message, msgParams);
- };
- };
- }
-
-}
diff --git a/manifmerger/src/main/java/com/android/manifmerger/MergerXmlUtils.java b/manifmerger/src/main/java/com/android/manifmerger/MergerXmlUtils.java
deleted file mode 100755
index bb60464..0000000
--- a/manifmerger/src/main/java/com/android/manifmerger/MergerXmlUtils.java
+++ /dev/null
@@ -1,915 +0,0 @@
-/*
- * Copyright (C) 2011 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.annotations.NonNull;
-import com.android.annotations.Nullable;
-import com.android.manifmerger.IMergerLog.FileAndLine;
-import com.android.manifmerger.IMergerLog.Severity;
-import com.android.utils.ILogger;
-import com.android.utils.XmlUtils;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXParseException;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-/**
- * A few XML handling utilities.
- */
-class MergerXmlUtils {
-
- private static final String DATA_ORIGIN_FILE = "manif.merger.file"; //$NON-NLS-1$
- private static final String DATA_FILE_NAME = "manif.merger.filename"; //$NON-NLS-1$
- private static final String DATA_LINE_NUMBER = "manif.merger.line#"; //$NON-NLS-1$
-
- /**
- * Parses the given XML file as a DOM document.
- * The parser does not validate the DTD nor any kind of schema.
- * It is namespace aware.
- * <p/>
- * This adds a user tag with the original {@link File} to the returned document.
- * You can retrieve this file later by using {@link #extractXmlFilename(Node)}.
- *
- * @param xmlFile The XML {@link File} to parse. Must not be null.
- * @param log An {@link ILogger} for reporting errors. Must not be null.
- * @return A new DOM {@link Document}, or null.
- */
- @Nullable
- static Document parseDocument(@NonNull final File xmlFile, @NonNull final IMergerLog log) {
- try {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- Reader reader = new BufferedReader(new FileReader(xmlFile));
- InputSource is = new InputSource(reader);
- factory.setNamespaceAware(true);
- factory.setValidating(false);
- DocumentBuilder builder = factory.newDocumentBuilder();
-
- // We don't want the default handler which prints errors to stderr.
- builder.setErrorHandler(new ErrorHandler() {
- @Override
- public void warning(SAXParseException e) {
- log.error(Severity.WARNING,
- new FileAndLine(xmlFile.getAbsolutePath(), 0),
- "Warning when parsing: %1$s",
- e.toString());
- }
- @Override
- public void fatalError(SAXParseException e) {
- log.error(Severity.ERROR,
- new FileAndLine(xmlFile.getAbsolutePath(), 0),
- "Fatal error when parsing: %1$s",
- xmlFile.getName(), e.toString());
- }
- @Override
- public void error(SAXParseException e) {
- log.error(Severity.ERROR,
- new FileAndLine(xmlFile.getAbsolutePath(), 0),
- "Error when parsing: %1$s",
- e.toString());
- }
- });
-
- Document doc = builder.parse(is);
- doc.setUserData(DATA_ORIGIN_FILE, xmlFile, null /*handler*/);
- findLineNumbers(doc, 1);
-
- return doc;
-
- } catch (FileNotFoundException e) {
- log.error(Severity.ERROR,
- new FileAndLine(xmlFile.getAbsolutePath(), 0),
- "XML file not found");
-
- } catch (Exception e) {
- log.error(Severity.ERROR,
- new FileAndLine(xmlFile.getAbsolutePath(), 0),
- "Failed to parse XML file: %1$s",
- e.toString());
- }
-
- return null;
- }
-
- /**
- * Parses the given XML string as a DOM document.
- * The parser does not validate the DTD nor any kind of schema.
- * It is namespace aware.
- *
- * @param xml The XML string to parse. Must not be null.
- * @param log An {@link ILogger} for reporting errors. Must not be null.
- * @return A new DOM {@link Document}, or null.
- */
- @Nullable
- static Document parseDocument(@NonNull String xml,
- @NonNull IMergerLog log,
- @NonNull FileAndLine errorContext) {
- try {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- InputSource is = new InputSource(new StringReader(xml));
- factory.setNamespaceAware(true);
- factory.setValidating(false);
- DocumentBuilder builder = factory.newDocumentBuilder();
- Document doc = builder.parse(is);
- findLineNumbers(doc, 1);
- return doc;
- } catch (Exception e) {
- log.error(Severity.ERROR, errorContext, "Failed to parse XML string");
- }
-
- return null;
- }
-
- /**
- * Decorates the document with the specified file name, which can be
- * retrieved later by calling {@link #extractLineNumber(Node)}.
- * <p/>
- * It also tries to add line number information, with the caveat that the
- * current implementation is a gross approximation.
- * <p/>
- * There is no need to call this after calling one of the {@code parseDocument()}
- * methods since they already decorated their own document.
- *
- * @param doc The document to decorate.
- * @param fileName The name to retrieve later for that document.
- */
- static void decorateDocument(@NonNull Document doc, @NonNull String fileName) {
- doc.setUserData(DATA_FILE_NAME, fileName, null /*handler*/);
- findLineNumbers(doc, 1);
- }
-
- /**
- * Returns a new {@link FileAndLine} structure that identifies
- * the base filename & line number from which the XML node was parsed.
- * <p/>
- * When the line number is unknown (e.g. if a {@link Document} instance is given)
- * then line number 0 will be used.
- *
- * @param node The node or document where the error occurs. Must not be null.
- * @return A new non-null {@link FileAndLine} combining the file name and line number.
- */
- @NonNull
- static FileAndLine xmlFileAndLine(@NonNull Node node) {
- String name = extractXmlFilename(node);
- int line = extractLineNumber(node); // 0 in case of error or unknown
- return new FileAndLine(name, line);
- }
-
- /**
- * Extracts the origin {@link File} that {@link #parseDocument(File, IMergerLog)}
- * added to the XML document or the string added by
- *
- * @param xmlNode Any node from a document returned by {@link #parseDocument(File, IMergerLog)}.
- * @return The {@link File} object used to create the document or null.
- */
- @Nullable
- static String extractXmlFilename(@Nullable Node xmlNode) {
- if (xmlNode != null && xmlNode.getNodeType() != Node.DOCUMENT_NODE) {
- xmlNode = xmlNode.getOwnerDocument();
- }
- if (xmlNode != null) {
- Object data = xmlNode.getUserData(DATA_ORIGIN_FILE);
- if (data instanceof File) {
- return ((File) data).getName();
- }
- data = xmlNode.getUserData(DATA_FILE_NAME);
- if (data instanceof String) {
- return (String) data;
- }
- }
-
- return null;
- }
-
- /**
- * This is a CRUDE INEXACT HACK to decorate the DOM with some kind of line number
- * information for elements. It's inexact because by the time we get the DOM we
- * already have lost all the information about whitespace between attributes.
- * <p/>
- * Also we don't even try to deal with \n vs \r vs \r\n insanity. This only counts
- * the \n occurring in text nodes to determine line advances, which is clearly flawed.
- * <p/>
- * However it's good enough for testing, and we'll replace it by a PositionXmlParser
- * once it's moved into com.android.util.
- */
- private static int findLineNumbers(Node node, int line) {
- for (; node != null; node = node.getNextSibling()) {
- node.setUserData(DATA_LINE_NUMBER, Integer.valueOf(line), null /*handler*/);
-
- if (node.getNodeType() == Node.TEXT_NODE) {
- String text = node.getNodeValue();
- if (text.length() > 0) {
- for (int pos = 0; (pos = text.indexOf('\n', pos)) != -1; pos++) {
- ++line;
- }
- }
- }
-
- Node child = node.getFirstChild();
- if (child != null) {
- line = findLineNumbers(child, line);
- }
- }
- return line;
- }
-
- /**
- * Extracts the line number that {@link #findLineNumbers} added to the XML nodes.
- *
- * @param xmlNode Any node from a document returned by {@link #parseDocument(File, IMergerLog)}.
- * @return The line number if found or 0.
- */
- static int extractLineNumber(@Nullable Node xmlNode) {
- if (xmlNode != null) {
- Object data = xmlNode.getUserData(DATA_LINE_NUMBER);
- if (data instanceof Integer) {
- return ((Integer) data).intValue();
- }
- }
-
- return 0;
- }
-
- /**
- * Outputs the given XML {@link Document} to the file {@code outFile}.
- *
- * TODO right now reformats the document. Needs to output as-is, respecting white-space.
- *
- * @param doc The document to output. Must not be null.
- * @param outFile The {@link File} where to write the document.
- * @param log A log in case of error.
- * @return True if the file was written, false in case of error.
- */
- static boolean printXmlFile(
- @NonNull Document doc,
- @NonNull File outFile,
- @NonNull IMergerLog log) {
- // Quick thing based on comments from http://stackoverflow.com/questions/139076
- try {
- Transformer tf = TransformerFactory.newInstance().newTransformer();
- tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$
- tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
- tf.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
- tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", //$NON-NLS-1$
- "4"); //$NON-NLS-1$
- tf.transform(new DOMSource(doc), new StreamResult(outFile));
- return true;
- } catch (TransformerException e) {
- log.error(Severity.ERROR,
- new FileAndLine(outFile.getName(), 0),
- "Failed to write XML file: %1$s",
- e.toString());
- return false;
- }
- }
-
- /**
- * Outputs the given XML {@link Document} as a string.
- *
- * TODO right now reformats the document. Needs to output as-is, respecting white-space.
- *
- * @param doc The document to output. Must not be null.
- * @param log A log in case of error.
- * @return A string representation of the XML. Null in case of error.
- */
- static String printXmlString(
- @NonNull Document doc,
- @NonNull IMergerLog log) {
- try {
- Transformer tf = TransformerFactory.newInstance().newTransformer();
- tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$
- tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
- tf.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
- tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", //$NON-NLS-1$
- "4"); //$NON-NLS-1$
- StringWriter sw = new StringWriter();
- tf.transform(new DOMSource(doc), new StreamResult(sw));
- return sw.toString();
- } catch (TransformerException e) {
- log.error(Severity.ERROR,
- new FileAndLine(extractXmlFilename(doc), 0),
- "Failed to write XML file: %1$s",
- e.toString());
- return null;
- }
- }
-
- /**
- * Dumps the structure of the DOM to a simple text string.
- *
- * @param node The first node to dump (recursively). Can be null.
- * @param nextSiblings If true, will also dump the following siblings.
- * If false, it will just process the given node.
- * @return A string representation of the Node structure, useful for debugging.
- */
- @NonNull
- static String dump(@Nullable Node node, boolean nextSiblings) {
- return dump(node, 0 /*offset*/, nextSiblings, true /*deep*/, null /*keyAttr*/);
- }
-
-
- /**
- * Dumps the structure of the DOM to a simple text string.
- * Each line is terminated with a \n separator.
- *
- * @param node The first node to dump. Can be null.
- * @param offsetIndex The offset to add at the begining of each line. Each offset is
- * converted into 2 space characters.
- * @param nextSiblings If true, will also dump the following siblings.
- * If false, it will just process the given node.
- * @param deep If true, this will recurse into children.
- * @param keyAttr An optional attribute *local* name to insert when writing an element.
- * For example when writing an Activity, it helps to always insert "name" attribute.
- * @return A string representation of the Node structure, useful for debugging.
- */
- @NonNull
- static String dump(
- @Nullable Node node,
- int offsetIndex,
- boolean nextSiblings,
- boolean deep,
- @Nullable String keyAttr) {
- StringBuilder sb = new StringBuilder();
-
- String offset = ""; //$NON-NLS-1$
- for (int i = 0; i < offsetIndex; i++) {
- offset += " "; //$NON-NLS-1$
- }
-
- if (node == null) {
- sb.append(offset).append("(end reached)\n");
-
- } else {
- for (; node != null; node = node.getNextSibling()) {
- String type = null;
- short t = node.getNodeType();
- switch(t) {
- case Node.ELEMENT_NODE:
- String attr = "";
- if (keyAttr != null) {
- NamedNodeMap attrs = node.getAttributes();
- if (attrs != null) {
- for (int i = 0; i < attrs.getLength(); i++) {
- Node a = attrs.item(i);
- if (a != null && keyAttr.equals(a.getLocalName())) {
- attr = String.format(" %1$s=%2$s",
- a.getNodeName(), a.getNodeValue());
- break;
- }
- }
- }
- }
- sb.append(String.format("%1$s<%2$s%3$s>\n",
- offset, node.getNodeName(), attr));
- break;
- case Node.COMMENT_NODE:
- sb.append(String.format("%1$s<!-- %2$s -->\n",
- offset, node.getNodeValue()));
- break;
- case Node.TEXT_NODE:
- String txt = node.getNodeValue().trim();
- if (txt.length() == 0) {
- // Keep this for debugging. TODO make it a flag
- // to dump whitespace on debugging. Otherwise ignore it.
- // txt = "[whitespace]";
- break;
- }
- sb.append(String.format("%1$s%2$s\n", offset, txt));
- break;
- case Node.ATTRIBUTE_NODE:
- sb.append(String.format("%1$s @%2$s = %3$s\n",
- offset, node.getNodeName(), node.getNodeValue()));
- break;
- case Node.CDATA_SECTION_NODE:
- type = "cdata"; //$NON-NLS-1$
- break;
- case Node.DOCUMENT_NODE:
- type = "document"; //$NON-NLS-1$
- break;
- case Node.PROCESSING_INSTRUCTION_NODE:
- type = "PI"; //$NON-NLS-1$
- break;
- default:
- type = Integer.toString(t);
- }
-
- if (type != null) {
- sb.append(String.format("%1$s[%2$s] <%3$s> %4$s\n",
- offset, type, node.getNodeName(), node.getNodeValue()));
- }
-
- if (deep) {
- List<Attr> attrs = sortedAttributeList(node.getAttributes());
- for (Attr attr : attrs) {
- sb.append(String.format("%1$s @%2$s = %3$s\n",
- offset, attr.getNodeName(), attr.getNodeValue()));
- }
-
- Node child = node.getFirstChild();
- if (child != null) {
- sb.append(dump(child, offsetIndex+1, true, true, keyAttr));
- }
- }
-
- if (!nextSiblings) {
- break;
- }
- }
- }
- return sb.toString();
- }
-
- /**
- * Returns a sorted list of attributes.
- * The list is never null and does not contain null items.
- *
- * @param attrMap A Node map as returned by {@link Node#getAttributes()}.
- * Can be null, in which case an empty list is returned.
- * @return A non-null, possible empty, list of all nodes that are actual {@link Attr},
- * sorted by increasing attribute name.
- */
- @NonNull
- static List<Attr> sortedAttributeList(@Nullable NamedNodeMap attrMap) {
- List<Attr> list = new ArrayList<Attr>();
-
- if (attrMap != null) {
- for (int i = 0; i < attrMap.getLength(); i++) {
- Node attr = attrMap.item(i);
- if (attr instanceof Attr) {
- list.add((Attr) attr);
- }
- }
- }
-
- if (list.size() > 1) {
- // Sort it by attribute name
- Collections.sort(list, getAttrComparator());
- }
-
- return list;
- }
-
- /**
- * Returns a comparator for {@link Attr}, alphabetically sorted by name.
- * The "name" attribute is special and always sorted to the front.
- */
- @NonNull
- static Comparator<? super Attr> getAttrComparator() {
- return new Comparator<Attr>() {
- @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$
-
- int prio1 = s1.equals("name") ? 0 : 1; //$NON-NLS-1$
- int prio2 = s2.equals("name") ? 0 : 1; //$NON-NLS-1$
- if (prio1 == 0 || prio2 == 0) {
- return prio1 - prio2;
- }
-
- return s1.compareTo(s2);
- }
- };
- }
-
- /**
- * Inject attributes into an existing document.
- * <p/>
- * The map keys are "/manifest/elements...|attribute-ns-uri attribute-local-name",
- * for example "/manifest/uses-sdk|http://schemas.android.com/apk/res/android minSdkVersion".
- * (note the space separator between the attribute URI and its local name.)
- * The elements will be created if they don't exists. Existing attributes will be modified.
- * The replacement is done on the main document <em>before</em> merging.
- * The value can be null to remove an existing attribute.
- *
- * @param doc The document to modify in-place.
- * @param attributeMap A map of attributes to inject in the form [pseudo-xpath] => value.
- * @param log A log in case of error.
- */
- static void injectAttributes(
- @Nullable Document doc,
- @Nullable Map<String, String> attributeMap,
- @NonNull IMergerLog log) {
- if (doc == null || attributeMap == null || attributeMap.isEmpty()) {
- return;
- }
-
- // 1=path 2=URI 3=local name
- final Pattern keyRx = Pattern.compile("^/([^\\|]+)\\|([^ ]*) +(.+)$"); //$NON-NLS-1$
- final FileAndLine docInfo = xmlFileAndLine(doc);
-
- nextAttribute: for (Entry<String, String> entry : attributeMap.entrySet()) {
- String key = entry.getKey();
- String value = entry.getValue();
- if (key == null || key.isEmpty()) {
- continue;
- }
-
- Matcher m = keyRx.matcher(key);
- if (!m.matches()) {
- log.error(Severity.WARNING, docInfo, "Invalid injected attribute key: %s", key);
- continue;
- }
- String path = m.group(1);
- String attrNsUri = m.group(2);
- String attrName = m.group(3);
-
- String[] segment = path.split(Pattern.quote("/")); //$NON-NLS-1$
-
- // Get the path elements. Create them as needed if they don't exist.
- Node element = doc;
- nextSegment: for (int i = 0; i < segment.length; i++) {
- // Find a child with the segment's name
- String name = segment[i];
- for (Node child = element.getFirstChild();
- child != null;
- child = child.getNextSibling()) {
- if (child.getNodeType() == Node.ELEMENT_NODE &&
- child.getNamespaceURI() == null &&
- child.getNodeName().equals(name)) {
- // Found it. Continue to the next inner segment.
- element = child;
- continue nextSegment;
- }
- }
- // No such element. Create it.
- if (value == null) {
- // If value is null, we want to remove, not create and if can't find the
- // element, then we're done: there's no such attribute to remove.
- break nextAttribute;
- }
-
- Element child = doc.createElement(name);
- element = element.insertBefore(child, element.getFirstChild());
- }
-
- if (element == null) {
- log.error(Severity.WARNING, docInfo, "Invalid injected attribute path: %s", path);
- return;
- }
-
- NamedNodeMap attrs = element.getAttributes();
- if (attrs != null) {
-
-
- if (attrNsUri != null && attrNsUri.isEmpty()) {
- attrNsUri = null;
- }
- Node attr = attrs.getNamedItemNS(attrNsUri, attrName);
-
- if (value == null) {
- // We want to remove the attribute from the attribute map.
- if (attr != null) {
- attrs.removeNamedItemNS(attrNsUri, attrName);
- }
-
- } else {
- // We want to add or replace the attribute.
- if (attr == null) {
- attr = doc.createAttributeNS(attrNsUri, attrName);
- if (attrNsUri != null) {
- attr.setPrefix(XmlUtils.lookupNamespacePrefix(element, attrNsUri));
- }
- attrs.setNamedItemNS(attr);
- }
- attr.setNodeValue(value);
- }
- }
- }
- }
-
- // -------
-
- /**
- * Flatten the element to a string. This "pretty prints" the XML tree starting
- * from the given node and all its children and attributes.
- * <p/>
- * The output is designed to be printed using {@link #printXmlDiff}.
- *
- * @param node The root node to print.
- * @param nsPrefix A map that is filled with all the URI=>prefix found.
- * The internal string only contains the expanded URIs but this is rather verbose
- * so when printing the diff these will be replaced by the prefixes collected here.
- * @param prefix A "space" prefix added at the beginning of each line for indentation
- * purposes. The diff printer later relies on this to find out the structure.
- */
- @NonNull
- static String printElement(
- @NonNull Node node,
- @NonNull Map<String, String> nsPrefix,
- @NonNull String prefix) {
- StringBuilder sb = new StringBuilder();
- sb.append(prefix).append('<');
- String uri = node.getNamespaceURI();
- if (uri != null) {
- sb.append(uri).append(':');
- nsPrefix.put(uri, node.getPrefix());
- }
- sb.append(node.getLocalName());
- printAttributes(sb, node, nsPrefix, prefix);
- sb.append(">\n"); //$NON-NLS-1$
- printChildren(sb, node.getFirstChild(), true, nsPrefix, prefix + " "); //$NON-NLS-1$
-
- sb.append(prefix).append("</"); //$NON-NLS-1$
- if (uri != null) {
- sb.append(uri).append(':');
- }
- sb.append(node.getLocalName());
- sb.append(">\n"); //$NON-NLS-1$
-
- return sb.toString();
- }
-
- /**
- * Flatten several children elements to a string.
- * This is an implementation detail for {@link #printElement(Node, Map, String)}.
- * <p/>
- * If {@code nextSiblings} is false, the string conversion takes only the given
- * child element and stops there.
- * <p/>
- * If {@code nextSiblings} is true, the string conversion also takes _all_ the siblings
- * after the given element. The idea is the caller can call this with the first child
- * of a parent and get a string showing all the children at the same time. They are
- * sorted to avoid the ordering issue.
- */
- @NonNull
- private static StringBuilder printChildren(
- @NonNull StringBuilder sb,
- @NonNull Node child,
- boolean nextSiblings,
- @NonNull Map<String, String> nsPrefix,
- @NonNull String prefix) {
- ArrayList<String> children = new ArrayList<String>();
-
- boolean hasText = false;
- for (; child != null; child = child.getNextSibling()) {
- short t = child.getNodeType();
- if (nextSiblings && t == Node.TEXT_NODE) {
- // We don't typically have meaningful text nodes in an Android manifest.
- // If there are, just dump them as-is into the element representation.
- // We do trim whitespace and ignore all-whitespace or empty text nodes.
- String s = child.getNodeValue().trim();
- if (s.length() > 0) {
- sb.append(s);
- hasText = true;
- }
- } else if (t == Node.ELEMENT_NODE) {
- children.add(printElement(child, nsPrefix, prefix));
- if (!nextSiblings) {
- break;
- }
- }
- }
-
- if (hasText) {
- sb.append('\n');
- }
-
- if (!children.isEmpty()) {
- Collections.sort(children);
- for (String s : children) {
- sb.append(s);
- }
- }
-
- return sb;
- }
-
- /**
- * Flatten several attributes to a string using their alphabethical order.
- * This is an implementation detail for {@link #printElement(Node, Map, String)}.
- */
- @NonNull
- private static StringBuilder printAttributes(
- @NonNull StringBuilder sb,
- @NonNull Node node,
- @NonNull Map<String, String> nsPrefix,
- @NonNull String prefix) {
- ArrayList<String> attrs = new ArrayList<String>();
-
- NamedNodeMap attrMap = node.getAttributes();
- if (attrMap != null) {
- StringBuilder sb2 = new StringBuilder();
- for (int i = 0; i < attrMap.getLength(); i++) {
- Node attr = attrMap.item(i);
- if (attr instanceof Attr) {
- sb2.setLength(0);
- sb2.append('@');
- String uri = attr.getNamespaceURI();
- if (uri != null) {
- sb2.append(uri).append(':');
- nsPrefix.put(uri, attr.getPrefix());
- }
- sb2.append(attr.getLocalName());
- sb2.append("=\"").append(attr.getNodeValue()).append('\"'); //$NON-NLS-1$
- attrs.add(sb2.toString());
- }
- }
- }
-
- Collections.sort(attrs);
-
- for(String attr : attrs) {
- sb.append('\n');
- sb.append(prefix).append(" ").append(attr); //$NON-NLS-1$
- }
- return sb;
- }
-
- //------------
-
- /**
- * Computes a quick diff between two strings generated by
- * {@link #printElement(Node, Map, String)}.
- * <p/>
- * This is a <em>not</em> designed to be a full contextual diff.
- * It just stops at the first difference found, printing up to 3 lines of diff
- * and backtracking to add prior contextual information to understand the
- * structure of the element where the first diff line occured (by printing
- * each parent found till the root one as well as printing the attribute
- * named by {@code keyAttr}).
- *
- * @param sb The string builder where to output is written.
- * @param expected The expected XML tree (as generated by {@link #printElement}.)
- * For best result this would be the "destination" XML we're merging into,
- * e.g. the main manifest.
- * @param actual The actual XML tree (as generated by {@link #printElement}.)
- * For best result this would be the "source" XML we're merging from,
- * e.g. a library manifest.
- * @param nsPrefixE The map of URI=>prefix for the expected XML tree.
- * @param nsPrefixA The map of URI=>prefix for the actual XML tree.
- * @param keyAttr An optional attribute *full* name (uri:local name) to always
- * insert when writing the contextual lines before a diff line.
- * For example when writing an Activity, it helps to always insert
- * the "name" attribute since that's the key element to help the user
- * identify which node is being dumped.
- */
- static void printXmlDiff(
- StringBuilder sb,
- String expected,
- String actual,
- Map<String, String> nsPrefixE,
- Map<String, String> nsPrefixA,
- String keyAttr) {
- String[] aE = expected.split("\n");
- String[] aA = actual.split("\n");
- int lE = aE.length;
- int lA = aA.length;
- int lm = lE < lA ? lA : lE;
- boolean eofE = false;
- boolean eofA = false;
- boolean contextE = true;
- boolean contextA = true;
- int numDiff = 0;
-
- StringBuilder sE = new StringBuilder();
- StringBuilder sA = new StringBuilder();
-
- outerLoop: for (int i = 0, iE = 0, iA = 0; i < lm; i++) {
- if (iE < lE && iA < lA && aE[iE].equals(aA[iA])) {
- if (numDiff > 0) {
- // If we found a difference, stop now.
- break outerLoop;
- }
- iE++;
- iA++;
- continue;
- } else {
- // Try to print some context for each side based on previous lines's space prefix.
- if (contextE) {
- if (iE > 0) {
- String p = diffGetPrefix(aE[iE]);
- for (int kE = iE-1; kE >= 0; kE--) {
- if (!aE[kE].startsWith(p)) {
- sE.insert(0, '\n').insert(0, diffReplaceNs(aE[kE], nsPrefixE)).insert(0, " ");
- if (p.length() == 0) {
- break;
- }
- p = diffGetPrefix(aE[kE]);
- } else if (aE[kE].contains(keyAttr) || kE == 0) {
- sE.insert(0, '\n').insert(0, diffReplaceNs(aE[kE], nsPrefixE)).insert(0, " ");
- }
- }
- }
- contextE = false;
- }
- if (iE >= lE) {
- if (!eofE) {
- sE.append("--(end reached)\n");
- eofE = true;
- }
- } else {
- sE.append("--").append(diffReplaceNs(aE[iE++], nsPrefixE)).append('\n');
- }
-
- if (contextA) {
- if (iA > 0) {
- String p = diffGetPrefix(aA[iA]);
- for (int kA = iA-1; kA >= 0; kA--) {
- if (!aA[kA].startsWith(p)) {
- sA.insert(0, '\n').insert(0, diffReplaceNs(aA[kA], nsPrefixA)).insert(0, " ");
- p = diffGetPrefix(aA[kA]);
- if (p.length() == 0) {
- break;
- }
- } else if (aA[kA].contains(keyAttr) || kA == 0) {
- sA.insert(0, '\n').insert(0, diffReplaceNs(aA[kA], nsPrefixA)).insert(0, " ");
- }
- }
- }
- contextA = false;
- }
- if (iA >= lA) {
- if (!eofA) {
- sA.append("++(end reached)\n");
- eofA = true;
- }
- } else {
- sA.append("++").append(diffReplaceNs(aA[iA++], nsPrefixA)).append('\n');
- }
-
- // Dump up to 3 lines of difference
- numDiff++;
- if (numDiff == 3) {
- break outerLoop;
- }
- }
- }
-
- sb.append(sE);
- sb.append(sA);
- }
-
- /**
- * Returns all the whitespace at the beginning of a string.
- * Implementation details for {@link #printXmlDiff} used to find the "parent"
- * element and include it in the context of the diff.
- */
- private static String diffGetPrefix(String str) {
- int pos = 0;
- int len = str.length();
- while (pos < len && str.charAt(pos) == ' ') {
- pos++;
- }
- return str.substring(0, pos);
- }
-
- /**
- * Simplifies a diff line by replacing NS URIs by their prefix.
- * Implementation details for {@link #printXmlDiff}.
- */
- private static String diffReplaceNs(String str, Map<String, String> nsPrefix) {
- for (Entry<String, String> entry : nsPrefix.entrySet()) {
- String uri = entry.getKey();
- String prefix = entry.getValue();
- if (prefix != null && str.contains(uri)) {
- str = str.replaceAll(Pattern.quote(uri), Matcher.quoteReplacement(prefix));
- }
- }
- return str;
- }
-
-}
diff --git a/manifmerger/src/test/java/com/android/manifmerger/ManifestMergerTest.java b/manifmerger/src/test/java/com/android/manifmerger/ManifestMergerTest.java
deleted file mode 100755
index a5d0aa1..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/ManifestMergerTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * 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 test03_inject_attributes() throws Exception {
- processTestFiles();
- }
-
- public void test04_inject_attributes() 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();
- }
-
- public void test60_merge_order() throws Exception {
- processTestFiles();
- }
-
- public void test65_override_app() throws Exception {
- processTestFiles();
- }
-
- public void test66_remove_app() throws Exception {
- processTestFiles();
- }
-
- public void test67_override_activities() throws Exception {
- processTestFiles();
- }
-
- public void test68_override_uses() throws Exception {
- processTestFiles();
- }
-
- public void test69_remove_uses() throws Exception {
- processTestFiles();
- }
-
- public void test70_expand_fqcns() throws Exception {
- processTestFiles();
- }
-
- public void test71_extract_package_prefix() throws Exception {
- processTestFiles();
- }
-
- public void test75_app_metadata_merge() throws Exception {
- processTestFiles();
- }
-
- public void test76_app_metadata_ignore() throws Exception {
- processTestFiles();
- }
-
- public void test77_app_metadata_conflict() throws Exception {
- processTestFiles();
- }
-}
diff --git a/manifmerger/src/test/java/com/android/manifmerger/ManifestMergerTestCase.java b/manifmerger/src/test/java/com/android/manifmerger/ManifestMergerTestCase.java
deleted file mode 100755
index 29378f0..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/ManifestMergerTestCase.java
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
- * 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.annotations.NonNull;
-import com.android.manifmerger.IMergerLog.FileAndLine;
-import com.android.sdklib.mock.MockLog;
-
-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.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-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";
- /**
- * Delimiter for starts a section that declares how to inject an attribute.
- * The section is composed of one or more lines with the
- * syntax: "/node/node|attr-URI attrName=attrValue".
- * This is essentially a pseudo XPath-like expression that is described in
- * {@link ManifestMerger#process(Document, File[], Map)}.
- */
- private static final String DELIM_INJECT_ATTR = "inject";
- /**
- * Delimiter for a section that declares how to toggle a ManifMerger option.
- * The section is composed of one or more lines with the
- * syntax: "functionName=false|true".
- */
- private static final String DELIM_FEATURES = "features";
-
- static class TestFiles {
- private final File mMain;
- private final File[] mLibs;
- private final Map<String, String> mInjectAttributes;
- private final File mActualResult;
- private final String mExpectedResult;
- private final String mExpectedErrors;
- private final boolean mShouldFail;
- private final Map<String, Boolean> mFeatures;
-
- /** Files used by a given test case. */
- public TestFiles(
- boolean shouldFail,
- @NonNull File main,
- @NonNull File[] libs,
- @NonNull Map<String, Boolean> features,
- @NonNull Map<String, String> injectAttributes,
- @NonNull File actualResult,
- @NonNull String expectedResult,
- @NonNull String expectedErrors) {
- mShouldFail = shouldFail;
- mMain = main;
- mLibs = libs;
- mFeatures = features;
- mInjectAttributes = injectAttributes;
- mActualResult = actualResult;
- mExpectedResult = expectedResult;
- mExpectedErrors = expectedErrors;
- }
-
- public boolean getShouldFail() {
- return mShouldFail;
- }
-
- @NonNull
- public File getMain() {
- return mMain;
- }
-
- @NonNull
- public File[] getLibs() {
- return mLibs;
- }
-
- public Map<String, Boolean> getFeatures() {
- return mFeatures;
- }
-
- public Map<String, String> getInjectAttributes() {
- return mInjectAttributes;
- }
-
- @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 &lt; 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;
- Map<String, Boolean> features = new HashMap<String, Boolean>();
- Map<String, String> injectAttributes = new HashMap<String, String>();
- 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) ||
- delimiter.equals(DELIM_FEATURES) ||
- delimiter.equals(DELIM_INJECT_ATTR));
-
- 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) &&
- !delimiter.equals(DELIM_FEATURES) &&
- !delimiter.equals(DELIM_INJECT_ATTR)) {
- 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');
- } else if (DELIM_INJECT_ATTR.equals(delimiter)) {
- String[] in = line.split("=");
- if (in != null && in.length == 2) {
- injectAttributes.put(in[0], "null".equals(in[1]) ? null : in[1]);
- }
- } else if (DELIM_FEATURES.equals(delimiter)) {
- String[] in = line.split("=");
- if (in != null && in.length == 2) {
- features.put(in[0], Boolean.parseBoolean(in[1]));
- }
- }
- }
-
- 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()]),
- features,
- injectAttributes,
- 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[], Map)}:
- * 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;
- }
- });
-
- for (Entry<String, Boolean> feature : testFiles.getFeatures().entrySet()) {
- Method m = merger.getClass().getMethod(
- feature.getKey(),
- new Class<?>[] { boolean.class } );
- m.invoke(merger, new Object[] { feature.getValue() } );
- }
-
- boolean processOK = merger.process(testFiles.getActualResult(),
- testFiles.getMain(),
- testFiles.getLibs(),
- testFiles.getInjectAttributes());
-
- 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 = MergerXmlUtils.parseDocument(testFiles.getActualResult(), mergerLog);
- assertNotNull(document);
- assert document != null; // for Eclipse null analysis
- String actual = MergerXmlUtils.printXmlString(document, mergerLog);
- assertEquals("Error parsing actual result XML", "[]", log.toString());
- log.clear();
- document = MergerXmlUtils.parseDocument(
- testFiles.getExpectedResult(),
- mergerLog,
- new FileAndLine("<expected-result>", 0));
- assertNotNull("Failed to parse result document: " + testFiles.getExpectedResult(),document);
- assert document != null;
- String expected = MergerXmlUtils.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/manifmerger/src/test/java/com/android/manifmerger/data/00_noop.xml b/manifmerger/src/test/java/com/android/manifmerger/data/00_noop.xml
deleted file mode 100755
index 2160f69..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/00_noop.xml
+++ /dev/null
@@ -1,229 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/01_ignore_app_attr.xml b/manifmerger/src/test/java/com/android/manifmerger/data/01_ignore_app_attr.xml
deleted file mode 100755
index b939dd7..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/01_ignore_app_attr.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/02_ignore_instrumentation.xml b/manifmerger/src/test/java/com/android/manifmerger/data/02_ignore_instrumentation.xml
deleted file mode 100755
index ed0dbbc..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/02_ignore_instrumentation.xml
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/03_inject_attributes.xml b/manifmerger/src/test/java/com/android/manifmerger/data/03_inject_attributes.xml
deleted file mode 100755
index 0a7057c..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/03_inject_attributes.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Test:
-# - Inject attributes in a main manifest.
-#
-
-@inject
-/manifest|http://schemas.android.com/apk/res/android versionCode=101
-/manifest|http://schemas.android.com/apk/res/android versionName=1.0.1
-/manifest/uses-sdk|http://schemas.android.com/apk/res/android minSdkVersion=10
-/manifest/uses-sdk|http://schemas.android.com/apk/res/android targetSdkVersion=14
-/manifest/application|http://schemas.android.com/apk/res/android label=null
-/manifest/application|http://schemas.android.com/apk/res/android icon=null
-
-@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>
-
-@result
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.app1"
- android:versionCode="101"
- android:versionName="1.0.1"><uses-sdk android:minSdkVersion="10" android:targetSdkVersion="14"/>
-
- <application
- 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/manifmerger/src/test/java/com/android/manifmerger/data/04_inject_attributes.xml b/manifmerger/src/test/java/com/android/manifmerger/data/04_inject_attributes.xml
deleted file mode 100755
index 57f4e84..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/04_inject_attributes.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# Test:
-# - Inject attributes in a main manifest.
-# The attributes are injected and then the merge is done. In this case the app
-# starts with a minSdkVersion of 20, which is higher than the lib1's 15 value.
-# However the injection replaces it by 10, which is now lower than the lib's
-# version and thus a warning will be generated.
-#
-
-@fails
-
-@inject
-/manifest/uses-sdk|http://schemas.android.com/apk/res/android minSdkVersion=10
-/manifest/uses-sdk|http://schemas.android.com/apk/res/android targetSdkVersion=14
-/manifest/application|http://schemas.android.com/apk/res/android label=null
-/manifest/application|http://schemas.android.com/apk/res/android icon=null
-
-@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="20" android:targetSdkVersion="21"/>
-
- <application android:name="com.example.TheApp" />
-
-</manifest>
-
-@lib1
-
-<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="15" android:targetSdkVersion="16"/>
-
- <application android:name="com.example.TheApp" />
-
-</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="10" android:targetSdkVersion="14"/>
-
- <application android:name="com.example.TheApp" />
-
-</manifest>
-
-@errors
-
-E [ManifestMergerTest0_main.xml:3, ManifestMergerTest1_lib1.xml:3] Main manifest has <uses-sdk android:minSdkVersion='10'> but library uses minSdkVersion='15'
-W [ManifestMergerTest0_main.xml:3, ManifestMergerTest1_lib1.xml:3] Main manifest has <uses-sdk android:targetSdkVersion='14'> but library uses targetSdkVersion='16'
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/10_activity_merge.xml b/manifmerger/src/test/java/com/android/manifmerger/data/10_activity_merge.xml
deleted file mode 100755
index 59c5c42..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/10_activity_merge.xml
+++ /dev/null
@@ -1,378 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/11_activity_dup.xml b/manifmerger/src/test/java/com/android/manifmerger/data/11_activity_dup.xml
deleted file mode 100755
index ef163b0..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/11_activity_dup.xml
+++ /dev/null
@@ -1,406 +0,0 @@
-#
-# 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"
---</activity>
---(end reached)
- <activity
- @android:name="com.example.WidgetConfigurationUI"
-++ <intent-filter>
-++ <action
-++ @android:name="android.appwidget.action.APPWIDGET_CONFIGURE">
-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">
--- <intent-filter>
--- <action
- <activity
-++ @android:name="com.example.LibActivity"
-++ @android:theme="@style/Lib.Theme">
-++ <intent-filter>
-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"
- @android:name="android.intent.action.MAIN">
- @android:name="android.intent.category.LAUNCHER">
--- </intent-filter>
---</activity>
---(end reached)
- <activity
- @android:name="com.example.LibActivity2"
- <intent-filter>
- @android:name="android.intent.action.MAIN">
- @android:name="android.intent.category.LAUNCHER">
-++ <category
-++ @android:name="android.intent.category.MOARCATZPLZ">
-++ </category>
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/12_alias_dup.xml b/manifmerger/src/test/java/com/android/manifmerger/data/12_alias_dup.xml
deleted file mode 100755
index 7b5aed3..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/12_alias_dup.xml
+++ /dev/null
@@ -1,211 +0,0 @@
-#
-# 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:icon="@drawable/alias_icon2"
--- @android:label="@string/alias_name2"
--- @android:name="com.example.alias.MyActivity2"
- <activity-alias
-++ @android:name="com.example.alias.MyActivity2"
-++ @android:targetActivity="com.example.MainActivity2">
-++</activity-alias>
-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:targetActivity="com.example.MainActivity3">
--- <intent-filter>
- <activity-alias
-++ @android:name="com.example.alias.MyActivity3">
-++ <intent-filter>
-++ <category
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/13_service_dup.xml b/manifmerger/src/test/java/com/android/manifmerger/data/13_service_dup.xml
deleted file mode 100755
index 4c257fa..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/13_service_dup.xml
+++ /dev/null
@@ -1,167 +0,0 @@
-#
-# 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">
---</service>
---(end reached)
- <service
- @android:name="com.example.AppService2">
-++ <intent-filter>
-++ <action
-++ @android:name="android.intent.action.MAIN">
-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">
--- <intent-filter>
--- <action
--- @android:name="android.intent.action.MAIN">
- <service
- @android:name="com.example.AppService3">
-++</service>
-++(end reached)
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/14_receiver_dup.xml b/manifmerger/src/test/java/com/android/manifmerger/data/14_receiver_dup.xml
deleted file mode 100755
index 777ba22..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/14_receiver_dup.xml
+++ /dev/null
@@ -1,186 +0,0 @@
-#
-# 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:icon="@drawable/app_icon"
--- @android:name="com.example.AppReceiver2">
--- <intent-filter>
- <receiver
-++ @android:name="com.example.AppReceiver2">
-++</receiver>
-++(end reached)
-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_CUSTOM1">
- <receiver
- @android:name="com.example.AppReceiver3">
- <intent-filter>
- <action
-++ @android:name="com.example.action.ACTION_CUSTOM">
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/15_provider_dup.xml b/manifmerger/src/test/java/com/android/manifmerger/data/15_provider_dup.xml
deleted file mode 100755
index bd0c8fe..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/15_provider_dup.xml
+++ /dev/null
@@ -1,153 +0,0 @@
-#
-# 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">
---</provider>
---(end reached)
- <provider
-++ @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:enabled="@bool/someConditionalValue"
--- @android:name="com.example.Provider3">
---</provider>
- <provider
-++ @android:name="com.example.Provider3">
-++</provider>
-++(end reached)
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/16_fqcn_merge.xml b/manifmerger/src/test/java/com/android/manifmerger/data/16_fqcn_merge.xml
deleted file mode 100755
index 8414a3c..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/16_fqcn_merge.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/17_fqcn_conflict.xml b/manifmerger/src/test/java/com/android/manifmerger/data/17_fqcn_conflict.xml
deleted file mode 100755
index b4f5ea0..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/17_fqcn_conflict.xml
+++ /dev/null
@@ -1,120 +0,0 @@
-#
-# 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.
- We just emit a warning in this case.
- -->
-
- <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/manifmerger/src/test/java/com/android/manifmerger/data/20_uses_lib_merge.xml b/manifmerger/src/test/java/com/android/manifmerger/data/20_uses_lib_merge.xml
deleted file mode 100755
index a5eecce..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/20_uses_lib_merge.xml
+++ /dev/null
@@ -1,176 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/21_uses_lib_errors.xml b/manifmerger/src/test/java/com/android/manifmerger/data/21_uses_lib_errors.xml
deleted file mode 100755
index 9e8f5a0..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/21_uses_lib_errors.xml
+++ /dev/null
@@ -1,202 +0,0 @@
-#
-# 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 has 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/manifmerger/src/test/java/com/android/manifmerger/data/25_permission_merge.xml b/manifmerger/src/test/java/com/android/manifmerger/data/25_permission_merge.xml
deleted file mode 100755
index 07208ad..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/25_permission_merge.xml
+++ /dev/null
@@ -1,259 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/26_permission_dup.xml b/manifmerger/src/test/java/com/android/manifmerger/data/26_permission_dup.xml
deleted file mode 100755
index bd9a4f1..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/26_permission_dup.xml
+++ /dev/null
@@ -1,314 +0,0 @@
-#
-# 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:description="Insert boring description here"
--- @android:icon="@drawable/robot"
- <permission
-++ @android:description="Different description here"
-++ @android:icon="@drawable/not_the_same_icon"
-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:protectionLevel="signatureOrSystem">
- <permission
- @android:name="com.example.WhatWereYouThinking"
-++ @android:protectionLevel="normal">
-E [ManifestMergerTest0_main.xml:16, ManifestMergerTest1_lib1.xml:5] Trying to merge incompatible /manifest/permission-group[@name=com.example.MasterControlPermission] element:
- <permission-group
--- @android:icon="@drawable/ignored_icon"
--- @android:label="the Spanish Inquisition"
--- @android:name="com.example.MasterControlPermission">
- <permission-group
-++ @android:label="the Spanish Inquisition"
-++ @android:name="com.example.MasterControlPermission">
-++</permission-group>
-E [ManifestMergerTest0_main.xml:18, ManifestMergerTest1_lib1.xml:6] Trying to merge incompatible /manifest/permission-tree[@name=com.example.PermTree] element:
- <permission-tree
--- @android:label="This is not a label"
- <permission-tree
-++ @android:label="This is not the same label"
-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:protectionLevel="normal">
- <permission
- @android:name="com.example.Permission1"
-++ @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">
---</permission-tree>
---(end reached)
- <permission-tree
-++ @android:description="Extra description"
-++ @android:name="com.example.PermTree1">
-++</permission-tree>
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/28_uses_perm_merge.xml b/manifmerger/src/test/java/com/android/manifmerger/data/28_uses_perm_merge.xml
deleted file mode 100755
index ecc644a..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/28_uses_perm_merge.xml
+++ /dev/null
@@ -1,156 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/30_uses_sdk_ok.xml b/manifmerger/src/test/java/com/android/manifmerger/data/30_uses_sdk_ok.xml
deleted file mode 100755
index bcee4ce..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/30_uses_sdk_ok.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/32_uses_sdk_minsdk_ok.xml b/manifmerger/src/test/java/com/android/manifmerger/data/32_uses_sdk_minsdk_ok.xml
deleted file mode 100755
index b94efe8..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/32_uses_sdk_minsdk_ok.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/33_uses_sdk_minsdk_conflict.xml b/manifmerger/src/test/java/com/android/manifmerger/data/33_uses_sdk_minsdk_conflict.xml
deleted file mode 100755
index 8edbedb..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/33_uses_sdk_minsdk_conflict.xml
+++ /dev/null
@@ -1,148 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/36_uses_sdk_targetsdk_warning.xml b/manifmerger/src/test/java/com/android/manifmerger/data/36_uses_sdk_targetsdk_warning.xml
deleted file mode 100755
index df8b717..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/36_uses_sdk_targetsdk_warning.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/40_uses_feat_merge.xml b/manifmerger/src/test/java/com/android/manifmerger/data/40_uses_feat_merge.xml
deleted file mode 100755
index d14dcaa..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/40_uses_feat_merge.xml
+++ /dev/null
@@ -1,178 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/41_uses_feat_errors.xml b/manifmerger/src/test/java/com/android/manifmerger/data/41_uses_feat_errors.xml
deleted file mode 100755
index b86f74a..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/41_uses_feat_errors.xml
+++ /dev/null
@@ -1,205 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/45_uses_feat_gles_once.xml b/manifmerger/src/test/java/com/android/manifmerger/data/45_uses_feat_gles_once.xml
deleted file mode 100755
index 57937a6..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/45_uses_feat_gles_once.xml
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/47_uses_feat_gles_conflict.xml b/manifmerger/src/test/java/com/android/manifmerger/data/47_uses_feat_gles_conflict.xml
deleted file mode 100755
index 936d009..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/47_uses_feat_gles_conflict.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/50_uses_conf_warning.xml b/manifmerger/src/test/java/com/android/manifmerger/data/50_uses_conf_warning.xml
deleted file mode 100755
index b1cb3f9..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/50_uses_conf_warning.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/52_support_screens_warning.xml b/manifmerger/src/test/java/com/android/manifmerger/data/52_support_screens_warning.xml
deleted file mode 100755
index 363fb2b..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/52_support_screens_warning.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/54_compat_screens_warning.xml b/manifmerger/src/test/java/com/android/manifmerger/data/54_compat_screens_warning.xml
deleted file mode 100755
index 1e1c2d2..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/54_compat_screens_warning.xml
+++ /dev/null
@@ -1,204 +0,0 @@
-#
-# 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/manifmerger/src/test/java/com/android/manifmerger/data/56_support_gltext_warning.xml b/manifmerger/src/test/java/com/android/manifmerger/data/56_support_gltext_warning.xml
deleted file mode 100755
index 114e9f4..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/56_support_gltext_warning.xml
+++ /dev/null
@@ -1,151 +0,0 @@
-#
-# Test supports-gl-texture:
-# - it's a warning if the library defines a supports-gl-texture 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
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/60_merge_order.xml b/manifmerger/src/test/java/com/android/manifmerger/data/60_merge_order.xml
deleted file mode 100755
index d6767f7..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/60_merge_order.xml
+++ /dev/null
@@ -1,318 +0,0 @@
-#
-# Test merge order:
-# - When activity / activity-alias / service / receiver / provider are merged,
-# we do a comparison to check whether the elements are already present in the
-# main manifest. The order of the elements must NOT matter in the comparison,
-# nor does the whitespace between them.
-# - What this checks is that the order of the elements or attributes within
-# the elements should not matter.
-#
-
-@main
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.app1">
-
- <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.Activity1"
- 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>
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- <meta-data
- android:name="metaName"
- android:value="metaValue"
- android:resource="@color/someColor" />
- </activity>
-
- <!-- Receiver -->
- <receiver
- android:name="com.example.AppReceiver"
- android:icon="@drawable/app_icon">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- <intent-filter>
- <action android:name="com.example.intent.action.DO_THIS" />
- </intent-filter>
- <intent-filter>
- <action android:name="com.example.intent.action.DO_THAT" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.TIMEZONE_CHANGED" />
- <action android:name="android.intent.action.TIME_SET" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.PHONE_STATE"/>
- </intent-filter>
- </receiver>
-
- <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="com.example.IN_APP_NOTIFY" />
- <action android:name="com.example.RESPONSE_CODE" />
- <action android:name="com.example.PURCHASE_STATE_CHANGED" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- <meta-data
- android:name="metaName2"
- android:value="metaValue2"
- android:resource="@color/someColor2"
- />
- </activity>
- </application>
-</manifest>
-
-
-@lib1
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.lib1">
-
- <!-- Redefine the same elements as in the main manifest except it changes
- the attribute order and the the inner elements order. -->
- <application
- android:name="com.example.TheApp"
- android:icon="@drawable/app_icon"
- android:label="@string/app_name"
- android:allowBackup="true"
- android:killAfterRestore="true"
- android:restoreAnyVersion="true"
- android:backupAgent="com.example.app.BackupAgentClass"
- >
-
- <!-- Receiver -->
- <receiver
- android:icon="@drawable/app_icon"
- android:name="com.example.AppReceiver"
- >
- <intent-filter>
- <action android:name="android.intent.action.TIME_SET" />
- <action android:name="android.intent.action.TIMEZONE_CHANGED" />
- </intent-filter>
- <intent-filter>
- <action android:name="com.example.intent.action.DO_THIS" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.PHONE_STATE"/>
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- <intent-filter>
- <action android:name="com.example.intent.action.DO_THAT" />
- </intent-filter>
- </receiver>
-
- <activity
- android:theme="@style/Lib.Theme"
- android:name="com.example.LibActivity"
- android:icon="@drawable/lib_activity_icon"
- android:label="@string/lib_activity_name"
- >
- <!-- When comparing duplicate elements, whitespace and comments are ignored. -->
- <intent-filter>
- <category android:name="android.intent.category.LAUNCHER" />
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- <meta-data
- android:resource="@color/someColor2"
- android:value="metaValue2"
- android:name="metaName2">
- </meta-data>
- <intent-filter>
- <action android:name="com.example.IN_APP_NOTIFY" />
- <action android:name="com.example.PURCHASE_STATE_CHANGED" />
- <action android:name="com.example.RESPONSE_CODE" />
- </intent-filter>
- </activity>
-
- <activity
- android:icon="@drawable/activity_icon"
- android:label="@string/activity_name"
- android:name="com.example.Activity1"
- android:theme="@style/Some.Theme">
- <meta-data
- android:value="metaValue"
- android:name="metaName"
- android:resource="@color/someColor" />
- <intent-filter>
- <category android:name="android.intent.category.LAUNCHER" />
- <action android:name="android.intent.action.MAIN" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
-
-
-@lib2
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.lib2">
-
- <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" >
-
- <!-- The whitespace and alignment is also drastically different here and has
- no impact whatsoever on the content's comparison.
- Some empty elements have been 'uncollapsed' with their closing element separated. -->
- <activity android:label="@string/activity_name" android:icon="@drawable/activity_icon" android:theme="@style/Some.Theme" android:name="com.example.Activity1">
- <intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter>
- <intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter>
- <meta-data android:value="metaValue" android:resource="@color/someColor" android:name="metaName" />
- </activity>
- <activity android:label="@string/lib_activity_name" android:icon="@drawable/lib_activity_icon" android:name="com.example.LibActivity" android:theme="@style/Lib.Theme"><intent-filter>
- <action android:name="com.example.IN_APP_NOTIFY" /> <action android:name="com.example.RESPONSE_CODE" /> <action android:name="com.example.PURCHASE_STATE_CHANGED" />
- </intent-filter>
- <intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- <meta-data android:name="metaName2" android:value="metaValue2" android:resource="@color/someColor2"
- />
- </activity>
-
- <!-- Receiver -->
- <receiver android:icon="@drawable/app_icon" android:name="com.example.AppReceiver" >
- <intent-filter><action android:name="android.intent.action.TIME_SET"></action>
- <action android:name="android.intent.action.TIMEZONE_CHANGED" /></intent-filter>
- <intent-filter><action android:name="android.intent.action.PHONE_STATE" >
- </action></intent-filter>
- <intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- <intent-filter><action android:name="com.example.intent.action.DO_THIS" /></intent-filter>
- <intent-filter><action android:name="com.example.intent.action.DO_THAT" /></intent-filter>
- </receiver>
- </application>
-</manifest>
-
-
-
-@result
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.app1">
-
- <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.Activity1"
- 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>
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- <meta-data
- android:name="metaName"
- android:value="metaValue"
- android:resource="@color/someColor" />
- </activity>
-
- <!-- Receiver -->
- <receiver
- android:name="com.example.AppReceiver"
- android:icon="@drawable/app_icon">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- <intent-filter>
- <action android:name="com.example.intent.action.DO_THIS" />
- </intent-filter>
- <intent-filter>
- <action android:name="com.example.intent.action.DO_THAT" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.TIMEZONE_CHANGED" />
- <action android:name="android.intent.action.TIME_SET" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.PHONE_STATE"/>
- </intent-filter>
- </receiver>
-
- <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="com.example.IN_APP_NOTIFY" />
- <action android:name="com.example.RESPONSE_CODE" />
- <action android:name="com.example.PURCHASE_STATE_CHANGED" />
- </intent-filter>
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- <meta-data
- android:name="metaName2"
- android:value="metaValue2"
- android:resource="@color/someColor2"
- />
- </activity>
- </application>
-</manifest>
-
-@errors
-
-P [ManifestMergerTest0_main.xml:37, ManifestMergerTest1_lib1.xml:26] Skipping identical /manifest/application/activity[@name=com.example.LibActivity] element.
-P [ManifestMergerTest0_main.xml:5, ManifestMergerTest1_lib1.xml:41] Skipping identical /manifest/application/activity[@name=com.example.Activity1] element.
-P [ManifestMergerTest0_main.xml:18, ManifestMergerTest1_lib1.xml:7] Skipping identical /manifest/application/receiver[@name=com.example.AppReceiver] element.
-P [ManifestMergerTest0_main.xml:5, ManifestMergerTest2_lib2.xml:6] Skipping identical /manifest/application/activity[@name=com.example.Activity1] element.
-P [ManifestMergerTest0_main.xml:37, ManifestMergerTest2_lib2.xml:11] Skipping identical /manifest/application/activity[@name=com.example.LibActivity] element.
-P [ManifestMergerTest0_main.xml:18, ManifestMergerTest2_lib2.xml:20] Skipping identical /manifest/application/receiver[@name=com.example.AppReceiver] element.
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/65_override_app.xml b/manifmerger/src/test/java/com/android/manifmerger/data/65_override_app.xml
deleted file mode 100755
index 464b52f..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/65_override_app.xml
+++ /dev/null
@@ -1,197 +0,0 @@
-#
-# Test the tools:merge="override" tag on an application.
-# It essentially ignores _any_ application tag from libraries.
-# All other non-application elements are merged as usual.
-#
-
-@main
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- 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" />
-
- <application
- tools:merge="override"
- 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">
-
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
-
- <permission
- android:name="com.example.WhatWereYouThinking"
- android:permissionGroup="com.example.MasterControlPermission"
- android:protectionLevel="signatureOrSystem" />
-
- <!-- This is overridden by main manifest and never merged, INCLUDING all activities. -->
- <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">
-
- <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" />
-
- <!-- This is overridden by main manifest and never merged, INCLUDING all activities. -->
- <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">
-
- <permission-group
- android:description="Nobody expects..."
- android:icon="@drawable/ignored_icon"
- android:label="the Spanish Inquisition"
- android:name="com.example.MasterControlPermission" />
-
- <!-- This is overridden by main manifest and never merged, INCLUDING all activities. -->
- <application android:name="com.example.app1.TheApp">
- <activity android:name=".WidgetLibrary3" />
- </application>
-
-</manifest>
-
-
-@lib4_not_package
-
-<!-- It's an error for the manifest to lack a 'package' attribute.
- We just emit a warning in this case.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- Permission tree for lib4 -->
- <permission-tree
- android:label="This is not a label"
- android:name="com.example.PermTree" />
-
- <!-- This is overridden by main manifest and never merged, INCLUDING all activities. -->
- <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">
-
- <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" />
-
- <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" />
- </application>
-
- <permission
- android:name="com.example.WhatWereYouThinking"
- android:permissionGroup="com.example.MasterControlPermission"
- android:protectionLevel="signatureOrSystem" />
-
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
-
- <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" />
-
- <uses-feature
- android:name="android.hardware.touchscreen"
- android:required="false" />
-
- <permission-group
- android:description="Nobody expects..."
- android:icon="@drawable/ignored_icon"
- android:label="the Spanish Inquisition"
- android:name="com.example.MasterControlPermission" />
-
- <!-- Permission tree for lib4 -->
- <permission-tree
- android:label="This is not a label"
- android:name="com.example.PermTree" />
-
-</manifest>
-
-@errors
-
-W [ManifestMergerTest4_lib4_not_package.xml:1] Missing 'package' attribute in manifest.
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/66_remove_app.xml b/manifmerger/src/test/java/com/android/manifmerger/data/66_remove_app.xml
deleted file mode 100755
index a1b04b5..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/66_remove_app.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Test how elements are removed by tools:merge="remove".
-#
-
-@main
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.example.app1"
- android:versionCode="100"
- android:versionName="1.0.0">
-
- <!-- The "remove" tag will eradicate this element from the output. -->
- <application
- tools:merge="remove"
- 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">
-
- <!-- This application and all its activities or content is ignored because the
- main manifest requested to remove the application element. -->
- <application android:name="TheApp" >
- <activity android:name=".WidgetLibrary1" />
- </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">
-
- <!-- The "remove" tag will eradicate this element from the output. -->
-</manifest>
-
-@errors
-
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/67_override_activities.xml b/manifmerger/src/test/java/com/android/manifmerger/data/67_override_activities.xml
deleted file mode 100755
index 8bcdb63..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/67_override_activities.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-#
-# Test how elements are overriden by tools:merge="override".
-# The override only blocks elements that would be merged.
-#
-
-@main
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.example"
- android:versionCode="100"
- android:versionName="1.0.0">
-
- <application
- android:name="TheApp"
- android:backupAgent=".MyBackupAgent" >
- <activity android:name=".MainActivity" tools:merge="override" />
- <receiver android:name="AppReceiver" tools:merge="override"/>
- <activity android:name="com.example.lib2.LibActivity" />
- <service android:name="com.example.AppService1" tools:merge="override" />
- <provider android:name="com.example.Provider1" tools:merge="override" />
- <activity-alias android:name="AliasActivity1" tools:merge="override" />
-
- </application>
-</manifest>
-
-
-@lib1
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example">
-
- <application>
- <!-- Activity merged -->
- <activity android:name=".WidgetLibrary1" />
-
- <!-- Conflicting activity ignored by override -->
- <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>
-
- <!-- Conflicting receiver ignored by override -->
- <receiver
- android:name="com.example.AppReceiver"
- android:icon="@drawable/app_icon">
- <intent-filter>
- <action android:name="com.example.action.ACTION_CUSTOM" />
- </intent-filter>
- </receiver>
-
- <!-- Receiver merged -->
- <receiver android:name="LibReceiver" />
-
- <!-- Conflicting alias activity ignored by override -->
- <activity-alias
- android:name="com.example.AliasActivity1"
- 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>
-
- <!-- Alias activity merged -->
- <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>
-
- <!-- Conflicting service ignored by override -->
- <service
- android:icon="@drawable/app_icon"
- android:name="com.example.AppService1" />
-
- <!-- Service merged -->
- <service
- android:icon="@drawable/app_icon"
- android:name="com.example.AppService2" />
-
- <!-- Conflicting provider ignored by override -->
- <provider
- android:name="com.example.Provider1"
- android:authorities="com.example.android.apis.app.thingy1"
- android:enabled="@bool/someConditionalValue" />
-
- <!-- Provider merged -->
- <provider
- android:name="com.example.Provider2" />
-
- </application>
-</manifest>
-
-
-@result
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example"
- android:versionCode="100"
- android:versionName="1.0.0">
-
- <application
- android:name="com.example.TheApp"
- android:backupAgent="com.example.MyBackupAgent" >
- <activity android:name="com.example.MainActivity" />
- <receiver android:name="com.example.AppReceiver" />
- <activity android:name="com.example.lib2.LibActivity" />
- <service android:name="com.example.AppService1" />
- <provider android:name="com.example.Provider1" />
- <activity-alias android:name="com.example.AliasActivity1" />
- <!-- Activity merged -->
- <activity android:name="com.example.WidgetLibrary1" />
-
- <!-- Alias activity merged -->
- <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>
-
- <!-- Service merged -->
- <service
- android:icon="@drawable/app_icon"
- android:name="com.example.AppService2" />
-
- <!-- Receiver merged -->
- <receiver android:name="com.example.LibReceiver" />
-
- <!-- Provider merged -->
- <provider
- android:name="com.example.Provider2" />
-
- </application>
-</manifest>
-
-@errors
-
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/68_override_uses.xml b/manifmerger/src/test/java/com/android/manifmerger/data/68_override_uses.xml
deleted file mode 100755
index c33f489..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/68_override_uses.xml
+++ /dev/null
@@ -1,206 +0,0 @@
-#
-# Test how elements are overriden by tools:merge="override".
-# The removal prevents the actual merge operation.
-# However items are still checked out for consistency (just not merged anymore)
-# and thus still produce warnings.
-#
-
-@main
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.example"
- android:versionCode="100"
- android:versionName="1.0.0">
-
- <!-- This is the same as writing android:minSdkVersion="1" -->
- <uses-sdk android:targetSdkVersion="14" tools:merge="override" />
-
- <!-- Ignore permissions elements from lib that would conflict because
- their definition is different. -->
- <permission
- tools:merge="override"
- android:name="com.example.WhatWereYouThinking"
- android:permissionGroup="com.example.MasterControlPermission"
- android:protectionLevel="signatureOrSystem" />
-
- <permission-group
- tools:merge="override"
- android:description="Nobody expects..."
- android:icon="@drawable/ignored_icon"
- android:label="the Spanish Inquisition"
- android:name="com.example.MasterControlPermission" />
-
- <permission-tree
- tools:merge="override"
- android:label="This is not a label"
- android:name="com.example.PermTree" />
-
- <!-- uses-feature is never merged, only checked, so tools:merge=override does nothing. -->
- <uses-feature
- android:name="com.example.SomeFeature0"
- android:glEsVersion="0x00020001" />
- <!-- Ignore uses-feature from library, which would change required to
- true if it were merged. -->
- <uses-feature
- tools:merge="override"
- android:name="com.example.SomeFeature1"
- android:required="false" />
-
- <!-- supports-screens is never merged, only checked, so tools:merge=override does nothing. -->
- <supports-screens
- tools:merge="override"
- android:smallScreens="true"
- android:resizeable="false"
- />
-
- <!-- supports-gl-texture-screens-feature is never merged, only checked, so tools:merge=override does nothing. -->
- <supports-gl-texture android:name="some.gl.texture1" tools:merge="override" />
-
- <application android:name="com.example.TheApp" >
- <!-- Ignore uses-library from library, which would change required to
- true if it were merged. -->
- <uses-library
- android:name="com.example.SomeLibrary4_RequiredFalse"
- android:required="false"
- tools:merge="override" />
-
- </application>
-
-</manifest>
-
-
-@lib1
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example">
-
- <!-- The app can cope with API 1 but this library can only cope with API 4. -->
- <uses-sdk android:minSdkVersion="4" />
-
- <!-- Ignored permissions -->
- <permission
- android:name="com.example.WhatWereYouThinking"
- android:permissionGroup="com.example.AnotherGroup"
- android:protectionLevel="system" />
-
- <permission-group
- android:label="Nobody expects the Spanish Inquisition"
- android:name="com.example.MasterControlPermission" />
-
- <permission-tree
- android:description="This is not the same label"
- android:name="com.example.PermTree" />
-
- <!-- GL 0.0 is a warning which is not prevented by tools:merge=override. -->
- <uses-feature
- android:name="com.example.SomeFeature0"
- android:glEsVersion="0x00000000" />
- <uses-feature
- android:name="com.example.SomeFeature1"
- android:required="true" />
-
- <!-- supports-screens isn't really merged, just checked, so tools:merge=override does nothing. -->
- <!-- this is the not same supports-screens than in the main, will till make a warning. -->
- <supports-screens
- android:smallScreens="false"
- android:resizeable="false"
- />
-
- <!-- supports-gl-texture isn't really merged, just checked, so tools:merge=override does nothing. -->
- <!-- this is the not same supports-gl-texture than in the main. -->
- <supports-gl-texture android:name="some.gl.texture3" />
-
- <application android:name="com.example.TheApp" >
- <!-- Ignored uses-library -->
- <uses-library
- android:name="com.example.SomeLibrary4_RequiredFalse"
- android:required="true" />
-
- </application>
-
-</manifest>
-
-
-@lib2
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example">
-
- <!-- The app targets API 14 but this library targets 42. -->
- <uses-sdk android:targetSdkVersion="42" />
-
-</manifest>
-
-
-@result
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example"
- android:versionCode="100"
- android:versionName="1.0.0">
-
- <!-- This is the same as writing android:minSdkVersion="1" -->
- <uses-sdk android:targetSdkVersion="14" />
-
- <!-- Ignore permissions elements from lib that would conflict because
- their definition is different. -->
- <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" />
-
- <!-- uses-feature is never merged, only checked, so tools:merge=override does nothing. -->
- <uses-feature
- android:name="com.example.SomeFeature0"
- android:glEsVersion="0x00020001" />
- <!-- Ignore uses-feature from library, which would change required to
- true if it were merged. -->
- <uses-feature
- android:name="com.example.SomeFeature1"
- android:required="false" />
-
- <!-- supports-screens is never merged, only checked, so tools:merge=override does nothing. -->
- <supports-screens
- android:smallScreens="true"
- android:resizeable="false"
- />
-
- <!-- supports-gl-texture-screens-feature is never merged, only checked, so tools:merge=override does nothing. -->
- <supports-gl-texture android:name="some.gl.texture1" />
-
- <application android:name="com.example.TheApp" >
- <!-- Ignore uses-library from library, which would change required to
- true if it were merged. -->
- <uses-library
- android:name="com.example.SomeLibrary4_RequiredFalse"
- android:required="false" />
-
- </application>
-
-</manifest>
-
-@errors
-
-W [ManifestMergerTest0_main.xml:1, ManifestMergerTest1_lib1.xml:19] /manifest/supports-screens defined in library, missing from main manifest:
-<supports-screens>
- @android:resizeable = false
- @android:smallScreens = false
-W [ManifestMergerTest0_main.xml:1, ManifestMergerTest1_lib1.xml:23] /manifest/supports-gl-texture defined in library, missing from main manifest:
-<supports-gl-texture>
- @android:name = some.gl.texture3
-W [ManifestMergerTest1_lib1.xml:14] Ignoring <uses-feature android:glEsVersion='0x00000000'> because it's smaller than 1.0.
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/69_remove_uses.xml b/manifmerger/src/test/java/com/android/manifmerger/data/69_remove_uses.xml
deleted file mode 100755
index 03ba65c..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/69_remove_uses.xml
+++ /dev/null
@@ -1,178 +0,0 @@
-#
-# Test how elements are removed by tools:merge="remove".
-# The removal prevents the actual merge operation.
-# However items are still checked out for consistency (just not merged anymore)
-# and thus still produce warnings.
-#
-
-@main
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.example"
- android:versionCode="100"
- android:versionName="1.0.0">
-
- <!-- This is the same as writing android:minSdkVersion="1" -->
- <uses-sdk android:targetSdkVersion="14" tools:merge="remove" />
-
- <!-- Ignore permissions elements from lib that would conflict because
- their definition is different. -->
- <permission
- tools:merge="remove"
- android:name="com.example.WhatWereYouThinking"
- android:permissionGroup="com.example.MasterControlPermission"
- android:protectionLevel="signatureOrSystem" />
-
- <permission-group
- tools:merge="remove"
- android:description="Nobody expects..."
- android:icon="@drawable/ignored_icon"
- android:label="the Spanish Inquisition"
- android:name="com.example.MasterControlPermission" />
-
- <permission-tree
- tools:merge="remove"
- android:label="This is not a label"
- android:name="com.example.PermTree" />
-
- <!-- uses-feature is never merged, only checked, so tools:merge=remove does nothing. -->
- <uses-feature
- tools:merge="remove"
- android:name="com.example.SomeFeature0"
- android:glEsVersion="0x00020001" />
- <!-- Ignore uses-feature from library, which would change required to
- true if it were merged. -->
- <uses-feature
- tools:merge="remove"
- android:name="com.example.SomeFeature1"
- android:required="false" />
-
- <!-- supports-screens is never merged, only checked, so tools:merge=remove does nothing. -->
- <supports-screens
- tools:merge="remove"
- android:smallScreens="true"
- android:resizeable="false"
- />
-
- <!-- supports-gl-texture-screens-feature is never merged, only checked, so tools:merge=remove does nothing. -->
- <supports-gl-texture android:name="some.gl.texture1" tools:merge="remove" />
-
- <application android:name="com.example.TheApp" >
- <!-- Ignore uses-library from library, which would change required to
- true if it were merged. -->
- <uses-library
- tools:merge="remove"
- 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">
-
- <!-- The app can cope with API 1 but this library can only cope with API 4. -->
- <uses-sdk android:minSdkVersion="4" />
-
- <!-- Ignored permissions -->
- <permission
- android:name="com.example.WhatWereYouThinking"
- android:permissionGroup="com.example.AnotherGroup"
- android:protectionLevel="system" />
-
- <permission-group
- android:label="Nobody expects the Spanish Inquisition"
- android:name="com.example.MasterControlPermission" />
-
- <permission-tree
- android:description="This is not the same label"
- android:name="com.example.PermTree" />
-
- <!-- GL 0.0 is a warning which is not prevented by tools:merge=remove. -->
- <uses-feature
- android:name="com.example.SomeFeature0"
- android:glEsVersion="0x00000000" />
- <uses-feature
- android:name="com.example.SomeFeature1"
- android:required="true" />
-
- <!-- supports-screens isn't really merged, just checked, so tools:merge=remove does nothing. -->
- <!-- this is the not same supports-screens than in the main, will till make a warning. -->
- <supports-screens
- android:smallScreens="false"
- android:resizeable="false"
- />
-
- <!-- supports-gl-texture isn't really merged, just checked, so tools:merge=remove does nothing. -->
- <!-- this is the not same supports-gl-texture than in the main. -->
- <supports-gl-texture android:name="some.gl.texture3" />
-
- <application android:name="com.example.TheApp" >
- <!-- Ignored uses-library -->
- <uses-library
- android:name="com.example.SomeLibrary4_RequiredFalse"
- android:required="true" />
-
- </application>
-
-</manifest>
-
-
-@lib2
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example">
-
- <!-- The app targets API 14 but this library targets 42. -->
- <uses-sdk android:targetSdkVersion="42" />
-
-</manifest>
-
-
-@result
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example"
- android:versionCode="100"
- android:versionName="1.0.0">
-
- <!-- This is the same as writing android:minSdkVersion="1" -->
-
- <!-- Ignore permissions elements from lib that would conflict because
- their definition is different. -->
-
- <!-- uses-feature is never merged, only checked, so tools:merge=remove does nothing. -->
- <!-- Ignore uses-feature from library, which would change required to
- true if it were merged. -->
-
- <!-- supports-screens is never merged, only checked, so tools:merge=remove does nothing. -->
-
- <!-- supports-gl-texture-screens-feature is never merged, only checked, so tools:merge=remove does nothing. -->
-
- <application android:name="com.example.TheApp" >
- <!-- Ignore uses-library from library, which would change required to
- true if it were merged. -->
-
- </application>
-
-</manifest>
-
-@errors
-
-W [ManifestMergerTest0_main.xml:1, ManifestMergerTest1_lib1.xml:19] /manifest/supports-screens defined in library, missing from main manifest:
-<supports-screens>
- @android:resizeable = false
- @android:smallScreens = false
-W [ManifestMergerTest0_main.xml:1, ManifestMergerTest1_lib1.xml:23] /manifest/supports-gl-texture defined in library, missing from main manifest:
-<supports-gl-texture>
- @android:name = some.gl.texture3
-W [ManifestMergerTest1_lib1.xml:14] Ignoring <uses-feature android:glEsVersion='0x00000000'> because it's smaller than 1.0.
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/70_expand_fqcns.xml b/manifmerger/src/test/java/com/android/manifmerger/data/70_expand_fqcns.xml
deleted file mode 100755
index 9a51a8a..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/70_expand_fqcns.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-#
-# Tests the option to extract prefixes.
-# The default is for the manifest merger to expand all the class names
-# it finds from their short form (e.g. when the package name is implied)
-# to their FQCN.
-#
-
-@main
-
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.blankactivity5"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-sdk
- android:minSdkVersion="11"
- android:targetSdkVersion="16" />
-
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- <!-- The activity name will be expanded to its full FQCN by default. -->
- <activity
- android:name=".MainActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
-
-
-@lib1
-
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.blankactivity5" >
-
- <application>
- <!-- The activity name will be expanded to its full FQCN by default. -->
- <activity
- android:name=".FooActivity"
- android:label="@string/title_activity_foo" >
- </activity>
- </application>
-
-</manifest>
-
-
-@result
-
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.blankactivity5"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-sdk
- android:minSdkVersion="11"
- android:targetSdkVersion="16" />
-
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- <!-- The activity name will be expanded to its full FQCN by default. -->
- <activity
- android:name="com.example.blankactivity5.MainActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <!-- The activity name will be expanded to its full FQCN by default. -->
- <activity
- android:name="com.example.blankactivity5.FooActivity"
- android:label="@string/title_activity_foo" >
- </activity>
- </application>
-
-</manifest>
-
-@errors
-
-
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/71_extract_package_prefix.xml b/manifmerger/src/test/java/com/android/manifmerger/data/71_extract_package_prefix.xml
deleted file mode 100755
index cf2757e..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/71_extract_package_prefix.xml
+++ /dev/null
@@ -1,99 +0,0 @@
-#
-# Tests the option to extract prefixes.
-# The default is for the manifest merger to expand all the class names
-# it finds from their short form (e.g. when the package name is implied)
-# to their FQCN. Setting ManifMerger.setExtractPackagePrefix(true) prevents
-# this expansion and keeps the short class names in the merged result.
-#
-
-@features
-setExtractPackagePrefix=true
-
-@main
-
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.blankactivity5"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-sdk
- android:minSdkVersion="11"
- android:targetSdkVersion="16" />
-
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- <!-- The activity name will NOT be expanded to its full FQCN because
- ManifMerger.setExtractPackagePrefix is set to true. -->
- <activity
- android:name=".MainActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
-
-
-@lib1
-
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.blankactivity5" >
-
- <application>
- <!-- The activity name will NOT be expanded to its full FQCN. -->
- <activity
- android:name=".FooActivity"
- android:label="@string/title_activity_foo" >
- </activity>
- </application>
-
-</manifest>
-
-
-@result
-
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.blankactivity5"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-sdk
- android:minSdkVersion="11"
- android:targetSdkVersion="16" />
-
- <application
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- <!-- The activity name will NOT be expanded to its full FQCN because
- ManifMerger.setExtractPackagePrefix is set to true. -->
- <activity
- android:name=".MainActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
-
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <!-- The activity name will NOT be expanded to its full FQCN. -->
- <activity
- android:name=".FooActivity"
- android:label="@string/title_activity_foo" >
- </activity>
- </application>
-
-</manifest>
-
-@errors
-
-
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/75_app_metadata_merge.xml b/manifmerger/src/test/java/com/android/manifmerger/data/75_app_metadata_merge.xml
deleted file mode 100755
index f8ebf49..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/75_app_metadata_merge.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-#
-# Tests merging application/meta-data.
-# Several APIs provide app-specific keys (e.g. Android Backup API, Google Maps API.)
-# and the key needs to be placed in the <application> element as meta-data.
-#
-# This tests the default behavior which is to merge the elements from the library which are new.
-#
-
-@main
-
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.example.app1"
- android:versionCode="100"
- android:versionName="1.0.0">
-
- <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
-
- <application
- android:name="TheApp"
- android:backupAgent=".MyBackupAgent" >
- <activity android:name=".MainActivity" />
- <receiver android:name="AppReceiver" />
- <activity android:name="com.example.lib2.LibActivity" />
-
- <!-- This key is defined in the main application. -->
- <meta-data
- android:name="name.for.yet.another.api.key"
- android:value="your_yet_another_api_key"/>
-
- <!-- Merged elements will be appended here at the end. -->
- </application>
-
-</manifest>
-
-
-@lib1
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.app1">
-
- <application android:name="TheApp" >
- <activity android:name=".Library1" />
-
- <!-- The library maps API key gets merged in the main application. -->
- <meta-data
- android:name="name.for.maps.api.key"
- android:value="your_maps_api_key"/>
-
- <!-- The library backup key gets merged in the main application. -->
- <meta-data
- android:name="name.for.backup.api.key"
- android:value="your_backup_api_key" />
- </application>
-
-</manifest>
-
-
-@result
-
-<?xml version="1.0" encoding="utf-8"?>
-<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"/>
-
- <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" />
-
- <!-- This key is defined in the main application. -->
- <meta-data
- android:name="name.for.yet.another.api.key"
- android:value="your_yet_another_api_key"/>
-
- <!-- Merged elements will be appended here at the end. -->
- <activity android:name="com.example.app1.Library1" />
-
- <!-- The library maps API key gets merged in the main application. -->
- <meta-data
- android:name="name.for.maps.api.key"
- android:value="your_maps_api_key"/>
-
- <!-- The library backup key gets merged in the main application. -->
- <meta-data
- android:name="name.for.backup.api.key"
- android:value="your_backup_api_key" />
- </application>
-
-</manifest>
-
-
-@errors
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/76_app_metadata_ignore.xml b/manifmerger/src/test/java/com/android/manifmerger/data/76_app_metadata_ignore.xml
deleted file mode 100755
index c0ad444..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/76_app_metadata_ignore.xml
+++ /dev/null
@@ -1,103 +0,0 @@
-#
-# Tests merging application/meta-data.
-# Several APIs provide app-specific keys (e.g. Android Backup API, Google Maps API.)
-# and the key needs to be placed in the <application> element as meta-data.
-#
-# This tests that an application can selectively prevent specific meta-data from
-# being merged by using the tools:merge="remove" attribute.
-#
-
-@main
-
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.example.app1"
- android:versionCode="100"
- android:versionName="1.0.0">
-
- <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
-
- <application
- android:name="TheApp"
- android:backupAgent=".MyBackupAgent" >
- <activity android:name=".MainActivity" />
- <receiver android:name="AppReceiver" />
- <activity android:name="com.example.lib2.LibActivity" />
-
- <!-- This key is defined in the main application. -->
- <meta-data
- android:name="name.for.yet.another.api.key"
- android:value="your_yet_another_api_key"/>
-
- <!-- We do not want any maps API key to be merged here. -->
- <meta-data
- android:name="name.for.maps.api.key"
- tools:merge="remove" />
-
- <!-- Merged elements will be appended here at the end. -->
- </application>
-
-</manifest>
-
-
-@lib1
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.app1">
-
- <application android:name="TheApp" >
- <activity android:name=".Library1" />
-
- <!-- The library maps API key gets merged in the main application. -->
- <meta-data
- android:name="name.for.maps.api.key"
- android:value="your_maps_api_key"/>
-
- <!-- The library backup key gets merged in the main application. -->
- <meta-data
- android:name="name.for.backup.api.key"
- android:value="your_backup_api_key" />
- </application>
-
-</manifest>
-
-
-@result
-
-<?xml version="1.0" encoding="utf-8"?>
-<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"/>
-
- <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" />
-
- <!-- This key is defined in the main application. -->
- <meta-data
- android:name="name.for.yet.another.api.key"
- android:value="your_yet_another_api_key"/>
-
- <!-- We do not want any maps API key to be merged here. -->
-
- <!-- Merged elements will be appended here at the end. -->
- <activity android:name="com.example.app1.Library1" />
-
- <!-- The library backup key gets merged in the main application. -->
- <meta-data
- android:name="name.for.backup.api.key"
- android:value="your_backup_api_key" />
- </application>
-
-</manifest>
-
-
-@errors
diff --git a/manifmerger/src/test/java/com/android/manifmerger/data/77_app_metadata_conflict.xml b/manifmerger/src/test/java/com/android/manifmerger/data/77_app_metadata_conflict.xml
deleted file mode 100755
index 9c96b44..0000000
--- a/manifmerger/src/test/java/com/android/manifmerger/data/77_app_metadata_conflict.xml
+++ /dev/null
@@ -1,131 +0,0 @@
-#
-# Tests merging application/meta-data.
-# Several APIs provide app-specific keys (e.g. Android Backup API, Google Maps API.)
-# and the key needs to be placed in the <application> element as meta-data.
-#
-# This tests the default behavior which is to conflict when a library tries to
-# add a meta-data which is has the same name but not the same value as one already
-# defined in the application.
-#
-# The application can also override a meta-data using the tools:merge="override" attribute.
-# This lets the main application define a meta-data and prevent any library ones from being
-# merged and potentially conflict.
-#
-
-@fails
-
-@main
-
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- package="com.example.app1"
- android:versionCode="100"
- android:versionName="1.0.0">
-
- <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="11"/>
-
- <application
- android:name="TheApp"
- android:backupAgent=".MyBackupAgent" >
- <activity android:name=".MainActivity" />
- <receiver android:name="AppReceiver" />
- <activity android:name="com.example.lib2.LibActivity" />
-
- <!-- This key is defined in the main application. -->
- <meta-data
- android:name="name.for.yet.another.api.key"
- android:value="your_yet_another_api_key"/>
-
- <!-- The library has a maps API key that would conflict but it will
- actually be ignored since the merge-override flag is set. -->
- <meta-data
- tools:merge="override"
- android:name="name.for.maps.api.key"
- android:value="the_apps_maps_api_key"/>
-
- <!-- The library has a backup API key will conflict since it has a
- different value and the merge operation isn't overridden. -->
- <meta-data
- android:name="name.for.backup.api.key"
- android:value="the_apps_backup_api_key" />
-
- <!-- Merged elements will be appended here at the end. -->
- </application>
-
-</manifest>
-
-
-@lib1
-
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.app1">
-
- <application android:name="TheApp" >
- <activity android:name=".Library1" />
-
- <!-- The library maps API key doesn't get merged in the main application. -->
- <meta-data
- android:name="name.for.maps.api.key"
- android:value="the_library1_maps_api_key"/>
-
- <!-- The library backup key doesn't get merged in the main application. -->
- <meta-data
- android:name="name.for.backup.api.key"
- android:value="the_library1_backup_api_key" />
- </application>
-
-</manifest>
-
-
-@result
-
-<?xml version="1.0" encoding="utf-8"?>
-<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"/>
-
- <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" />
-
- <!-- This key is defined in the main application. -->
- <meta-data
- android:name="name.for.yet.another.api.key"
- android:value="your_yet_another_api_key"/>
-
- <!-- The library has a maps API key that would conflict but it will
- actually be ignored since the merge-override flag is set. -->
- <meta-data
- android:name="name.for.maps.api.key"
- android:value="the_apps_maps_api_key"/>
-
- <!-- The library has a backup API key will conflict since it has a
- different value and the merge operation isn't overridden. -->
- <meta-data
- android:name="name.for.backup.api.key"
- android:value="the_apps_backup_api_key" />
-
- <!-- Merged elements will be appended here at the end. -->
- <activity android:name="com.example.app1.Library1" />
- </application>
-
-</manifest>
-
-
-@errors
-
-E [ManifestMergerTest0_main.xml:17, ManifestMergerTest1_lib1.xml:10] Trying to merge incompatible /manifest/application/meta-data[@name=name.for.backup.api.key] element:
- <meta-data
- @android:name="name.for.backup.api.key"
--- @android:value="the_apps_backup_api_key">
- <meta-data
- @android:name="name.for.backup.api.key"
-++ @android:value="the_library1_backup_api_key">