Merge "when corruption occurs, log a warning before closing db"
diff --git a/api/current.xml b/api/current.xml
index 4af2a43..047c25c 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -193673,6 +193673,17 @@
  visibility="public"
 >
 </method>
+<method name="getPluginState"
+ return="android.webkit.WebSettings.PluginState"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getPluginsEnabled"
  return="boolean"
  abstract="false"
@@ -193680,7 +193691,7 @@
  synchronized="true"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 </method>
@@ -194206,7 +194217,7 @@
 <parameter name="flag" type="boolean">
 </parameter>
 </method>
-<method name="setPluginsEnabled"
+<method name="setPluginState"
  return="void"
  abstract="false"
  native="false"
@@ -194216,6 +194227,19 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="state" type="android.webkit.WebSettings.PluginState">
+</parameter>
+</method>
+<method name="setPluginsEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
 <parameter name="flag" type="boolean">
 </parameter>
 </method>
@@ -194525,6 +194549,39 @@
 >
 </method>
 </class>
+<class name="WebSettings.PluginState"
+ extends="java.lang.Enum"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="valueOf"
+ return="android.webkit.WebSettings.PluginState"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="name" type="java.lang.String">
+</parameter>
+</method>
+<method name="values"
+ return="android.webkit.WebSettings.PluginState[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
 <class name="WebSettings.RenderPriority"
  extends="java.lang.Enum"
  abstract="false"
@@ -195424,7 +195481,7 @@
 </parameter>
 <parameter name="encoding" type="java.lang.String">
 </parameter>
-<parameter name="failUrl" type="java.lang.String">
+<parameter name="historyUrl" type="java.lang.String">
 </parameter>
 </method>
 <method name="loadUrl"
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index e8ab51fd..b3223e5 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -19,6 +19,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.ConfigurationInfo;
 import android.content.pm.IPackageDataObserver;
 import android.graphics.Bitmap;
@@ -859,6 +860,22 @@
     }
     
     /**
+     * Returns a list of application processes installed on external media
+     * that are running on the device.
+     *
+     * @return Returns a list of ApplicationInfo records, or null if none
+     * This list ordering is not specified.
+     * @hide
+     */
+    public List<ApplicationInfo> getRunningExternalApplications() {
+        try {
+            return ActivityManagerNative.getDefault().getRunningExternalApplications();
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
      * Returns a list of application processes that are running on the device.
      * 
      * @return Returns a list of RunningAppProcessInfo records, or null if there are no
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index adadfeb..f694285 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -491,6 +491,14 @@
             return true;
         }
 
+        case GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            List<ApplicationInfo> list = getRunningExternalApplications();
+            reply.writeNoException();
+            reply.writeTypedList(list);
+            return true;
+        }
+
         case MOVE_TASK_TO_FRONT_TRANSACTION: {
             data.enforceInterface(IActivityManager.descriptor);
             int task = data.readInt();
@@ -1716,6 +1724,19 @@
         reply.recycle();
         return list;
     }
+    public List<ApplicationInfo> getRunningExternalApplications()
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION, data, reply, 0);
+        reply.readException();
+        ArrayList<ApplicationInfo> list
+        = reply.createTypedArrayList(ApplicationInfo.CREATOR);
+        data.recycle();
+        reply.recycle();
+        return list;
+    }
     public void moveTaskToFront(int task) throws RemoteException
     {
         Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index fa6abec..a556a32 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -278,6 +278,10 @@
 
         int mClientCount = 0;
 
+        Application getApplication() {
+            return mApplication;
+        }
+
         public PackageInfo(ActivityThread activityThread, ApplicationInfo aInfo,
                 ActivityThread mainThread, ClassLoader baseLoader,
                 boolean securityViolation, boolean includeCode) {
@@ -648,7 +652,7 @@
             }
             mActivityThread.mAllApplications.add(app);
             mApplication = app;
-            
+
             if (instrumentation != null) {
                 try {
                     instrumentation.callApplicationOnCreate(app);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index f296f43..4c2b36f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -260,7 +260,8 @@
     
     @Override
     public Context getApplicationContext() {
-        return mMainThread.getApplication();
+        return (mPackageInfo != null) ?
+                mPackageInfo.getApplication() : mMainThread.getApplication();
     }
     
     @Override
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index ea0e952..31f0a63 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -262,9 +262,13 @@
      * SIGUSR1 is delivered. All others are ignored.
      */
     public void signalPersistentProcesses(int signal) throws RemoteException;
-    // Retrieve running application processes in the system
+    // Retrieve info of applications installed on external media that are currently
+    // running.
     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses()
             throws RemoteException;
+ // Retrieve running application processes in the system
+    public List<ApplicationInfo> getRunningExternalApplications()
+            throws RemoteException;
     // Get device configuration
     public ConfigurationInfo getDeviceConfigurationInfo() throws RemoteException;
     
@@ -508,4 +512,5 @@
     int START_ACTIVITY_AND_WAIT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+104;
     int WILL_ACTIVITY_BE_VISIBLE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+105;
     int START_ACTIVITY_WITH_CONFIG_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+106;
+    int GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+107;
 }
diff --git a/core/java/android/net/http/Headers.java b/core/java/android/net/http/Headers.java
index b0923d1..09f6f4f 100644
--- a/core/java/android/net/http/Headers.java
+++ b/core/java/android/net/http/Headers.java
@@ -72,6 +72,7 @@
     public final static String SET_COOKIE = "set-cookie";
     public final static String PRAGMA = "pragma";
     public final static String REFRESH = "refresh";
+    public final static String X_PERMITTED_CROSS_DOMAIN_POLICIES = "x-permitted-cross-domain-policies";
 
     // following hash are generated by String.hashCode()
     private final static int HASH_TRANSFER_ENCODING = 1274458357;
@@ -92,6 +93,7 @@
     private final static int HASH_SET_COOKIE = 1237214767;
     private final static int HASH_PRAGMA = -980228804;
     private final static int HASH_REFRESH = 1085444827;
+    private final static int HASH_X_PERMITTED_CROSS_DOMAIN_POLICIES = -1345594014;
 
     // keep any headers that require direct access in a presized
     // string array
@@ -113,8 +115,9 @@
     private final static int IDX_SET_COOKIE = 15;
     private final static int IDX_PRAGMA = 16;
     private final static int IDX_REFRESH = 17;
+    private final static int IDX_X_PERMITTED_CROSS_DOMAIN_POLICIES = 18;
 
-    private final static int HEADER_COUNT = 18;
+    private final static int HEADER_COUNT = 19;
 
     /* parsed values */
     private long transferEncoding;
@@ -141,7 +144,8 @@
         ETAG,
         SET_COOKIE,
         PRAGMA,
-        REFRESH
+        REFRESH,
+        X_PERMITTED_CROSS_DOMAIN_POLICIES
     };
 
     // Catch-all for headers not explicitly handled
@@ -287,6 +291,11 @@
                 mHeaders[IDX_REFRESH] = val;
             }
             break;
+        case HASH_X_PERMITTED_CROSS_DOMAIN_POLICIES:
+            if (name.equals(X_PERMITTED_CROSS_DOMAIN_POLICIES)) {
+                mHeaders[IDX_X_PERMITTED_CROSS_DOMAIN_POLICIES] = val;
+            }
+            break;
         default:
             mExtraHeaderNames.add(name);
             mExtraHeaderValues.add(val);
@@ -361,6 +370,10 @@
         return mHeaders[IDX_REFRESH];
     }
 
+    public String getXPermittedCrossDomainPolicies() {
+        return mHeaders[IDX_X_PERMITTED_CROSS_DOMAIN_POLICIES];
+    }
+
     public void setContentLength(long value) {
         this.contentLength = value;
     }
@@ -409,6 +422,10 @@
         mHeaders[IDX_ETAG] = value;
     }
 
+    public void setXPermittedCrossDomainPolicies(String value) {
+        mHeaders[IDX_X_PERMITTED_CROSS_DOMAIN_POLICIES] = value;
+    }
+
     public interface HeaderCallback {
         public void header(String name, String value);
     }
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 183fce3..255e317 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -28,6 +28,7 @@
  */
 public class Surface implements Parcelable {
     private static final String LOG_TAG = "Surface";
+    private static final boolean DEBUG_RELEASE = false;
     
     /* flags used in constructor (keep in sync with ISurfaceComposer.h) */
 
@@ -155,6 +156,9 @@
     // non compatibility mode.
     private Matrix mCompatibleMatrix;
 
+    @SuppressWarnings("unused")
+    private Exception mCreationStack;
+
     /**
      * Exception thrown when a surface couldn't be created or resized
      */
@@ -181,6 +185,9 @@
     public Surface(SurfaceSession s,
             int pid, int display, int w, int h, int format, int flags)
         throws OutOfResourcesException {
+        if (DEBUG_RELEASE) {
+            mCreationStack = new Exception();
+        }
         mCanvas = new CompatibleCanvas();
         init(s,pid,null,display,w,h,format,flags);
     }
@@ -192,6 +199,9 @@
     public Surface(SurfaceSession s,
             int pid, String name, int display, int w, int h, int format, int flags)
         throws OutOfResourcesException {
+        if (DEBUG_RELEASE) {
+            mCreationStack = new Exception();
+        }
         mCanvas = new CompatibleCanvas();
         init(s,pid,name,display,w,h,format,flags);
     }
@@ -202,6 +212,9 @@
      * {@hide}
      */
     public Surface() {
+        if (DEBUG_RELEASE) {
+            mCreationStack = new Exception();
+        }
         mCanvas = new CompatibleCanvas();
     }
 
@@ -407,6 +420,15 @@
     /* no user serviceable parts here ... */
     @Override
     protected void finalize() throws Throwable {
+        if (mSurface != 0 || mSurfaceControl != 0) {
+            if (DEBUG_RELEASE) {
+                Log.w(LOG_TAG, "Surface.finalize() has work. You should have called release() (" 
+                        + mSurface + ", " + mSurfaceControl + ")", mCreationStack);
+            } else {
+                Log.w(LOG_TAG, "Surface.finalize() has work. You should have called release() (" 
+                        + mSurface + ", " + mSurfaceControl + ")");
+            }
+        }
         release();
     }
     
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index c44854a..7f7d207 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -422,7 +422,7 @@
                 if (visibleChanged && (!visible || mNewSurfaceNeeded)) {
                     reportSurfaceDestroyed();
                 }
-                
+
                 mNewSurfaceNeeded = false;
                 
                 mSurfaceLock.lock();
@@ -470,6 +470,8 @@
                                 c.surfaceChanged(mSurfaceHolder, mFormat, mWidth, mHeight);
                             }
                         }
+                    } else {
+                        mSurface.release();
                     }
                 } finally {
                     mIsCreating = false;
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 9df8ac3..74943f3 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -1500,8 +1500,10 @@
                         focus.getFocusedRect(mTempRect);
                         if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Focus " + focus
                                 + ": focusRect=" + mTempRect.toShortString());
-                        ((ViewGroup) mView).offsetDescendantRectToMyCoords(
-                                focus, mTempRect);
+                        if (mView instanceof ViewGroup) {
+                            ((ViewGroup) mView).offsetDescendantRectToMyCoords(
+                                    focus, mTempRect);
+                        }
                         if (DEBUG_INPUT_RESIZE) Log.v(TAG,
                                 "Focus in window: focusRect="
                                 + mTempRect.toShortString()
@@ -2491,8 +2493,12 @@
                                 // of previous focused into the coord system of
                                 // newly focused view
                                 focused.getFocusedRect(mTempRect);
-                                ((ViewGroup) mView).offsetDescendantRectToMyCoords(focused, mTempRect);
-                                ((ViewGroup) mView).offsetRectIntoDescendantCoords(v, mTempRect);
+                                if (mView instanceof ViewGroup) {
+                                    ((ViewGroup) mView).offsetDescendantRectToMyCoords(
+                                            focused, mTempRect);
+                                    ((ViewGroup) mView).offsetRectIntoDescendantCoords(
+                                            v, mTempRect);
+                                }
                                 focusPassed = v.requestFocus(direction, mTempRect);
                             }
 
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 344b390..6983d9f 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -213,21 +213,19 @@
 
     /**
      * Load the content as if it was loaded by the provided base URL. The
-     * failUrl is used as the history entry for the load data. If null or
-     * an empty string is passed for the failUrl, then no history entry is
-     * created.
+     * historyUrl is used as the history entry for the load data.
      * 
      * @param baseUrl Base URL used to resolve relative paths in the content
      * @param data Content to render in the browser
      * @param mimeType Mimetype of the data being passed in
      * @param encoding Character set encoding of the provided data.
-     * @param failUrl URL to use if the content fails to load or null.
+     * @param historyUrl URL to use as the history entry.
      */
     public void loadData(String baseUrl, String data, String mimeType,
-            String encoding, String failUrl) {
+            String encoding, String historyUrl) {
         mLoadInitFromJava = true;
-        if (failUrl == null) {
-            failUrl = "";
+        if (historyUrl == null || historyUrl.length() == 0) {
+            historyUrl = "about:blank";
         }
         if (data == null) {
             data = "";
@@ -241,7 +239,7 @@
         if (mimeType == null || mimeType.length() == 0) {
             mimeType = "text/html";
         }
-        nativeLoadData(baseUrl, data, mimeType, encoding, failUrl);
+        nativeLoadData(baseUrl, data, mimeType, encoding, historyUrl);
         mLoadInitFromJava = false;
     }
 
@@ -916,7 +914,7 @@
     private native void nativePostUrl(String url, byte[] postData);
 
     private native void nativeLoadData(String baseUrl, String data,
-            String mimeType, String encoding, String failUrl);
+            String mimeType, String encoding, String historyUrl);
 
     /**
      * Stop loading the current page.
diff --git a/core/java/android/webkit/CacheLoader.java b/core/java/android/webkit/CacheLoader.java
index aeb537c..05c02b0 100644
--- a/core/java/android/webkit/CacheLoader.java
+++ b/core/java/android/webkit/CacheLoader.java
@@ -67,5 +67,9 @@
         if (!TextUtils.isEmpty(mCacheResult.contentdisposition)) {
             headers.setContentDisposition(mCacheResult.contentdisposition);
         }
+
+        if (!TextUtils.isEmpty(mCacheResult.crossDomain)) {
+            headers.setXPermittedCrossDomainPolicies(mCacheResult.crossDomain);
+        }
     }
 }
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index 4f680e5..d19805e 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -99,6 +99,7 @@
         String location;
         String encoding;
         String contentdisposition;
+        String crossDomain;
 
         // these fields are NOT saved to the database
         InputStream inStream;
@@ -733,6 +734,11 @@
             ret.contentdisposition = contentDisposition;
         }
 
+        String crossDomain = headers.getXPermittedCrossDomainPolicies();
+        if (crossDomain != null) {
+            ret.crossDomain = crossDomain;
+        }
+
         // lastModified and etag may be set back to http header. So they can't
         // be empty string.
         String lastModified = headers.getLastModified();
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index d1da5ea..1b801d4 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -120,6 +120,21 @@
         LOW
     }
 
+    /**
+     * The plugin state effects how plugins are treated on a page. ON means
+     * that any object will be loaded even if a plugin does not exist to handle
+     * the content. ON_DEMAND means that if there is a plugin installed that
+     * can handle the content, a placeholder is shown until the user clicks on
+     * the placeholder. Once clicked, the plugin will be enabled on the page.
+     * OFF means that all plugins will be turned off and any fallback content
+     * will be used.
+     */
+    public enum PluginState {
+        ON,
+        ON_DEMAND,
+        OFF
+    }
+
     // WebView associated with this WebSettings.
     private WebView mWebView;
     // BrowserFrame used to access the native frame pointer.
@@ -157,7 +172,7 @@
     private boolean         mBlockNetworkImage = false;
     private boolean         mBlockNetworkLoads;
     private boolean         mJavaScriptEnabled = false;
-    private boolean         mPluginsEnabled = false;
+    private PluginState     mPluginState = PluginState.OFF;
     private boolean         mJavaScriptCanOpenWindowsAutomatically = false;
     private boolean         mUseDoubleTree = false;
     private boolean         mUseWideViewport = false;
@@ -1011,10 +1026,23 @@
     /**
      * Tell the WebView to enable plugins.
      * @param flag True if the WebView should load plugins.
+     * @deprecated This method has been deprecated in favor of
+     *             {@link #setPluginState}
      */
     public synchronized void setPluginsEnabled(boolean flag) {
-        if (mPluginsEnabled != flag) {
-            mPluginsEnabled = flag;
+        setPluginState(PluginState.ON);
+    }
+
+    /**
+     * Tell the WebView to enable, disable, or have plugins on demand. On
+     * demand mode means that if a plugin exists that can handle the embedded
+     * content, a placeholder icon will be shown instead of the plugin. When
+     * the placeholder is clicked, the plugin will be enabled.
+     * @param state One of the PluginState values.
+     */
+    public synchronized void setPluginState(PluginState state) {
+        if (mPluginState != state) {
+            mPluginState = state;
             postSync();
         }
     }
@@ -1176,9 +1204,18 @@
     /**
      * Return true if plugins are enabled.
      * @return True if plugins are enabled.
+     * @deprecated This method has been replaced by {@link #getPluginState}
      */
     public synchronized boolean getPluginsEnabled() {
-        return mPluginsEnabled;
+        return mPluginState == PluginState.ON;
+    }
+
+    /**
+     * Return the current plugin state.
+     * @return A value corresponding to the enum PluginState.
+     */
+    public synchronized PluginState getPluginState() {
+        return mPluginState;
     }
 
     /**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index f886eef..6722bc6 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1483,10 +1483,8 @@
     /**
      * Load the given data into the WebView, use the provided URL as the base
      * URL for the content. The base URL is the URL that represents the page
-     * that is loaded through this interface. As such, it is used for the
-     * history entry and to resolve any relative URLs. The failUrl is used if
-     * browser fails to load the data provided. If it is empty or null, and the
-     * load fails, then no history entry is created.
+     * that is loaded through this interface. As such, it is used to resolve any
+     * relative URLs. The historyUrl is used for the history entry.
      * <p>
      * Note for post 1.0. Due to the change in the WebKit, the access to asset
      * files through "file:///android_asset/" for the sub resources is more
@@ -1501,10 +1499,10 @@
      * @param mimeType The MIMEType of the data. i.e. text/html. If null,
      *            defaults to "text/html"
      * @param encoding The encoding of the data. i.e. utf-8, us-ascii
-     * @param failUrl URL to use if the content fails to load or null.
+     * @param historyUrl URL to use as the history entry.  Can be null.
      */
     public void loadDataWithBaseURL(String baseUrl, String data,
-            String mimeType, String encoding, String failUrl) {
+            String mimeType, String encoding, String historyUrl) {
 
         if (baseUrl != null && baseUrl.toLowerCase().startsWith("data:")) {
             loadData(data, mimeType, encoding);
@@ -1516,7 +1514,7 @@
         arg.mData = data;
         arg.mMimeType = mimeType;
         arg.mEncoding = encoding;
-        arg.mFailUrl = failUrl;
+        arg.mHistoryUrl = historyUrl;
         mWebViewCore.sendMessage(EventHub.LOAD_DATA, arg);
         clearTextEntry(false);
     }
@@ -1668,7 +1666,7 @@
         }
         nativeClearCursor(); // start next trackball movement from page edge
         if (bottom) {
-            return pinScrollTo(mScrollX, computeVerticalScrollRange(), true, 0);
+            return pinScrollTo(mScrollX, computeRealVerticalScrollRange(), true, 0);
         }
         // Page down.
         int h = getHeight();
@@ -1907,7 +1905,7 @@
     private int pinLocY(int y) {
         if (mInOverScrollMode) return y;
         return pinLoc(y, getViewHeightWithTitle(),
-                      computeVerticalScrollRange() + getTitleHeight());
+                      computeRealVerticalScrollRange() + getTitleHeight());
     }
 
     /**
@@ -2258,8 +2256,7 @@
         return false;
     }
 
-    @Override
-    protected int computeHorizontalScrollRange() {
+    private int computeRealHorizontalScrollRange() {
         if (mDrawHistory) {
             return mHistoryWidth;
         } else {
@@ -2269,7 +2266,27 @@
     }
 
     @Override
-    protected int computeVerticalScrollRange() {
+    protected int computeHorizontalScrollRange() {
+        int range = computeRealHorizontalScrollRange();
+
+        // Adjust reported range if overscrolled to compress the scroll bars
+        final int scrollX = mScrollX;
+        final int overscrollRight = computeMaxScrollX();
+        if (scrollX < 0) {
+            range -= scrollX;
+        } else if (scrollX > overscrollRight) {
+            range += scrollX - overscrollRight;
+        }
+
+        return range;
+    }
+
+    @Override
+    protected int computeHorizontalScrollOffset() {
+        return Math.max(mScrollX, 0);
+    }
+
+    private int computeRealVerticalScrollRange() {
         if (mDrawHistory) {
             return mHistoryHeight;
         } else {
@@ -2279,6 +2296,22 @@
     }
 
     @Override
+    protected int computeVerticalScrollRange() {
+        int range = computeRealVerticalScrollRange();
+
+        // Adjust reported range if overscrolled to compress the scroll bars
+        final int scrollY = mScrollY;
+        final int overscrollBottom = computeMaxScrollY();
+        if (scrollY < 0) {
+            range -= scrollY;
+        } else if (scrollY > overscrollBottom) {
+            range += scrollY - overscrollBottom;
+        }
+
+        return range;
+    }
+
+    @Override
     protected int computeVerticalScrollOffset() {
         return Math.max(mScrollY - getTitleHeight(), 0);
     }
@@ -3134,14 +3167,14 @@
             canvas.save();
             canvas.translate(mScrollX, mScrollY);
             canvas.clipRect(-mScrollX, top - mScrollY,
-                    computeHorizontalScrollRange() - mScrollX, top
-                            + computeVerticalScrollRange() - mScrollY,
+                    computeRealHorizontalScrollRange() - mScrollX, top
+                            + computeRealVerticalScrollRange() - mScrollY,
                     Region.Op.DIFFERENCE);
             canvas.drawPaint(mOverScrollBackground);
             canvas.restore();
             // next clip the region for the content
-            canvas.clipRect(0, top, computeHorizontalScrollRange(), top
-                    + computeVerticalScrollRange());
+            canvas.clipRect(0, top, computeRealHorizontalScrollRange(), top
+                    + computeRealVerticalScrollRange());
         }
         if (mTitleBar != null) {
             canvas.translate(0, (int) mTitleBar.getHeight());
@@ -4272,7 +4305,7 @@
         public DragTrackerHandler(float x, float y, DragTracker proxy) {
             mProxy = proxy;
 
-            int docBottom = computeVerticalScrollRange() + getTitleHeight();
+            int docBottom = computeRealVerticalScrollRange() + getTitleHeight();
             int viewTop = getScrollY();
             int viewBottom = viewTop + getHeight();
 
@@ -5364,11 +5397,11 @@
     }
 
     private int computeMaxScrollX() {
-        return Math.max(computeHorizontalScrollRange() - getViewWidth(), 0);
+        return Math.max(computeRealHorizontalScrollRange() - getViewWidth(), 0);
     }
 
     private int computeMaxScrollY() {
-        return Math.max(computeVerticalScrollRange() + getTitleHeight()
+        return Math.max(computeRealVerticalScrollRange() + getTitleHeight()
                 - getViewHeightWithTitle(), 0);
     }
 
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 4e949dc..410227b 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -627,7 +627,7 @@
         String mData;
         String mMimeType;
         String mEncoding;
-        String mFailUrl;
+        String mHistoryUrl;
     }
 
     static class CursorData {
@@ -981,7 +981,7 @@
                                     loadParams.mData,
                                     loadParams.mMimeType,
                                     loadParams.mEncoding,
-                                    loadParams.mFailUrl);
+                                    loadParams.mHistoryUrl);
                             break;
 
                         case STOP_LOADING:
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index a75e6f0..b18419d 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -51,9 +51,10 @@
     // 7 -> 8 Move cache to its own db
     // 8 -> 9 Store both scheme and host when storing passwords
     // 9 -> 10 Update httpauth table UNIQUE
-    private static final int CACHE_DATABASE_VERSION = 3;
+    private static final int CACHE_DATABASE_VERSION = 4;
     // 1 -> 2 Add expires String
     // 2 -> 3 Add content-disposition
+    // 3 -> 4 Add crossdomain (For x-permitted-cross-domain-policies header)
 
     private static WebViewDatabase mInstance = null;
 
@@ -126,6 +127,8 @@
 
     private static final String CACHE_CONTENTDISPOSITION_COL = "contentdisposition";
 
+    private static final String CACHE_CROSSDOMAIN_COL = "crossdomain";
+
     // column id strings for "password" table
     private static final String PASSWORD_HOST_COL = "host";
 
@@ -166,6 +169,7 @@
     private static int mCacheLocationColIndex;
     private static int mCacheContentLengthColIndex;
     private static int mCacheContentDispositionColIndex;
+    private static int mCacheCrossDomainColIndex;
 
     private static int mCacheTransactionRefcount;
 
@@ -269,6 +273,8 @@
                         .getColumnIndex(CACHE_CONTENTLENGTH_COL);
                 mCacheContentDispositionColIndex = mCacheInserter
                         .getColumnIndex(CACHE_CONTENTDISPOSITION_COL);
+                mCacheCrossDomainColIndex = mCacheInserter
+                        .getColumnIndex(CACHE_CROSSDOMAIN_COL);
             }
         }
 
@@ -378,6 +384,7 @@
                     + " TEXT," + CACHE_HTTP_STATUS_COL + " INTEGER, "
                     + CACHE_LOCATION_COL + " TEXT, " + CACHE_CONTENTLENGTH_COL
                     + " INTEGER, " + CACHE_CONTENTDISPOSITION_COL + " TEXT, "
+                    + CACHE_CROSSDOMAIN_COL + " TEXT,"
                     + " UNIQUE (" + CACHE_URL_COL + ") ON CONFLICT REPLACE);");
             mCacheDatabase.execSQL("CREATE INDEX cacheUrlIndex ON cache ("
                     + CACHE_URL_COL + ")");
@@ -620,7 +627,7 @@
         Cursor cursor = null;
         final String query = "SELECT filepath, lastmodify, etag, expires, "
                 + "expiresstring, mimetype, encoding, httpstatus, location, contentlength, "
-                + "contentdisposition FROM cache WHERE url = ?";
+                + "contentdisposition, crossdomain FROM cache WHERE url = ?";
         try {
             cursor = mCacheDatabase.rawQuery(query, new String[] { url });
             if (cursor.moveToFirst()) {
@@ -636,6 +643,7 @@
                 ret.location = cursor.getString(8);
                 ret.contentLength = cursor.getLong(9);
                 ret.contentdisposition = cursor.getString(10);
+                ret.crossDomain = cursor.getString(11);
                 return ret;
             }
         } catch (IllegalStateException e) {
@@ -684,6 +692,7 @@
         mCacheInserter.bind(mCacheContentLengthColIndex, c.contentLength);
         mCacheInserter.bind(mCacheContentDispositionColIndex,
                 c.contentdisposition);
+        mCacheInserter.bind(mCacheCrossDomainColIndex, c.crossDomain);
         mCacheInserter.execute();
     }
 
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index eb2da71..e15a520 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -92,6 +92,13 @@
 
     private static final int HINT_VIEW_ID = 0x17;
 
+    /**
+     * This value controls the length of time that the user
+     * must leave a pointer down without scrolling to expand
+     * the autocomplete dropdown list to cover the IME.
+     */
+    private static final int EXPAND_LIST_TIMEOUT = 250;
+
     private CharSequence mHintText;
     private int mHintResource;
 
@@ -132,6 +139,7 @@
 
     private ListSelectorHider mHideSelector;
     private Runnable mShowDropDownRunnable;
+    private Runnable mResizePopupRunnable = new ResizePopupRunnable();
 
     private PassThroughClickListener mPassThroughClickListener;
     private PopupDataSetObserver mObserver;
@@ -1297,6 +1305,7 @@
                 public void onNothingSelected(AdapterView<?> parent) {
                 }
             });
+            mDropDownList.setOnScrollListener(new PopupScrollListener());
 
             if (mItemSelectedListener != null) {
                 mDropDownList.setOnItemSelectedListener(mItemSelectedListener);
@@ -1437,17 +1446,41 @@
         }
     }
 
+    private class ResizePopupRunnable implements Runnable {
+        public void run() {
+            mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
+            showDropDown();
+        }
+    }
+
     private class PopupTouchInterceptor implements OnTouchListener {
         public boolean onTouch(View v, MotionEvent event) {
-            if (event.getAction() == MotionEvent.ACTION_DOWN &&
+            final int action = event.getAction();
+            if (action == MotionEvent.ACTION_DOWN &&
                     mPopup != null && mPopup.isShowing()) {
-                mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
-                showDropDown();
+                postDelayed(mResizePopupRunnable, EXPAND_LIST_TIMEOUT);
+            } else if (action == MotionEvent.ACTION_UP) {
+                removeCallbacks(mResizePopupRunnable);
             }
             return false;
         }
     }
     
+    private class PopupScrollListener implements ListView.OnScrollListener {
+        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+                int totalItemCount) {
+
+        }
+
+        public void onScrollStateChanged(AbsListView view, int scrollState) {
+            if (scrollState == SCROLL_STATE_TOUCH_SCROLL &&
+                    !isInputMethodNotNeeded() && mPopup.getContentView() != null) {
+                removeCallbacks(mResizePopupRunnable);
+                mResizePopupRunnable.run();
+            }
+        }
+    }
+
     private class DropDownItemClickListener implements AdapterView.OnItemClickListener {
         public void onItemClick(AdapterView parent, View v, int position, long id) {
             performCompletion(v, position, id);
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index 3dab9f2..6b845b0 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -206,7 +206,12 @@
         if (format == null || "".equals(format)) {
             return DateFormat.getDateInstance(DateFormat.SHORT);
         } else {
-            return new SimpleDateFormat(format);
+            try {
+                return new SimpleDateFormat(format);
+            } catch (IllegalArgumentException e) {
+                // If we tried to use a bad format string, fall back to a default.
+                return DateFormat.getDateInstance(DateFormat.SHORT);
+            }
         }
     }
 
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 239c5f4..f009432 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -573,6 +573,7 @@
         } else {
             super.scrollTo(scrollX, scrollY);
         }
+        awakenScrollBars();
     }
     
     private int getOverscrollMax() {
@@ -1297,7 +1298,6 @@
                 mScrollViewMovedFocus = false;
             }
     
-            awakenScrollBars(mScroller.getDuration());
             invalidate();
         }
     }
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index b6f3997..b41bad0 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -164,8 +164,11 @@
 using namespace android;
 
 class NinePatchPeeker : public SkImageDecoder::Peeker {
+    SkImageDecoder* fHost;
 public:
-    NinePatchPeeker() {
+    NinePatchPeeker(SkImageDecoder* host) {
+        // the host lives longer than we do, so a raw ptr is safe
+        fHost = host;
         fPatchIsValid = false;
     }
 
@@ -197,6 +200,19 @@
             //       fPatch.sizeLeft, fPatch.sizeTop,
             //       fPatch.sizeRight, fPatch.sizeBottom);
             fPatchIsValid = true;
+
+            // now update our host to force index or 32bit config
+            // 'cause we don't want 565 predithered, since as a 9patch, we know
+            // we will be stretched, and therefore we want to dither afterwards.
+            static const SkBitmap::Config gNo565Pref[] = {
+                SkBitmap::kIndex8_Config,
+                SkBitmap::kIndex8_Config,
+                SkBitmap::kARGB_8888_Config,
+                SkBitmap::kARGB_8888_Config,
+                SkBitmap::kARGB_8888_Config,
+                SkBitmap::kARGB_8888_Config,
+            };
+            fHost->setPrefConfigTable(gNo565Pref);
         } else {
             fPatch = NULL;
         }
@@ -364,7 +380,7 @@
     decoder->setSampleSize(sampleSize);
     decoder->setDitherImage(doDither);
 
-    NinePatchPeeker     peeker;
+    NinePatchPeeker     peeker(decoder);
     JavaPixelAllocator  javaAllocator(env, reportSizeToVM);
     SkBitmap*           bitmap = new SkBitmap;
     Res_png_9patch      dummy9Patch;
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 060ca50..ed26cbe 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -35,6 +35,11 @@
 
 namespace android {
 
+enum {
+    // should match Parcelable.java
+    PARCELABLE_WRITE_RETURN_VALUE = 0x0001
+};
+
 // ----------------------------------------------------------------------------
 
 static const char* const OutOfResourcesException =
@@ -612,6 +617,9 @@
 
     const sp<SurfaceControl>& control(getSurfaceControl(env, clazz));
     SurfaceControl::writeSurfaceToParcel(control, parcel);
+    if (flags & PARCELABLE_WRITE_RETURN_VALUE) {
+        setSurfaceControl(env, clazz, 0);
+    }
 }
 
 // ----------------------------------------------------------------------------
diff --git a/core/res/assets/webkit/togglePlugin.png b/core/res/assets/webkit/togglePlugin.png
new file mode 100644
index 0000000..008333c
--- /dev/null
+++ b/core/res/assets/webkit/togglePlugin.png
Binary files differ
diff --git a/core/res/assets/webkit/togglePluginBg.png b/core/res/assets/webkit/togglePluginBg.png
new file mode 100644
index 0000000..2c65acb
--- /dev/null
+++ b/core/res/assets/webkit/togglePluginBg.png
Binary files differ
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/ConnectivityManagerTest/Android.mk
similarity index 94%
rename from tests/ConnectivityManagerTest/Android.mk
rename to core/tests/ConnectivityManagerTest/Android.mk
index bd773d0..a1546fa 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/ConnectivityManagerTest/Android.mk
@@ -1,4 +1,4 @@
-# Copyright 2010, The Android Open Source Project
+# 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.
diff --git a/tests/ConnectivityManagerTest/AndroidManifest.xml b/core/tests/ConnectivityManagerTest/AndroidManifest.xml
similarity index 100%
rename from tests/ConnectivityManagerTest/AndroidManifest.xml
rename to core/tests/ConnectivityManagerTest/AndroidManifest.xml
diff --git a/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
similarity index 94%
rename from tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
rename to core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
index 1dffa02..badcc1b 100644
--- a/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java
@@ -1,3 +1,19 @@
+/*
+ * 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 com.android.connectivitymanagertest;
 
 import android.app.Activity;
diff --git a/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
similarity index 62%
rename from tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
rename to core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
index 3affa65..592be92 100644
--- a/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
@@ -1,3 +1,19 @@
+/*
+ * 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 com.android.connectivitymanagertest;
 
 import android.os.Bundle;
@@ -13,7 +29,7 @@
  *
  * To run the connectivity manager tests:
  *
- * adb shell am instrument \
+ * adb shell am instrument -e ssid <ssid> \
  *     -w com.android.connectivitymanagertest/.ConnectivityManagerTestRunner
  */
 
@@ -39,5 +55,5 @@
         }
     }
 
-    public String TEST_SSID = "GoogleGuest";
+    public String TEST_SSID = null;
 }
diff --git a/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
similarity index 91%
rename from tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
rename to core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
index 925120e..2e5a0f8 100644
--- a/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/NetworkState.java
@@ -1,3 +1,19 @@
+/*
+ * 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 com.android.connectivitymanagertest;
 
 import android.net.NetworkInfo.State;
diff --git a/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
similarity index 88%
rename from tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
rename to core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
index ab81bb8..ad564ae 100644
--- a/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java
@@ -1,3 +1,21 @@
+/*
+ * 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 com.android.connectivitymanagertest.functional;
 
 import com.android.connectivitymanagertest.ConnectivityManagerTestActivity;
@@ -86,7 +104,7 @@
             Log.v(LOG_TAG, "the state for WIFI is changed");
             Log.v(LOG_TAG, "reason: " +
                     cmActivity.getTransitionFailureReason(ConnectivityManager.TYPE_WIFI));
-            assertTrue(false);
+            assertTrue("state validation fail", false);
         }
         if (!cmActivity.validateNetworkStates(ConnectivityManager.TYPE_MOBILE)) {
             Log.v(LOG_TAG, "the state for MOBILE is changed");
@@ -101,6 +119,7 @@
     // Test case 2: test connection to a given AP
     @LargeTest
     public void testConnectToWifi() {
+        assertNotNull("SSID is null", TEST_ACCESS_POINT);
         //Prepare for connectivity verification
         NetworkInfo networkInfo = cmActivity.mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
         cmActivity.setStateTransitionCriteria(ConnectivityManager.TYPE_MOBILE, networkInfo.getState(),
diff --git a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
index 9c9d777..ca0094e 100644
--- a/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
+++ b/core/tests/hosttests/src/android/content/pm/PackageManagerHostTests.java
@@ -16,6 +16,7 @@
 
 package android.content.pm;
 
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.IShellOutputReceiver;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.MultiLineReceiver;
@@ -35,17 +36,56 @@
  */
 public class PackageManagerHostTests extends DeviceTestCase {
 
+    private static final String LOG_TAG = "PackageManagerHostTests";
+
+    // TODO: get this value from Android Environment instead of hardcoding
+    private static final String APP_PRIVATE_PATH = "/data/app-private/";
+    private static final String DEVICE_APP_PATH = "/data/app/";
+    private static final String SDCARD_APP_PATH = "/mnt/secure/asec/";
+
+    private static final int MAX_WAIT_FOR_DEVICE_TIME = 120 * 1000;
+    private static final int WAIT_FOR_DEVICE_POLL_TIME = 10 * 1000;
+
+    // Various test files and their corresponding package names...
+
     // testPushAppPrivate constants
     // these constants must match values defined in test-apps/SimpleTestApp
     private static final String SIMPLE_APK = "SimpleTestApp.apk";
     private static final String SIMPLE_PKG = "com.android.framework.simpletestapp";
-    // TODO: get this value from Android Environment instead of hardcoding
-    private static final String APP_PRIVATE_PATH = "/data/app-private/";
 
-    private static final String LOG_TAG = "PackageManagerHostTests";
-
-    private static final int MAX_WAIT_FOR_DEVICE_TIME = 120 * 1000;
-    private static final int WAIT_FOR_DEVICE_POLL_TIME = 10 * 1000;
+    // Apk with install location set to auto
+    private static final String AUTO_LOC_APK = "AutoLocTestApp.apk";
+    private static final String AUTO_LOC_PKG = "com.android.framework.autoloctestapp";
+    // Apk with install location set to internalOnly
+    private static final String INTERNAL_LOC_APK = "InternalLocTestApp.apk";
+    private static final String INTERNAL_LOC_PKG = "com.android.framework.internalloctestapp";
+    // Apk with install location set to preferExternal
+    private static final String EXTERNAL_LOC_APK = "ExternalLocTestApp.apk";
+    private static final String EXTERNAL_LOC_PKG = "com.android.framework.externalloctestapp";
+    // Apk with no install location set
+    private static final String NO_LOC_APK = "NoLocTestApp.apk";
+    private static final String NO_LOC_PKG = "com.android.framework.noloctestapp";
+    // Apk with 2 different versions - v1 is set to external, v2 has no location setting
+    private static final String UPDATE_EXTERNAL_LOC_V1_EXT_APK
+            = "UpdateExternalLocTestApp_v1_ext.apk";
+    private static final String UPDATE_EXTERNAL_LOC_V2_NONE_APK
+            = "UpdateExternalLocTestApp_v2_none.apk";
+    private static final String UPDATE_EXTERNAL_LOC_PKG
+            = "com.android.framework.updateexternalloctestapp";
+    // Apk with 2 different versions - v1 is set to external, v2 is set to internalOnly
+    private static final String UPDATE_EXT_TO_INT_LOC_V1_EXT_APK
+            = "UpdateExtToIntLocTestApp_v1_ext.apk";
+    private static final String UPDATE_EXT_TO_INT_LOC_V2_INT_APK
+            = "UpdateExtToIntLocTestApp_v2_int.apk";
+    private static final String UPDATE_EXT_TO_INT_LOC_PKG
+            = "com.android.framework.updateexttointloctestapp";
+    // Apks with the same package name, but install location set to
+    // one of: Internal, External, Auto, or None
+    private static final String VERSATILE_LOC_PKG = "com.android.framework.versatiletestapp";
+    private static final String VERSATILE_LOC_INTERNAL_APK = "VersatileTestApp_Internal.apk";
+    private static final String VERSATILE_LOC_EXTERNAL_APK = "VersatileTestApp_External.apk";
+    private static final String VERSATILE_LOC_AUTO_APK = "VersatileTestApp_Auto.apk";
+    private static final String VERSATILE_LOC_NONE_APK = "VersatileTestApp_None.apk";
 
     @Override
     protected void setUp() throws Exception {
@@ -94,6 +134,18 @@
     }
 
     /**
+     * Helper method to install a file to device
+     * @param localFilePath the absolute file system path to file on local host to install
+     * @param reinstall set to <code>true</code> if re-install of app should be performed
+     * @throws IOException
+     */
+    private void installFile(final String localFilePath, final boolean replace)
+            throws IOException {
+        String result = getDevice().installPackage(localFilePath, replace);
+        assertEquals(null, result);
+    }
+
+    /**
      * Helper method to determine if file on device exists.
      *
      * @param destPath the absolute path of file on device to check
@@ -107,6 +159,21 @@
     }
 
     /**
+     * Helper method to determine if file exists on the device containing a given string.
+     *
+     * @param destPath the
+     * @return <code>true</code> if file exists containing given string,
+     *         <code>false</code> otherwise.
+     * @throws IOException if adb shell command failed
+     */
+    private boolean doesRemoteFileExistContainingString(String destPath, String searchString)
+            throws IOException {
+        String lsResult = executeShellCommand(String.format("ls %s",
+                destPath));
+        return lsResult.contains(searchString);
+    }
+
+    /**
      * Helper method to determine if package on device exists.
      *
      * @param packageName the Android manifest package to check.
@@ -120,6 +187,28 @@
     }
 
     /**
+     * Helper method to determine if app was installed on device.
+     *
+     * @param packageName package name to check for
+     * @return <code>true</code> if file exists, <code>false</code> otherwise.
+     * @throws IOException if adb shell command failed
+     */
+    private boolean doesAppExistOnDevice(String packageName) throws IOException {
+        return doesRemoteFileExistContainingString(DEVICE_APP_PATH, packageName);
+    }
+
+    /**
+     * Helper method to determine if app was installed on SD card.
+     *
+     * @param packageName package name to check for
+     * @return <code>true</code> if file exists, <code>false</code> otherwise.
+     * @throws IOException if adb shell command failed
+     */
+    private boolean doesAppExistOnSDCard(String packageName) throws IOException {
+        return doesRemoteFileExistContainingString(SDCARD_APP_PATH, packageName);
+    }
+
+    /**
      * Waits for device's package manager to respond.
      *
      * @throws InterruptedException
@@ -213,4 +302,218 @@
             // ignore
         }
     }
+
+    /**
+     * Helper method for installing an app to wherever is specified in its manifest, and
+     * then verifying the app was installed onto SD Card.
+     * <p/>
+     * Assumes adb is running as root in device under test.
+     */
+    void installAppAndVerifyExistsOnSDCard(String apkName, String pkgName, boolean overwrite)
+            throws IOException, InterruptedException {
+        // Start with a clean slate if we're not overwriting
+        if (!overwrite) {
+            // cleanup test app just in case it already exists
+            getDevice().uninstallPackage(pkgName);
+            // grep for package to make sure its not installed
+            assertFalse(doesPackageExist(pkgName));
+        }
+
+        installFile(getTestAppFilePath(apkName), overwrite);
+        assertTrue(doesAppExistOnSDCard(pkgName));
+        assertFalse(doesAppExistOnDevice(pkgName));
+        waitForDevice();
+
+        // grep for package to make sure it is installed
+        assertTrue(doesPackageExist(pkgName));
+    }
+
+    /**
+     * Helper method for installing an app to wherever is specified in its manifest, and
+     * then verifying the app was installed onto device.
+     * <p/>
+     * Assumes adb is running as root in device under test.
+     */
+    void installAppAndVerifyExistsOnDevice(String apkName, String pkgName, boolean overwrite)
+            throws IOException, InterruptedException {
+        // Start with a clean slate if we're not overwriting
+        if (!overwrite) {
+            // cleanup test app just in case it already exists
+            getDevice().uninstallPackage(pkgName);
+            // grep for package to make sure its not installed
+            assertFalse(doesPackageExist(pkgName));
+        }
+
+        installFile(getTestAppFilePath(apkName), overwrite);
+        assertFalse(doesAppExistOnSDCard(pkgName));
+        assertTrue(doesAppExistOnDevice(pkgName));
+        waitForDevice();
+
+        // grep for package to make sure it is installed
+        assertTrue(doesPackageExist(pkgName));
+    }
+
+    /**
+     * Helper method for uninstalling an app.
+     * <p/>
+     * Assumes adb is running as root in device under test.
+     */
+    void uninstallApp(String pkgName) throws IOException, InterruptedException {
+        getDevice().uninstallPackage(pkgName);
+        // make sure its not installed anymore
+        assertFalse(doesPackageExist(pkgName));
+    }
+
+    /**
+     * Regression test to verify that an app with its manifest set to installLocation=auto
+     * will install the app to the device.
+     * <p/>
+     * Assumes adb is running as root in device under test.
+     */
+    public void testInstallAppAutoLoc() throws IOException, InterruptedException {
+        Log.i(LOG_TAG, "Test an app with installLocation=auto gets installed on device");
+
+        try {
+            installAppAndVerifyExistsOnDevice(AUTO_LOC_APK, AUTO_LOC_PKG, false);
+        }
+        // cleanup test app
+        finally {
+            uninstallApp(AUTO_LOC_PKG);
+        }
+    }
+
+    /**
+     * Regression test to verify that an app with its manifest set to installLocation=internalOnly
+     * will install the app to the device.
+     * <p/>
+     * Assumes adb is running as root in device under test.
+     */
+    public void testInstallAppInternalLoc() throws IOException, InterruptedException {
+        Log.i(LOG_TAG, "Test an app with installLocation=internalOnly gets installed on device");
+
+        try {
+            installAppAndVerifyExistsOnDevice(INTERNAL_LOC_APK, INTERNAL_LOC_PKG, false);
+        }
+        // cleanup test app
+        finally {
+            uninstallApp(INTERNAL_LOC_PKG);
+        }
+    }
+
+    /**
+     * Regression test to verify that an app with its manifest set to installLocation=preferExternal
+     * will install the app to the SD card.
+     * <p/>
+     * Assumes adb is running as root in device under test.
+     */
+    public void testInstallAppExternalLoc() throws IOException, InterruptedException {
+        Log.i(LOG_TAG, "Test an app with installLocation=preferExternal gets installed on SD Card");
+
+        try {
+            installAppAndVerifyExistsOnSDCard(EXTERNAL_LOC_APK, EXTERNAL_LOC_PKG, false);
+        }
+        // cleanup test app
+        finally {
+            uninstallApp(EXTERNAL_LOC_PKG);
+        }
+    }
+
+    /**
+     * Regression test to verify that we can install an app onto the device,
+     * uninstall it, and reinstall it onto the SD card.
+     * <p/>
+     * Assumes adb is running as root in device under test.
+     */
+    // TODO: This currently relies on the app's manifest to switch from device to
+    // SD card install locations. We might want to make Device's installPackage()
+    // accept a installLocation flag so we can install a package to the
+    // destination of our choosing.
+    public void testReinstallInternalToExternal() throws IOException, InterruptedException {
+        Log.i(LOG_TAG, "Test installing an app first to the device, then to the SD Card");
+
+        try {
+            installAppAndVerifyExistsOnDevice(VERSATILE_LOC_INTERNAL_APK, VERSATILE_LOC_PKG, false);
+            uninstallApp(VERSATILE_LOC_PKG);
+            installAppAndVerifyExistsOnSDCard(VERSATILE_LOC_EXTERNAL_APK, VERSATILE_LOC_PKG, false);
+        }
+        // cleanup test app
+        finally {
+            uninstallApp(VERSATILE_LOC_PKG);
+        }
+    }
+
+    /**
+     * Regression test to verify that we can install an app onto the SD Card,
+     * uninstall it, and reinstall it onto the device.
+     * <p/>
+     * Assumes adb is running as root in device under test.
+     */
+    // TODO: This currently relies on the app's manifest to switch from device to
+    // SD card install locations. We might want to make Device's installPackage()
+    // accept a installLocation flag so we can install a package to the
+    // destination of our choosing.
+    public void testReinstallExternalToInternal() throws IOException, InterruptedException {
+        Log.i(LOG_TAG, "Test installing an app first to the SD Care, then to the device");
+
+        try {
+            // install the app externally
+            installAppAndVerifyExistsOnSDCard(VERSATILE_LOC_EXTERNAL_APK, VERSATILE_LOC_PKG, false);
+            uninstallApp(VERSATILE_LOC_PKG);
+            // then replace the app with one marked for internalOnly
+            installAppAndVerifyExistsOnDevice(VERSATILE_LOC_INTERNAL_APK, VERSATILE_LOC_PKG, true);
+        }
+        // cleanup test app
+        finally {
+            uninstallApp(VERSATILE_LOC_PKG);
+        }
+    }
+
+    /**
+     * Regression test to verify that updating an app on the SD card will install
+     * the update onto the SD card as well when location is not explicitly set in the
+     * updated apps' manifest file.
+     * <p/>
+     * Assumes adb is running as root in device under test.
+     */
+    public void testUpdateToSDCard() throws IOException, InterruptedException {
+        Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
+
+        try {
+            // install the app externally
+            installAppAndVerifyExistsOnSDCard(UPDATE_EXTERNAL_LOC_V1_EXT_APK,
+                    UPDATE_EXTERNAL_LOC_PKG, false);
+            // now replace the app with one where the location is blank (app should stay external)
+            installAppAndVerifyExistsOnSDCard(UPDATE_EXTERNAL_LOC_V2_NONE_APK,
+                    UPDATE_EXTERNAL_LOC_PKG, true);
+        }
+        // cleanup test app
+        finally {
+            uninstallApp(UPDATE_EXTERNAL_LOC_PKG);
+        }
+    }
+
+    /**
+     * Regression test to verify that updating an app on the SD card will install
+     * the update onto the SD card as well when location is not explicitly set in the
+     * updated apps' manifest file.
+     * <p/>
+     * Assumes adb is running as root in device under test.
+     */
+    public void testUpdateSDCardToDevice() throws IOException, InterruptedException {
+        Log.i(LOG_TAG, "Test updating an app on the SD card to the Device through manifest change");
+
+        try {
+            // install the app externally
+            installAppAndVerifyExistsOnSDCard(UPDATE_EXT_TO_INT_LOC_V1_EXT_APK,
+                    UPDATE_EXT_TO_INT_LOC_PKG, false);
+            // now replace the app with an update marked for internalOnly...
+            installAppAndVerifyExistsOnDevice(UPDATE_EXT_TO_INT_LOC_V2_INT_APK,
+                    UPDATE_EXT_TO_INT_LOC_PKG, true);
+        }
+        // cleanup test app
+        finally {
+            uninstallApp(UPDATE_EXT_TO_INT_LOC_PKG);
+        }
+    }
+
 }
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/AutoLocTestApp/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/AutoLocTestApp/Android.mk
index bd773d0..b3cab48 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/AutoLocTestApp/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := AutoLocTestApp
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/AutoLocTestApp/AndroidManifest.xml b/core/tests/hosttests/test-apps/AutoLocTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..d8c806a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/AutoLocTestApp/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.autoloctestapp"
+       android:installLocation="auto">
+
+    <application android:label="AutoLocTestApp"/>
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/AutoLocTestApp/src/com/android/framework/autoloctestapp/AutoLocTestAppActivity.java b/core/tests/hosttests/test-apps/AutoLocTestApp/src/com/android/framework/autoloctestapp/AutoLocTestAppActivity.java
new file mode 100644
index 0000000..fba5691
--- /dev/null
+++ b/core/tests/hosttests/test-apps/AutoLocTestApp/src/com/android/framework/autoloctestapp/AutoLocTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.autoloctestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class AutoLocTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/ExternalLocPermsFLTestApp/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/ExternalLocPermsFLTestApp/Android.mk
index bd773d0..9a05fa6 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/ExternalLocPermsFLTestApp/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := ExternalLocPermFLTestApp
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/ExternalLocPermsFLTestApp/AndroidManifest.xml b/core/tests/hosttests/test-apps/ExternalLocPermsFLTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..f45c627
--- /dev/null
+++ b/core/tests/hosttests/test-apps/ExternalLocPermsFLTestApp/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.externallocpermsfltestapp"
+       android:installLocation="preferExternal">
+
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+
+    <application android:label="ExternalLocPermsFLTestApp"/>
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/ExternalLocPermsFLTestApp/src/com/android/framework/externallocpermsfltestapp/ExternalLocPermsFLTestAppActivity.java b/core/tests/hosttests/test-apps/ExternalLocPermsFLTestApp/src/com/android/framework/externallocpermsfltestapp/ExternalLocPermsFLTestAppActivity.java
new file mode 100644
index 0000000..48fd744
--- /dev/null
+++ b/core/tests/hosttests/test-apps/ExternalLocPermsFLTestApp/src/com/android/framework/externallocpermsfltestapp/ExternalLocPermsFLTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.externallocpermsfltestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class ExternalLocPermsFLTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/ExternalLocTestApp/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/ExternalLocTestApp/Android.mk
index bd773d0..5aec78a 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/ExternalLocTestApp/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := ExternalLocTestApp
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/ExternalLocTestApp/AndroidManifest.xml b/core/tests/hosttests/test-apps/ExternalLocTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..a0c7b02
--- /dev/null
+++ b/core/tests/hosttests/test-apps/ExternalLocTestApp/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.externalloctestapp"
+       android:installLocation="preferExternal">
+
+    <application android:label="ExternalLocTestApp"/>
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/ExternalLocTestApp/src/com/android/framework/externalloctestapp/ExternalLocTestAppActivity.java b/core/tests/hosttests/test-apps/ExternalLocTestApp/src/com/android/framework/externalloctestapp/ExternalLocTestAppActivity.java
new file mode 100644
index 0000000..0a61628
--- /dev/null
+++ b/core/tests/hosttests/test-apps/ExternalLocTestApp/src/com/android/framework/externalloctestapp/ExternalLocTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.externalloctestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class ExternalLocTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/InternalLocTestApp/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/InternalLocTestApp/Android.mk
index bd773d0..5b58e72 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/InternalLocTestApp/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := InternalLocTestApp
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/InternalLocTestApp/AndroidManifest.xml b/core/tests/hosttests/test-apps/InternalLocTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..fae3ae0
--- /dev/null
+++ b/core/tests/hosttests/test-apps/InternalLocTestApp/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.internalloctestapp"
+       android:installLocation="internalOnly">
+
+    <application android:label="InternalLocTestApp"/>
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/InternalLocTestApp/src/com/android/framework/internalloctestapp/InternalLocTestAppActivity.java b/core/tests/hosttests/test-apps/InternalLocTestApp/src/com/android/framework/internalloctestapp/InternalLocTestAppActivity.java
new file mode 100644
index 0000000..6934641
--- /dev/null
+++ b/core/tests/hosttests/test-apps/InternalLocTestApp/src/com/android/framework/internalloctestapp/InternalLocTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.internalloctestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class InternalLocTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/NoLocTestApp/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/NoLocTestApp/Android.mk
index bd773d0..11916b0 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/NoLocTestApp/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := NoLocTestApp
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/NoLocTestApp/AndroidManifest.xml b/core/tests/hosttests/test-apps/NoLocTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..bfdad37
--- /dev/null
+++ b/core/tests/hosttests/test-apps/NoLocTestApp/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.noloctestapp">
+
+    <application android:label="NoLocTestApp"/>
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/NoLocTestApp/src/com/android/framework/noloctestapp/NoLocTestAppActivity.java b/core/tests/hosttests/test-apps/NoLocTestApp/src/com/android/framework/noloctestapp/NoLocTestAppActivity.java
new file mode 100644
index 0000000..72c8d2b
--- /dev/null
+++ b/core/tests/hosttests/test-apps/NoLocTestApp/src/com/android/framework/noloctestapp/NoLocTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.noloctestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class NoLocTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v1_ext/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v1_ext/Android.mk
index bd773d0..f2baefe 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v1_ext/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := UpdateExtToIntLocTestApp_v1_ext
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v1_ext/AndroidManifest.xml b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v1_ext/AndroidManifest.xml
new file mode 100644
index 0000000..b572e86
--- /dev/null
+++ b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v1_ext/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.updateexttointloctestapp"
+       android:installLocation="preferExternal"
+       android:versionCode="1"
+       android:versionName="1.0">
+
+    <application android:label="UpdateExtToIntLocTestApp"/>
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v1_ext/src/com/android/framework/updateexttointloctestapp/UpdateExtToIntLocTestAppActivity.java b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v1_ext/src/com/android/framework/updateexttointloctestapp/UpdateExtToIntLocTestAppActivity.java
new file mode 100644
index 0000000..5c51fb7
--- /dev/null
+++ b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v1_ext/src/com/android/framework/updateexttointloctestapp/UpdateExtToIntLocTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.updateexttointloctestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class UpdateExtToIntLocTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v2_int/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v2_int/Android.mk
index bd773d0..492c326 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v2_int/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := UpdateExtToIntLocTestApp_v2_int
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v2_int/AndroidManifest.xml b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v2_int/AndroidManifest.xml
new file mode 100644
index 0000000..c9437ae
--- /dev/null
+++ b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v2_int/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.updateexttointloctestapp"
+       android:installLocation="internalOnly"
+       android:versionCode="2"
+       android:versionName="2.0">
+
+    <application android:label="UpdateExtToIntLocTestApp"/>
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v2_int/src/com/android/framework/updateexttointloctestapp/UpdateExtToIntLocTestAppActivity.java b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v2_int/src/com/android/framework/updateexttointloctestapp/UpdateExtToIntLocTestAppActivity.java
new file mode 100644
index 0000000..5c51fb7
--- /dev/null
+++ b/core/tests/hosttests/test-apps/UpdateExtToIntLocTestApp_v2_int/src/com/android/framework/updateexttointloctestapp/UpdateExtToIntLocTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.updateexttointloctestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class UpdateExtToIntLocTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v1_ext/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v1_ext/Android.mk
index bd773d0..45867f7 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v1_ext/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := UpdateExternalLocTestApp_v1_ext
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v1_ext/AndroidManifest.xml b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v1_ext/AndroidManifest.xml
new file mode 100644
index 0000000..ec622ce
--- /dev/null
+++ b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v1_ext/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.updateexternalloctestapp"
+       android:installLocation="preferExternal"
+       android:versionCode="1"
+       android:versionName="1.0">
+
+    <application android:label="UpdateExternalLocTestApp"/>
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v1_ext/src/com/android/framework/updateexternalloctestapp/UpdateExternalLocTestAppActivity.java b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v1_ext/src/com/android/framework/updateexternalloctestapp/UpdateExternalLocTestAppActivity.java
new file mode 100644
index 0000000..02ecb75
--- /dev/null
+++ b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v1_ext/src/com/android/framework/updateexternalloctestapp/UpdateExternalLocTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.updateexternalloctestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class UpdateExternalLocTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v2_none/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v2_none/Android.mk
index bd773d0..780a9d7 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v2_none/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := UpdateExternalLocTestApp_v2_none
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v2_none/AndroidManifest.xml b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v2_none/AndroidManifest.xml
new file mode 100644
index 0000000..50fb104
--- /dev/null
+++ b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v2_none/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.updateexternalloctestapp"
+       android:versionCode="2"
+       android:versionName="2.0">
+
+    <application android:label="UpdateExternalLocTestApp"/>
+</manifest>
diff --git a/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v2_none/src/com/android/framework/updateexternalloctestapp/UpdateExternalLocTestAppActivity.java b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v2_none/src/com/android/framework/updateexternalloctestapp/UpdateExternalLocTestAppActivity.java
new file mode 100644
index 0000000..02ecb75
--- /dev/null
+++ b/core/tests/hosttests/test-apps/UpdateExternalLocTestApp_v2_none/src/com/android/framework/updateexternalloctestapp/UpdateExternalLocTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.updateexternalloctestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class UpdateExternalLocTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/VersatileTestApp_Auto/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/VersatileTestApp_Auto/Android.mk
index bd773d0..fc42bc4a 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_Auto/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := VersatileTestApp_Auto
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/VersatileTestApp_Auto/AndroidManifest.xml b/core/tests/hosttests/test-apps/VersatileTestApp_Auto/AndroidManifest.xml
new file mode 100644
index 0000000..f249250
--- /dev/null
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_Auto/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.versatiletestapp"
+       android:installLocation="auto">
+
+    <application android:label="VersatileTestApp"/>
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/VersatileTestApp_Auto/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java b/core/tests/hosttests/test-apps/VersatileTestApp_Auto/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java
new file mode 100644
index 0000000..c201c7a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_Auto/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.versatiletestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class VersatileTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/VersatileTestApp_External/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/VersatileTestApp_External/Android.mk
index bd773d0..c72a92c 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_External/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := VersatileTestApp_External
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/VersatileTestApp_External/AndroidManifest.xml b/core/tests/hosttests/test-apps/VersatileTestApp_External/AndroidManifest.xml
new file mode 100644
index 0000000..0d17ac2
--- /dev/null
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_External/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.versatiletestapp"
+       android:installLocation="preferExternal">
+
+    <application android:label="VersatileTestApp"/>
+
+</manifest>
diff --git a/core/tests/hosttests/test-apps/VersatileTestApp_External/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java b/core/tests/hosttests/test-apps/VersatileTestApp_External/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java
new file mode 100644
index 0000000..c201c7a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_External/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.versatiletestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class VersatileTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/VersatileTestApp_Internal/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/VersatileTestApp_Internal/Android.mk
index bd773d0..e477825 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_Internal/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := VersatileTestApp_Internal
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/VersatileTestApp_Internal/AndroidManifest.xml b/core/tests/hosttests/test-apps/VersatileTestApp_Internal/AndroidManifest.xml
new file mode 100644
index 0000000..e8cae6e
--- /dev/null
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_Internal/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.versatiletestapp"
+       android:installLocation="internalOnly">
+
+    <application android:label="VersatileTestApp"/>
+</manifest>
diff --git a/core/tests/hosttests/test-apps/VersatileTestApp_Internal/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java b/core/tests/hosttests/test-apps/VersatileTestApp_Internal/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java
new file mode 100644
index 0000000..c201c7a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_Internal/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.versatiletestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class VersatileTestAppActivity extends Activity {
+
+}
diff --git a/tests/ConnectivityManagerTest/Android.mk b/core/tests/hosttests/test-apps/VersatileTestApp_None/Android.mk
similarity index 67%
copy from tests/ConnectivityManagerTest/Android.mk
copy to core/tests/hosttests/test-apps/VersatileTestApp_None/Android.mk
index bd773d0..1fc516c 100644
--- a/tests/ConnectivityManagerTest/Android.mk
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_None/Android.mk
@@ -1,10 +1,10 @@
-# Copyright 2010, The Android Open Source Project
+# 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
+#      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,
@@ -13,18 +13,15 @@
 # limitations under the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
-# We only want this apk build for tests.
 LOCAL_MODULE_TAGS := tests
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityManagerTest
+LOCAL_SDK_VERSION := current
 
-#LOCAL_INSTRUMENTATION_FOR := connectivitymanagertest
+LOCAL_PACKAGE_NAME := VersatileTestApp_None
 
 include $(BUILD_PACKAGE)
diff --git a/core/tests/hosttests/test-apps/VersatileTestApp_None/AndroidManifest.xml b/core/tests/hosttests/test-apps/VersatileTestApp_None/AndroidManifest.xml
new file mode 100644
index 0000000..1df40d4
--- /dev/null
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_None/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+       package="com.android.framework.versatiletestapp">
+
+    <application android:label="VersatileTestApp"/>
+</manifest>
diff --git a/core/tests/hosttests/test-apps/VersatileTestApp_None/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java b/core/tests/hosttests/test-apps/VersatileTestApp_None/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java
new file mode 100644
index 0000000..c201c7a
--- /dev/null
+++ b/core/tests/hosttests/test-apps/VersatileTestApp_None/src/com/android/framework/versatiletestapp/VersatileTestAppActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.framework.versatiletestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Empty activity, not needed for this test
+ */
+public class VersatileTestAppActivity extends Activity {
+
+}
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 8dc206c..15d692c 100755
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -63,13 +63,14 @@
 import java.util.Date;
 import java.util.Properties;
 import java.util.Map.Entry;
+import java.util.concurrent.CountDownLatch;
 
 /**
  * A GPS implementation of LocationProvider used by LocationManager.
  *
  * {@hide}
  */
-public class GpsLocationProvider implements LocationProviderInterface, Runnable {
+public class GpsLocationProvider implements LocationProviderInterface {
 
     private static final String TAG = "GpsLocationProvider";
 
@@ -190,7 +191,7 @@
     private static final int NO_FIX_TIMEOUT = 60;
 
     // true if we are enabled
-    private boolean mEnabled;
+    private volatile boolean mEnabled;
     
     // true if we have network connectivity
     private boolean mNetworkAvailable;
@@ -236,7 +237,13 @@
     private Bundle mLocationExtras = new Bundle();
     private ArrayList<Listener> mListeners = new ArrayList<Listener>();
 
+    // GpsLocationProvider's handler thread
+    private final Thread mThread;
+    // Handler for processing events in mThread.
     private Handler mHandler;
+    // Used to signal when our main thread has initialized everything
+    private final CountDownLatch mInitializedLatch = new CountDownLatch(1);
+    // Thread for receiving events from the native code
     private Thread mEventThread;
 
     private String mAGpsApn;
@@ -389,8 +396,17 @@
             Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE);
         }
 
-        Thread thread = new Thread(null, this, "GpsLocationProvider");
-        thread.start();
+        // wait until we are fully initialized before returning
+        mThread = new GpsLocationProviderThread();
+        mThread.start();
+        while (true) {
+            try {
+                mInitializedLatch.await();
+                break;
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+            }
+        }
     }
 
     private void initialize() {
@@ -673,7 +689,7 @@
     }
 
     private void handleDisable() {
-        if (DEBUG) Log.d(TAG, "handleEnable");
+        if (DEBUG) Log.d(TAG, "handleDisable");
         if (!mEnabled) return;
 
         mEnabled = false;
@@ -1327,7 +1343,7 @@
     // native_wait_for_event() will callback to us via reportLocation(), reportStatus(), etc.
     // this is necessary because native code cannot call Java on a thread that the JVM does
     // not know about.
-    private class GpsEventThread extends Thread {
+    private final class GpsEventThread extends Thread {
 
         public GpsEventThread() {
             super("GpsEventThread");
@@ -1384,13 +1400,21 @@
         }
     };
 
-    public void run()
-    {
-        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-        initialize();
-        Looper.prepare();
-        mHandler = new ProviderHandler();
-        Looper.loop();
+    private final class GpsLocationProviderThread extends Thread {
+
+        public GpsLocationProviderThread() {
+            super("GpsLocationProvider");
+        }
+
+        public void run() {
+            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+            initialize();
+            Looper.prepare();
+            mHandler = new ProviderHandler();
+            // signal when we are initialized and ready to go
+            mInitializedLatch.countDown();
+            Looper.loop();
+        }
     }
 
     // for GPS SV statistics
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 164df72..407fd57 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -1153,6 +1153,8 @@
             Mutex::Autolock autoLock(mLock);
             if (mFlags & PREPARE_CANCELLED) {
                 LOGI("prepare was cancelled before preparing the prefetcher");
+
+                prefetcher.clear();
                 abortPrepare(UNKNOWN_ERROR);
                 return;
             }
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 3f029a6..2c43e59 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -159,6 +159,7 @@
     private final static boolean LOG_SURFACE = false;
     private final static boolean LOG_RENDERER = false;
     private final static boolean LOG_RENDERER_DRAW_FRAME = false;
+    private final static boolean LOG_EGL = false;
     // Work-around for bug 2263168
     private final static boolean DRAW_TWICE_AFTER_SIZE_CHANGED = true;
     /**
@@ -683,7 +684,14 @@
 
         public void destroyContext(EGL10 egl, EGLDisplay display,
                 EGLContext context) {
-            egl.eglDestroyContext(display, context);
+            if (!egl.eglDestroyContext(display, context)) {
+                Log.e("DefaultContextFactory", "display:" + display + " context: " + context);
+                if (LOG_THREADS) {
+                    Log.i("DefaultContextFactory", "tid=" + Thread.currentThread().getId());
+                }
+                throw new RuntimeException("eglDestroyContext failed: "
+                        + EGLLogWrapper.getErrorString(egl.eglGetError()));
+            }
         }
     }
 
@@ -880,6 +888,9 @@
          * @param configSpec
          */
         public void start() {
+            if (LOG_EGL) {
+                Log.w("EglHelper", "start() tid=" + Thread.currentThread().getId());
+            }
             /*
              * Get an EGL instance
              */
@@ -909,8 +920,12 @@
             */
             mEglContext = mEGLContextFactory.createContext(mEgl, mEglDisplay, mEglConfig);
             if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) {
+                mEglContext = null;
                 throwEglException("createContext");
             }
+            if (LOG_EGL) {
+                Log.w("EglHelper", "createContext " + mEglContext + " tid=" + Thread.currentThread().getId());
+            }
 
             mEglSurface = null;
         }
@@ -920,6 +935,21 @@
          * OpenGL interface that renders to that surface.
          */
         public GL createSurface(SurfaceHolder holder) {
+            if (LOG_EGL) {
+                Log.w("EglHelper", "createSurface()  tid=" + Thread.currentThread().getId());
+            }
+            /*
+             * Check preconditions.
+             */
+            if (mEgl == null) {
+                throw new RuntimeException("egl not initialized");
+            }
+            if (mEglDisplay == null) {
+                throw new RuntimeException("eglDisplay not initialized");
+            }
+            if (mEglConfig == null) {
+                throw new RuntimeException("mEglConfig not initialized");
+            }
             /*
              *  The window size has changed, so we need to create a new
              *  surface.
@@ -942,6 +972,8 @@
                     mEglDisplay, mEglConfig, holder);
 
             if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
+                Log.w("EglHelper", "createWindowSurface failed. mEglDisplay: " + mEglDisplay +
+                        " mEglConfig: " + mEglConfig + " holder: " + holder);
                 throwEglException("createWindowSurface");
             }
 
@@ -996,6 +1028,9 @@
         }
 
         public void destroySurface() {
+            if (LOG_EGL) {
+                Log.w("EglHelper", "destroySurface()  tid=" + Thread.currentThread().getId());
+            }
             if (mEglSurface != null && mEglSurface != EGL10.EGL_NO_SURFACE) {
                 mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
                         EGL10.EGL_NO_SURFACE,
@@ -1006,6 +1041,9 @@
         }
 
         public void finish() {
+            if (LOG_EGL) {
+                Log.w("EglHelper", "finish() tid=" + Thread.currentThread().getId());
+            }
             if (mEglContext != null) {
                 mEGLContextFactory.destroyContext(mEgl, mEglDisplay, mEglContext);
                 mEglContext = null;
@@ -1021,7 +1059,11 @@
         }
 
         private void throwEglException(String function, int error) {
-            throw new RuntimeException(function + " failed: " + error);
+            String message = function + " failed: " + EGLLogWrapper.getErrorString(error);
+            if (LOG_THREADS) {
+                Log.e("EglHelper", "throwEglException tid=" + Thread.currentThread().getId() + " " + message);
+            }
+            throw new RuntimeException(message);
         }
 
         EGL10 mEgl;
@@ -1174,9 +1216,14 @@
 
                                 // If we don't have an EGL context, try to acquire one.
                                 if ((! mHaveEglContext) && sGLThreadManager.tryAcquireEglContextLocked(this)) {
+                                    try {
+                                        mEglHelper.start();
+                                    } catch (RuntimeException t) {
+                                        sGLThreadManager.releaseEglContextLocked(this);
+                                        throw t;
+                                    }
                                     mHaveEglContext = true;
                                     createEglContext = true;
-                                    mEglHelper.start();
 
                                     sGLThreadManager.notifyAll();
                                 }
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 53415c7..4d7b393 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -5258,7 +5258,7 @@
             String sourceFile = getCodePath();
             // Remove dex file
             if (mInstaller != null) {
-                int retCode = mInstaller.rmdex(sourceFile.toString());
+                int retCode = mInstaller.rmdex(sourceFile);
                 if (retCode < 0) {
                     Slog.w(TAG, "Couldn't remove dex file for package: "
                             + " at location "
@@ -5613,7 +5613,7 @@
     }
 
     // Utility method used to move dex files during install.
-    private int moveDexFiles(PackageParser.Package newPackage) {
+    private int moveDexFilesLI(PackageParser.Package newPackage) {
         int retCode;
         if ((newPackage.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
             retCode = mInstaller.movedex(newPackage.mScanPath, newPackage.mPath);
@@ -5636,7 +5636,7 @@
             mSettings.writeLP();
         }
 
-        if ((res.returnCode = moveDexFiles(newPackage))
+        if ((res.returnCode = moveDexFilesLI(newPackage))
                 != PackageManager.INSTALL_SUCCEEDED) {
             // Discontinue if moving dex files failed.
             return;
@@ -9697,41 +9697,43 @@
                    sendResourcesChangedBroadcast(false, pkgList, uidArr);
 
                    // Update package code and resource paths
-                   synchronized (mPackages) {
-                       PackageParser.Package pkg = mPackages.get(mp.packageName);
-                       if (pkg != null) {
-                           String oldCodePath = pkg.mPath;
-                           String newCodePath = mp.targetArgs.getCodePath();
-                           String newResPath = mp.targetArgs.getResourcePath();
-                           pkg.mPath = newCodePath;
-                           // Move dex files around
-                           if (moveDexFiles(pkg)
-                                   != PackageManager.INSTALL_SUCCEEDED) {
-                               // Moving of dex files failed. Set
-                               // error code and abort move.
-                               pkg.mPath = pkg.mScanPath;
-                               returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
-                               moveSucceeded = false;
-                           } else {
-                               pkg.mScanPath = newCodePath;
-                               pkg.applicationInfo.sourceDir = newCodePath;
-                               pkg.applicationInfo.publicSourceDir = newResPath;
-                               PackageSetting ps = (PackageSetting) pkg.mExtras;
-                               ps.codePath = new File(pkg.applicationInfo.sourceDir);
-                               ps.codePathString = ps.codePath.getPath();
-                               ps.resourcePath = new File(pkg.applicationInfo.publicSourceDir);
-                               ps.resourcePathString = ps.resourcePath.getPath();
-                               // Set the application info flag correctly.
-                               if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
-                                   pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
+                   synchronized (mInstallLock) {
+                       synchronized (mPackages) {
+                           PackageParser.Package pkg = mPackages.get(mp.packageName);
+                           if (pkg != null) {
+                               String oldCodePath = pkg.mPath;
+                               String newCodePath = mp.targetArgs.getCodePath();
+                               String newResPath = mp.targetArgs.getResourcePath();
+                               pkg.mPath = newCodePath;
+                               // Move dex files around
+                               if (moveDexFilesLI(pkg)
+                                       != PackageManager.INSTALL_SUCCEEDED) {
+                                   // Moving of dex files failed. Set
+                                   // error code and abort move.
+                                   pkg.mPath = pkg.mScanPath;
+                                   returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+                                   moveSucceeded = false;
                                } else {
-                                   pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
+                                   pkg.mScanPath = newCodePath;
+                                   pkg.applicationInfo.sourceDir = newCodePath;
+                                   pkg.applicationInfo.publicSourceDir = newResPath;
+                                   PackageSetting ps = (PackageSetting) pkg.mExtras;
+                                   ps.codePath = new File(pkg.applicationInfo.sourceDir);
+                                   ps.codePathString = ps.codePath.getPath();
+                                   ps.resourcePath = new File(pkg.applicationInfo.publicSourceDir);
+                                   ps.resourcePathString = ps.resourcePath.getPath();
+                                   // Set the application info flag correctly.
+                                   if ((mp.flags & PackageManager.INSTALL_EXTERNAL) != 0) {
+                                       pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
+                                   } else {
+                                       pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
+                                   }
+                                   ps.setFlags(pkg.applicationInfo.flags);
+                                   mAppDirs.remove(oldCodePath);
+                                   mAppDirs.put(newCodePath, pkg);
+                                   // Persist settings
+                                   mSettings.writeLP();
                                }
-                               ps.setFlags(pkg.applicationInfo.flags);
-                               mAppDirs.remove(oldCodePath);
-                               mAppDirs.put(newCodePath, pkg);
-                               // Persist settings
-                               mSettings.writeLP();
                            }
                        }
                    }
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index f734053..d1edc35 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -69,6 +69,7 @@
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.net.Uri;
@@ -122,6 +123,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 
 public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor {
     static final String TAG = "ActivityManager";
@@ -9352,6 +9354,32 @@
         return runList;
     }
 
+    public List<ApplicationInfo> getRunningExternalApplications() {
+        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
+        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
+        if (runningApps != null && runningApps.size() > 0) {
+            Set<String> extList = new HashSet<String>();
+            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
+                if (app.pkgList != null) {
+                    for (String pkg : app.pkgList) {
+                        extList.add(pkg);
+                    }
+                }
+            }
+            IPackageManager pm = ActivityThread.getPackageManager();
+            for (String pkg : extList) {
+                try {
+                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
+                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
+                        retList.add(info);
+                    }
+                } catch (RemoteException e) {
+                }
+            }
+        }
+        return retList;
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (checkCallingPermission(android.Manifest.permission.DUMP)
diff --git a/services/java/com/android/server/status/UsbStorageActivity.java b/services/java/com/android/server/status/UsbStorageActivity.java
index b3ee257..e8631c5 100644
--- a/services/java/com/android/server/status/UsbStorageActivity.java
+++ b/services/java/com/android/server/status/UsbStorageActivity.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.R;
 import android.app.Activity;
+import android.app.ActivityManager;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.BroadcastReceiver;
@@ -26,6 +27,9 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.DialogInterface.OnCancelListener;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.Handler;
@@ -43,6 +47,8 @@
 import android.view.Window;
 import android.util.Log;
 
+import java.util.List;
+
 /**
  * This activity is shown to the user for him/her to enable USB mass storage
  * on-demand (that is, when the USB cable is connected). It uses the alert
@@ -175,7 +181,7 @@
                     .setTitle(R.string.dlg_confirm_kill_storage_users_title)
                     .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
                         public void onClick(DialogInterface dialog, int which) {
-                            mStorageManager.enableUsbMassStorage();
+                            switchUsbMassStorageAsync(true);
                         }})
                     .setNegativeButton(R.string.cancel, null)
                     .setMessage(R.string.dlg_confirm_kill_storage_users_text)
@@ -222,15 +228,25 @@
             // Display error dialog
             showDialogInner(DLG_ERROR_SHARING);
         }
-        String path = Environment.getExternalStorageDirectory().getPath();
-        int stUsers[] = null;
+        String extStoragePath = Environment.getExternalStorageDirectory().toString();
+        boolean showDialog = false;
         try {
-            if (localLOGV) Log.i(TAG, "Checking getStorageUsers");
-            stUsers = ims.getStorageUsers(path);
+            int[] stUsers = ims.getStorageUsers(extStoragePath);
+            if (stUsers != null && stUsers.length > 0) {
+                showDialog = true;
+            } else {
+                // List of applications on sdcard.
+                ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
+                List<ApplicationInfo> infoList = am.getRunningExternalApplications();
+                if (infoList != null && infoList.size() > 0) {
+                    showDialog = true;
+                }
+            }
         } catch (RemoteException e) {
+            // Display error dialog
             showDialogInner(DLG_ERROR_SHARING);
         }
-        if (stUsers != null && stUsers.length > 0) {
+        if (showDialog) {
             // Display dialog to user
             showDialogInner(DLG_CONFIRM_KILL_STORAGE_USERS);
         } else {