Merge "GpsLocationProvider: Be less aggressive about getting fixes in bad conditions if we have a long fix interval."
diff --git a/api/current.xml b/api/current.xml
index 67c5dc2..43e8aa8 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -113183,6 +113183,28 @@
  visibility="public"
 >
 </method>
+<method name="getGlobalClassInitCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGlobalClassInitTime"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getGlobalExternalAllocCount"
  return="int"
  abstract="false"
@@ -113429,6 +113451,28 @@
  visibility="public"
 >
 </method>
+<method name="resetGlobalClassInitCount"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="resetGlobalClassInitTime"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="resetGlobalExternalAllocCount"
  return="void"
  abstract="false"
@@ -215825,7 +215869,7 @@
  synchronized="false"
  static="true"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </method>
@@ -215908,7 +215952,7 @@
  value="&quot;/sdcard/dmtrace.trace&quot;"
  static="true"
  final="true"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </field>
@@ -215945,6 +215989,28 @@
  visibility="public"
 >
 </field>
+<field name="KIND_GLOBAL_CLASS_INIT_COUNT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="32"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="KIND_GLOBAL_CLASS_INIT_TIME"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="64"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="KIND_GLOBAL_EXT_ALLOCATED_BYTES"
  type="int"
  transient="false"
@@ -216044,6 +216110,28 @@
  visibility="public"
 >
 </field>
+<field name="KIND_THREAD_CLASS_INIT_COUNT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2097152"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="KIND_THREAD_CLASS_INIT_TIME"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4194304"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="KIND_THREAD_EXT_ALLOCATED_BYTES"
  type="int"
  transient="false"
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index d640de1..b6c9de4 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -88,6 +88,8 @@
 
         if (op.equals("start")) {
             runStart();
+        } else if (op.equals("startservice")) {
+            runStartService();
         } else if (op.equals("instrument")) {
             runInstrument();
         } else if (op.equals("broadcast")) {
@@ -183,6 +185,15 @@
         return intent;
     }
 
+    private void runStartService() throws Exception {
+        Intent intent = makeIntent();
+        System.out.println("Starting service: " + intent);
+        ComponentName cn = mAm.startService(null, intent, intent.getType());
+        if (cn == null) {
+            System.err.println("Error: Not found; no service started.");
+        }
+    }
+
     private void runStart() throws Exception {
         Intent intent = makeIntent();
         System.out.println("Starting: " + intent);
@@ -496,6 +507,8 @@
                 "    start an Activity: am start [-D] <INTENT>\n" +
                 "        -D: enable debugging\n" +
                 "\n" +
+                "    start a Service: am startservice <INTENT>\n" +
+                "\n" +
                 "    send a broadcast Intent: am broadcast <INTENT>\n" +
                 "\n" +
                 "    start an Instrumentation: am instrument [flags] <COMPONENT>\n" +
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 92ae310..66f3676 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -68,7 +68,7 @@
 /* other handy constants */
 
 #define PROTECTED_DIR_PREFIX  "/data/app-private/"
-#define SDCARD_DIR_PREFIX  "/asec/"
+#define SDCARD_DIR_PREFIX  "/mnt/asec/"
 
 #define DALVIK_CACHE_PREFIX   "/data/dalvik-cache/"
 #define DALVIK_CACHE_POSTFIX  "/classes.dex"
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 68d8bb0..52f767e 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -17,6 +17,8 @@
 
 LOCAL_CFLAGS += -Wno-multichar
 
+LOCAL_MODULE_TAGS := debug
+
 LOCAL_MODULE:= stagefright
 
 include $(BUILD_EXECUTABLE)
@@ -39,6 +41,8 @@
 
 LOCAL_CFLAGS += -Wno-multichar
 
+LOCAL_MODULE_TAGS := debug
+
 LOCAL_MODULE:= record
 
 include $(BUILD_EXECUTABLE)
@@ -61,6 +65,8 @@
 
 LOCAL_CFLAGS += -Wno-multichar
 
+LOCAL_MODULE_TAGS := debug
+
 LOCAL_MODULE:= audioloop
 
 include $(BUILD_EXECUTABLE)
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index cf9c58f..e77e76f 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -664,6 +664,10 @@
      * determine which channel to connect to.
      * <p>The remote device will be authenticated and communication on this
      * socket will be encrypted.
+     * <p>Hint: If you are connecting to a Bluetooth serial board then try
+     * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB.
+     * However if you are connecting to an Android peer then please generate
+     * your own unique UUID.
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
      *
      * @param uuid service record uuid to lookup RFCOMM channel
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index f793a00..399a87d 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -309,7 +309,7 @@
      * MountService uses this to call into the package manager to update
      * status of sdcard.
      */
-    void updateExternalMediaStatus(boolean mounted);
+    boolean updateExternalMediaStatus(boolean mounted);
 
     String nextPackageToClean(String lastPackage);
 
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 9ee251e..a4c595d 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -541,6 +541,14 @@
     public static int getGlobalFreedSize() {
         return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
     }
+    public static int getGlobalClassInitCount() {
+        /* number of classes that have been successfully initialized */
+        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT);
+    }
+    public static int getGlobalClassInitTime() {
+        /* cumulative elapsed time for class initialization, in usec */
+        return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME);
+    }
     public static int getGlobalExternalAllocCount() {
         return VMDebug.getAllocCount(VMDebug.KIND_GLOBAL_EXT_ALLOCATED_OBJECTS);
     }
@@ -584,6 +592,12 @@
     public static void resetGlobalFreedSize() {
         VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_FREED_BYTES);
     }
+    public static void resetGlobalClassInitCount() {
+        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_COUNT);
+    }
+    public static void resetGlobalClassInitTime() {
+        VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_CLASS_INIT_TIME);
+    }
     public static void resetGlobalExternalAllocCount() {
         VMDebug.resetAllocCount(VMDebug.KIND_GLOBAL_EXT_ALLOCATED_OBJECTS);
     }
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 1023036..38ac9b7 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1936,6 +1936,11 @@
 
     public static final int DIR_LEFT_TO_RIGHT = 1;
     public static final int DIR_RIGHT_TO_LEFT = -1;
+    
+    /* package */ static final int DIR_REQUEST_LTR = 1;
+    /* package */ static final int DIR_REQUEST_RTL = -1;
+    /* package */ static final int DIR_REQUEST_DEFAULT_LTR = 2;
+    /* package */ static final int DIR_REQUEST_DEFAULT_RTL = -2;
 
     public enum Alignment {
         ALIGN_NORMAL,
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 6de9c65..600ec7e 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -234,215 +234,9 @@
             }
 
             if (!easy) {
-                AndroidCharacter.getDirectionalities(chs, chdirs, end - start);
-
-                /*
-                 * Determine primary paragraph direction
-                 */
-
-                for (int j = start; j < end; j++) {
-                    int d = chdirs[j - start];
-
-                    if (d == Character.DIRECTIONALITY_LEFT_TO_RIGHT) {
-                        dir = DIR_LEFT_TO_RIGHT;
-                        break;
-                    }
-                    if (d == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
-                        dir = DIR_RIGHT_TO_LEFT;
-                        break;
-                    }
-                }
-
-                /*
-                 * XXX Explicit overrides should go here
-                 */
-
-                /*
-                 * Weak type resolution
-                 */
-
-                final byte SOR = dir == DIR_LEFT_TO_RIGHT ?
-                                    Character.DIRECTIONALITY_LEFT_TO_RIGHT :
-                                    Character.DIRECTIONALITY_RIGHT_TO_LEFT;
-
-                // dump(chdirs, n, "initial");
-
-                // W1 non spacing marks
-                for (int j = 0; j < n; j++) {
-                    if (chdirs[j] == Character.NON_SPACING_MARK) {
-                        if (j == 0)
-                            chdirs[j] = SOR;
-                        else
-                            chdirs[j] = chdirs[j - 1];
-                    }
-                }
-
-                // dump(chdirs, n, "W1");
-
-                // W2 european numbers
-                byte cur = SOR;
-                for (int j = 0; j < n; j++) {
-                    byte d = chdirs[j];
-
-                    if (d == Character.DIRECTIONALITY_LEFT_TO_RIGHT ||
-                        d == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
-                        d == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC)
-                        cur = d;
-                    else if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER) {
-                         if (cur ==
-                            Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC)
-                            chdirs[j] = Character.DIRECTIONALITY_ARABIC_NUMBER;
-                    }
-                }
-
-                // dump(chdirs, n, "W2");
-
-                // W3 arabic letters
-                for (int j = 0; j < n; j++) {
-                    if (chdirs[j] == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC)
-                        chdirs[j] = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
-                }
-
-                // dump(chdirs, n, "W3");
-
-                // W4 single separator between numbers
-                for (int j = 1; j < n - 1; j++) {
-                    byte d = chdirs[j];
-                    byte prev = chdirs[j - 1];
-                    byte next = chdirs[j + 1];
-
-                    if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR) {
-                        if (prev == Character.DIRECTIONALITY_EUROPEAN_NUMBER &&
-                            next == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
-                            chdirs[j] = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
-                    } else if (d == Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR) {
-                        if (prev == Character.DIRECTIONALITY_EUROPEAN_NUMBER &&
-                            next == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
-                            chdirs[j] = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
-                        if (prev == Character.DIRECTIONALITY_ARABIC_NUMBER &&
-                            next == Character.DIRECTIONALITY_ARABIC_NUMBER)
-                            chdirs[j] = Character.DIRECTIONALITY_ARABIC_NUMBER;
-                    }
-                }
-
-                // dump(chdirs, n, "W4");
-
-                // W5 european number terminators
-                boolean adjacent = false;
-                for (int j = 0; j < n; j++) {
-                    byte d = chdirs[j];
-
-                    if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
-                        adjacent = true;
-                    else if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR && adjacent)
-                        chdirs[j] = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
-                    else
-                        adjacent = false;
-                }
-
-                //dump(chdirs, n, "W5");
-
-                // W5 european number terminators part 2,
-                // W6 separators and terminators
-                adjacent = false;
-                for (int j = n - 1; j >= 0; j--) {
-                    byte d = chdirs[j];
-
-                    if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
-                        adjacent = true;
-                    else if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR) {
-                        if (adjacent)
-                            chdirs[j] = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
-                        else
-                            chdirs[j] = Character.DIRECTIONALITY_OTHER_NEUTRALS;
-                    }
-                    else {
-                        adjacent = false;
-
-                        if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR ||
-                            d == Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR ||
-                            d == Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR ||
-                            d == Character.DIRECTIONALITY_SEGMENT_SEPARATOR)
-                            chdirs[j] = Character.DIRECTIONALITY_OTHER_NEUTRALS;
-                    }
-                }
-
-                // dump(chdirs, n, "W6");
-
-                // W7 strong direction of european numbers
-                cur = SOR;
-                for (int j = 0; j < n; j++) {
-                    byte d = chdirs[j];
-
-                    if (d == SOR ||
-                        d == Character.DIRECTIONALITY_LEFT_TO_RIGHT ||
-                        d == Character.DIRECTIONALITY_RIGHT_TO_LEFT)
-                        cur = d;
-
-                    if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
-                        chdirs[j] = cur;
-                }
-
-                // dump(chdirs, n, "W7");
-
-                // N1, N2 neutrals
-                cur = SOR;
-                for (int j = 0; j < n; j++) {
-                    byte d = chdirs[j];
-
-                    if (d == Character.DIRECTIONALITY_LEFT_TO_RIGHT ||
-                        d == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
-                        cur = d;
-                    } else if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER ||
-                               d == Character.DIRECTIONALITY_ARABIC_NUMBER) {
-                        cur = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
-                    } else {
-                        byte dd = SOR;
-                        int k;
-
-                        for (k = j + 1; k < n; k++) {
-                            dd = chdirs[k];
-
-                            if (dd == Character.DIRECTIONALITY_LEFT_TO_RIGHT ||
-                                dd == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
-                                break;
-                            }
-                            if (dd == Character.DIRECTIONALITY_EUROPEAN_NUMBER ||
-                                dd == Character.DIRECTIONALITY_ARABIC_NUMBER) {
-                                dd = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
-                                break;
-                            }
-                        }
-
-                        for (int y = j; y < k; y++) {
-                            if (dd == cur)
-                                chdirs[y] = cur;
-                            else
-                                chdirs[y] = SOR;
-                        }
-
-                        j = k - 1;
-                    }
-                }
-
-                // dump(chdirs, n, "final");
-
-                // extra: enforce that all tabs and surrogate characters go the
-                // primary direction
-                // TODO: actually do directions right for surrogates
-
-                for (int j = 0; j < n; j++) {
-                    char c = chs[j];
-
-                    if (c == '\t' || (c >= 0xD800 && c <= 0xDFFF)) {
-                        chdirs[j] = SOR;
-                    }
-                }
-
-                // extra: enforce that object replacements go to the
-                // primary direction
-                // and that none of the underlying characters are treated
-                // as viable breakpoints
+                // Ensure that none of the underlying characters are treated
+                // as viable breakpoints, and that the entire run gets the
+                // same bidi direction.
 
                 if (source instanceof Spanned) {
                     Spanned sp = (Spanned) source;
@@ -453,12 +247,14 @@
                         int b = sp.getSpanEnd(spans[y]);
 
                         for (int x = a; x < b; x++) {
-                            chdirs[x - start] = SOR;
                             chs[x - start] = '\uFFFC';
                         }
                     }
                 }
 
+                // XXX put override flags, etc. into chdirs
+                dir = bidi(dir, chs, chdirs, n, false);
+
                 // Do mirroring for right-to-left segments
 
                 for (int i = 0; i < n; i++) {
@@ -810,6 +606,239 @@
         }
     }
 
+    /**
+     * Runs the unicode bidi algorithm on the first n chars in chs, returning
+     * the char dirs in chInfo and the base line direction of the first
+     * paragraph.
+     * 
+     * XXX change result from dirs to levels
+     *  
+     * @param dir the direction flag, either DIR_REQUEST_LTR,
+     * DIR_REQUEST_RTL, DIR_REQUEST_DEFAULT_LTR, or DIR_REQUEST_DEFAULT_RTL.
+     * @param chs the text to examine
+     * @param chInfo on input, if hasInfo is true, override and other flags 
+     * representing out-of-band embedding information. On output, the generated 
+     * dirs of the text.
+     * @param n the length of the text/information in chs and chInfo
+     * @param hasInfo true if chInfo has input information, otherwise the
+     * input data in chInfo is ignored.
+     * @return the resolved direction level of the first paragraph, either
+     * DIR_LEFT_TO_RIGHT or DIR_RIGHT_TO_LEFT.
+     */
+    /* package */ static int bidi(int dir, char[] chs, byte[] chInfo, int n, 
+            boolean hasInfo) {
+        
+        AndroidCharacter.getDirectionalities(chs, chInfo, n);
+
+        /*
+         * Determine primary paragraph direction if not specified
+         */
+        if (dir != DIR_REQUEST_LTR && dir != DIR_REQUEST_RTL) {
+            // set up default
+            dir = dir >= 0 ? DIR_LEFT_TO_RIGHT : DIR_RIGHT_TO_LEFT;
+            for (int j = 0; j < n; j++) {
+                int d = chInfo[j];
+
+                if (d == Character.DIRECTIONALITY_LEFT_TO_RIGHT) {
+                    dir = DIR_LEFT_TO_RIGHT;
+                    break;
+                }
+                if (d == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
+                    dir = DIR_RIGHT_TO_LEFT;
+                    break;
+                }
+            }
+        }
+
+        final byte SOR = dir == DIR_LEFT_TO_RIGHT ?
+                Character.DIRECTIONALITY_LEFT_TO_RIGHT :
+                Character.DIRECTIONALITY_RIGHT_TO_LEFT;
+
+        /*
+         * XXX Explicit overrides should go here
+         */
+
+        /*
+         * Weak type resolution
+         */
+
+        // dump(chdirs, n, "initial");
+
+        // W1 non spacing marks
+        for (int j = 0; j < n; j++) {
+            if (chInfo[j] == Character.NON_SPACING_MARK) {
+                if (j == 0)
+                    chInfo[j] = SOR;
+                else
+                    chInfo[j] = chInfo[j - 1];
+            }
+        }
+
+        // dump(chdirs, n, "W1");
+
+        // W2 european numbers
+        byte cur = SOR;
+        for (int j = 0; j < n; j++) {
+            byte d = chInfo[j];
+
+            if (d == Character.DIRECTIONALITY_LEFT_TO_RIGHT ||
+                d == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
+                d == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC)
+                cur = d;
+            else if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER) {
+                 if (cur ==
+                    Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC)
+                    chInfo[j] = Character.DIRECTIONALITY_ARABIC_NUMBER;
+            }
+        }
+
+        // dump(chdirs, n, "W2");
+
+        // W3 arabic letters
+        for (int j = 0; j < n; j++) {
+            if (chInfo[j] == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC)
+                chInfo[j] = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
+        }
+
+        // dump(chdirs, n, "W3");
+
+        // W4 single separator between numbers
+        for (int j = 1; j < n - 1; j++) {
+            byte d = chInfo[j];
+            byte prev = chInfo[j - 1];
+            byte next = chInfo[j + 1];
+
+            if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR) {
+                if (prev == Character.DIRECTIONALITY_EUROPEAN_NUMBER &&
+                    next == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
+                    chInfo[j] = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
+            } else if (d == Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR) {
+                if (prev == Character.DIRECTIONALITY_EUROPEAN_NUMBER &&
+                    next == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
+                    chInfo[j] = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
+                if (prev == Character.DIRECTIONALITY_ARABIC_NUMBER &&
+                    next == Character.DIRECTIONALITY_ARABIC_NUMBER)
+                    chInfo[j] = Character.DIRECTIONALITY_ARABIC_NUMBER;
+            }
+        }
+
+        // dump(chdirs, n, "W4");
+
+        // W5 european number terminators
+        boolean adjacent = false;
+        for (int j = 0; j < n; j++) {
+            byte d = chInfo[j];
+
+            if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
+                adjacent = true;
+            else if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR && adjacent)
+                chInfo[j] = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
+            else
+                adjacent = false;
+        }
+
+        //dump(chdirs, n, "W5");
+
+        // W5 european number terminators part 2,
+        // W6 separators and terminators
+        adjacent = false;
+        for (int j = n - 1; j >= 0; j--) {
+            byte d = chInfo[j];
+
+            if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
+                adjacent = true;
+            else if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR) {
+                if (adjacent)
+                    chInfo[j] = Character.DIRECTIONALITY_EUROPEAN_NUMBER;
+                else
+                    chInfo[j] = Character.DIRECTIONALITY_OTHER_NEUTRALS;
+            }
+            else {
+                adjacent = false;
+
+                if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR ||
+                    d == Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR ||
+                    d == Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR ||
+                    d == Character.DIRECTIONALITY_SEGMENT_SEPARATOR)
+                    chInfo[j] = Character.DIRECTIONALITY_OTHER_NEUTRALS;
+            }
+        }
+
+        // dump(chdirs, n, "W6");
+
+        // W7 strong direction of european numbers
+        cur = SOR;
+        for (int j = 0; j < n; j++) {
+            byte d = chInfo[j];
+
+            if (d == SOR ||
+                d == Character.DIRECTIONALITY_LEFT_TO_RIGHT ||
+                d == Character.DIRECTIONALITY_RIGHT_TO_LEFT)
+                cur = d;
+
+            if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER)
+                chInfo[j] = cur;
+        }
+
+        // dump(chdirs, n, "W7");
+
+        // N1, N2 neutrals
+        cur = SOR;
+        for (int j = 0; j < n; j++) {
+            byte d = chInfo[j];
+
+            if (d == Character.DIRECTIONALITY_LEFT_TO_RIGHT ||
+                d == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
+                cur = d;
+            } else if (d == Character.DIRECTIONALITY_EUROPEAN_NUMBER ||
+                       d == Character.DIRECTIONALITY_ARABIC_NUMBER) {
+                cur = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
+            } else {
+                byte dd = SOR;
+                int k;
+
+                for (k = j + 1; k < n; k++) {
+                    dd = chInfo[k];
+
+                    if (dd == Character.DIRECTIONALITY_LEFT_TO_RIGHT ||
+                        dd == Character.DIRECTIONALITY_RIGHT_TO_LEFT) {
+                        break;
+                    }
+                    if (dd == Character.DIRECTIONALITY_EUROPEAN_NUMBER ||
+                        dd == Character.DIRECTIONALITY_ARABIC_NUMBER) {
+                        dd = Character.DIRECTIONALITY_RIGHT_TO_LEFT;
+                        break;
+                    }
+                }
+
+                for (int y = j; y < k; y++) {
+                    if (dd == cur)
+                        chInfo[y] = cur;
+                    else
+                        chInfo[y] = SOR;
+                }
+
+                j = k - 1;
+            }
+        }
+
+        // dump(chdirs, n, "final");
+
+        // extra: enforce that all tabs and surrogate characters go the
+        // primary direction
+        // TODO: actually do directions right for surrogates
+
+        for (int j = 0; j < n; j++) {
+            char c = chs[j];
+
+            if (c == '\t' || (c >= 0xD800 && c <= 0xDFFF)) {
+                chInfo[j] = SOR;
+            }
+        }
+        
+        return dir;
+    }
+
     private static final char FIRST_CJK = '\u2E80';
     /**
      * Returns true if the specified character is one of those specified
diff --git a/core/java/android/webkit/PluginManager.java b/core/java/android/webkit/PluginManager.java
index cdcb662..df7d0c4 100644
--- a/core/java/android/webkit/PluginManager.java
+++ b/core/java/android/webkit/PluginManager.java
@@ -165,6 +165,7 @@
                     continue;
                 }
 
+/*              temporarily disable signatures checking
                 // check to ensure the plugin is properly signed
                 Signature signatures[] = pkgInfo.signatures;
                 if (signatures == null) {
@@ -184,7 +185,7 @@
                         continue;
                     }
                 }
-
+*/
                 // determine the type of plugin from the manifest
                 if (serviceInfo.metaData == null) {
                     Log.e(LOGTAG, "The plugin '" + serviceInfo.name + "' has no type defined");
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index aa9062b..bf63607 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -24,6 +24,7 @@
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.Gravity;
+import android.view.ViewDebug;
 import android.view.accessibility.AccessibilityEvent;
 
 
@@ -73,7 +74,8 @@
     public void toggle() {
         setChecked(!mChecked);
     }
-    
+
+    @ViewDebug.ExportedProperty
     public boolean isChecked() {
         return mChecked;
     }
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 98b0976..bf02ad3 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -26,6 +26,7 @@
 import android.os.Parcelable;
 import android.util.AttributeSet;
 import android.view.Gravity;
+import android.view.ViewDebug;
 import android.view.accessibility.AccessibilityEvent;
 
 /**
@@ -98,6 +99,7 @@
         return super.performClick();
     }
 
+    @ViewDebug.ExportedProperty
     public boolean isChecked() {
         return mChecked;
     }
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 1dcb203..6dc9f78 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -36,6 +36,7 @@
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.View;
+import android.view.ViewDebug;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
@@ -335,6 +336,7 @@
      *
      * @return true if the progress bar is in indeterminate mode
      */
+    @ViewDebug.ExportedProperty
     public synchronized boolean isIndeterminate() {
         return mIndeterminate;
     }
@@ -607,6 +609,7 @@
      * @see #setMax(int)
      * @see #getMax()
      */
+    @ViewDebug.ExportedProperty
     public synchronized int getProgress() {
         return mIndeterminate ? 0 : mProgress;
     }
@@ -623,6 +626,7 @@
      * @see #setMax(int)
      * @see #getMax()
      */
+    @ViewDebug.ExportedProperty
     public synchronized int getSecondaryProgress() {
         return mIndeterminate ? 0 : mSecondaryProgress;
     }
@@ -636,6 +640,7 @@
      * @see #getProgress()
      * @see #getSecondaryProgress()
      */
+    @ViewDebug.ExportedProperty
     public synchronized int getMax() {
         return mMax;
     }
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 7ba0fa1..cea6d3b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5731,6 +5731,7 @@
     /**
      * Convenience for {@link Selection#getSelectionStart}.
      */
+    @ViewDebug.ExportedProperty
     public int getSelectionStart() {
         return Selection.getSelectionStart(getText());
     }
@@ -5738,6 +5739,7 @@
     /**
      * Convenience for {@link Selection#getSelectionEnd}.
      */
+    @ViewDebug.ExportedProperty
     public int getSelectionEnd() {
         return Selection.getSelectionEnd(getText());
     }
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index bc7dbf4..c5db83f 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -36,7 +36,7 @@
     public static final int RECOMMEND_INSTALL_EXTERNAL = 2;
     public static final int RECOMMEND_FAILED_INSUFFICIENT_STORAGE = -1;
     public static final int RECOMMEND_FAILED_INVALID_APK = -2;
-    private static final boolean DEBUG_SD_INSTALL = true;
+    private static final boolean localLOGV = true;
     private static final String TAG = "PackageHelper";
 
     public static IMountService getMountService() {
@@ -58,7 +58,7 @@
         if ((len - (mbLen * 1024 * 1024)) > 0) {
             mbLen++;
         }
-        if (DEBUG_SD_INSTALL) Log.i(TAG, "Size of resource " + mbLen);
+        if (localLOGV) Log.i(TAG, "Size of resource " + mbLen);
 
         try {
             int rc = mountService.createSecureContainer(
@@ -68,7 +68,7 @@
                 return null;
             }
             String cachePath = mountService.getSecureContainerPath(cid);
-            if (DEBUG_SD_INSTALL) Log.i(TAG, "Created secure container " + cid +
+            if (localLOGV) Log.i(TAG, "Created secure container " + cid +
                     " at " + cachePath);
                 return cachePath;
         } catch (RemoteException e) {
@@ -93,7 +93,7 @@
 
    public static boolean unMountSdDir(String cid) {
     try {
-        int rc = getMountService().unmountSecureContainer(cid, false);
+        int rc = getMountService().unmountSecureContainer(cid, true);
         if (rc != StorageResultCode.OperationSucceeded) {
             Log.e(TAG, "Failed to unmount " + cid + " with rc " + rc);
             return false;
@@ -148,7 +148,8 @@
 
     public static boolean destroySdDir(String cid) {
         try {
-            int rc = getMountService().destroySecureContainer(cid, false);
+            if (localLOGV) Log.i(TAG, "Forcibly destroying container " + cid);
+            int rc = getMountService().destroySecureContainer(cid, true);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.i(TAG, "Failed to destroy container " + cid);
                 return false;
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index a82a21e..5afa0342 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1466,19 +1466,25 @@
     for (size_t i=0; ((ssize_t)i)<N; i++, bag++) {
         value = bag->map.value;
         jstring str = NULL;
-        
+
         // Take care of resolving the found resource to its final value.
         ssize_t block = res.resolveReference(&value, bag->stringBlock, NULL);
         if (value.dataType == Res_value::TYPE_STRING) {
-            const char16_t* str16 = res.getTableStringBlock(block)->stringAt(value.data, &strLen);
-            str = env->NewString(str16, strLen);
-            if (str == NULL) {
-                doThrow(env, "java/lang/OutOfMemoryError");
-                res.unlockBag(startOfBag);
-                return NULL;
+            const ResStringPool* pool = res.getTableStringBlock(block);
+            const char* str8 = pool->string8At(value.data, &strLen);
+            if (str8 != NULL) {
+                str = env->NewStringUTF(str8);
+            } else {
+                const char16_t* str16 = pool->stringAt(value.data, &strLen);
+                str = env->NewString(str16, strLen);
+                if (str == NULL) {
+                    doThrow(env, "java/lang/OutOfMemoryError");
+                    res.unlockBag(startOfBag);
+                    return NULL;
+                }
             }
         }
-        
+
         env->SetObjectArrayElement(array, i, str);
     }
     res.unlockBag(startOfBag);
diff --git a/core/jni/android_util_StringBlock.cpp b/core/jni/android_util_StringBlock.cpp
index ffb271c..641fbce 100644
--- a/core/jni/android_util_StringBlock.cpp
+++ b/core/jni/android_util_StringBlock.cpp
@@ -89,6 +89,11 @@
     }
 
     size_t len;
+    const char* str8 = osb->string8At(idx, &len);
+    if (str8 != NULL) {
+        return env->NewStringUTF(str8);
+    }
+
     const char16_t* str = osb->stringAt(idx, &len);
     if (str == NULL) {
         doThrow(env, "java/lang/IndexOutOfBoundsException");
diff --git a/core/res/res/drawable-hdpi/btn_dropdown_disabled.9.png b/core/res/res/drawable-hdpi/btn_dropdown_disabled.9.png
new file mode 100644
index 0000000..c6503c7
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_dropdown_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_dropdown_disabled_focused.9.png b/core/res/res/drawable-hdpi/btn_dropdown_disabled_focused.9.png
new file mode 100644
index 0000000..152de8b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_dropdown_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_dropdown_disabled.9.png b/core/res/res/drawable-mdpi/btn_dropdown_disabled.9.png
new file mode 100644
index 0000000..f7464c7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_dropdown_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_dropdown_disabled_focused.9.png b/core/res/res/drawable-mdpi/btn_dropdown_disabled_focused.9.png
new file mode 100644
index 0000000..ffe219f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_dropdown_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_dropdown.xml b/core/res/res/drawable/btn_dropdown.xml
index 8ec8ece..34a0504 100644
--- a/core/res/res/drawable/btn_dropdown.xml
+++ b/core/res/res/drawable/btn_dropdown.xml
@@ -15,10 +15,24 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item  android:state_window_focused="false" android:drawable="@drawable/btn_dropdown_normal" />
-    <item android:state_pressed="true" android:drawable="@drawable/btn_dropdown_pressed" />
-    <item android:state_focused="true" android:state_pressed="false"
+    <item
+        android:state_window_focused="false" android:state_enabled="true"
+        android:drawable="@drawable/btn_dropdown_normal" />
+    <item
+        android:state_window_focused="false" android:state_enabled="false"
+        android:drawable="@drawable/btn_dropdown_disabled" />
+    <item
+        android:state_pressed="true"
+        android:drawable="@drawable/btn_dropdown_pressed" />
+    <item
+        android:state_focused="true" android:state_enabled="true"
         android:drawable="@drawable/btn_dropdown_selected" />
-    <item android:drawable="@drawable/btn_dropdown_normal" />
+    <item
+        android:state_enabled="true"
+        android:drawable="@drawable/btn_dropdown_normal" />
+    <item
+        android:state_focused="true"
+        android:drawable="@drawable/btn_dropdown_disabled_focused" />
+    <item
+        android:drawable="@drawable/btn_dropdown_disabled" />
 </selector>
-
diff --git a/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java b/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java
new file mode 100644
index 0000000..ccd0dae
--- /dev/null
+++ b/core/tests/coretests/src/android/text/StaticLayoutBidiTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+package android.text;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests StaticLayout bidi implementation.
+ */
+public class StaticLayoutBidiTest extends TestCase {
+    
+    public static final int REQ_DL = 2; // Layout.DIR_REQUEST_DEFAULT_LTR;
+    public static final int REQ_DR = -2; // Layout.DIR_REQUEST_DEFAULT_RTL;
+    public static final int REQ_L = 1; // Layout.DIR_REQUEST_LTR;
+    public static final int REQ_R = -1; // Layout.DIR_REQUEST_RTL;
+    public static final int L = Layout.DIR_LEFT_TO_RIGHT;
+    public static final int R = Layout.DIR_RIGHT_TO_LEFT;
+    
+    public static final String SP = " ";
+    public static final String ALEF = "\u05d0";
+    public static final String BET = "\u05d1";
+    public static final String GIMEL = "\u05d2";
+    public static final String DALET = "\u05d3";
+    
+    @SmallTest
+    public void testAllLtr() {
+        expectBidi(REQ_DL, "a test", "000000", L);
+    }
+    
+    @SmallTest
+    public void testLtrRtl() {
+        expectBidi(REQ_DL, "abc " + ALEF + BET + GIMEL, "0000111", L);
+    }
+    
+    @SmallTest
+    public void testAllRtl() {
+        expectBidi(REQ_DL, ALEF + SP + ALEF + BET + GIMEL + DALET, "111111", R);
+    }
+    
+    @SmallTest
+    public void testRtlLtr() {
+        expectBidi(REQ_DL,  ALEF + BET + GIMEL + " abc", "1111000", R);
+    }
+    
+    @SmallTest
+    public void testRAllLtr() {
+        expectBidi(REQ_R, "a test", "000000", R);
+    }
+    
+    @SmallTest
+    public void testRLtrRtl() {
+        expectBidi(REQ_R, "abc " + ALEF + BET + GIMEL, "0001111", R);
+    }
+    
+    @SmallTest
+    public void testLAllRtl() {
+        expectBidi(REQ_L, ALEF + SP + ALEF + BET + GIMEL + DALET, "111111", L);
+    }
+    
+    @SmallTest
+    public void testLRtlLtr() {
+        expectBidi(REQ_L,  ALEF + BET + GIMEL + " abc", "1110000", L);
+    }
+    
+    private void expectBidi(int dir, String text, 
+            String expectedLevels, int expectedDir) {
+        char[] chs = text.toCharArray();
+        int n = chs.length;
+        byte[] chInfo = new byte[n];
+        
+        int resultDir = StaticLayout.bidi(dir, chs, chInfo, n, false);
+        
+        {
+            StringBuilder sb = new StringBuilder("xdirs:");
+            for (int i = 0; i < n; ++i) {
+                sb.append(" ").append(String.valueOf(chInfo[i]));
+            }
+            Log.i("BIDI", sb.toString());
+        }
+        
+        char[] resultLevelChars = new char[n];
+        for (int i = 0; i < n; ++i) {
+            resultLevelChars[i] = (char)('0' + chInfo[i]);
+        }
+        String resultLevels = new String(resultLevelChars);
+        assertEquals("direction", expectedDir, resultDir);
+        assertEquals("levels", expectedLevels, resultLevels);
+    }
+}
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 13ea27e..cd657e8 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -447,6 +447,8 @@
     }
     const char16_t* stringAt(size_t idx, size_t* outLen) const;
 
+    const char* string8At(size_t idx, size_t* outLen) const;
+
     const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const;
     const ResStringPool_span* styleAt(size_t idx) const;
 
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index e8bd5cf..38600b9 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -497,6 +497,34 @@
     return NULL;
 }
 
+const char* ResStringPool::string8At(size_t idx, size_t* outLen) const
+{
+    if (mError == NO_ERROR && idx < mHeader->stringCount) {
+        const bool isUTF8 = (mHeader->flags&ResStringPool_header::UTF8_FLAG) != 0;
+        const uint32_t off = mEntries[idx]/(isUTF8?sizeof(char):sizeof(char16_t));
+        if (off < (mStringPoolSize-1)) {
+            if (isUTF8) {
+                const uint8_t* strings = (uint8_t*)mStrings;
+                const uint8_t* str = strings+off;
+                DECODE_LENGTH(str, sizeof(uint8_t), *outLen)
+                size_t encLen;
+                DECODE_LENGTH(str, sizeof(uint8_t), encLen)
+                if ((uint32_t)(str+encLen-strings) < mStringPoolSize) {
+                    return (const char*)str;
+                } else {
+                    LOGW("Bad string block: string #%d extends to %d, past end at %d\n",
+                            (int)idx, (int)(str+encLen-strings), (int)mStringPoolSize);
+                }
+            }
+        } else {
+            LOGW("Bad string block: string #%d entry is at %d, past end at %d\n",
+                    (int)idx, (int)(off*sizeof(uint16_t)),
+                    (int)(mStringPoolSize*sizeof(uint16_t)));
+        }
+    }
+    return NULL;
+}
+
 const ResStringPool_span* ResStringPool::styleAt(const ResStringPool_ref& ref) const
 {
     return styleAt(ref.index);
@@ -4018,14 +4046,19 @@
         printf("(attribute) 0x%08x\n", value.data);
     } else if (value.dataType == Res_value::TYPE_STRING) {
         size_t len;
-        const char16_t* str = pkg->header->values.stringAt(
+        const char* str8 = pkg->header->values.string8At(
                 value.data, &len);
-        if (str == NULL) {
-            printf("(string) null\n");
+        if (str8 != NULL) {
+            printf("(string8) \"%s\"\n", str8);
         } else {
-            printf("(string%d) \"%s\"\n",
-                    pkg->header->values.isUTF8()?8:16,
-                    String8(str, len).string());
+            const char16_t* str16 = pkg->header->values.stringAt(
+                    value.data, &len);
+            if (str16 != NULL) {
+                printf("(string16) \"%s\"\n",
+                    String8(str16, len).string());
+            } else {
+                printf("(string) null\n");
+            }
         } 
     } else if (value.dataType == Res_value::TYPE_FLOAT) {
         printf("(float) %g\n", *(const float*)&value.data);
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 95ab684..a79f0cd 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -39,7 +39,7 @@
  */
 public class DefaultContainerService extends IntentService {
     private static final String TAG = "DefContainer";
-    private static final boolean localLOGV = false;
+    private static final boolean localLOGV = true;
 
     private IMediaContainerService.Stub mBinder = new IMediaContainerService.Stub() {
         /*
@@ -211,6 +211,8 @@
                 if (PackageHelper.isContainerMounted(newCid)) {
                     if (localLOGV) Log.i(TAG, "Unmounting " + newCid +
                             " at path " + newCachePath + " after " + errMsg);
+                    // Force a gc to avoid being killed.
+                    Runtime.getRuntime().gc();
                     PackageHelper.unMountSdDir(newCid);
                 } else {
                     if (localLOGV) Log.i(TAG, "Container " + newCid + " not mounted");
@@ -328,8 +330,8 @@
         boolean auto = true;
         // To make final copy
         long reqInstallSize = pkgLen;
-        // For dex files
-        long reqInternalSize = 1 * pkgLen;
+        // For dex files. Just ignore and fail when extracting. Max limit of 2Gig for now.
+        long reqInternalSize = 0;
         boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
         boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalFlashSize);
         boolean fitsOnSd = (reqInstallSize < availSDSize) && intThresholdOk &&
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 39ee314..2dc12f6 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -1003,7 +1003,11 @@
         warnOnNotMounted();
 
         synchronized (mAsecMountSet) {
-            if (mAsecMountSet.contains(oldId)) {
+            /*
+             * Because a mounted container has active internal state which cannot be 
+             * changed while active, we must ensure both ids are not currently mounted.
+             */
+            if (mAsecMountSet.contains(oldId) || mAsecMountSet.contains(newId)) {
                 return StorageResultCode.OperationFailedStorageMounted;
             }
         }
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 4a7fc9c..9e0d623 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -4858,42 +4858,67 @@
                 String oldCodePath) {
             String newCacheId = getNextCodePath(oldCodePath, pkgName, "/" + RES_FILE_NAME);
             String newCachePath = null;
-            final int RENAME_FAILED = 1;
-            final int MOUNT_FAILED = 2;
-            final int PASS = 4;
-            int errCode = RENAME_FAILED;
-            String errMsg = "RENAME_FAILED";
-            boolean mounted = PackageHelper.isContainerMounted(cid);
-            if (mounted) {
-                // Unmount the container
-                if (!PackageHelper.unMountSdDir(cid)) {
-                    Log.i(TAG, "Failed to unmount " + cid + " before renaming");
+            boolean enableRename = false;
+            if (enableRename) {
+                if (PackageHelper.isContainerMounted(cid)) {
+                    // Unmount the container
+                    if (!PackageHelper.unMountSdDir(cid)) {
+                        Log.i(TAG, "Failed to unmount " + cid + " before renaming");
+                        return false;
+                    }
+                }
+                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
+                    Log.e(TAG, "Failed to rename " + cid + " to " + newCacheId);
                     return false;
                 }
-                mounted = false;
-            }
-            if (PackageHelper.renameSdDir(cid, newCacheId)) {
-                errCode = MOUNT_FAILED;
-                errMsg = "MOUNT_FAILED";
-                if ((newCachePath = PackageHelper.mountSdDir(newCacheId,
-                        getEncryptKey(), Process.SYSTEM_UID)) != null) {
-                    errCode = PASS;
-                    errMsg = "PASS";
+                if (!PackageHelper.isContainerMounted(newCacheId)) {
+                    Log.w(TAG, "Mounting container " + newCacheId);
+                    newCachePath = PackageHelper.mountSdDir(newCacheId,
+                            getEncryptKey(), Process.SYSTEM_UID);
+                } else {
+                    newCachePath = PackageHelper.getSdDir(newCacheId);
                 }
-            }
-            if (errCode != PASS) {
-                Log.i(TAG, "Failed to rename " + cid + " to " + newCacheId +
-                        " at path: " + cachePath + " to new path: " + newCachePath +
-                        "err = " + errMsg);
+                if (newCachePath == null) {
+                    Log.w(TAG, "Failed to get cache path for  " + newCacheId);
+                    return false;
+                }
                 // Mount old container?
-                return false;
+                Log.i(TAG, "Succesfully renamed " + cid +
+                        " at path: " + cachePath + " to " + newCacheId +
+                        " at new path: " + newCachePath);
+                cid = newCacheId;
+                cachePath = newCachePath;
+                return true;
             } else {
-                Log.i(TAG, "Succesfully renamed " + cid + " to " + newCacheId +
-                        " at path: " + cachePath + " to new path: " + newCachePath);
+                // STOPSHIP work around for rename
+                Log.i(TAG, "Copying instead of renaming");
+                File srcFile = new File(getCodePath());
+                // Create new container
+                newCachePath = PackageHelper.createSdDir(srcFile, newCacheId,
+                        getEncryptKey(), Process.SYSTEM_UID);
+                Log.i(TAG, "Created rename container " + newCacheId);
+                File destFile = new File(newCachePath + "/" + RES_FILE_NAME);
+                if (!FileUtils.copyFile(srcFile, destFile)) {
+                    Log.e(TAG, "Failed to copy " + srcFile + " to " + destFile);
+                    return false;
+                }
+                Log.i(TAG, "Successfully copied resource to " + newCachePath);
+                if (!PackageHelper.finalizeSdDir(newCacheId)) {
+                    Log.e(TAG, "Failed to finalize " + newCacheId);
+                    PackageHelper.destroySdDir(newCacheId);
+                    return false;
+                }
+                Log.i(TAG, "Finalized " + newCacheId);
+                Runtime.getRuntime().gc();
+                // Unmount first
+                PackageHelper.unMountSdDir(cid);
+                // Delete old container
+                PackageHelper.destroySdDir(cid);
+                // Dont have to mount. Already mounted.
+                cid = newCacheId;
+                cachePath = newCachePath;
+                return true;
             }
-            cid = newCacheId;
-            cachePath = newCachePath;
-            return true;
         }
 
         int doPostInstall(int status) {
@@ -5403,6 +5428,7 @@
             res.returnCode = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
             return;
         }
+
         if (!args.doRename(res.returnCode, pkgName, oldCodePath)) {
             res.returnCode = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
             return;
@@ -8809,7 +8835,7 @@
     }
 
    static String getTempContainerId() {
-       String prefix = "smdl1tmp";
+       String prefix = "smdl2tmp";
        int tmpIdx = 1;
        String list[] = PackageHelper.getSecureContainerList();
        if (list != null) {
@@ -8851,30 +8877,45 @@
        return prefix + tmpIdx;
    }
 
-   public void updateExternalMediaStatus(final boolean mediaStatus) {
+   public boolean updateExternalMediaStatus(final boolean mediaStatus) {
        synchronized (mPackages) {
            if (DEBUG_SD_INSTALL) Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" +
                    mediaStatus+", mMediaMounted=" + mMediaMounted);
            if (mediaStatus == mMediaMounted) {
-               return;
+               return false;
            }
            mMediaMounted = mediaStatus;
+           final HashMap<SdInstallArgs, String> processCids =
+                   new HashMap<SdInstallArgs, String>();
+           final int[] uidArr = getExternalMediaPackages(mediaStatus, processCids);
+           if (processCids.size() == 0) {
+               return false;
+           }
             // Queue up an async operation since the package installation may take a little while.
            mHandler.post(new Runnable() {
                public void run() {
                    mHandler.removeCallbacks(this);
-                   updateExternalMediaStatusInner(mediaStatus);
+                   if (mediaStatus) {
+                       if (DEBUG_SD_INSTALL) Log.i(TAG, "Loading packages");
+                       loadMediaPackages(processCids, uidArr);
+                       startCleaningPackages();
+                   } else {
+                       if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading packages");
+                       unloadMediaPackages(processCids, uidArr);
+                   }
                }
            });
+           return true;
        }
    }
 
-   void updateExternalMediaStatusInner(boolean mediaStatus) {
+    private int[] getExternalMediaPackages(boolean mediaStatus,
+            Map<SdInstallArgs, String> processCids) {
        final String list[] = PackageHelper.getSecureContainerList();
        if (list == null || list.length == 0) {
-           return;
+           return null;
        }
-       HashMap<SdInstallArgs, String> processCids = new HashMap<SdInstallArgs, String>();
+
        int uidList[] = new int[list.length];
        int num = 0;
        synchronized (mPackages) {
@@ -8916,14 +8957,7 @@
                }
            }
        }
-       if (mediaStatus) {
-           if (DEBUG_SD_INSTALL) Log.i(TAG, "Loading packages");
-           loadMediaPackages(processCids, uidArr);
-           startCleaningPackages();
-       } else {
-           if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading packages");
-           unloadMediaPackages(processCids, uidArr);
-       }
+       return uidArr;
    }
 
    private void sendResourcesChangedBroadcast(boolean mediaStatus,
@@ -8943,7 +8977,7 @@
        }
    }
 
-   void loadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[]) {
+   private void loadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[]) {
        ArrayList<String> pkgList = new ArrayList<String>();
        Set<SdInstallArgs> keys = processCids.keySet();
        for (SdInstallArgs args : keys) {
@@ -8993,7 +9027,7 @@
        }
    }
 
-   void unloadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[]) {
+   private void unloadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[]) {
        if (DEBUG_SD_INSTALL) Log.i(TAG, "unloading media packages");
        ArrayList<String> pkgList = new ArrayList<String>();
        ArrayList<SdInstallArgs> failedList = new ArrayList<SdInstallArgs>();
diff --git a/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java b/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java
index 3bbb447..e85254d 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java
@@ -132,6 +132,14 @@
         return ms.destroySecureContainer(fullId, force);
     }
 
+    private boolean isContainerMounted(String localId) throws RemoteException {
+        Assert.assertTrue(isMediaMounted());
+        String fullId = "com.android.unittests.AsecTests." + localId;
+
+        IMountService ms = getMs();
+        return ms.isSecureContainerMounted(fullId);
+    }
+
     private IMountService getMs() {
         IBinder service = ServiceManager.getService("mount");
         if (service != null) {
@@ -300,7 +308,7 @@
         }
     }
 
-    public void testRenameMountedContainer() {
+    public void testRenameSrcMountedContainer() {
         try {
             Assert.assertEquals(StorageResultCode.OperationSucceeded,
                     createContainer("testRenameContainer.1", 4, "none"));
@@ -312,12 +320,15 @@
         }
     }
 
-    public void testRenameToExistingContainer() {
+    public void testRenameDstMountedContainer() {
         try {
             Assert.assertEquals(StorageResultCode.OperationSucceeded,
                     createContainer("testRenameContainer.1", 4, "none"));
 
             Assert.assertEquals(StorageResultCode.OperationSucceeded,
+                    unmountContainer("testRenameContainer.1", false));
+
+            Assert.assertEquals(StorageResultCode.OperationSucceeded,
                     createContainer("testRenameContainer.2", 4, "none"));
 
             Assert.assertEquals(StorageResultCode.OperationFailedStorageMounted,
@@ -326,4 +337,25 @@
             failStr(e);
         }
     }
+
+    public void testIsContainerMountedAfterRename() {
+        try {
+            Assert.assertEquals(StorageResultCode.OperationSucceeded,
+                    createContainer("testRenameContainer.1", 4, "none"));
+
+            Assert.assertEquals(StorageResultCode.OperationSucceeded,
+                    unmountContainer("testRenameContainer.1", false));
+
+            Assert.assertEquals(StorageResultCode.OperationSucceeded,
+                    renameContainer("testRenameContainer.1", "testRenameContainer.2"));
+
+            Assert.assertEquals(false, containerExists("testRenameContainer.1"));
+            Assert.assertEquals(true, containerExists("testRenameContainer.2"));
+            // Check if isContainerMounted returns valid value
+            Assert.assertEquals(true, isContainerMounted("testRenameContainer.2"));
+        } catch (Exception e) {
+            failStr(e);
+        }
+    }
+
 }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
index 9c5c44d..d161a88 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
@@ -57,17 +57,25 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.storage.IMountService;
+import android.os.storage.IMountServiceListener;
+import android.os.storage.StorageEventListener;
+import android.os.storage.StorageManager;
 import android.os.storage.StorageResultCode;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StatFs;
 import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
 
 public class PackageManagerTests extends AndroidTestCase {
     private static final boolean localLOGV = true;
     public static final String TAG="PackageManagerTests";
     public final long MAX_WAIT_TIME=120*1000;
     public final long WAIT_TIME_INCR=20*1000;
+    private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec";
+    private static final int APP_INSTALL_AUTO = 0;
+    private static final int APP_INSTALL_DEVICE = 1;
+    private static final int APP_INSTALL_SDCARD = 2;
 
     void failStr(String errMsg) {
         Log.w(TAG, "errMsg="+errMsg);
@@ -244,9 +252,46 @@
         packageParser = null;
         return pkg;
     }
-
-    private void assertInstall(String pkgName, int flags) {
+    private boolean getInstallLoc(int flags, int expInstallLocation) {
+        // Flags explicitly over ride everything else.
+        if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0 ) {
+            return false;
+        } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0 ) {
+            return true;
+        }
+        // Manifest option takes precedence next
+        if (expInstallLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
+            return true;
+        }
+        // TODO Out of memory checks here.
+        boolean checkSd = false;
+        int setLoc = 0;
         try {
+            setLoc = Settings.System.getInt(mContext.getContentResolver(), Settings.System.SET_INSTALL_LOCATION);
+        } catch (SettingNotFoundException e) {
+            failStr(e);
+        }
+        if (setLoc == 1) {
+            int userPref = APP_INSTALL_AUTO;
+            try {
+                userPref = Settings.System.getInt(mContext.getContentResolver(), Settings.System.DEFAULT_INSTALL_LOCATION);
+            } catch (SettingNotFoundException e) {
+                failStr(e);
+            }
+            if (userPref == APP_INSTALL_DEVICE) {
+                checkSd = false;
+            } else if (userPref == APP_INSTALL_SDCARD) {
+                checkSd = true;
+            } else if (userPref == APP_INSTALL_AUTO) {
+                // Might be determined dynamically. TODO fix this
+                checkSd = false;
+            }
+        }
+        return checkSd;
+    }
+    private void assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation) {
+        try {
+            String pkgName = pkg.packageName;
         ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0);
         assertNotNull(info);
         assertEquals(pkgName, info.packageName);
@@ -264,15 +309,14 @@
             assertEquals(publicSrcPath, appInstallPath);
         } else {
             assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0);
-            if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
-                assertTrue((info.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0);
-                // Hardcoded for now
-                assertTrue(srcPath.startsWith("/asec"));
-                assertTrue(publicSrcPath.startsWith("/asec"));
-            } else {
+            if (!getInstallLoc(flags, expInstallLocation)) {
                 assertEquals(srcPath, appInstallPath);
                 assertEquals(publicSrcPath, appInstallPath);
                 assertFalse((info.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0);
+            } else {
+                assertTrue((info.flags & ApplicationInfo.FLAG_ON_SDCARD) != 0);
+                assertTrue(srcPath.startsWith(SECURE_CONTAINERS_PREFIX));
+                assertTrue(publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX));
             }
         }
         } catch (NameNotFoundException e) {
@@ -300,7 +344,7 @@
 
     private InstallParams sampleInstallFromRawResource(int flags, boolean cleanUp) {
         return installFromRawResource("install.apk", R.raw.install, flags, cleanUp,
-                false, -1);
+                false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
     }
 
     public void clearSecureContainersForPkg(String pkgName) {
@@ -327,7 +371,8 @@
      * PackageManager api to install it.
      */
     private InstallParams installFromRawResource(String outFileName,
-            int rawResId, int flags, boolean cleanUp, boolean fail, int result) {
+            int rawResId, int flags, boolean cleanUp, boolean fail, int result,
+            int expInstallLocation) {
         File filesDir = mContext.getFilesDir();
         File outFile = new File(filesDir, outFileName);
         Uri packageURI = getInstallablePackage(rawResId, outFile);
@@ -337,9 +382,7 @@
         // Make sure the package doesn't exist
         getPm().deletePackage(pkg.packageName, null, 0);
         // Clean up the containers as well
-        if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) {
-            clearSecureContainersForPkg(pkg.packageName);
-        }
+        clearSecureContainersForPkg(pkg.packageName);
         try {
             try {
                 if (fail) {
@@ -351,7 +394,7 @@
                     assertTrue(invokeInstallPackage(packageURI, flags,
                             pkg.packageName, receiver));
                     // Verify installed information
-                    assertInstall(pkg.packageName, flags);
+                    assertInstall(pkg, flags, expInstallLocation);
                     ip = new InstallParams(pkg, outFileName, packageURI);
                 }
             } catch (Exception e) {
@@ -443,6 +486,7 @@
     public void replaceFromRawResource(int flags) {
         InstallParams ip = sampleInstallFromRawResource(flags, false);
         boolean replace = ((flags & PackageManager.INSTALL_REPLACE_EXISTING) != 0);
+        Log.i(TAG, "replace=" + replace);
         GenericReceiver receiver;
         if (replace) {
             receiver = new ReplaceReceiver(ip.pkg.packageName);
@@ -455,7 +499,7 @@
                 assertEquals(invokeInstallPackage(ip.packageURI, flags,
                         ip.pkg.packageName, receiver), replace);
                 if (replace) {
-                    assertInstall(ip.pkg.packageName, flags);
+                    assertInstall(ip.pkg, flags, ip.pkg.installLocation);
                 }
             } catch (Exception e) {
                 failStr("Failed with exception : " + e);
@@ -738,51 +782,73 @@
         }
     }
 
+    class StorageListener extends StorageEventListener {
+        String oldState;
+        String newState;
+        String path;
+        private boolean doneFlag = false;
+        @Override
+        public void onStorageStateChanged(String path, String oldState, String newState) {
+            if (localLOGV) Log.i(TAG, "Storage state changed from " + oldState + " to " + newState);
+            synchronized (this) {
+                this.oldState = oldState;
+                this.newState = newState;
+                this.path = path;
+                doneFlag = true;
+                notifyAll();
+            }
+        }
+
+        public boolean isDone() {
+            return doneFlag;
+        }
+    }
+
     private boolean unmountMedia() {
         if (!getMediaState()) {
             return true;
         }
+        String path = Environment.getExternalStorageDirectory().toString();
+        StorageListener observer = new StorageListener();
+        StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
+        sm.registerListener(observer);
         try {
-        String mPath = Environment.getExternalStorageDirectory().toString();
-        int ret = getMs().unmountVolume(mPath, false);
-        return ret == StorageResultCode.OperationSucceeded;
-        } catch (RemoteException e) {
-            return true;
+            // Wait on observer
+            synchronized(observer) {
+                getMs().unmountVolume(path, false);
+                long waitTime = 0;
+                while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
+                    observer.wait(WAIT_TIME_INCR);
+                    waitTime += WAIT_TIME_INCR;
+                }
+                if(!observer.isDone()) {
+                    throw new Exception("Timed out waiting for packageInstalled callback");
+                }
+                return true;
+            }
+        } catch (Exception e) {
+            return false;
+        } finally {
+            sm.unregisterListener(observer);
         }
     }
 
-    /*
-     * Install package on sdcard. Unmount and then mount the media.
-     * (Use PackageManagerService private api for now)
-     * Make sure the installed package is available.
-     * STOPSHIP will uncomment when MountService api's to mount/unmount
-     * are made asynchronous.
-     */
-    public void xxxtestMountSdNormalInternal() {
-        assertTrue(mountFromRawResource());
-    }
-
     private boolean mountFromRawResource() {
         // Install pkg on sdcard
-        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL |
-                PackageManager.INSTALL_REPLACE_EXISTING, false);
+        InstallParams ip = sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, false);
         if (localLOGV) Log.i(TAG, "Installed pkg on sdcard");
         boolean origState = getMediaState();
+        boolean registeredReceiver = false;
         SdMountReceiver receiver = new SdMountReceiver(new String[]{ip.pkg.packageName});
         try {
             if (localLOGV) Log.i(TAG, "Unmounting media");
             // Unmount media
             assertTrue(unmountMedia());
             if (localLOGV) Log.i(TAG, "Unmounted media");
-            try {
-                if (localLOGV) Log.i(TAG, "Sleeping for 10 second");
-                Thread.sleep(10*1000);
-            } catch (InterruptedException e) {
-                failStr(e);
-            }
             // Register receiver here
             PackageManager pm = getPm();
             mContext.registerReceiver(receiver, receiver.filter);
+            registeredReceiver = true;
 
             // Wait on receiver
             synchronized (receiver) {
@@ -807,7 +873,7 @@
             failStr(e);
             return false;
         } finally {
-            mContext.unregisterReceiver(receiver);
+            if (registeredReceiver) mContext.unregisterReceiver(receiver);
             // Restore original media state
             if (origState) {
                 mountMedia();
@@ -819,6 +885,17 @@
         }
     }
 
+    /*
+     * Install package on sdcard. Unmount and then mount the media.
+     * (Use PackageManagerService private api for now)
+     * Make sure the installed package is available.
+     * STOPSHIP will uncomment when MountService api's to mount/unmount
+     * are made asynchronous.
+     */
+    public void xxxtestMountSdNormalInternal() {
+        assertTrue(mountFromRawResource());
+    }
+
     void cleanUpInstall(InstallParams ip) {
         if (ip == null) {
             return;
@@ -834,28 +911,29 @@
 
     public void testManifestInstallLocationInternal() {
         installFromRawResource("install.apk", R.raw.install_loc_internal,
-                0, true, false, -1);
+                0, true, false, -1, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
     }
 
     public void testManifestInstallLocationSdcard() {
         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
-                0, true, false, -1);
+                0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
     }
 
     public void testManifestInstallLocationAuto() {
         installFromRawResource("install.apk", R.raw.install_loc_auto,
-                0, true, false, -1);
+                0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
     }
 
     public void testManifestInstallLocationUnspecified() {
         installFromRawResource("install.apk", R.raw.install_loc_unspecified,
-                0, true, false, -1);
+                0, true, false, -1, PackageInfo.INSTALL_LOCATION_AUTO);
     }
 
     public void testManifestInstallLocationFwdLockedSdcard() {
         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
                 PackageManager.INSTALL_FORWARD_LOCK, true, true,
-                PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION);
+                PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
+                PackageInfo.INSTALL_LOCATION_AUTO);
     }
 
     public void xxxtestClearAllSecureContainers() {
diff --git a/tests/LocationTracker/res/layout/entrylist_item.xml b/tests/LocationTracker/res/layout/entrylist_item.xml
index 8187677..d2a8033 100644
--- a/tests/LocationTracker/res/layout/entrylist_item.xml
+++ b/tests/LocationTracker/res/layout/entrylist_item.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 /*
- * Copyright (C) 2006-2008 Google Inc.
+ * Copyright (C) 2006-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.
diff --git a/tests/LocationTracker/res/menu/menu.xml b/tests/LocationTracker/res/menu/menu.xml
index 94c589a..05d13fd 100644
--- a/tests/LocationTracker/res/menu/menu.xml
+++ b/tests/LocationTracker/res/menu/menu.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 /**
-* Copyright (c) 2008 Google Inc.
+* 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.
diff --git a/tests/LocationTracker/res/values/strings.xml b/tests/LocationTracker/res/values/strings.xml
index bb3ea86..ea6bf2d 100644
--- a/tests/LocationTracker/res/values/strings.xml
+++ b/tests/LocationTracker/res/values/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 /*
-* Copyright (C) 2008 Google Inc.
+* 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.
diff --git a/tests/LocationTracker/res/xml/preferences.xml b/tests/LocationTracker/res/xml/preferences.xml
index b57837f..61d4817 100755
--- a/tests/LocationTracker/res/xml/preferences.xml
+++ b/tests/LocationTracker/res/xml/preferences.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 Google Inc.
+<!-- 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.
diff --git a/tests/LocationTracker/src/com/android/locationtracker/SettingsActivity.java b/tests/LocationTracker/src/com/android/locationtracker/SettingsActivity.java
index c5b2432..cb77118 100755
--- a/tests/LocationTracker/src/com/android/locationtracker/SettingsActivity.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/SettingsActivity.java
@@ -1,5 +1,5 @@
 /*

- * Copyright (C) 2008 Google Inc.

+ * 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.

diff --git a/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java b/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java
index 92e7803..98d0a50 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/TrackerActivity.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Google Inc.
+ * 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.
diff --git a/tests/LocationTracker/src/com/android/locationtracker/TrackerService.java b/tests/LocationTracker/src/com/android/locationtracker/TrackerService.java
index 4206da7..5b75653 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/TrackerService.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/TrackerService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Google Inc.
+ * 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.
diff --git a/tests/LocationTracker/src/com/android/locationtracker/data/CSVFormatter.java b/tests/LocationTracker/src/com/android/locationtracker/data/CSVFormatter.java
index 22ddf45..672ce28 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/data/CSVFormatter.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/data/CSVFormatter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Google Inc.
+ * 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.
diff --git a/tests/LocationTracker/src/com/android/locationtracker/data/DateUtils.java b/tests/LocationTracker/src/com/android/locationtracker/data/DateUtils.java
index 1691f27..13226bd 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/data/DateUtils.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/data/DateUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Google Inc.
+ * 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.
diff --git a/tests/LocationTracker/src/com/android/locationtracker/data/IFormatter.java b/tests/LocationTracker/src/com/android/locationtracker/data/IFormatter.java
index d413191..af0b5ed 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/data/IFormatter.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/data/IFormatter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Google Inc.
+ * 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.
diff --git a/tests/LocationTracker/src/com/android/locationtracker/data/KMLFormatter.java b/tests/LocationTracker/src/com/android/locationtracker/data/KMLFormatter.java
index ef4bbbb..a5e1816 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/data/KMLFormatter.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/data/KMLFormatter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Google Inc.
+ * 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
diff --git a/tests/LocationTracker/src/com/android/locationtracker/data/TrackerDataHelper.java b/tests/LocationTracker/src/com/android/locationtracker/data/TrackerDataHelper.java
index ad25126..a3838df 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/data/TrackerDataHelper.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/data/TrackerDataHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Google Inc.
+ * 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
diff --git a/tests/LocationTracker/src/com/android/locationtracker/data/TrackerEntry.java b/tests/LocationTracker/src/com/android/locationtracker/data/TrackerEntry.java
index 8c961d1..b2741f6 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/data/TrackerEntry.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/data/TrackerEntry.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Google Inc.
+ * 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
diff --git a/tests/LocationTracker/src/com/android/locationtracker/data/TrackerListHelper.java b/tests/LocationTracker/src/com/android/locationtracker/data/TrackerListHelper.java
index 0247ef0..55d4d1e 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/data/TrackerListHelper.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/data/TrackerListHelper.java
@@ -1,5 +1,5 @@
 /*

- * Copyright (C) 2008 Google Inc.

+ * 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

diff --git a/tests/LocationTracker/src/com/android/locationtracker/data/TrackerProvider.java b/tests/LocationTracker/src/com/android/locationtracker/data/TrackerProvider.java
index ea849e0..88f24c3 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/data/TrackerProvider.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/data/TrackerProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Google Inc.
+ * 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
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
index 51afc0a..a09cec0 100644
--- a/tools/aapt/StringPool.cpp
+++ b/tools/aapt/StringPool.cpp
@@ -25,8 +25,12 @@
     const size_t NS = pool->size();
     for (size_t s=0; s<NS; s++) {
         size_t len;
-        printf("String #%ld: %s\n", s,
-                String8(pool->stringAt(s, &len)).string());
+        const char *str = (const char*)pool->string8At(s, &len);
+        if (str == NULL) {
+            str = String8(pool->stringAt(s, &len)).string();
+        }
+
+        printf("String #%ld: %s\n", s, str);
     }
 }
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
index 73a3986..744bfbe 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
@@ -927,6 +927,7 @@
         return null;
     }
 
+    @Override
     public File getExternalCacheDir() {
         // TODO Auto-generated method stub
         return null;
@@ -964,6 +965,7 @@
         return null;
     }
 
+    @Override
     public File getExternalFilesDir(String type) {
         // TODO Auto-generated method stub
         return null;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
index efd222e..6a98780 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeTypedArray.java
@@ -392,7 +392,8 @@
 
         if (s == null) {
             return defValue;
-        } else if (s.equals(BridgeConstants.MATCH_PARENT)) {
+        } else if (s.equals(BridgeConstants.MATCH_PARENT) ||
+                s.equals(BridgeConstants.FILL_PARENT)) {
             return LayoutParams.MATCH_PARENT;
         } else if (s.equals(BridgeConstants.WRAP_CONTENT)) {
             return LayoutParams.WRAP_CONTENT;
@@ -460,7 +461,8 @@
 
         if (s == null) {
             return defValue;
-        } else if (s.equals(BridgeConstants.MATCH_PARENT)) {
+        } else if (s.equals(BridgeConstants.MATCH_PARENT) ||
+                s.equals(BridgeConstants.FILL_PARENT)) {
             return LayoutParams.MATCH_PARENT;
         } else if (s.equals(BridgeConstants.WRAP_CONTENT)) {
             return LayoutParams.WRAP_CONTENT;