Merge "Fix package renaming."
diff --git a/builder/src/main/java/com/android/builder/AndroidBuilder.java b/builder/src/main/java/com/android/builder/AndroidBuilder.java
index 23b6879..a3574f0 100644
--- a/builder/src/main/java/com/android/builder/AndroidBuilder.java
+++ b/builder/src/main/java/com/android/builder/AndroidBuilder.java
@@ -59,6 +59,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
@@ -78,7 +79,7 @@
  *
  * then build steps can be done with
  * {@link #generateBuildConfig(String, boolean, java.util.List, String)}
- * {@link #processManifest(java.io.File, java.util.List, java.util.List, int, String, int, int, String)}
+ * {@link #processManifest(java.io.File, java.util.List, java.util.List, String, int, String, int, int, String)}
  * {@link #processTestManifest(String, int, String, String, java.util.List, String)}
  * {@link #processResources(java.io.File, java.io.File, java.io.File, java.util.List, String, String, String, String, String, com.android.builder.VariantConfiguration.Type, boolean, AaptOptions)}
  * {@link #compileAllAidlFiles(java.util.List, java.io.File, java.util.List, com.android.builder.compiling.DependencyFileProcessor)}
@@ -237,6 +238,7 @@
      * @param mainManifest The main manifest of the application.
      * @param manifestOverlays manifest overlays coming from flavors and build types
      * @param libraries the library dependency graph
+     * @param packageOverride a package name override. Can be null.
      * @param versionCode a version code to inject in the manifest or -1 to do nothing.
      * @param versionName a version name to inject in the manifest or null to do nothing.
      * @param minSdkVersion a minSdkVersion to inject in the manifest or -1 to do nothing.
@@ -256,6 +258,7 @@
             @NonNull File mainManifest,
             @NonNull List<File> manifestOverlays,
             @NonNull List<? extends ManifestDependency> libraries,
+                     String packageOverride,
                      int versionCode,
                      String versionName,
                      int minSdkVersion,
@@ -274,17 +277,12 @@
             if (manifestOverlays.isEmpty() && libraries.isEmpty()) {
                 // if no manifest to merge, just copy to location, unless we have to inject
                 // attributes
-                if (attributeInjection.isEmpty()) {
+                if (attributeInjection.isEmpty() && packageOverride == null) {
                     Files.copy(mainManifest, new File(outManifestLocation));
                 } else {
                     ManifestMerger merger = new ManifestMerger(MergerLog.wrapSdkLog(mLogger), null);
-                    if (!merger.process(
-                            new File(outManifestLocation),
-                            mainManifest,
-                            new File[0],
-                            attributeInjection)) {
-                        throw new RuntimeException();
-                    }
+                    doMerge(merger, new File(outManifestLocation), mainManifest,
+                            attributeInjection, packageOverride);
                 }
             } else {
                 File outManifest = new File(outManifestLocation);
@@ -301,13 +299,8 @@
                     }
 
                     ManifestMerger merger = new ManifestMerger(MergerLog.wrapSdkLog(mLogger), null);
-                    if (!merger.process(
-                            mainManifestOut,
-                            mainManifest,
-                            manifestOverlays.toArray(new File[manifestOverlays.size()]),
-                            attributeInjection)) {
-                        throw new RuntimeException();
-                    }
+                    doMerge(merger, mainManifestOut, mainManifest, manifestOverlays,
+                            attributeInjection, packageOverride);
 
                     // now the main manifest is the newly merged one
                     mainManifest = mainManifestOut;
@@ -319,12 +312,13 @@
                     // recursively merge all manifests starting with the leaves and up toward the
                     // root (the app)
                     mergeLibraryManifests(mainManifest, libraries,
-                            new File(outManifestLocation), attributeInjection);
+                            new File(outManifestLocation), attributeInjection, packageOverride);
                 }
             }
         } catch (IOException e) {
             throw new RuntimeException(e);
-        }    }
+        }
+    }
 
     /**
      * Creates the manifest for a test variant
@@ -373,7 +367,7 @@
                         generatedTestManifest,
                         libraries,
                         new File(outManifestLocation),
-                        null);
+                        null, null);
             } catch (IOException e) {
                 throw new RuntimeException(e);
             }
@@ -406,11 +400,12 @@
         }
     }
 
+    @NonNull
     private Map<String, String> getAttributeInjectionMap(
-            int versionCode,
-            String versionName,
-            int minSdkVersion,
-            int targetSdkVersion) {
+                      int versionCode,
+            @Nullable String versionName,
+                      int minSdkVersion,
+                      int targetSdkVersion) {
 
         Map<String, String> attributeInjection = Maps.newHashMap();
 
@@ -450,12 +445,13 @@
     private void mergeLibraryManifests(
             File mainManifest,
             Iterable<? extends ManifestDependency> directLibraries,
-            File outManifest, Map<String, String> attributeInjection) throws IOException {
+            File outManifest, Map<String, String> attributeInjection, String packageOverride)
+            throws IOException {
 
         List<File> manifests = Lists.newArrayList();
         for (ManifestDependency library : directLibraries) {
             List<? extends ManifestDependency> subLibraries = library.getManifestDependencies();
-            if (subLibraries == null || subLibraries.size() == 0) {
+            if (subLibraries.isEmpty()) {
                 manifests.add(library.getManifest());
             } else {
                 File mergeLibManifest = File.createTempFile("manifestMerge", ".xml");
@@ -463,17 +459,27 @@
 
                 // don't insert the attribute injection into libraries
                 mergeLibraryManifests(
-                        library.getManifest(), subLibraries, mergeLibManifest, null);
+                        library.getManifest(), subLibraries, mergeLibManifest, null, null);
 
                 manifests.add(mergeLibManifest);
             }
         }
 
         ManifestMerger merger = new ManifestMerger(MergerLog.wrapSdkLog(mLogger), null);
-        if (!merger.process(
-                outManifest,
-                mainManifest,
-                manifests.toArray(new File[manifests.size()]), attributeInjection)) {
+        doMerge(merger, outManifest, mainManifest, manifests, attributeInjection, packageOverride);
+    }
+
+    private void doMerge(ManifestMerger merger, File output, File input,
+                               Map<String, String> injectionMap, String packageOverride) {
+        List<File> list = Collections.emptyList();
+        doMerge(merger, output, input, list, injectionMap, packageOverride);
+    }
+
+    private void doMerge(ManifestMerger merger, File output, File input, List<File> subManifests,
+                               Map<String, String> injectionMap, String packageOverride) {
+        if (!merger.process(output, input,
+                subManifests.toArray(new File[subManifests.size()]),
+                injectionMap, packageOverride)) {
             throw new RuntimeException();
         }
     }
@@ -485,6 +491,7 @@
      * @param resFolder the merged res folder
      * @param assetsDir the merged asset folder
      * @param libraries the flat list of libraries
+     * @param packageForR Package override to generate the R class in a different package.
      * @param sourceOutputDir optional source folder to generate R.java
      * @param resPackageOutput optional filepath for packaged resources
      * @param proguardOutput optional filepath for proguard file to generate
@@ -501,7 +508,7 @@
             @NonNull  File resFolder,
             @Nullable File assetsDir,
             @NonNull  List<? extends SymbolFileProvider> libraries,
-            @Nullable String packageOverride,
+            @Nullable String packageForR,
             @Nullable String sourceOutputDir,
             @Nullable String symbolOutputDir,
             @Nullable String resPackageOutput,
@@ -581,10 +588,10 @@
         }
 
         if (type == VariantConfiguration.Type.DEFAULT) {
-            if (packageOverride != null) {
-                command.add("--rename-manifest-package");
-                command.add(packageOverride);
-                mLogger.verbose("Inserting package '%s' in AndroidManifest.xml", packageOverride);
+            if (packageForR != null) {
+                command.add("--custom-package");
+                command.add(packageForR);
+                mLogger.verbose("Custom package for R class: '%s'", packageForR);
             }
         }
 
@@ -624,7 +631,7 @@
             // 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;
+            String appPackageName = packageForR;
             if (appPackageName == null) {
                 appPackageName = VariantConfiguration.getManifestPackage(manifestFile);
             }
diff --git a/builder/src/main/java/com/android/builder/VariantConfiguration.java b/builder/src/main/java/com/android/builder/VariantConfiguration.java
index 59e5c74..ac88e7c 100644
--- a/builder/src/main/java/com/android/builder/VariantConfiguration.java
+++ b/builder/src/main/java/com/android/builder/VariantConfiguration.java
@@ -351,7 +351,7 @@
 
     /**
      * Returns the package name for this variant. This could be coming from the manifest or
-     * could be overridden through the product flavors.
+     * could be overridden through the product flavors and/or the build Type.
      * @return the package
      */
     @Nullable
@@ -389,8 +389,8 @@
     }
 
     /**
-     * Returns the package override values coming from the Product Flavor. If the package is not
-     * overridden then this returns null.
+     * Returns the package override values coming from the Product Flavor and/or the Build Type.
+     * If the package is not overridden then this returns null.
      * @return the package override or null
      */
     @Nullable
diff --git a/changelog.txt b/changelog.txt
index 8358ccb..91db840 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -3,6 +3,7 @@
 * Fixes:
    - Fix support for subfolders in assets/
    - Fix cases where Android Libraries have local Jars dependencies
+   - Fix renaming of package through DSL to ensure resources are compiled in the new namespace
 
 0.3
 
diff --git a/gradle/src/build-test/groovy/com/android/build/gradle/AutomatedBuildTest.java b/gradle/src/build-test/groovy/com/android/build/gradle/AutomatedBuildTest.java
index 2cf2814..d284c85 100644
--- a/gradle/src/build-test/groovy/com/android/build/gradle/AutomatedBuildTest.java
+++ b/gradle/src/build-test/groovy/com/android/build/gradle/AutomatedBuildTest.java
@@ -36,8 +36,8 @@
     private static final String[] sBuiltProjects = new String[] {
             "aidl", "api", "applibtest", "assets", "basic", "dependencies", "flavored",
             "flavorlib", "flavors", "libsTest", "localJars", "migrated", "multiproject", "multires",
-            "overlay1", "overlay2", "renderscript", "renderscriptInLib", "renderscriptMultiSrc",
-            "tictactoe"
+            "overlay1", "overlay2", "pkgOverride", "renderscript", "renderscriptInLib",
+            "renderscriptMultiSrc", "tictactoe"
     };
 
     private static final String[] sReportProjects = new String[] {
diff --git a/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java b/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java
index bb78d2e..52a000f 100644
--- a/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java
+++ b/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java
@@ -39,7 +39,7 @@
 
     private static final String[] sBuiltProjects = new String[] {
         "api", "assets", "applibtest", "basic", "flavored", "flavorlib",
-        "flavors", "libsTest", "migrated", "multires", "overlay1", "overlay2",
+        "flavors", "libsTest", "migrated", "multires", "overlay1", "overlay2", "pkgOverride",
     };
 
     public static Test suite() {
diff --git a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
index 2d7fddc..d6defef 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
@@ -311,6 +311,9 @@
         processManifestTask.conventionMapping.manifestOverlays = {
             config.manifestOverlays
         }
+        processManifestTask.conventionMapping.packageName = {
+            config.packageOverride
+        }
         processManifestTask.conventionMapping.versionName = {
             config.versionName
         }
@@ -494,11 +497,8 @@
         processResources.conventionMapping.libraries = {
             getTextSymbolDependencies(config.allLibraries)
         }
-        processResources.conventionMapping.packageOverride = {
-            if (config.testedConfig != null) {
-                return config.testedConfig.packageOverride
-            }
-            config.packageOverride
+        processResources.conventionMapping.packageForR = {
+            config.originalPackageName
         }
 
         // TODO: unify with generateBuilderConfig, compileAidl, and library packaging somehow?
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/TestFlavorTask.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/TestFlavorTask.groovy
index 7c15af6..2c7e14d 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/TestFlavorTask.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/TestFlavorTask.groovy
@@ -109,7 +109,6 @@
                 mLogger.info("Device '%s': installing %s", mDeviceName, mTestApk.absolutePath)
                 mDevice.installPackage(mTestApk.absolutePath, true /*reinstall*/)
 
-
                 RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
                         mVariant.config.packageName, mVariant.config.instrumentationRunner,
                         mDevice)
diff --git a/gradle/src/main/groovy/com/android/build/gradle/tasks/ProcessAndroidResources.groovy b/gradle/src/main/groovy/com/android/build/gradle/tasks/ProcessAndroidResources.groovy
index d5b5498..1484e0d 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/tasks/ProcessAndroidResources.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/tasks/ProcessAndroidResources.groovy
@@ -57,7 +57,7 @@
     List<SymbolFileProviderImpl> libraries
 
     @Input @Optional
-    String packageOverride
+    String packageForR
 
     // this doesn't change from one build to another, so no need to annotate
     VariantConfiguration.Type type
@@ -75,7 +75,7 @@
                 getResDir(),
                 getAssetsDir(),
                 getLibraries(),
-                getPackageOverride(),
+                getPackageForR(),
                 getSourceOutputDir()?.absolutePath,
                 getTextSymbolOutputDir()?.absolutePath,
                 getPackageOutputFile()?.absolutePath,
diff --git a/gradle/src/main/groovy/com/android/build/gradle/tasks/ProcessAppManifest.groovy b/gradle/src/main/groovy/com/android/build/gradle/tasks/ProcessAppManifest.groovy
index 76bb31a..d0cf411 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/tasks/ProcessAppManifest.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/tasks/ProcessAppManifest.groovy
@@ -36,6 +36,9 @@
     @Nested
     List<ManifestDependencyImpl> libraries
 
+    @Input @Optional
+    String packageName
+
     @Input
     int versionCode
 
@@ -54,6 +57,7 @@
                 getMainManifest(),
                 getManifestOverlays(),
                 getLibraries(),
+                getPackageName(),
                 getVersionCode(),
                 getVersionName(),
                 getMinSdkVersion(),
diff --git a/tests/pkgOverride/build.gradle b/tests/pkgOverride/build.gradle
new file mode 100644
index 0000000..b057996
--- /dev/null
+++ b/tests/pkgOverride/build.gradle
@@ -0,0 +1,17 @@
+buildscript {
+    repositories {
+        maven { url '../../repo' }
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
+    }
+}
+apply plugin: 'android'
+
+android {
+    compileSdkVersion 15
+
+    defaultConfig {
+        packageName "com.android.tests.basic.foo"
+    }
+}
\ No newline at end of file
diff --git a/tests/pkgOverride/src/instrumentTest/java/com/android/tests/basic/MainTest.java b/tests/pkgOverride/src/instrumentTest/java/com/android/tests/basic/MainTest.java
new file mode 100644
index 0000000..40e4749
--- /dev/null
+++ b/tests/pkgOverride/src/instrumentTest/java/com/android/tests/basic/MainTest.java
@@ -0,0 +1,44 @@
+package com.android.tests.basic;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.TextView;
+
+public class MainTest extends ActivityInstrumentationTestCase2<Main> {
+
+    private TextView mTextView;
+    private int mId;
+
+    /**
+     * Creates an {@link ActivityInstrumentationTestCase2} that tests the {@link Main} activity.
+     */
+    public MainTest() {
+        super(Main.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        final Main a = getActivity();
+        // ensure a valid handle to the activity has been returned
+        assertNotNull(a);
+        mTextView = (TextView) a.findViewById(R.id.text);
+        mId = a.mId;
+    }
+
+    /**
+     * 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(mTextView);
+    }
+    
+    public void testResourceQuery() {
+        assertTrue(mId != 0);
+    }
+}
+
diff --git a/tests/pkgOverride/src/main/AndroidManifest.xml b/tests/pkgOverride/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a34d937
--- /dev/null
+++ b/tests/pkgOverride/src/main/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.android.tests.basic">
+    <application android:label="@string/app_name" android:icon="@drawable/icon">
+        <activity android:name=".Main"
+                  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>
diff --git a/tests/pkgOverride/src/main/java/com/android/tests/basic/Main.java b/tests/pkgOverride/src/main/java/com/android/tests/basic/Main.java
new file mode 100644
index 0000000..0eae98e
--- /dev/null
+++ b/tests/pkgOverride/src/main/java/com/android/tests/basic/Main.java
@@ -0,0 +1,19 @@
+package com.android.tests.basic;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class Main extends Activity
+{
+    int mId;
+    
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+
+        mId = getResources().getIdentifier("icon", "drawable", getPackageName());
+    }
+}
diff --git a/tests/pkgOverride/src/main/res/drawable/icon.png b/tests/pkgOverride/src/main/res/drawable/icon.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/tests/pkgOverride/src/main/res/drawable/icon.png
Binary files differ
diff --git a/tests/pkgOverride/src/main/res/layout/main.xml b/tests/pkgOverride/src/main/res/layout/main.xml
new file mode 100644
index 0000000..b199751
--- /dev/null
+++ b/tests/pkgOverride/src/main/res/layout/main.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    >
+<TextView
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:text="Test App - Basic"
+    android:id="@+id/text"
+    />
+</LinearLayout>
+
diff --git a/tests/pkgOverride/src/main/res/values/strings.xml b/tests/pkgOverride/src/main/res/values/strings.xml
new file mode 100644
index 0000000..60ea2d0
--- /dev/null
+++ b/tests/pkgOverride/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">_Test-Basic</string>
+</resources>