Merge "Cleanup bitmap uploads Implement standalone mipmap generation." into honeycomb
diff --git a/api/current.xml b/api/current.xml
index 3451402..d790c4f 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -34814,6 +34814,32 @@
 <parameter name="d" type="android.graphics.drawable.Drawable">
 </parameter>
 </method>
+<method name="setProgressNumberFormat"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="format" type="java.lang.String">
+</parameter>
+</method>
+<method name="setProgressPercentFormat"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="format" type="java.text.NumberFormat">
+</parameter>
+</method>
 <method name="setProgressStyle"
  return="void"
  abstract="false"
diff --git a/core/java/android/app/ProgressDialog.java b/core/java/android/app/ProgressDialog.java
index af1b294..d421173 100644
--- a/core/java/android/app/ProgressDialog.java
+++ b/core/java/android/app/ProgressDialog.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.graphics.drawable.Drawable;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -75,12 +74,20 @@
     
     public ProgressDialog(Context context) {
         super(context);
+        initFormats();
     }
 
     public ProgressDialog(Context context, int theme) {
         super(context, theme);
+        initFormats();
     }
 
+    private void initFormats() {
+        mProgressNumberFormat = "%1d/%2d";
+        mProgressPercentFormat = NumberFormat.getPercentInstance();
+        mProgressPercentFormat.setMaximumFractionDigits(0);
+    }
+    
     public static ProgressDialog show(Context context, CharSequence title,
             CharSequence message) {
         return show(context, title, message, false);
@@ -125,22 +132,27 @@
                     /* Update the number and percent */
                     int progress = mProgress.getProgress();
                     int max = mProgress.getMax();
-                    double percent = (double) progress / (double) max;
-                    String format = mProgressNumberFormat;
-                    mProgressNumber.setText(String.format(format, progress, max));
-                    SpannableString tmp = new SpannableString(mProgressPercentFormat.format(percent));
-                    tmp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
-                            0, tmp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-                    mProgressPercent.setText(tmp);
+                    if (mProgressNumberFormat != null) {
+                        String format = mProgressNumberFormat;
+                        mProgressNumber.setText(String.format(format, progress, max));
+                    } else {
+                        mProgressNumber.setText("");
+                    }
+                    if (mProgressPercentFormat != null) {
+                        double percent = (double) progress / (double) max;
+                        SpannableString tmp = new SpannableString(mProgressPercentFormat.format(percent));
+                        tmp.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
+                                0, tmp.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+                        mProgressPercent.setText(tmp);
+                    } else {
+                        mProgressPercent.setText("");
+                    }
                 }
             };
             View view = inflater.inflate(R.layout.alert_dialog_progress, null);
             mProgress = (ProgressBar) view.findViewById(R.id.progress);
             mProgressNumber = (TextView) view.findViewById(R.id.progress_number);
-            mProgressNumberFormat = "%d/%d";
             mProgressPercent = (TextView) view.findViewById(R.id.progress_percent);
-            mProgressPercentFormat = NumberFormat.getPercentInstance();
-            mProgressPercentFormat.setMaximumFractionDigits(0);
             setView(view);
         } else {
             View view = inflater.inflate(R.layout.progress_dialog, null);
@@ -304,19 +316,36 @@
     }
 
     /**
-     * Change the format of Progress Number. The default is "current/max".
+     * Change the format of the small text showing current and maximum units
+     * of progress.  The default is "%1d/%2d".
      * Should not be called during the number is progressing.
-     * @param format Should contain two "%d". The first is used for current number
-     * and the second is used for the maximum.
-     * @hide
+     * @param format A string passed to {@link String#format String.format()};
+     * use "%1d" for the current number and "%2d" for the maximum.  If null,
+     * nothing will be shown.
      */
     public void setProgressNumberFormat(String format) {
         mProgressNumberFormat = format;
+        onProgressChanged();
+    }
+
+    /**
+     * Change the format of the small text showing the percentage of progress.
+     * The default is
+     * {@link NumberFormat#getPercentInstance() NumberFormat.getPercentageInstnace().}
+     * Should not be called during the number is progressing.
+     * @param format An instance of a {@link NumberFormat} to generate the
+     * percentage text.  If null, nothing will be shown.
+     */
+    public void setProgressPercentFormat(NumberFormat format) {
+        mProgressPercentFormat = format;
+        onProgressChanged();
     }
     
     private void onProgressChanged() {
         if (mProgressStyle == STYLE_HORIZONTAL) {
-            mViewUpdateHandler.sendEmptyMessage(0);
+            if (!mViewUpdateHandler.hasMessages(0)) {
+                mViewUpdateHandler.sendEmptyMessage(0);
+            }
         }
     }
 }
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index ae729d2d..31bc3fc 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -548,26 +548,22 @@
            }
         }
 
-        // STOPSHIP: Hack for MOT keyboards
-        boolean motKeyboard = false;
-        String name = mBluetoothService.getRemoteName(address);
-        if (name == null && address.startsWith("00:0F:F6") ||
-            (name != null && name.startsWith("Motorola"))) {
-                motKeyboard = true;
-        }
-
-        if (!motKeyboard) {
-            if (btDeviceClass == BluetoothClass.Device.PERIPHERAL_KEYBOARD ||
-                btDeviceClass == BluetoothClass.Device.PERIPHERAL_KEYBOARD_POINTING) {
-                // Its a keyboard. Follow the HID spec recommendation of creating the
-                // passkey and displaying it to the user.
-                // Generate a variable PIN. This is not truly random but good enough.
-                int pin = (int) Math.floor(Math.random() * 10000);
-                sendDisplayPinIntent(address, pin);
+        if (btDeviceClass == BluetoothClass.Device.PERIPHERAL_KEYBOARD ||
+            btDeviceClass == BluetoothClass.Device.PERIPHERAL_KEYBOARD_POINTING) {
+            // Its a keyboard. Follow the HID spec recommendation of creating the
+            // passkey and displaying it to the user. If the keyboard doesn't follow
+            // the spec recommendation, check if the keyboard has a fixed PIN zero
+            // and pair.
+            if (mBluetoothService.isFixedPinZerosAutoPairKeyboard(address)) {
+                mBluetoothService.setPin(address, BluetoothDevice.convertPinToBytes("0000"));
                 return;
             }
-        }
 
+            // Generate a variable PIN. This is not truly random but good enough.
+            int pin = (int) Math.floor(Math.random() * 10000);
+            sendDisplayPinIntent(address, pin);
+            return;
+        }
         // Acquire wakelock during PIN code request to bring up LCD display
         mWakeLock.acquire();
         Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 9261ff6..32e609c 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -678,6 +678,11 @@
         return false;
     }
 
+    /*package*/ synchronized boolean isFixedPinZerosAutoPairKeyboard(String address) {
+        // Check for keyboards which have fixed PIN 0000 as the pairing pin
+        return mBondState.isFixedPinZerosAutoPairKeyboard(address);
+    }
+
     /*package*/ synchronized void onCreatePairedDeviceResult(String address, int result) {
         if (result == BluetoothDevice.BOND_SUCCESS) {
             setBondState(address, BluetoothDevice.BOND_BONDED);
@@ -748,6 +753,7 @@
         private ArrayList<String>  mAutoPairingAddressBlacklist;
         private ArrayList<String> mAutoPairingExactNameBlacklist;
         private ArrayList<String> mAutoPairingPartialNameBlacklist;
+        private ArrayList<String> mAutoPairingFixedPinZerosKeyboardList;
         // Addresses added to blacklist dynamically based on usage.
         private ArrayList<String> mAutoPairingDynamicAddressBlacklist;
 
@@ -863,6 +869,19 @@
             return false;
         }
 
+        public boolean isFixedPinZerosAutoPairKeyboard(String address) {
+            // Note: the meaning of blacklist is reversed in this case.
+            // If its in the list, we can go ahead and auto pair since
+            // by default keyboard should have a variable PIN that we don't
+            // auto pair using 0000.
+            if (mAutoPairingFixedPinZerosKeyboardList != null) {
+                for (String blacklistAddress : mAutoPairingFixedPinZerosKeyboardList) {
+                    if (address.startsWith(blacklistAddress)) return true;
+                }
+            }
+            return false;
+        }
+
         public synchronized int getBondState(String address) {
             Integer state = mState.get(address);
             if (state == null) {
@@ -929,7 +948,6 @@
             FileOutputStream out = null;
             try {
                 file = new File(DYNAMIC_AUTO_PAIRING_BLACKLIST);
-                if (file.exists()) return;
 
                 in = new FileInputStream(AUTO_PAIRING_BLACKLIST);
                 out= new FileOutputStream(DYNAMIC_AUTO_PAIRING_BLACKLIST);
@@ -975,6 +993,9 @@
                         } else if (value[0].equalsIgnoreCase("PartialNameBlacklist")) {
                             mAutoPairingPartialNameBlacklist =
                                 new ArrayList<String>(Arrays.asList(val));
+                        } else if (value[0].equalsIgnoreCase("FixedPinZerosKeyboardBlacklist")) {
+                            mAutoPairingFixedPinZerosKeyboardList =
+                                new ArrayList<String>(Arrays.asList(val));
                         } else if (value[0].equalsIgnoreCase("DynamicAddressBlacklist")) {
                             mAutoPairingDynamicAddressBlacklist =
                                 new ArrayList<String>(Arrays.asList(val));
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 8c4e654..7dd6cc6 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -160,7 +160,8 @@
     static native void nResizeLayer(int layerId, int layerTextureId, int width, int height,
             int[] layerInfo);
     static native void nDestroyLayer(int layerId, int layerTextureId);    
-    
+    static native void nDestroyLayerDeferred(int layerId, int layerTextureId);    
+
     ///////////////////////////////////////////////////////////////////////////
     // Canvas management
     ///////////////////////////////////////////////////////////////////////////
diff --git a/core/java/android/view/GLES20Layer.java b/core/java/android/view/GLES20Layer.java
index 336e07a..7587657 100644
--- a/core/java/android/view/GLES20Layer.java
+++ b/core/java/android/view/GLES20Layer.java
@@ -128,7 +128,7 @@
         protected void finalize() throws Throwable {
             try {
                 if (mLayerId != 0 || mLayerTextureId != 0) {
-                    GLES20Canvas.nDestroyLayer(mLayerId, mLayerTextureId);
+                    GLES20Canvas.nDestroyLayerDeferred(mLayerId, mLayerTextureId);
                 }
             } finally {
                 super.finalize();
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index d6991e6..4aed9b1 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -501,6 +501,11 @@
     LayerRenderer::destroyLayer(layerId, layerTextureId);
 }
 
+static void android_view_GLES20Canvas_destroyLayerDeferred(JNIEnv* env,
+        jobject clazz, jint layerId, jint layerTextureId) {
+    LayerRenderer::destroyLayerDeferred(layerId, layerTextureId);
+}
+
 static void android_view_GLES20Canvas_drawLayer(JNIEnv* env,
         jobject canvas, OpenGLRenderer* renderer,
         jfloat left, jfloat top, jfloat right, jfloat bottom,
@@ -593,13 +598,14 @@
     { "nGetDisplayListRenderer", "(I)I",       (void*) android_view_GLES20Canvas_getDisplayListRenderer },
     { "nDrawDisplayList",        "(II)V",      (void*) android_view_GLES20Canvas_drawDisplayList },
 
-    { "nInterrupt",              "(I)V",        (void*) android_view_GLES20Canvas_interrupt },
-    { "nResume",                 "(I)V",        (void*) android_view_GLES20Canvas_resume },
+    { "nInterrupt",              "(I)V",       (void*) android_view_GLES20Canvas_interrupt },
+    { "nResume",                 "(I)V",       (void*) android_view_GLES20Canvas_resume },
 
     { "nCreateLayerRenderer",    "(I)I",       (void*) android_view_GLES20Canvas_createLayerRenderer },
     { "nCreateLayer",            "(II[I)I",    (void*) android_view_GLES20Canvas_createLayer },
     { "nResizeLayer",            "(IIII[I)V",  (void*) android_view_GLES20Canvas_resizeLayer },
     { "nDestroyLayer",           "(II)V",      (void*) android_view_GLES20Canvas_destroyLayer },
+    { "nDestroyLayerDeferred",   "(II)V",      (void*) android_view_GLES20Canvas_destroyLayerDeferred },
     { "nDrawLayer",              "(IFFFFIFFI)V",
             (void*) android_view_GLES20Canvas_drawLayer },
 
diff --git a/core/res/res/layout-xlarge/keyguard_screen_lock.xml b/core/res/res/layout-xlarge/keyguard_screen_lock.xml
index 733a350..c7aa654 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_lock.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_lock.xml
@@ -16,7 +16,7 @@
 ** limitations under the License.
 */
 -->
-        
+
 <!-- This is the general lock screen which shows information about the
   state of the device, as well as instructions on how to get past it
   depending on the state of the device.  It is the same for landscape
@@ -25,9 +25,7 @@
     android:orientation="vertical"
     android:gravity="bottom"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="#ff800000"
-        >
+    android:layout_height="match_parent">
 
     <LinearLayout
         android:orientation="vertical"
diff --git a/core/res/res/layout-xlarge/keyguard_screen_tab_unlock.xml b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock.xml
index 1c7b7e2..c9c1692 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock.xml
@@ -26,8 +26,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
-    android:id="@+id/root"
-    android:background="#70000000">
+    android:id="@+id/root">
 
     <!-- top: status -->
     <RelativeLayout
diff --git a/core/res/res/layout-xlarge/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock_land.xml
index c24eecc..fbb9983 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_tab_unlock_land.xml
@@ -25,7 +25,6 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="horizontal"
-    android:background="#70000000"
     android:id="@+id/root">
 
     <!-- left side: status -->
diff --git a/core/res/res/layout-xlarge/keyguard_screen_unlock_landscape.xml b/core/res/res/layout-xlarge/keyguard_screen_unlock_landscape.xml
index ec7c272..8acb656 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_unlock_landscape.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_unlock_landscape.xml
@@ -25,8 +25,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="horizontal"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="#70000000">
+    android:layout_height="match_parent">
 
     <!-- left side: status  -->
     <RelativeLayout
diff --git a/core/res/res/layout-xlarge/keyguard_screen_unlock_portrait.xml b/core/res/res/layout-xlarge/keyguard_screen_unlock_portrait.xml
index 84ddd6a..f35897e 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_unlock_portrait.xml
@@ -21,9 +21,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="#70000000"
-        >
+    android:layout_height="match_parent">
 
     <!-- top: status -->
     <LinearLayout
diff --git a/core/res/res/layout/alert_dialog_progress.xml b/core/res/res/layout/alert_dialog_progress.xml
index c519692..ac95cdb 100644
--- a/core/res/res/layout/alert_dialog_progress.xml
+++ b/core/res/res/layout/alert_dialog_progress.xml
@@ -40,9 +40,9 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:paddingBottom="12dip"
-            android:layout_marginLeft="50dip"
-            android:layout_marginRight="15dip"
-            android:layout_alignParentLeft="true"
+            android:layout_marginLeft="10dip"
+            android:layout_marginRight="10dip"
+            android:layout_alignParentRight="true"
             android:layout_below="@id/progress"
         />
 </RelativeLayout>
diff --git a/core/res/res/layout/keyguard_screen_password_landscape.xml b/core/res/res/layout/keyguard_screen_password_landscape.xml
index 3d52f71..4d8c688 100644
--- a/core/res/res/layout/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_password_landscape.xml
@@ -20,7 +20,6 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
-    android:background="#70000000"
     android:gravity="center_horizontal">
 
     <LinearLayout
diff --git a/core/res/res/layout/keyguard_screen_password_portrait.xml b/core/res/res/layout/keyguard_screen_password_portrait.xml
index af8a3ef..93966de 100644
--- a/core/res/res/layout/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_password_portrait.xml
@@ -20,7 +20,6 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
-    android:background="#70000000"
     android:gravity="center_horizontal">
 
     <!-- "Enter PIN(Password) to unlock" -->
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock.xml b/core/res/res/layout/keyguard_screen_tab_unlock.xml
index 8367157..5fe38d5 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock.xml
@@ -25,7 +25,6 @@
     xmlns:tabunlock="http://schemas.android.com/apk/res/com.android.tabunlock"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="#70000000"
     android:gravity="center_horizontal"
     android:id="@+id/root">
 
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
index 9547660..3c2ad9a 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
@@ -25,7 +25,6 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="horizontal"
-    android:background="#70000000"
     android:id="@+id/root">
 
     <!-- left side -->
diff --git a/core/res/res/layout/keyguard_screen_unlock_landscape.xml b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
index 759c906..c7b78c4 100644
--- a/core/res/res/layout/keyguard_screen_unlock_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
@@ -25,9 +25,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="horizontal"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="#70000000"
-        >
+    android:layout_height="match_parent">
 
     <!-- left side: instructions and emergency call button -->
     <LinearLayout
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index c438412..15f2afb 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -25,9 +25,7 @@
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:gravity="center_horizontal"
-    android:background="#70000000"
-    >
+    android:gravity="center_horizontal">
 
     <RelativeLayout
         android:layout_width="match_parent"
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 2aaac66..d40c857 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -369,6 +369,8 @@
         <item name="searchViewGoIcon">@android:drawable/ic_go_search_api_holo_light</item>
         <item name="searchViewVoiceIcon">@android:drawable/ic_voice_search_api_holo_light</item>
         <item name="searchViewEditQuery">@android:drawable/ic_commit_search_api_holo_light</item>
+
+        <item name="detailsElementBackground">@android:drawable/panel_bg_holo_light</item>
     </style>
 
     <!-- Variant of the light theme with no title bar -->
diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
index 30a43c3..0e65df5 100755
--- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
+++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java
@@ -623,6 +623,11 @@
 
     @LargeTest
     public void testInstallSdcard() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         mountMedia();
         sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
     }
@@ -724,6 +729,11 @@
 
     @LargeTest
     public void testReplaceFailSdcard() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         sampleReplaceFromRawResource(PackageManager.INSTALL_EXTERNAL);
     }
 
@@ -740,6 +750,11 @@
 
     @LargeTest
     public void testReplaceSdcard() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         sampleReplaceFromRawResource(PackageManager.INSTALL_REPLACE_EXISTING |
                 PackageManager.INSTALL_EXTERNAL);
     }
@@ -864,6 +879,11 @@
 
     @LargeTest
     public void testDeleteSdcard() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, 0);
     }
 
@@ -879,6 +899,11 @@
 
     @LargeTest
     public void testDeleteSdcardRetainData() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         deleteFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.DONT_DELETE_DATA);
     }
 
@@ -977,6 +1002,11 @@
     }
 
     boolean mountMedia() {
+        // We can't mount emulated storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return true;
+        }
+
         if (checkMediaState(Environment.MEDIA_MOUNTED)) {
             return true;
         }
@@ -1011,6 +1041,11 @@
     }
 
     private boolean unmountMedia() {
+        // We can't unmount emulated storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return true;
+        }
+
         if (checkMediaState(Environment.MEDIA_UNMOUNTED)) {
             return true;
         }
@@ -1100,6 +1135,11 @@
      */
     @LargeTest
     public void testMountSdNormalInternal() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         assertTrue(mountFromRawResource());
     }
 
@@ -1137,6 +1177,11 @@
 
     @LargeTest
     public void testManifestInstallLocationSdcard() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
                 0, true, false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
     }
@@ -1155,6 +1200,11 @@
 
     @LargeTest
     public void testManifestInstallLocationFwdLockedFlagSdcard() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         installFromRawResource("install.apk", R.raw.install_loc_unspecified,
                 PackageManager.INSTALL_FORWARD_LOCK |
                 PackageManager.INSTALL_EXTERNAL, true, true,
@@ -1164,6 +1214,11 @@
 
     @LargeTest
     public void testManifestInstallLocationFwdLockedSdcard() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         installFromRawResource("install.apk", R.raw.install_loc_sdcard,
                 PackageManager.INSTALL_FORWARD_LOCK, true, false,
                 -1,
@@ -1177,6 +1232,11 @@
      */
     @LargeTest
     public void testReplaceFlagInternalSdcard() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         int iFlags = 0;
         int rFlags = PackageManager.INSTALL_EXTERNAL;
         InstallParams ip = sampleInstallFromRawResource(iFlags, false);
@@ -1199,6 +1259,11 @@
      */
     @LargeTest
     public void testReplaceFlagSdcardInternal() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         int iFlags = PackageManager.INSTALL_EXTERNAL;
         int rFlags = 0;
         InstallParams ip = sampleInstallFromRawResource(iFlags, false);
@@ -1216,6 +1281,11 @@
 
     @LargeTest
     public void testManifestInstallLocationReplaceInternalSdcard() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         int iFlags = 0;
         int iApk = R.raw.install_loc_internal;
         int rFlags = 0;
@@ -1239,6 +1309,11 @@
 
     @LargeTest
     public void testManifestInstallLocationReplaceSdcardInternal() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         int iFlags = 0;
         int iApk = R.raw.install_loc_sdcard;
         int rFlags = 0;
@@ -1471,6 +1546,11 @@
 
     @LargeTest
     public void testMoveAppInternalToExternal() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         int installFlags = PackageManager.INSTALL_INTERNAL;
         int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
         boolean fail = false;
@@ -1489,30 +1569,53 @@
 
     @LargeTest
     public void testMoveAppExternalToExternal() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         int installFlags = PackageManager.INSTALL_EXTERNAL;
         int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
         boolean fail = true;
         int result = PackageManager.MOVE_FAILED_INVALID_LOCATION;
         sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
     }
+
     @LargeTest
     public void testMoveAppExternalToInternal() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         int installFlags = PackageManager.INSTALL_EXTERNAL;
         int moveFlags = PackageManager.MOVE_INTERNAL;
         boolean fail = false;
         int result = PackageManager.MOVE_SUCCEEDED;
         sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
     }
+
     @LargeTest
     public void testMoveAppForwardLocked() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         int installFlags = PackageManager.INSTALL_FORWARD_LOCK;
         int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
         boolean fail = true;
         int result = PackageManager.MOVE_FAILED_FORWARD_LOCKED;
         sampleMoveFromRawResource(installFlags, moveFlags, fail, result);
     }
+
     @LargeTest
     public void testMoveAppFailInternalToExternalDelete() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         int installFlags = 0;
         int moveFlags = PackageManager.MOVE_EXTERNAL_MEDIA;
         boolean fail = true;
@@ -1541,12 +1644,18 @@
             setInstallLoc(origDefaultLoc);
         }
     }
+
     /*
      * Test that an install error code is returned when media is unmounted
      * and package installed on sdcard via package manager flag.
      */
     @LargeTest
     public void testInstallSdcardUnmount() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
         try {
             // Unmount sdcard
@@ -1572,6 +1681,11 @@
      */
     @LargeTest
     public void testInstallManifestSdcardUnmount() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         boolean origState = checkMediaState(Environment.MEDIA_MOUNTED);
         try {
             // Unmount sdcard
@@ -1599,71 +1713,83 @@
     * User: UserI, UserE, UserA, User suffix absent if not existing.
     *
     */
-   /*
-    * Install an app on internal flash
-    */
-   @LargeTest
-   public void testFlagI() {
-       sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
-   }
-   /*
-    * Install an app on sdcard.
-    */
-   @LargeTest
-   public void testFlagE() {
-       sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
-   }
 
-   /*
-    * Install an app on sdcard.
-    */
-   @LargeTest
-   public void testFlagF() {
-       sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
-   }
-   /*
-    * Install an app with both internal and external flags set. should fail
-    */
-   @LargeTest
-   public void testFlagIE() {
-       installFromRawResource("install.apk", R.raw.install,
-               PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
-               false,
-               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
-               PackageInfo.INSTALL_LOCATION_AUTO);
-   }
+    /*
+     * Install an app on internal flash
+     */
+    @LargeTest
+    public void testFlagI() {
+        sampleInstallFromRawResource(PackageManager.INSTALL_INTERNAL, true);
+    }
 
-   /*
-    * Install an app with both internal and external flags set. should fail
-    */
-   @LargeTest
-   public void testFlagIF() {
-       sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK |
-               PackageManager.INSTALL_INTERNAL, true);
-   }
-   /*
-    * Install an app with both internal and external flags set. should fail
-    */
-   @LargeTest
-   public void testFlagEF() {
-       installFromRawResource("install.apk", R.raw.install,
-               PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_EXTERNAL,
-               false,
-               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
-               PackageInfo.INSTALL_LOCATION_AUTO);
-   }
-   /*
-    * Install an app with both internal and external flags set. should fail
-    */
-   @LargeTest
-   public void testFlagIEF() {
-       installFromRawResource("install.apk", R.raw.install,
-               PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
-               PackageManager.INSTALL_EXTERNAL,
-               false,
-               true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
-               PackageInfo.INSTALL_LOCATION_AUTO);
-   }
+    /*
+     * Install an app on sdcard.
+     */
+    @LargeTest
+    public void testFlagE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        sampleInstallFromRawResource(PackageManager.INSTALL_EXTERNAL, true);
+    }
+
+    /*
+     * Install an app forward-locked.
+     */
+    @LargeTest
+    public void testFlagF() {
+        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK, true);
+    }
+
+    /*
+     * Install an app with both internal and external flags set. should fail
+     */
+    @LargeTest
+    public void testFlagIE() {
+        installFromRawResource("install.apk", R.raw.install,
+                PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_INTERNAL,
+                false,
+                true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
+                PackageInfo.INSTALL_LOCATION_AUTO);
+    }
+
+    /*
+     * Install an app with both internal and forward-lock flags set.
+     */
+    @LargeTest
+    public void testFlagIF() {
+        sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK
+                | PackageManager.INSTALL_INTERNAL, true);
+    }
+
+    /*
+     * Install an app with both external and forward-lock flags set. should fail
+     */
+    @LargeTest
+    public void testFlagEF() {
+        installFromRawResource("install.apk", R.raw.install,
+                PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_EXTERNAL,
+                false,
+                true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
+                PackageInfo.INSTALL_LOCATION_AUTO);
+    }
+
+    /*
+     * Install an app with both internal and external flags set with forward
+     * lock. Should fail.
+     */
+    @LargeTest
+    public void testFlagIEF() {
+        installFromRawResource("install.apk", R.raw.install,
+                PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_INTERNAL |
+                PackageManager.INSTALL_EXTERNAL,
+                false,
+                true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION,
+                PackageInfo.INSTALL_LOCATION_AUTO);
+    }
+
    /*
     * Install an app with both internal and manifest option set.
     * should install on internal.
@@ -1706,321 +1832,402 @@
     */
    @LargeTest
    public void testFlagEManifestI() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
        installFromRawResource("install.apk", R.raw.install_loc_internal,
                PackageManager.INSTALL_EXTERNAL,
                true,
                false, -1,
                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
    }
+
    /*
     * Install an app with both external and manifest preference for
     * preferExternal. Should install externally.
     */
    @LargeTest
    public void testFlagEManifestE() {
-       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
-               PackageManager.INSTALL_EXTERNAL,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
-   /*
-    * Install an app with both external and manifest preference for
-    * auto. should install on external media.
-    */
-   @LargeTest
-   public void testFlagEManifestA() {
-       installFromRawResource("install.apk", R.raw.install_loc_auto,
-               PackageManager.INSTALL_EXTERNAL,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
-   /*
-    * Install an app with fwd locked flag set and install location set to
-    * internal. should install internally.
-    */
-   @LargeTest
-   public void testFlagFManifestI() {
-       installFromRawResource("install.apk", R.raw.install_loc_internal,
-               PackageManager.INSTALL_EXTERNAL,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
-   /*
-    * Install an app with fwd locked flag set and install location set to
-    * preferExternal. should install internally.
-    */
-   @LargeTest
-   public void testFlagFManifestE() {
-       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
-               PackageManager.INSTALL_EXTERNAL,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
-   /*
-    * Install an app with fwd locked flag set and install location set to
-    * auto. should install internally.
-    */
-   @LargeTest
-   public void testFlagFManifestA() {
-       installFromRawResource("install.apk", R.raw.install_loc_auto,
-               PackageManager.INSTALL_EXTERNAL,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
-   /* The following test functions verify install location for existing apps.
-    * ie existing app can be installed internally or externally. If install
-    * flag is explicitly set it should override current location. If manifest location
-    * is set, that should over ride current location too. if not the existing install
-    * location should be honoured.
-    * testFlagI/E/F/ExistingI/E -
-    */
-   @LargeTest
-   public void testFlagIExistingI() {
-       int iFlags = PackageManager.INSTALL_INTERNAL;
-       int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install,
-               rFlags,
-               true,
-               false, -1,
-               -1);
-   }
-   @LargeTest
-   public void testFlagIExistingE() {
-       int iFlags = PackageManager.INSTALL_EXTERNAL;
-       int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install,
-               rFlags,
-               true,
-               false, -1,
-               -1);
-   }
-   @LargeTest
-   public void testFlagEExistingI() {
-       int iFlags = PackageManager.INSTALL_INTERNAL;
-       int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install,
-               rFlags,
-               true,
-               false, -1,
-               -1);
-   }
-   @LargeTest
-   public void testFlagEExistingE() {
-       int iFlags = PackageManager.INSTALL_EXTERNAL;
-       int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install,
-               rFlags,
-               true,
-               false, -1,
-               -1);
-   }
-   @LargeTest
-   public void testFlagFExistingI() {
-       int iFlags = PackageManager.INSTALL_INTERNAL;
-       int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install,
-               rFlags,
-               true,
-               false, -1,
-               -1);
-   }
-   @LargeTest
-   public void testFlagFExistingE() {
-       int iFlags = PackageManager.INSTALL_EXTERNAL;
-       int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install,
-               rFlags,
-               true,
-               false, -1,
-               -1);
-   }
-   /*
-    * The following set of tests verify the installation of apps with
-    * install location attribute set to internalOnly, preferExternal and auto.
-    * The manifest option should dictate the install location.
-    * public void testManifestI/E/A
-    * TODO out of memory fall back behaviour.
-    */
-   @LargeTest
-   public void testManifestI() {
-       installFromRawResource("install.apk", R.raw.install_loc_internal,
-               0,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
-   }
-   @LargeTest
-   public void testManifestE() {
-       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
-               0,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
-   @LargeTest
-   public void testManifestA() {
-       installFromRawResource("install.apk", R.raw.install_loc_auto,
-               0,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
-   }
-   /*
-    * The following set of tests verify the installation of apps
-    * with install location attribute set to internalOnly, preferExternal and auto
-    * for already existing apps. The manifest option should take precedence.
-    * TODO add out of memory fall back behaviour.
-    * testManifestI/E/AExistingI/E
-    */
-   @LargeTest
-   public void testManifestIExistingI() {
-       int iFlags = PackageManager.INSTALL_INTERNAL;
-       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install_loc_internal,
-               rFlags,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
-   }
-   @LargeTest
-   public void testManifestIExistingE() {
-       int iFlags = PackageManager.INSTALL_EXTERNAL;
-       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install_loc_internal,
-               rFlags,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
-   }
-   @LargeTest
-   public void testManifestEExistingI() {
-       int iFlags = PackageManager.INSTALL_INTERNAL;
-       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
-               rFlags,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
-   @LargeTest
-   public void testManifestEExistingE() {
-       int iFlags = PackageManager.INSTALL_EXTERNAL;
-       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install_loc_sdcard,
-               rFlags,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
-   @LargeTest
-   public void testManifestAExistingI() {
-       int iFlags = PackageManager.INSTALL_INTERNAL;
-       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install_loc_auto,
-               rFlags,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_AUTO);
-   }
-   @LargeTest
-   public void testManifestAExistingE() {
-       int iFlags = PackageManager.INSTALL_EXTERNAL;
-       int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
-       // First install.
-       installFromRawResource("install.apk", R.raw.install,
-               iFlags,
-               false,
-               false, -1,
-               -1);
-       // Replace now
-       installFromRawResource("install.apk", R.raw.install_loc_auto,
-               rFlags,
-               true,
-               false, -1,
-               PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+                PackageManager.INSTALL_EXTERNAL,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
+    /*
+     * Install an app with both external and manifest preference for
+     * auto. should install on external media.
+     */
+    @LargeTest
+    public void testFlagEManifestA() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        installFromRawResource("install.apk", R.raw.install_loc_auto,
+                PackageManager.INSTALL_EXTERNAL,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
+    /*
+     * Install an app with fwd locked flag set and install location set to
+     * internal. should install internally.
+     */
+    @LargeTest
+    public void testFlagFManifestI() {
+        installFromRawResource("install.apk", R.raw.install_loc_internal,
+                PackageManager.INSTALL_FORWARD_LOCK,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
+    /*
+     * Install an app with fwd locked flag set and install location set to
+     * preferExternal. should install internally.
+     */
+    @LargeTest
+    public void testFlagFManifestE() {
+        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+                PackageManager.INSTALL_FORWARD_LOCK,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
+    /*
+     * Install an app with fwd locked flag set and install location set to
+     * auto. should install internally.
+     */
+    @LargeTest
+    public void testFlagFManifestA() {
+        installFromRawResource("install.apk", R.raw.install_loc_auto,
+                PackageManager.INSTALL_FORWARD_LOCK,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
+    /* The following test functions verify install location for existing apps.
+     * ie existing app can be installed internally or externally. If install
+     * flag is explicitly set it should override current location. If manifest location
+     * is set, that should over ride current location too. if not the existing install
+     * location should be honoured.
+     * testFlagI/E/F/ExistingI/E -
+     */
+    @LargeTest
+    public void testFlagIExistingI() {
+        int iFlags = PackageManager.INSTALL_INTERNAL;
+        int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install,
+                rFlags,
+                true,
+                false, -1,
+                -1);
+    }
+
+    @LargeTest
+    public void testFlagIExistingE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int iFlags = PackageManager.INSTALL_EXTERNAL;
+        int rFlags = PackageManager.INSTALL_INTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install,
+                rFlags,
+                true,
+                false, -1,
+                -1);
+    }
+
+    @LargeTest
+    public void testFlagEExistingI() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int iFlags = PackageManager.INSTALL_INTERNAL;
+        int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install,
+                rFlags,
+                true,
+                false, -1,
+                -1);
+    }
+
+    @LargeTest
+    public void testFlagEExistingE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int iFlags = PackageManager.INSTALL_EXTERNAL;
+        int rFlags = PackageManager.INSTALL_EXTERNAL | PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install,
+                rFlags,
+                true,
+                false, -1,
+                -1);
+    }
+
+    @LargeTest
+    public void testFlagFExistingI() {
+        int iFlags = PackageManager.INSTALL_INTERNAL;
+        int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install,
+                rFlags,
+                true,
+                false, -1,
+                -1);
+    }
+
+    @LargeTest
+    public void testFlagFExistingE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int iFlags = PackageManager.INSTALL_EXTERNAL;
+        int rFlags = PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install,
+                rFlags,
+                true,
+                false, -1,
+                -1);
+    }
+
+    /*
+     * The following set of tests verify the installation of apps with
+     * install location attribute set to internalOnly, preferExternal and auto.
+     * The manifest option should dictate the install location.
+     * public void testManifestI/E/A
+     * TODO out of memory fall back behaviour.
+     */
+    @LargeTest
+    public void testManifestI() {
+        installFromRawResource("install.apk", R.raw.install_loc_internal,
+                0,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+    }
+
+    @LargeTest
+    public void testManifestE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+                0,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
+    @LargeTest
+    public void testManifestA() {
+        installFromRawResource("install.apk", R.raw.install_loc_auto,
+                0,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+    }
+
+    /*
+     * The following set of tests verify the installation of apps
+     * with install location attribute set to internalOnly, preferExternal and auto
+     * for already existing apps. The manifest option should take precedence.
+     * TODO add out of memory fall back behaviour.
+     * testManifestI/E/AExistingI/E
+     */
+    @LargeTest
+    public void testManifestIExistingI() {
+        int iFlags = PackageManager.INSTALL_INTERNAL;
+        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install_loc_internal,
+                rFlags,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+    }
+
+    @LargeTest
+    public void testManifestIExistingE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int iFlags = PackageManager.INSTALL_EXTERNAL;
+        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install_loc_internal,
+                rFlags,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+    }
+
+    @LargeTest
+    public void testManifestEExistingI() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int iFlags = PackageManager.INSTALL_INTERNAL;
+        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+                rFlags,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
+    @LargeTest
+    public void testManifestEExistingE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int iFlags = PackageManager.INSTALL_EXTERNAL;
+        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+                rFlags,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
+    @LargeTest
+    public void testManifestAExistingI() {
+        int iFlags = PackageManager.INSTALL_INTERNAL;
+        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install_loc_auto,
+                rFlags,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_AUTO);
+    }
+
+    @LargeTest
+    public void testManifestAExistingE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int iFlags = PackageManager.INSTALL_EXTERNAL;
+        int rFlags = PackageManager.INSTALL_REPLACE_EXISTING;
+        // First install.
+        installFromRawResource("install.apk", R.raw.install,
+                iFlags,
+                false,
+                false, -1,
+                -1);
+        // Replace now
+        installFromRawResource("install.apk", R.raw.install_loc_auto,
+                rFlags,
+                true,
+                false, -1,
+                PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
    /*
     * The following set of tests check install location for existing
     * application based on user setting.
@@ -2067,36 +2274,62 @@
        int iFlags = PackageManager.INSTALL_INTERNAL;
        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
    }
-   @LargeTest
-   public void testExistingIUserE() {
-       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
-       int iFlags = PackageManager.INSTALL_INTERNAL;
-       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
-   }
+
+    @LargeTest
+    public void testExistingIUserE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
+        int iFlags = PackageManager.INSTALL_INTERNAL;
+        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
+    }
+
    @LargeTest
    public void testExistingIUserA() {
        int userSetting = PackageHelper.APP_INSTALL_AUTO;
        int iFlags = PackageManager.INSTALL_INTERNAL;
        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY);
    }
-   @LargeTest
-   public void testExistingEUserI() {
-       int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
-       int iFlags = PackageManager.INSTALL_EXTERNAL;
-       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
-   @LargeTest
-   public void testExistingEUserE() {
-       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
-       int iFlags = PackageManager.INSTALL_EXTERNAL;
-       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
-   @LargeTest
-   public void testExistingEUserA() {
-       int userSetting = PackageHelper.APP_INSTALL_AUTO;
-       int iFlags = PackageManager.INSTALL_EXTERNAL;
-       setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-   }
+
+    @LargeTest
+    public void testExistingEUserI() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int userSetting = PackageHelper.APP_INSTALL_INTERNAL;
+        int iFlags = PackageManager.INSTALL_EXTERNAL;
+        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
+    @LargeTest
+    public void testExistingEUserE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
+        int iFlags = PackageManager.INSTALL_EXTERNAL;
+        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
+    @LargeTest
+    public void testExistingEUserA() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int userSetting = PackageHelper.APP_INSTALL_AUTO;
+        int iFlags = PackageManager.INSTALL_EXTERNAL;
+        setExistingXUserX(userSetting, iFlags, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
+    }
+
    /*
     * The following set of tests verify that the user setting defines
     * the install location.
@@ -2140,12 +2373,19 @@
        int iloc = getExpectedInstallLocation(userSetting);
        setUserX(true, userSetting, iloc);
    }
-   @LargeTest
-   public void testUserE() {
-       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
-       int iloc = getExpectedInstallLocation(userSetting);
-       setUserX(true, userSetting, iloc);
-   }
+
+    @LargeTest
+    public void testUserE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
+        int iloc = getExpectedInstallLocation(userSetting);
+        setUserX(true, userSetting, iloc);
+    }
+
    @LargeTest
    public void testUserA() {
        int userSetting = PackageHelper.APP_INSTALL_AUTO;
@@ -2162,12 +2402,19 @@
        int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
        setUserX(false, userSetting, iloc);
    }
-   @LargeTest
-   public void testUserPrefOffUserE() {
-       int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
-       int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
-       setUserX(false, userSetting, iloc);
-   }
+
+    @LargeTest
+    public void testUserPrefOffUserE() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
+        int userSetting = PackageHelper.APP_INSTALL_EXTERNAL;
+        int iloc = PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
+        setUserX(false, userSetting, iloc);
+    }
+
    @LargeTest
    public void testUserPrefOffA() {
        int userSetting = PackageHelper.APP_INSTALL_AUTO;
@@ -2379,6 +2626,11 @@
      */
     @LargeTest
     public void testInstallSdcardStaleContainer() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
         try {
             // Mount media first
@@ -2423,6 +2675,11 @@
      */
     @LargeTest
     public void testInstallSdcardStaleContainerReinstall() {
+        // Do not run on devices with emulated external storage.
+        if (Environment.isExternalStorageEmulated()) {
+            return;
+        }
+
         boolean origMediaState = checkMediaState(Environment.MEDIA_MOUNTED);
         try {
             // Mount media first
@@ -2458,6 +2715,7 @@
             }
         }
     }
+
     /*
      * The following series of tests are related to upgrading apps with
      * different certificates.
@@ -2846,6 +3104,7 @@
         installFromRawResource("install.apk", R.raw.install_uses_feature, 0, true, true, retCode,
                 PackageInfo.INSTALL_LOCATION_UNSPECIFIED);
     }
+
     /*---------- Recommended install location tests ----*/
     /*
      * TODO's
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index 3acf1ea..43758e7 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -66,7 +66,7 @@
     public boolean getLocalMatrix(Matrix localM) {
         if (mLocalMatrix != null) {
             localM.set(mLocalMatrix);
-            return true;
+            return !mLocalMatrix.isIdentity();
         }
         return false;
     }
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 406d09f..3563064 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -106,6 +106,32 @@
     textureCache.clearGarbage();
     gradientCache.clearGarbage();
     pathCache.clearGarbage();
+
+    Mutex::Autolock _l(mGarbageLock);
+
+    size_t count = mFboGarbage.size();
+    for (size_t i = 0; i < count; i++) {
+        GLuint fbo = mFboGarbage.itemAt(i);
+        if (fbo) glDeleteFramebuffers(1, &fbo);
+    }
+    mFboGarbage.clear();
+
+    count = mTextureGarbage.size();
+    for (size_t i = 0; i < count; i++) {
+        GLuint texture = mTextureGarbage.itemAt(i);
+        if (texture) glDeleteTextures(1, &texture);
+    }
+    mTextureGarbage.clear();
+}
+
+void Caches::deleteFboDeferred(GLuint fbo) {
+    Mutex::Autolock _l(mGarbageLock);
+    mFboGarbage.push(fbo);
+}
+
+void Caches::deleteTextureDeferred(GLuint texture) {
+    Mutex::Autolock _l(mGarbageLock);
+    mTextureGarbage.push(texture);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 318c120..34f48c9 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -90,6 +90,10 @@
     TextureVertex* mRegionMesh;
     GLuint mRegionMeshIndices;
 
+    mutable Mutex mGarbageLock;
+    Vector<GLuint> mFboGarbage;
+    Vector<GLuint> mTextureGarbage;
+
 public:
     /**
      * Indicates whether the renderer is in debug mode.
@@ -106,6 +110,16 @@
     void clearGarbage();
 
     /**
+     * Can be used to delete an FBO from a non EGL thread.
+     */
+    void deleteFboDeferred(GLuint fbo);
+
+    /**
+     * Can be used to delete a texture from a non EGL thread.
+     */
+    void deleteTextureDeferred(GLuint texture);
+
+    /**
      * Binds the VBO used to render simple textured quads.
      */
     void bindMeshBuffer();
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index a15165d..d309ade 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -116,5 +116,11 @@
     if (texture) glDeleteTextures(1, &texture);
 }
 
+void LayerRenderer::destroyLayerDeferred(GLuint fbo, GLuint texture) {
+    Caches& caches = Caches::getInstance();
+    if (fbo) caches.deleteFboDeferred(fbo);
+    if (texture) caches.deleteTextureDeferred(texture);
+}
+
 }; // namespace uirenderer
 }; // namespace android
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index a8f1ff7..800931a 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -42,6 +42,7 @@
     static void resizeLayer(GLuint fbo, GLuint texture, uint32_t width, uint32_t height,
             uint32_t* layerWidth, uint32_t* layerHeight);
     static void destroyLayer(GLuint fbo, GLuint texture);
+    static void destroyLayerDeferred(GLuint fbo, GLuint texture);
 
 private:
     GLuint mFbo;
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
index 82753b2..6b52454 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
@@ -18,6 +18,11 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.PixelFormat;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.telephony.TelephonyManager;
 import android.view.KeyEvent;
@@ -37,12 +42,34 @@
  */
 public abstract class KeyguardViewBase extends FrameLayout {
 
+    private static final int BACKGROUND_COLOR = 0x70000000;
     private KeyguardViewCallback mCallback;
     private AudioManager mAudioManager;
     private TelephonyManager mTelephonyManager = null;
 
     public KeyguardViewBase(Context context) {
         super(context);
+
+        // This is a faster way to draw the background on devices without hardware acceleration
+        setBackgroundDrawable(new Drawable() {
+            @Override
+            public void draw(Canvas canvas) {
+                canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC);
+            }
+
+            @Override
+            public void setAlpha(int alpha) {
+            }
+
+            @Override
+            public void setColorFilter(ColorFilter cf) {
+            }
+
+            @Override
+            public int getOpacity() {
+                return PixelFormat.TRANSLUCENT;
+            }
+        });
     }
 
     // used to inject callback