Fix generation of R class for libraries.
Xavier Ducrohet [Thu, 31 Jan 2013 20:57:38 +0000 (12:57 -0800)]
This adds support for libraries that shares the same package names
and libraries that use the app package name.

Also added two libraries to libsTest so that
lib2b shares the package name with lib2
libapp shares the package name with app.

Change-Id: I0c0fdb6fe553857e67227fad8d4f793d414de120

36 files changed:
builder/src/main/java/com/android/builder/AndroidBuilder.java
builder/src/main/java/com/android/builder/DefaultManifestParser.java
builder/src/main/java/com/android/builder/ManifestParser.java
builder/src/main/java/com/android/builder/internal/SymbolWriter.java
builder/src/test/java/com/android/builder/internal/SymbolWriterTest.java
gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy
tests/libsTest/app/build.gradle
tests/libsTest/app/src/main/java/com/android/tests/libstest/app/MainActivity.java
tests/libsTest/app/src/main/res/layout/main.xml
tests/libsTest/app/src/test/java/com/android/tests/libstest/app/MainActivityTest.java
tests/libsTest/build.gradle
tests/libsTest/lib2b/build.gradle [new file with mode: 0644]
tests/libsTest/lib2b/proguard-project.txt [new file with mode: 0644]
tests/libsTest/lib2b/src/main/AndroidManifest.xml [new file with mode: 0644]
tests/libsTest/lib2b/src/main/java/com/android/tests/libstest/lib2/Lib2b.java [new file with mode: 0644]
tests/libsTest/lib2b/src/main/java/com/android/tests/libstest/lib2/MainActivity2b.java [new file with mode: 0644]
tests/libsTest/lib2b/src/main/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
tests/libsTest/lib2b/src/main/res/drawable-ldpi/ic_launcher.png [new file with mode: 0644]
tests/libsTest/lib2b/src/main/res/drawable-mdpi/ic_launcher.png [new file with mode: 0644]
tests/libsTest/lib2b/src/main/res/layout/lib2b_main.xml [new file with mode: 0644]
tests/libsTest/lib2b/src/main/res/values/strings.xml [new file with mode: 0644]
tests/libsTest/lib2b/src/main/resources/com/android/tests/libstest/lib2/Lib2b.txt [new file with mode: 0644]
tests/libsTest/lib2b/src/test/java/com/android/tests/libstest/lib2/MainActivity2bTest.java [new file with mode: 0644]
tests/libsTest/libapp/build.gradle [new file with mode: 0644]
tests/libsTest/libapp/proguard-project.txt [new file with mode: 0644]
tests/libsTest/libapp/src/main/AndroidManifest.xml [new file with mode: 0644]
tests/libsTest/libapp/src/main/java/com/android/tests/libstest/app/LibApp.java [new file with mode: 0644]
tests/libsTest/libapp/src/main/java/com/android/tests/libstest/app/MainActivityLibApp.java [new file with mode: 0644]
tests/libsTest/libapp/src/main/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
tests/libsTest/libapp/src/main/res/drawable-ldpi/ic_launcher.png [new file with mode: 0644]
tests/libsTest/libapp/src/main/res/drawable-mdpi/ic_launcher.png [new file with mode: 0644]
tests/libsTest/libapp/src/main/res/layout/libapp_main.xml [new file with mode: 0644]
tests/libsTest/libapp/src/main/res/values/strings.xml [new file with mode: 0644]
tests/libsTest/libapp/src/main/resources/com/android/tests/libstest/app/Libapp.txt [new file with mode: 0644]
tests/libsTest/libapp/src/test/java/com/android/tests/libstest/libapp/MainActivityLibAppTest.java [new file with mode: 0644]
tests/libsTest/settings.gradle

index c484675..67a02d1 100644 (file)
@@ -46,14 +46,17 @@ import com.android.sdklib.IAndroidTarget;
 import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
 import com.android.sdklib.internal.repository.packages.FullRevision;
 import com.android.utils.ILogger;
+import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
 import com.google.common.io.Files;
 
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
@@ -616,31 +619,59 @@ public class AndroidBuilder {
         // now if the project has libraries, R needs to be created for each libraries,
         // but only if the current project is not a library.
         if (type != VariantConfiguration.Type.LIBRARY && !libraries.isEmpty()) {
-            SymbolLoader symbolValues = null;
+            SymbolLoader fullSymbolValues = null;
+
+            // First pass processing the libraries, collecting them by packageName,
+            // and ignoring the ones that have the same package name as the application
+            // (since that R class was already created).
+            String appPackageName = packageOverride;
+            if (appPackageName == null) {
+                appPackageName = VariantConfiguration.sManifestParser.getPackage(manifestFile);
+            }
+
+            // list of all the symbol loaders per package names.
+            Multimap<String, SymbolLoader> libMap = ArrayListMultimap.create();
 
             for (SymbolFileProvider lib : libraries) {
                 File rFile = lib.getSymbolFile();
                 // if the library has no resource, this file won't exist.
                 if (rFile.isFile()) {
-                    // load the values if that's not already been done.
+
+                    String packageName = VariantConfiguration.sManifestParser.getPackage(
+                            lib.getManifest());
+                    if (appPackageName.equals(packageName)) {
+                        // ignore libraries that have the same package name as the app
+                        continue;
+                    }
+
+                    // load the full values if that's not already been done.
                     // Doing it lazily allow us to support the case where there's no
                     // resources anywhere.
-                    if (symbolValues == null) {
-                        symbolValues = new SymbolLoader(new File(symbolOutputDir, "R.txt"),
+                    if (fullSymbolValues == null) {
+                        fullSymbolValues = new SymbolLoader(new File(symbolOutputDir, "R.txt"),
                                 mLogger);
-                        symbolValues.load();
+                        fullSymbolValues.load();
                     }
 
-                    SymbolLoader symbols = new SymbolLoader(rFile, mLogger);
-                    symbols.load();
+                    SymbolLoader libSymbols = new SymbolLoader(rFile, mLogger);
+                    libSymbols.load();
 
-                    String packageName = VariantConfiguration.sManifestParser.getPackage(
-                            lib.getManifest());
 
-                    SymbolWriter writer = new SymbolWriter(sourceOutputDir, packageName,
-                            symbols, symbolValues);
-                    writer.write();
+                    // store these symbols by associating them with the package name.
+                    libMap.put(packageName, libSymbols);
+                }
+            }
+
+            // now loop on all the package name, merge all the symbols to write, and write them
+            for (String packageName : libMap.keySet()) {
+                Collection<SymbolLoader> symbols = libMap.get(packageName);
+
+                SymbolWriter writer = new SymbolWriter(sourceOutputDir, packageName,
+                        fullSymbolValues);
+                for (SymbolLoader symbolLoader : symbols) {
+                    writer.addSymbolsToWrite(symbolLoader);
                 }
+                writer.write();
             }
         }
     }
index ab68f13..ba07453 100644 (file)
@@ -17,6 +17,7 @@
 package com.android.builder;
 
 import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
 import com.android.io.FileWrapper;
 import com.android.io.StreamException;
 import com.android.xml.AndroidManifest;
@@ -31,6 +32,7 @@ import java.io.FileNotFoundException;
 
 public class DefaultManifestParser implements ManifestParser {
 
+    @Nullable
     @Override
     public String getPackage(@NonNull File manifestFile) {
         XPath xpath = AndroidXPathFactory.newXPath();
@@ -47,6 +49,7 @@ public class DefaultManifestParser implements ManifestParser {
         return null;
     }
 
+    @Nullable
     @Override
     public String getVersionName(@NonNull File manifestFile) {
         XPath xpath = AndroidXPathFactory.newXPath();
index 3375b25..c9f0c11 100644 (file)
 package com.android.builder;
 
 import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
 
 import java.io.File;
 
 public interface ManifestParser {
 
+    @Nullable
     String getPackage(@NonNull File manifestFile);
+
     int getMinSdkVersion(@NonNull File manifestFile);
+
+    @Nullable
     String getVersionName(@NonNull File manifestFile);
 }
index 63f38a8..03f37c9 100644 (file)
@@ -20,6 +20,8 @@ import com.android.SdkConstants;
 import com.android.builder.internal.SymbolLoader.SymbolEntry;
 import com.google.common.base.Charsets;
 import com.google.common.base.Splitter;
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Table;
 import com.google.common.io.Closeables;
 import com.google.common.io.Files;
@@ -27,7 +29,11 @@ import com.google.common.io.Files;
 import java.io.BufferedWriter;
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  */
@@ -35,16 +41,29 @@ public class SymbolWriter {
 
     private final String mOutFolder;
     private final String mPackageName;
-    private final SymbolLoader mSymbols;
+    private final List<SymbolLoader> mSymbols = Lists.newArrayList();
     private final SymbolLoader mValues;
 
-    public SymbolWriter(String outFolder, String packageName, SymbolLoader symbols, SymbolLoader values) {
+    public SymbolWriter(String outFolder, String packageName, SymbolLoader values) {
         mOutFolder = outFolder;
         mPackageName = packageName;
-        mSymbols = symbols;
         mValues = values;
     }
 
+    public void addSymbolsToWrite(SymbolLoader symbols) {
+        mSymbols.add(symbols);
+    }
+
+    private Table<String, String, SymbolEntry> getAllSymbols() {
+        Table<String, String, SymbolEntry> symbols = HashBasedTable.create();
+
+        for (SymbolLoader symbolLoader : mSymbols) {
+            symbols.putAll(symbolLoader.getSymbols());
+        }
+
+        return symbols;
+    }
+
     public void write() throws IOException {
         Splitter splitter = Splitter.on('.');
         Iterable<String> folders = splitter.split(mPackageName);
@@ -70,17 +89,26 @@ public class SymbolWriter {
             writer.write(mPackageName);
             writer.write(";\n\npublic final class R {\n");
 
-            Table<String, String, SymbolEntry> symbols = mSymbols.getSymbols();
+            Table<String, String, SymbolEntry> symbols = getAllSymbols();
             Table<String, String, SymbolEntry> values = mValues.getSymbols();
 
-            for (String row : symbols.rowKeySet()) {
+            Set<String> rowSet = symbols.rowKeySet();
+            List<String> rowList = Lists.newArrayList(rowSet);
+            Collections.sort(rowList);
+
+            for (String row : rowList) {
                 writer.write("\tpublic static final class ");
                 writer.write(row);
                 writer.write(" {\n");
 
-                for (Map.Entry<String, SymbolEntry> symbol : symbols.row(row).entrySet()) {
+                Map<String, SymbolEntry> rowMap = symbols.row(row);
+                Set<String> symbolSet = rowMap.keySet();
+                ArrayList<String> symbolList = Lists.newArrayList(symbolSet);
+                Collections.sort(symbolList);
+
+                for (String symbolName : symbolList) {
                     // get the matching SymbolEntry from the values Table.
-                    SymbolEntry value = values.get(row, symbol.getKey());
+                    SymbolEntry value = values.get(row, symbolName);
                     if (value != null) {
                         writer.write("\t\tpublic static final ");
                         writer.write(value.getType());
index 757973a..a6f8595 100644 (file)
@@ -17,29 +17,62 @@ package com.android.builder.internal;
 
 import com.android.utils.NullLogger;
 import com.google.common.base.Charsets;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Table;
 import com.google.common.io.Files;
 import junit.framework.TestCase;
 
 import java.io.File;
+import java.util.List;
 
 @SuppressWarnings("javadoc")
 public class SymbolWriterTest extends TestCase {
-    private void check(String packageName, String rText, String rJava) throws Exception {
-        // Load symbols
+    private void check(String packageName, String rJava, String rValues, String... rTexts)
+            throws Exception {
+        if (rValues == null) {
+            if (rTexts.length == 1) {
+                rValues = rTexts[0];
+            } else {
+                throw new IllegalArgumentException(
+                        "Can't have a null rValues with rTexts.length!=1");
+            }
+        }
+
+        // Load the symbol values
+        // 1. write rText in a temp file
         File file = File.createTempFile(getClass().getSimpleName(), "txt");
         file.deleteOnExit();
-        Files.write(rText, file, Charsets.UTF_8);
-        SymbolLoader loader = new SymbolLoader(file, NullLogger.getLogger());
-        loader.load();
-        Table<String, String, SymbolLoader.SymbolEntry> symbols = loader.getSymbols();
-        assertNotNull(symbols);
+        Files.write(rValues, file, Charsets.UTF_8);
+        // 2. load symbol from temp file.
+        SymbolLoader symbolValues = new SymbolLoader(file, NullLogger.getLogger());
+        symbolValues.load();
+        Table<String, String, SymbolLoader.SymbolEntry> values = symbolValues.getSymbols();
+        assertNotNull(values);
+
+
+        // Load the symbols to write
+        List<SymbolLoader> symbolList = Lists.newArrayListWithCapacity(rTexts.length);
+        for (String rText : rTexts) {
+            // 1. write rText in a temp file
+            file = File.createTempFile(getClass().getSimpleName(), "txt");
+            file.deleteOnExit();
+            Files.write(rText, file, Charsets.UTF_8);
+            // 2. load symbol from temp file.
+            SymbolLoader loader = new SymbolLoader(file, NullLogger.getLogger());
+            loader.load();
+            Table<String, String, SymbolLoader.SymbolEntry> symbols = loader.getSymbols();
+            assertNotNull(symbols);
+            symbolList.add(loader);
+        }
 
         // Write symbols
         File outFolder = Files.createTempDir();
         outFolder.mkdirs();
 
-        SymbolWriter writer = new SymbolWriter(outFolder.getPath(), packageName, loader, loader);
+        SymbolWriter writer = new SymbolWriter(outFolder.getPath(), packageName, symbolValues);
+        for (SymbolLoader symbolLoader : symbolList) {
+            writer.addSymbolsToWrite(symbolLoader);
+        }
         writer.write();
 
         String contents = Files.toString(new File(outFolder,
@@ -55,9 +88,6 @@ public class SymbolWriterTest extends TestCase {
             // Package
             "test.pkg",
 
-            // R.txt
-            "int xml authenticator 0x7f040000\n",
-
             // R.java
             "/* AUTO-GENERATED FILE.  DO NOT MODIFY.\n" +
             " *\n" +
@@ -71,7 +101,13 @@ public class SymbolWriterTest extends TestCase {
             "    public static final class xml {\n" +
             "        public static final int authenticator = 0x7f040000;\n" +
             "    }\n" +
-            "}\n"
+            "}\n",
+
+            // R values
+            null,
+
+            // R.txt
+            "int xml authenticator 0x7f040000\n"
         );
     }
 
@@ -80,14 +116,6 @@ public class SymbolWriterTest extends TestCase {
             // Package
             "test.pkg",
 
-            // R.txt
-            "int drawable foobar 0x7f020000\n" +
-            "int drawable ic_launcher 0x7f020001\n" +
-            "int string app_name 0x7f030000\n" +
-            "int string lib1 0x7f030001\n" +
-            "int style AppBaseTheme 0x7f040000\n" +
-            "int style AppTheme 0x7f040001\n",
-
             // R.java
             "/* AUTO-GENERATED FILE.  DO NOT MODIFY.\n" +
             " *\n" +
@@ -98,19 +126,35 @@ public class SymbolWriterTest extends TestCase {
             "package test.pkg;\n" +
             "\n" +
             "public final class R {\n" +
-            "    public static final class style {\n" +
-            "        public static final int AppBaseTheme = 0x7f040000;\n" +
-            "        public static final int AppTheme = 0x7f040001;\n" +
+            "    public static final class drawable {\n" +
+            "        public static final int foobar = 0x7f020000;\n" +
+            "        public static final int ic_launcher = 0x7f020001;\n" +
             "    }\n" +
             "    public static final class string {\n" +
             "        public static final int app_name = 0x7f030000;\n" +
             "        public static final int lib1 = 0x7f030001;\n" +
             "    }\n" +
-            "    public static final class drawable {\n" +
-            "        public static final int ic_launcher = 0x7f020001;\n" +
-            "        public static final int foobar = 0x7f020000;\n" +
+            "    public static final class style {\n" +
+            "        public static final int AppBaseTheme = 0x7f040000;\n" +
+            "        public static final int AppTheme = 0x7f040001;\n" +
             "    }\n" +
-            "}\n"
+            "}\n",
+
+            // R values
+            "int drawable foobar 0x7f020000\n" +
+            "int drawable ic_launcher 0x7f020001\n" +
+            "int string app_name 0x7f030000\n" +
+            "int string lib1 0x7f030001\n" +
+            "int style AppBaseTheme 0x7f040000\n" +
+            "int style AppTheme 0x7f040001\n",
+
+            // R.txt
+            "int drawable foobar 0x7fffffff\n" +
+            "int drawable ic_launcher 0x7fffffff\n" +
+            "int string app_name 0x7fffffff\n" +
+            "int string lib1 0x7fffffff\n" +
+            "int style AppBaseTheme 0x7fffffff\n" +
+            "int style AppTheme 0x7fffffff\n"
         );
     }
 
@@ -119,14 +163,6 @@ public class SymbolWriterTest extends TestCase {
             // Package
             "test.pkg",
 
-            // R.txt
-            "int[] styleable TiledView { 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003, 0x7f010004 }\n" +
-            "int styleable TiledView_tileName 2\n" +
-            "int styleable TiledView_tilingEnum 4\n" +
-            "int styleable TiledView_tilingMode 3\n" +
-            "int styleable TiledView_tilingProperty 0\n" +
-            "int styleable TiledView_tilingResource 1\n",
-
             // R.java
             "/* AUTO-GENERATED FILE.  DO NOT MODIFY.\n" +
             " *\n" +
@@ -138,14 +174,25 @@ public class SymbolWriterTest extends TestCase {
             "\n" +
             "public final class R {\n" +
             "    public static final class styleable {\n" +
-            "        public static final int TiledView_tilingProperty = 0;\n" +
-            "        public static final int TiledView_tilingMode = 3;\n" +
-            "        public static final int TiledView_tilingResource = 1;\n" +
+            "        public static final int[] TiledView = { 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003, 0x7f010004 };\n" +
             "        public static final int TiledView_tileName = 2;\n" +
             "        public static final int TiledView_tilingEnum = 4;\n" +
-            "        public static final int[] TiledView = { 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003, 0x7f010004 };\n" +
+            "        public static final int TiledView_tilingMode = 3;\n" +
+            "        public static final int TiledView_tilingProperty = 0;\n" +
+            "        public static final int TiledView_tilingResource = 1;\n" +
             "    }\n" +
-            "}\n"
+            "}\n",
+
+            // R values
+            null,
+
+            // R.txt
+            "int[] styleable TiledView { 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003, 0x7f010004 }\n" +
+            "int styleable TiledView_tileName 2\n" +
+            "int styleable TiledView_tilingEnum 4\n" +
+            "int styleable TiledView_tilingMode 3\n" +
+            "int styleable TiledView_tilingProperty 0\n" +
+            "int styleable TiledView_tilingResource 1\n"
         );
     }
 
@@ -154,12 +201,6 @@ public class SymbolWriterTest extends TestCase {
             // Package
             "test.pkg",
 
-            // R.txt
-            "int[] styleable LimitedSizeLinearLayout { 0x7f010000, 0x7f010001 }\n" +
-            "int styleable LimitedSizeLinearLayout_max_height 1\n" +
-            "int styleable LimitedSizeLinearLayout_max_width 0\n" +
-            "int xml authenticator 0x7f040000\n",
-
             // R.java
             "/* AUTO-GENERATED FILE.  DO NOT MODIFY.\n" +
             " *\n" +
@@ -171,14 +212,74 @@ public class SymbolWriterTest extends TestCase {
             "\n" +
             "public final class R {\n" +
             "    public static final class styleable {\n" +
+            "        public static final int[] LimitedSizeLinearLayout = { 0x7f010000, 0x7f010001 };\n" +
             "        public static final int LimitedSizeLinearLayout_max_height = 1;\n" +
             "        public static final int LimitedSizeLinearLayout_max_width = 0;\n" +
-            "        public static final int[] LimitedSizeLinearLayout = { 0x7f010000, 0x7f010001 };\n" +
             "    }\n" +
             "    public static final class xml {\n" +
             "        public static final int authenticator = 0x7f040000;\n" +
             "    }\n" +
-            "}\n"
+            "}\n",
+
+            // R values
+            null,
+
+            // R.txt
+            "int[] styleable LimitedSizeLinearLayout { 0x7f010000, 0x7f010001 }\n" +
+            "int styleable LimitedSizeLinearLayout_max_height 1\n" +
+            "int styleable LimitedSizeLinearLayout_max_width 0\n" +
+            "int xml authenticator 0x7f040000\n"
+        );
+    }
+
+    public void testMerge() throws Exception {
+        check(
+            // Package
+            "test.pkg",
+
+            // R.java
+            "/* AUTO-GENERATED FILE.  DO NOT MODIFY.\n" +
+            " *\n" +
+            " * This class was automatically generated by the\n" +
+            " * aapt tool from the resource data it found.  It\n" +
+            " * should not be modified by hand.\n" +
+            " */\n" +
+            "package test.pkg;\n" +
+            "\n" +
+            "public final class R {\n" +
+            "    public static final class drawable {\n" +
+            "        public static final int foobar = 0x7f020000;\n" +
+            "        public static final int ic_launcher = 0x7f020001;\n" +
+            "    }\n" +
+            "    public static final class string {\n" +
+            "        public static final int app_name = 0x7f030000;\n" +
+            "        public static final int lib1 = 0x7f030001;\n" +
+            "    }\n" +
+            "    public static final class style {\n" +
+            "        public static final int AppBaseTheme = 0x7f040000;\n" +
+            "        public static final int AppTheme = 0x7f040001;\n" +
+            "    }\n" +
+            "}\n",
+
+            // R values
+            "int drawable foobar 0x7f020000\n" +
+            "int drawable ic_launcher 0x7f020001\n" +
+            "int string app_name 0x7f030000\n" +
+            "int string lib1 0x7f030001\n" +
+            "int style AppBaseTheme 0x7f040000\n" +
+            "int style AppTheme 0x7f040001\n",
+
+            // R.txt 1
+            "int drawable foobar 0x7fffffff\n" +
+            "int drawable ic_launcher 0x7fffffff\n" +
+            "int string app_name 0x7fffffff\n" +
+            "int string lib1 0x7fffffff\n" +
+
+            // R.txt 2
+            "int string app_name 0x80000000\n" +
+            "int string lib1 0x80000000\n" +
+            "int style AppBaseTheme 0x80000000\n" +
+            "int style AppTheme 0x80000000\n"
         );
     }
 }
index d1be77b..d350d6b 100644 (file)
@@ -36,6 +36,7 @@ import org.gradle.api.tasks.Copy
 import org.gradle.api.tasks.bundling.Jar
 import org.gradle.api.tasks.bundling.Zip
 import org.gradle.internal.reflect.Instantiator
+import org.gradle.tooling.BuildException
 
 import javax.inject.Inject
 
@@ -145,6 +146,11 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> {
         variantConfig.setJarDependencies(jars)
         variantConfig.setAndroidDependencies(libs)
 
+        String packageName = variantConfig.getPackageFromManifest()
+        if (packageName == null) {
+            throw new BuildException("Failed to read manifest")
+        }
+
         ProductionAppVariant variant = new ProductionAppVariant(variantConfig)
         variants.add(variant)
 
@@ -182,9 +188,10 @@ public class LibraryPlugin extends BasePlugin implements Plugin<Project> {
 
         jar.destinationDir = project.file("$project.buildDir/$DIR_BUNDLES/${variant.dirName}")
         jar.archiveName = "classes.jar"
-        String packageName = variantConfig.getPackageFromManifest().replace('.', '/');
+        packageName = packageName.replace('.', '/');
         jar.exclude(packageName + "/R.class")
         jar.exclude(packageName + "/R\$*.class")
+        jar.exclude(packageName + "/BuildConfig.class")
 
         // package the aidl files into the bundle folder
         Copy packageAidl = project.tasks.add("package${variant.name}Aidl", Copy)
index 29c70bc..eded7c2 100644 (file)
@@ -9,4 +9,6 @@ android {
 //
 dependencies {
     compile project(':lib1')
+    compile project(':lib2b')
+    compile project(':libapp')
 }
index 8992066..739f91e 100644 (file)
@@ -5,6 +5,7 @@ import android.os.Bundle;
 
 import com.android.tests.libstest.lib1.Lib1;
 import com.android.tests.libstest.lib2.Lib2;
+import com.android.tests.libstest.lib2.Lib2b;
 
 public class MainActivity extends Activity {
     /** Called when the activity is first created. */
@@ -16,5 +17,7 @@ public class MainActivity extends Activity {
         App.handleTextView(this);
         Lib1.handleTextView(this);
         Lib2.handleTextView(this);
+        Lib2b.handleTextView(this);
+        LibApp.handleTextView(this);
     }
 }
\ No newline at end of file
index f735960..fa1aaba 100644 (file)
@@ -18,4 +18,8 @@
 
     <include layout="@layout/lib1_main" />
 
+    <include layout="@layout/lib2b_main" />
+
+    <include layout="@layout/libapp_main" />
+
 </LinearLayout>
\ No newline at end of file
index 012a4e2..61a0a31 100644 (file)
@@ -45,6 +45,10 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
     private TextView mLib1TextView2;
     private TextView mLib2TextView1;
     private TextView mLib2TextView2;
+    private TextView mLib2bTextView1;
+    private TextView mLib2bTextView2;
+    private TextView mLibappTextView1;
+    private TextView mLibappTextView2;
 
     /**
      * Creates an {@link ActivityInstrumentationTestCase2} that tests the {@link Focus2} activity.
@@ -66,6 +70,10 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
         mLib1TextView2 = (TextView) a.findViewById(R.id.lib1_text2);
         mLib2TextView1 = (TextView) a.findViewById(R.id.lib2_text1);
         mLib2TextView2 = (TextView) a.findViewById(R.id.lib2_text2);
+        mLib2bTextView1 = (TextView) a.findViewById(R.id.lib2b_text1);
+        mLib2bTextView2 = (TextView) a.findViewById(R.id.lib2b_text2);
+        mLibappTextView1 = (TextView) a.findViewById(R.id.libapp_text1);
+        mLibappTextView2 = (TextView) a.findViewById(R.id.libapp_text2);
     }
 
     /**
@@ -82,6 +90,10 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
         assertNotNull(mLib1TextView2);
         assertNotNull(mLib2TextView1);
         assertNotNull(mLib2TextView2);
+        assertNotNull(mLib2bTextView1);
+        assertNotNull(mLib2bTextView2);
+        assertNotNull(mLibappTextView1);
+        assertNotNull(mLibappTextView2);
     }
 
     @MediumTest
@@ -89,6 +101,8 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
         assertEquals(mAppTextView1.getText(), "SUCCESS-APP");
         assertEquals(mLib1TextView1.getText(), "SUCCESS-LIB1");
         assertEquals(mLib2TextView1.getText(), "SUCCESS-LIB2");
+        assertEquals(mLib2bTextView1.getText(), "SUCCESS-LIB2b");
+        assertEquals(mLibappTextView1.getText(), "SUCCESS-LIBAPP");
     }
 
     @MediumTest
@@ -96,5 +110,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
         assertEquals(mAppTextView2.getText(), "SUCCESS-APP");
         assertEquals(mLib1TextView2.getText(), "SUCCESS-LIB1");
         assertEquals(mLib2TextView2.getText(), "SUCCESS-LIB2");
+        assertEquals(mLib2bTextView2.getText(), "SUCCESS-LIB2b");
+        assertEquals(mLibappTextView2.getText(), "SUCCESS-LIBAPP");
     }
 }
index a0832c6..8090336 100644 (file)
@@ -6,3 +6,5 @@ buildscript {
         classpath 'com.android.tools.build:gradle:0.3-SNAPSHOT'
     }
 }
+
+apply plugin: 'android-reporting'
\ No newline at end of file
diff --git a/tests/libsTest/lib2b/build.gradle b/tests/libsTest/lib2b/build.gradle
new file mode 100644 (file)
index 0000000..a810790
--- /dev/null
@@ -0,0 +1,6 @@
+apply plugin: 'android-library'
+
+android {
+    target = "android-15"
+
+}
\ No newline at end of file
diff --git a/tests/libsTest/lib2b/proguard-project.txt b/tests/libsTest/lib2b/proguard-project.txt
new file mode 100644 (file)
index 0000000..f2fe155
--- /dev/null
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/tests/libsTest/lib2b/src/main/AndroidManifest.xml b/tests/libsTest/lib2b/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..814af46
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.tests.libstest.lib2"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <application
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/lib2b_name" >
+        <activity
+            android:name="MainActivity2b"
+            android:label="@string/lib2b_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/tests/libsTest/lib2b/src/main/java/com/android/tests/libstest/lib2/Lib2b.java b/tests/libsTest/lib2b/src/main/java/com/android/tests/libstest/lib2/Lib2b.java
new file mode 100644 (file)
index 0000000..e4329e5
--- /dev/null
@@ -0,0 +1,43 @@
+package com.android.tests.libstest.lib2;
+
+import android.app.Activity;
+import android.widget.TextView;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class Lib2b {
+    
+    public static void handleTextView(Activity a) {
+        TextView tv = (TextView) a.findViewById(R.id.lib2b_text2);
+        if (tv != null) {
+            tv.setText(getContent());
+        }
+    }
+
+    private static String getContent() {
+        InputStream input = Lib2b.class.getResourceAsStream("Lib2b.txt");
+        if (input == null) {
+            return "FAILED TO FIND Lib2b.txt";
+        }
+
+        BufferedReader reader = null;
+        try {
+            reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
+
+            return reader.readLine();
+        } catch (IOException e) {
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        
+        return "FAILED TO READ CONTENT";
+    }
+}
diff --git a/tests/libsTest/lib2b/src/main/java/com/android/tests/libstest/lib2/MainActivity2b.java b/tests/libsTest/lib2b/src/main/java/com/android/tests/libstest/lib2/MainActivity2b.java
new file mode 100644 (file)
index 0000000..2e09018
--- /dev/null
@@ -0,0 +1,15 @@
+package com.android.tests.libstest.lib2;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivity2b extends Activity {
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.lib2b_main);
+        
+        Lib2b.handleTextView(this);
+    }
+}
diff --git a/tests/libsTest/lib2b/src/main/res/drawable-hdpi/ic_launcher.png b/tests/libsTest/lib2b/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..8074c4c
Binary files /dev/null and b/tests/libsTest/lib2b/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/tests/libsTest/lib2b/src/main/res/drawable-ldpi/ic_launcher.png b/tests/libsTest/lib2b/src/main/res/drawable-ldpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..1095584
Binary files /dev/null and b/tests/libsTest/lib2b/src/main/res/drawable-ldpi/ic_launcher.png differ
diff --git a/tests/libsTest/lib2b/src/main/res/drawable-mdpi/ic_launcher.png b/tests/libsTest/lib2b/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..a07c69f
Binary files /dev/null and b/tests/libsTest/lib2b/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/tests/libsTest/lib2b/src/main/res/layout/lib2b_main.xml b/tests/libsTest/lib2b/src/main/res/layout/lib2b_main.xml
new file mode 100644 (file)
index 0000000..01e6a9f
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/lib2b_text1"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/lib2b_string" />
+
+    <TextView
+        android:id="@+id/lib2b_text2"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/libsTest/lib2b/src/main/res/values/strings.xml b/tests/libsTest/lib2b/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..d21e21f
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="lib2b_name">LibsTest-lib2b</string>
+    <string name="lib2b_string">SUCCESS-LIB2b</string>
+
+</resources>
\ No newline at end of file
diff --git a/tests/libsTest/lib2b/src/main/resources/com/android/tests/libstest/lib2/Lib2b.txt b/tests/libsTest/lib2b/src/main/resources/com/android/tests/libstest/lib2/Lib2b.txt
new file mode 100644 (file)
index 0000000..59e6b48
--- /dev/null
@@ -0,0 +1 @@
+SUCCESS-LIB2b
\ No newline at end of file
diff --git a/tests/libsTest/lib2b/src/test/java/com/android/tests/libstest/lib2/MainActivity2bTest.java b/tests/libsTest/lib2b/src/test/java/com/android/tests/libstest/lib2/MainActivity2bTest.java
new file mode 100644 (file)
index 0000000..35c56e3
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tests.libstest.lib2;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.TextView;
+
+import com.android.tests.libstest.lib2.R;
+
+/**
+ * An example of an {@link ActivityInstrumentationTestCase2} of a specific activity {@link Focus2}.
+ * By virtue of extending {@link ActivityInstrumentationTestCase2}, the target activity is automatically
+ * launched and finished before and after each test.  This also extends
+ * {@link android.test.InstrumentationTestCase}, which provides
+ * access to methods for sending events to the target activity, such as key and
+ * touch events.  See {@link #sendKeys}.
+ *
+ * In general, {@link android.test.InstrumentationTestCase}s and {@link ActivityInstrumentationTestCase2}s
+ * are heavier weight functional tests available for end to end testing of your
+ * user interface.  When run via a {@link android.test.InstrumentationTestRunner},
+ * the necessary {@link android.app.Instrumentation} will be injected for you to
+ * user via {@link #getInstrumentation} in your tests.
+ *
+ * See {@link com.example.android.apis.AllTests} for documentation on running
+ * all tests and individual tests in this application.
+ */
+public class MainActivity2bTest extends ActivityInstrumentationTestCase2<MainActivity2b> {
+
+    private TextView mTextView1;
+    private TextView mTextView2;
+
+    /**
+     * Creates an {@link ActivityInstrumentationTestCase2} that tests the {@link Focus2} activity.
+     */
+    public MainActivity2bTest() {
+        super(MainActivity2b.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        final MainActivity2b a = getActivity();
+        // ensure a valid handle to the activity has been returned
+        assertNotNull(a);
+        
+        mTextView1 = (TextView) a.findViewById(R.id.lib2b_text1);
+        mTextView2 = (TextView) a.findViewById(R.id.lib2b_text2);
+    }
+
+    /**
+     * The name 'test preconditions' is a convention to signal that if this
+     * test doesn't pass, the test case was not set up properly and it might
+     * explain any and all failures in other tests.  This is not guaranteed
+     * to run before other tests, as junit uses reflection to find the tests.
+     */
+    @MediumTest
+    public void testPreconditions() {
+        assertNotNull(mTextView1);
+        assertNotNull(mTextView2);
+    }
+
+    @MediumTest
+    public void testAndroidStrings() {
+        assertEquals("SUCCESS-LIB2b", mTextView1.getText());
+    }
+
+    @MediumTest
+    public void testJavaStrings() {
+        assertEquals("SUCCESS-LIB2b", mTextView2.getText());
+    }
+}
diff --git a/tests/libsTest/libapp/build.gradle b/tests/libsTest/libapp/build.gradle
new file mode 100644 (file)
index 0000000..a810790
--- /dev/null
@@ -0,0 +1,6 @@
+apply plugin: 'android-library'
+
+android {
+    target = "android-15"
+
+}
\ No newline at end of file
diff --git a/tests/libsTest/libapp/proguard-project.txt b/tests/libsTest/libapp/proguard-project.txt
new file mode 100644 (file)
index 0000000..f2fe155
--- /dev/null
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/tests/libsTest/libapp/src/main/AndroidManifest.xml b/tests/libsTest/libapp/src/main/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..0592d2d
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.tests.libstest.app"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <application
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/libapp_name" >
+        <activity
+            android:name="MainActivityLibApp"
+            android:label="@string/libapp_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
\ No newline at end of file
diff --git a/tests/libsTest/libapp/src/main/java/com/android/tests/libstest/app/LibApp.java b/tests/libsTest/libapp/src/main/java/com/android/tests/libstest/app/LibApp.java
new file mode 100644 (file)
index 0000000..9a25e9e
--- /dev/null
@@ -0,0 +1,43 @@
+package com.android.tests.libstest.app;
+
+import android.app.Activity;
+import android.widget.TextView;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+public class LibApp {
+    
+    public static void handleTextView(Activity a) {
+        TextView tv = (TextView) a.findViewById(R.id.libapp_text2);
+        if (tv != null) {
+            tv.setText(getContent());
+        }
+    }
+
+    private static String getContent() {
+        InputStream input = LibApp.class.getResourceAsStream("Libapp.txt");
+        if (input == null) {
+            return "FAILED TO FIND Libapp.txt";
+        }
+
+        BufferedReader reader = null;
+        try {
+            reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
+
+            return reader.readLine();
+        } catch (IOException e) {
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        
+        return "FAILED TO READ CONTENT";
+    }
+}
diff --git a/tests/libsTest/libapp/src/main/java/com/android/tests/libstest/app/MainActivityLibApp.java b/tests/libsTest/libapp/src/main/java/com/android/tests/libstest/app/MainActivityLibApp.java
new file mode 100644 (file)
index 0000000..65460f7
--- /dev/null
@@ -0,0 +1,15 @@
+package com.android.tests.libstest.app;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class MainActivityLibApp extends Activity {
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.libapp_main);
+        
+        LibApp.handleTextView(this);
+    }
+}
diff --git a/tests/libsTest/libapp/src/main/res/drawable-hdpi/ic_launcher.png b/tests/libsTest/libapp/src/main/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..8074c4c
Binary files /dev/null and b/tests/libsTest/libapp/src/main/res/drawable-hdpi/ic_launcher.png differ
diff --git a/tests/libsTest/libapp/src/main/res/drawable-ldpi/ic_launcher.png b/tests/libsTest/libapp/src/main/res/drawable-ldpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..1095584
Binary files /dev/null and b/tests/libsTest/libapp/src/main/res/drawable-ldpi/ic_launcher.png differ
diff --git a/tests/libsTest/libapp/src/main/res/drawable-mdpi/ic_launcher.png b/tests/libsTest/libapp/src/main/res/drawable-mdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..a07c69f
Binary files /dev/null and b/tests/libsTest/libapp/src/main/res/drawable-mdpi/ic_launcher.png differ
diff --git a/tests/libsTest/libapp/src/main/res/layout/libapp_main.xml b/tests/libsTest/libapp/src/main/res/layout/libapp_main.xml
new file mode 100644 (file)
index 0000000..6bf607b
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="vertical" >
+
+    <TextView
+        android:id="@+id/libapp_text1"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:text="@string/libapp_string" />
+
+    <TextView
+        android:id="@+id/libapp_text2"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/libsTest/libapp/src/main/res/values/strings.xml b/tests/libsTest/libapp/src/main/res/values/strings.xml
new file mode 100644 (file)
index 0000000..0a0a597
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="libapp_name">LibsTest-libapp</string>
+    <string name="libapp_string">SUCCESS-LIBAPP</string>
+
+</resources>
\ No newline at end of file
diff --git a/tests/libsTest/libapp/src/main/resources/com/android/tests/libstest/app/Libapp.txt b/tests/libsTest/libapp/src/main/resources/com/android/tests/libstest/app/Libapp.txt
new file mode 100644 (file)
index 0000000..9d626ac
--- /dev/null
@@ -0,0 +1 @@
+SUCCESS-LIBAPP
\ No newline at end of file
diff --git a/tests/libsTest/libapp/src/test/java/com/android/tests/libstest/libapp/MainActivityLibAppTest.java b/tests/libsTest/libapp/src/test/java/com/android/tests/libstest/libapp/MainActivityLibAppTest.java
new file mode 100644 (file)
index 0000000..e6087a7
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tests.libstest.app;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.TextView;
+
+import com.android.tests.libstest.app.R;
+
+/**
+ * An example of an {@link ActivityInstrumentationTestCase2} of a specific activity {@link Focus2}.
+ * By virtue of extending {@link ActivityInstrumentationTestCase2}, the target activity is automatically
+ * launched and finished before and after each test.  This also extends
+ * {@link android.test.InstrumentationTestCase}, which provides
+ * access to methods for sending events to the target activity, such as key and
+ * touch events.  See {@link #sendKeys}.
+ *
+ * In general, {@link android.test.InstrumentationTestCase}s and {@link ActivityInstrumentationTestCase2}s
+ * are heavier weight functional tests available for end to end testing of your
+ * user interface.  When run via a {@link android.test.InstrumentationTestRunner},
+ * the necessary {@link android.app.Instrumentation} will be injected for you to
+ * user via {@link #getInstrumentation} in your tests.
+ *
+ * See {@link com.example.android.apis.AllTests} for documentation on running
+ * all tests and individual tests in this application.
+ */
+public class MainActivityLibAppTest extends ActivityInstrumentationTestCase2<MainActivityLibApp> {
+
+    private TextView mTextView1;
+    private TextView mTextView2;
+
+    /**
+     * Creates an {@link ActivityInstrumentationTestCase2} that tests the {@link Focus2} activity.
+     */
+    public MainActivityLibAppTest() {
+        super(MainActivityLibApp.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        final MainActivityLibApp a = getActivity();
+        // ensure a valid handle to the activity has been returned
+        assertNotNull(a);
+        
+        mTextView1 = (TextView) a.findViewById(R.id.libapp_text1);
+        mTextView2 = (TextView) a.findViewById(R.id.libapp_text2);
+    }
+
+    /**
+     * The name 'test preconditions' is a convention to signal that if this
+     * test doesn't pass, the test case was not set up properly and it might
+     * explain any and all failures in other tests.  This is not guaranteed
+     * to run before other tests, as junit uses reflection to find the tests.
+     */
+    @MediumTest
+    public void testPreconditions() {
+        assertNotNull(mTextView1);
+        assertNotNull(mTextView2);
+    }
+
+    @MediumTest
+    public void testAndroidStrings() {
+        assertEquals("SUCCESS-LIBAPP", mTextView1.getText());
+    }
+
+    @MediumTest
+    public void testJavaStrings() {
+        assertEquals("SUCCESS-LIBAPP", mTextView2.getText());
+    }
+}
index 1a602d2..c8ed4b4 100644 (file)
@@ -1,3 +1,5 @@
 include 'app'
 include 'lib1'
-include 'lib2'
\ No newline at end of file
+include 'lib2'
+include 'lib2b'
+include 'libapp'