Merge "Don't use dim behind for the search box."
diff --git a/api/current.xml b/api/current.xml
index 58ce3ee..4af2a43 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -88413,7 +88413,7 @@
  static="true"
  final="false"
  deprecated="not deprecated"
- visibility="private"
+ visibility="public"
 >
 <method name="startDownloadByUri"
  return="long"
diff --git a/core/java/android/content/ContentValues.java b/core/java/android/content/ContentValues.java
index c04625d..75787cd 100644
--- a/core/java/android/content/ContentValues.java
+++ b/core/java/android/content/ContentValues.java
@@ -66,7 +66,7 @@
      * Creates a set of values copied from the given HashMap. This is used
      * by the Parcel unmarshalling code.
      *
-     * @param from the values to start with
+     * @param values the values to start with
      * {@hide}
      */
     private ContentValues(HashMap<String, Object> values) {
@@ -248,7 +248,7 @@
      */
     public String getAsString(String key) {
         Object value = mValues.get(key);
-        return value != null ? mValues.get(key).toString() : null;
+        return value != null ? value.toString() : null;
     }
 
     /**
diff --git a/core/java/android/database/MergeCursor.java b/core/java/android/database/MergeCursor.java
index 7e91159..722d707 100644
--- a/core/java/android/database/MergeCursor.java
+++ b/core/java/android/database/MergeCursor.java
@@ -185,6 +185,7 @@
                 mCursors[i].deactivate();
             }
         }
+        super.deactivate();
     }
 
     @Override
@@ -194,6 +195,7 @@
             if (mCursors[i] == null) continue;
             mCursors[i].close();
         }
+        super.close();
     }
 
     @Override
diff --git a/core/java/android/net/Downloads.java b/core/java/android/net/Downloads.java
index 72106c8..3867385 100644
--- a/core/java/android/net/Downloads.java
+++ b/core/java/android/net/Downloads.java
@@ -469,7 +469,7 @@
     /**
      * Base class with common functionality for the various download classes
      */
-    private static class DownloadBase {
+    public static class DownloadBase {
         /** @hide */
         DownloadBase() {}
 
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index f2ea539..eca4569 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -1598,6 +1598,8 @@
                     end = query.length();
                 }
                 return decode(query.substring(equalsIndex + 1, end));
+            } else {
+                encodedKeySearchIndex = equalsIndex + 1;
             }
         }
         return null;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index b5eb5d5..784f886 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4195,7 +4195,15 @@
     @Override
     protected void onScrollChanged(int l, int t, int oldl, int oldt) {
         super.onScrollChanged(l, t, oldl, oldt);
-        sendOurVisibleRect();
+        if (!mInOverScrollMode) {
+            sendOurVisibleRect();
+            // update WebKit if visible title bar height changed. The logic is same
+            // as getVisibleTitleHeight.
+            int titleHeight = getTitleHeight();
+            if (Math.max(titleHeight - t, 0) != Math.max(titleHeight - oldt, 0)) {
+                sendViewSizeZoom();
+            }
+        }
     }
 
     @Override
diff --git a/core/tests/coretests/src/android/net/UriTest.java b/core/tests/coretests/src/android/net/UriTest.java
index ad71fcb..095ee13 100644
--- a/core/tests/coretests/src/android/net/UriTest.java
+++ b/core/tests/coretests/src/android/net/UriTest.java
@@ -574,5 +574,13 @@
             .appendQueryParameter("key", "y z")
             .build();
         assertEquals("y z", uri.getQueryParameter("key"));
+
+        // key is a substring of parameters, but not present
+        uri = Uri.parse("http://test/").buildUpon()
+            .appendQueryParameter("akeyb", "a b")
+            .appendQueryParameter("keya", "c d")
+            .appendQueryParameter("bkey", "e f")
+            .build();
+        assertNull(uri.getQueryParameter("key"));
     }
 }
diff --git a/data/fonts/DroidSansHebrew.ttf b/data/fonts/DroidSansHebrew.ttf
index 8cc670d..0b48628 100644
--- a/data/fonts/DroidSansHebrew.ttf
+++ b/data/fonts/DroidSansHebrew.ttf
Binary files differ
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 44a5a6b..8dc206c 100755
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -35,8 +35,12 @@
 import android.net.NetworkInfo;
 import android.net.SntpClient;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
 import android.os.PowerManager;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
@@ -65,13 +69,13 @@
  *
  * {@hide}
  */
-public class GpsLocationProvider implements LocationProviderInterface {
+public class GpsLocationProvider implements LocationProviderInterface, Runnable {
 
     private static final String TAG = "GpsLocationProvider";
 
     private static final boolean DEBUG = false;
     private static final boolean VERBOSE = false;
-    
+
     /**
      * Broadcast intent action indicating that the GPS has either been
      * enabled or disabled. An intent extra provides this state as a boolean,
@@ -155,6 +159,17 @@
     private static final int AGPS_DATA_CONNECTION_OPENING = 1;
     private static final int AGPS_DATA_CONNECTION_OPEN = 2;
 
+    // Handler messages
+    private static final int CHECK_LOCATION = 1;
+    private static final int ENABLE = 2;
+    private static final int ENABLE_TRACKING = 3;
+    private static final int UPDATE_NETWORK_STATE = 4;
+    private static final int INJECT_NTP_TIME = 5;
+    private static final int DOWNLOAD_XTRA_DATA = 6;
+    private static final int UPDATE_LOCATION = 7;
+    private static final int ADD_LISTENER = 8;
+    private static final int REMOVE_LISTENER = 9;
+
     private static final String PROPERTIES_FILE = "/etc/gps.conf";
 
     private int mLocationFlags = LOCATION_INVALID;
@@ -180,6 +195,11 @@
     // true if we have network connectivity
     private boolean mNetworkAvailable;
 
+    // flags to trigger NTP or XTRA data download when network becomes available
+    // initialized to true so we do NTP and XTRA when the network comes up after booting
+    private boolean mInjectNtpTimePending = true;
+    private boolean mDownloadXtraDataPending = true;
+
     // true if GPS is navigating
     private boolean mNavigating;
 
@@ -215,9 +235,9 @@
     private Location mLocation = new Location(LocationManager.GPS_PROVIDER);
     private Bundle mLocationExtras = new Bundle();
     private ArrayList<Listener> mListeners = new ArrayList<Listener>();
-    private GpsEventThread mEventThread;
-    private GpsNetworkThread mNetworkThread;
-    private Object mNetworkThreadLock = new Object();
+
+    private Handler mHandler;
+    private Thread mEventThread;
 
     private String mAGpsApn;
     private int mAGpsDataConnectionState;
@@ -333,11 +353,6 @@
         mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
         mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
 
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(ALARM_WAKEUP);
-        intentFilter.addAction(ALARM_TIMEOUT);
-        context.registerReceiver(mBroadcastReciever, intentFilter);
-
         mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
 
         // Battery statistics service to be notified when GPS turns on or off
@@ -373,6 +388,17 @@
         } catch (IOException e) {
             Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE);
         }
+
+        Thread thread = new Thread(null, this, "GpsLocationProvider");
+        thread.start();
+    }
+
+    private void initialize() {
+        // register our receiver on our thread rather than the main thread
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(ALARM_WAKEUP);
+        intentFilter.addAction(ALARM_TIMEOUT);
+        mContext.registerReceiver(mBroadcastReciever, intentFilter);
     }
 
     /**
@@ -391,6 +417,14 @@
     }
 
     public void updateNetworkState(int state, NetworkInfo info) {
+        mHandler.removeMessages(UPDATE_NETWORK_STATE);
+        Message m = Message.obtain(mHandler, UPDATE_NETWORK_STATE);
+        m.arg1 = state;
+        m.obj = info;
+        mHandler.sendMessage(m);
+    }
+
+    private void handleUpdateNetworkState(int state, NetworkInfo info) {
         mNetworkAvailable = (state == LocationProvider.AVAILABLE);
 
         if (DEBUG) {
@@ -414,10 +448,84 @@
             }
         }
 
-        if (mNetworkAvailable && mNetworkThread != null && mEnabled) {
-            // signal the network thread when the network becomes available
-            mNetworkThread.signal();
-        } 
+        if (mNetworkAvailable) {
+            if (mInjectNtpTimePending) {
+                mHandler.removeMessages(INJECT_NTP_TIME);
+                mHandler.sendMessage(Message.obtain(mHandler, INJECT_NTP_TIME));
+            }
+            if (mDownloadXtraDataPending) {
+                mHandler.removeMessages(DOWNLOAD_XTRA_DATA);
+                mHandler.sendMessage(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA));
+            }
+        }
+    }
+
+    private void handleInjectNtpTime() {
+        if (!mNetworkAvailable) {
+            // try again when network is up
+            mInjectNtpTimePending = true;
+            return;
+        }
+        mInjectNtpTimePending = false;
+
+        SntpClient client = new SntpClient();
+        long delay;
+
+        if (client.requestTime(mNtpServer, 10000)) {
+            long time = client.getNtpTime();
+            long timeReference = client.getNtpTimeReference();
+            int certainty = (int)(client.getRoundTripTime()/2);
+            long now = System.currentTimeMillis();
+            long systemTimeOffset = time - now;
+
+            Log.d(TAG, "NTP server returned: "
+                    + time + " (" + new Date(time)
+                    + ") reference: " + timeReference
+                    + " certainty: " + certainty
+                    + " system time offset: " + systemTimeOffset);
+
+            // sanity check NTP time and do not use if it is too far from system time
+            if (systemTimeOffset < 0) {
+                systemTimeOffset = -systemTimeOffset;
+            }
+            if (systemTimeOffset < MAX_NTP_SYSTEM_TIME_OFFSET) {
+                native_inject_time(time, timeReference, certainty);
+            } else {
+                Log.e(TAG, "NTP time differs from system time by " + systemTimeOffset
+                        + "ms.  Ignoring.");
+            }
+            delay = NTP_INTERVAL;
+        } else {
+            if (DEBUG) Log.d(TAG, "requestTime failed");
+            delay = RETRY_INTERVAL;
+        }
+
+        // send delayed message for next NTP injection
+        mHandler.removeMessages(INJECT_NTP_TIME);
+        mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay);
+    }
+
+    private void handleDownloadXtraData() {
+        if (!mDownloadXtraDataPending) {
+            // try again when network is up
+            mDownloadXtraDataPending = true;
+            return;
+        }
+        mDownloadXtraDataPending = false;
+
+
+        GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mContext, mProperties);
+        byte[] data = xtraDownloader.downloadXtraData();
+        if (data != null) {
+            if (DEBUG) {
+                Log.d(TAG, "calling native_inject_xtra_data");
+            }
+            native_inject_xtra_data(data, data.length);
+        } else {
+            // try again later
+            mHandler.removeMessages(DOWNLOAD_XTRA_DATA);
+            mHandler.sendMessageDelayed(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA), RETRY_INTERVAL);
+        }
     }
 
     /**
@@ -425,6 +533,13 @@
      * Someday we might use this for network location injection to aid the GPS
      */
     public void updateLocation(Location location) {
+        mHandler.removeMessages(UPDATE_LOCATION);
+        Message m = Message.obtain(mHandler, UPDATE_LOCATION);
+        m.obj = location;
+        mHandler.sendMessage(m);
+    }
+
+    private void handleUpdateLocation(Location location) {
         if (location.hasAccuracy()) {
             native_inject_location(location.getLatitude(), location.getLongitude(),
                     location.getAccuracy());
@@ -513,8 +628,17 @@
      * must be handled.  Hardware may be started up
      * when the provider is enabled.
      */
-    public synchronized void enable() {
-        if (DEBUG) Log.d(TAG, "enable");
+    public void enable() {
+        synchronized (mHandler) {
+            mHandler.removeMessages(ENABLE);
+            Message m = Message.obtain(mHandler, ENABLE);
+            m.arg1 = 1;
+            mHandler.sendMessage(m);
+        }
+    }
+
+    private void handleEnable() {
+        if (DEBUG) Log.d(TAG, "handleEnable");
         if (mEnabled) return;
         mEnabled = native_init();
 
@@ -529,16 +653,6 @@
             // run event listener thread while we are enabled
             mEventThread = new GpsEventThread();
             mEventThread.start();
-
-            if (requiresNetwork()) {
-                // run network thread for NTP and XTRA support
-                if (mNetworkThread == null) {
-                    mNetworkThread = new GpsNetworkThread();
-                    mNetworkThread.start();
-                } else {
-                    mNetworkThread.signal();
-                }
-            }
         } else {
             Log.w(TAG, "Failed to enable location provider");
         }
@@ -549,8 +663,17 @@
      * need not be handled.  Hardware may be shut
      * down while the provider is disabled.
      */
-    public synchronized void disable() {
-        if (DEBUG) Log.d(TAG, "disable");
+    public void disable() {
+        synchronized (mHandler) {
+            mHandler.removeMessages(ENABLE);
+            Message m = Message.obtain(mHandler, ENABLE);
+            m.arg1 = 0;
+            mHandler.sendMessage(m);
+        }
+    }
+
+    private void handleDisable() {
+        if (DEBUG) Log.d(TAG, "handleEnable");
         if (!mEnabled) return;
 
         mEnabled = false;
@@ -567,11 +690,6 @@
             mEventThread = null;
         }
 
-        if (mNetworkThread != null) {
-            mNetworkThread.setDone();
-            mNetworkThread = null;
-        }
-
         // do this before releasing wakelock
         native_cleanup();
 
@@ -610,6 +728,15 @@
     }
 
     public void enableLocationTracking(boolean enable) {
+        synchronized (mHandler) {
+            mHandler.removeMessages(ENABLE_TRACKING);
+            Message m = Message.obtain(mHandler, ENABLE_TRACKING);
+            m.arg1 = (enable ? 1 : 0);
+            mHandler.sendMessage(m);
+        }
+    }
+
+    private void handleEnableLocationTracking(boolean enable) {
         if (enable) {
             mTTFF = 0;
             mLastFixTime = 0;
@@ -659,6 +786,12 @@
     }
 
     public void addListener(int uid) {
+        Message m = Message.obtain(mHandler, ADD_LISTENER);
+        m.arg1 = uid;
+        mHandler.sendMessage(m);
+    }
+
+    private void handleAddListener(int uid) {
         synchronized(mListeners) {
             if (mClientUids.indexOfKey(uid) >= 0) {
                 // Shouldn't be here -- already have this uid.
@@ -677,6 +810,12 @@
     }
 
     public void removeListener(int uid) {
+        Message m = Message.obtain(mHandler, REMOVE_LISTENER);
+        m.arg1 = uid;
+        mHandler.sendMessage(m);
+    }
+
+    private void handleRemoveListener(int uid) {
         synchronized(mListeners) {
             if (mClientUids.indexOfKey(uid) < 0) {
                 // Shouldn't be here -- don't have this uid.
@@ -700,10 +839,12 @@
             return deleteAidingData(extras);
         }
         if ("force_time_injection".equals(command)) {
-            return forceTimeInjection();
+            mHandler.removeMessages(INJECT_NTP_TIME);
+            mHandler.sendMessage(Message.obtain(mHandler, INJECT_NTP_TIME));
+            return true;
         }
         if ("force_xtra_injection".equals(command)) {
-            if (native_supports_xtra() && mNetworkThread != null) {
+            if (native_supports_xtra()) {
                 xtraDownloadRequest();
                 return true;
             }
@@ -744,16 +885,7 @@
         return false;
     }
 
-    private boolean forceTimeInjection() {
-        if (DEBUG) Log.d(TAG, "forceTimeInjection");
-        if (mNetworkThread != null) {
-            mNetworkThread.timeInjectRequest();
-            return true;
-        }
-        return false;
-    }
-
-    public void startNavigating() {
+    private void startNavigating() {
         if (!mStarted) {
             if (DEBUG) Log.d(TAG, "startNavigating");
             mStarted = true;
@@ -784,7 +916,7 @@
         }
     }
 
-    public void stopNavigating() {
+    private void stopNavigating() {
         if (DEBUG) Log.d(TAG, "stopNavigating");
         if (mStarted) {
             mStarted = false;
@@ -1092,11 +1224,13 @@
         }
     }
 
+    /**
+     * called from native code to request XTRA data
+     */
     private void xtraDownloadRequest() {
         if (DEBUG) Log.d(TAG, "xtraDownloadRequest");
-        if (mNetworkThread != null) {
-            mNetworkThread.xtraDownloadRequest();
-        }
+        mHandler.removeMessages(DOWNLOAD_XTRA_DATA);
+        mHandler.sendMessage(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA));
     }
 
     //=============================================================
@@ -1189,6 +1323,10 @@
 		mNIHandler.handleNiNotification(notification);		
 	}
 
+    // this thread is used to receive events from the native code.
+    // 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 {
 
         public GpsEventThread() {
@@ -1207,157 +1345,52 @@
         }
     }
 
-    private class GpsNetworkThread extends Thread {
-
-        private long mNextNtpTime = 0;
-        private long mNextXtraTime = 0;
-        private boolean mTimeInjectRequested = false;
-        private boolean mXtraDownloadRequested = false;
-        private boolean mDone = false;
-
-        public GpsNetworkThread() {
-            super("GpsNetworkThread");
-        }
-
-        public void run() {
-            synchronized (mNetworkThreadLock) {
-                if (!mDone) {
-                    runLocked();
-                }
-            }
-        }
-
-        public void runLocked() {
-            if (DEBUG) Log.d(TAG, "NetworkThread starting");
-            
-            SntpClient client = new SntpClient();
-            GpsXtraDownloader xtraDownloader = null;
-            
-            if (native_supports_xtra()) {
-                xtraDownloader = new GpsXtraDownloader(mContext, mProperties);
-            }
-            
-            // thread exits after disable() is called
-            while (!mDone) {
-                long waitTime = getWaitTime();
-                do {                        
-                    synchronized (this) {
-                        try {
-                            if (!mNetworkAvailable) {
-                                if (DEBUG) Log.d(TAG, "NetworkThread wait for network");
-                                wait();
-                            } else if (waitTime > 0) {
-                                if (DEBUG) {
-                                    Log.d(TAG, "NetworkThread wait for " +
-                                            waitTime + "ms");
-                                }
-                                wait(waitTime);
-                            }
-                        } catch (InterruptedException e) {
-                            if (DEBUG) {
-                                Log.d(TAG, "InterruptedException in GpsNetworkThread");
-                            }
-                        }
+    private final class ProviderHandler extends Handler {
+        @Override
+        public void handleMessage(Message msg)
+        {
+            switch (msg.what) {
+                case ENABLE:
+                    if (msg.arg1 == 1) {
+                        handleEnable();
+                    } else {
+                        handleDisable();
                     }
-                    waitTime = getWaitTime();
-                } while (!mDone && ((!mXtraDownloadRequested &&
-                        !mTimeInjectRequested && waitTime > 0)
-                        || !mNetworkAvailable));
-                if (DEBUG) Log.d(TAG, "NetworkThread out of wake loop"); 
-                if (!mDone) {
-                    if (mNtpServer != null && 
-                            (mTimeInjectRequested || mNextNtpTime <= System.currentTimeMillis())) {
-                        if (DEBUG) {
-                            Log.d(TAG, "Requesting time from NTP server " + mNtpServer);
-                        }
-                        mTimeInjectRequested = false;
-                        if (client.requestTime(mNtpServer, 10000)) {
-                            long time = client.getNtpTime();
-                            long timeReference = client.getNtpTimeReference();
-                            int certainty = (int)(client.getRoundTripTime()/2);
-                            long now = System.currentTimeMillis();
-                            long systemTimeOffset = time - now;
-        
-                            Log.d(TAG, "NTP server returned: "
-                                    + time + " (" + new Date(time)
-                                    + ") reference: " + timeReference
-                                    + " certainty: " + certainty
-                                    + " system time offset: " + systemTimeOffset);
-
-                            // sanity check NTP time and do not use if it is too far from system time
-                            if (systemTimeOffset < 0) {
-                                systemTimeOffset = -systemTimeOffset;
-                            }
-                            if (systemTimeOffset < MAX_NTP_SYSTEM_TIME_OFFSET) {
-                                native_inject_time(time, timeReference, certainty);
-                            } else {
-                                Log.e(TAG, "NTP time differs from system time by " + systemTimeOffset
-                                        + "ms.  Ignoring.");
-                            }
-                            mNextNtpTime = now + NTP_INTERVAL;
-                        } else {
-                            if (DEBUG) Log.d(TAG, "requestTime failed");
-                            mNextNtpTime = System.currentTimeMillis() + RETRY_INTERVAL;
-                        }
+                    break;
+                case ENABLE_TRACKING:
+                    handleEnableLocationTracking(msg.arg1 == 1);
+                    break;
+                case UPDATE_NETWORK_STATE:
+                    handleUpdateNetworkState(msg.arg1, (NetworkInfo)msg.obj);
+                    break;
+                case INJECT_NTP_TIME:
+                    handleInjectNtpTime();
+                    break;
+                case DOWNLOAD_XTRA_DATA:
+                    if (native_supports_xtra()) {
+                        handleDownloadXtraData();
                     }
-
-                    if ((mXtraDownloadRequested || 
-                            (mNextXtraTime > 0 && mNextXtraTime <= System.currentTimeMillis()))
-                            && xtraDownloader != null) {
-                        mXtraDownloadRequested = false;
-                        byte[] data = xtraDownloader.downloadXtraData();
-                        if (data != null) {
-                            if (DEBUG) {
-                                Log.d(TAG, "calling native_inject_xtra_data");
-                            }
-                            native_inject_xtra_data(data, data.length);
-                            mNextXtraTime = 0;
-                        } else {
-                            mNextXtraTime = System.currentTimeMillis() + RETRY_INTERVAL;
-                        }
-                    }
-                }
+                    break;
+                case UPDATE_LOCATION:
+                    handleUpdateLocation((Location)msg.obj);
+                    break;
+                case ADD_LISTENER:
+                    handleAddListener(msg.arg1);
+                    break;
+                case REMOVE_LISTENER:
+                    handleRemoveListener(msg.arg1);
+                    break;
             }
-            if (DEBUG) Log.d(TAG, "NetworkThread exiting");
         }
-        
-        synchronized void xtraDownloadRequest() {
-            mXtraDownloadRequested = true;
-            notify();
-        }
+    };
 
-        synchronized void timeInjectRequest() {
-            mTimeInjectRequested = true;
-            notify();
-        }
-
-        synchronized void signal() {
-            notify();
-        }
-
-        synchronized void setDone() {
-            if (DEBUG) Log.d(TAG, "stopping NetworkThread");
-            mDone = true;
-            notify();
-        }
-
-        private long getWaitTime() {
-            long now = System.currentTimeMillis();
-            long waitTime = Long.MAX_VALUE;
-            if (mNtpServer != null) {
-                waitTime = mNextNtpTime - now;
-            }
-            if (mNextXtraTime != 0) {
-                long xtraWaitTime = mNextXtraTime - now;
-                if (xtraWaitTime < waitTime) {
-                    waitTime = xtraWaitTime;
-                }
-            }
-            if (waitTime < 0) {
-                waitTime = 0;
-            }
-            return waitTime;
-        }
+    public void run()
+    {
+        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+        initialize();
+        Looper.prepare();
+        mHandler = new ProviderHandler();
+        Looper.loop();
     }
 
     // for GPS SV statistics
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index fb39ac0..2ad663d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -301,18 +301,19 @@
              * enabled or disabled based on product resources.
              */
             db.beginTransaction();
+            SQLiteStatement stmt = null;
             try {
                 db.execSQL("DELETE FROM system WHERE name='"
                         + Settings.System.WINDOW_ANIMATION_SCALE + "'");
                 db.execSQL("DELETE FROM system WHERE name='"
                         + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
-                SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+                stmt = db.compileStatement("INSERT INTO system(name,value)"
                         + " VALUES(?,?);");
                 loadDefaultAnimationSettings(stmt);
-                stmt.close();
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
+                if (stmt != null) stmt.close();
             }
             upgradeVersion = 32;
         }
@@ -349,14 +350,15 @@
 
         if (upgradeVersion == 34) {
             db.beginTransaction();
+            SQLiteStatement stmt = null;
             try {
-                SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
+                stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
                         + " VALUES(?,?);");
                 loadSecure35Settings(stmt);
-                stmt.close();
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
+                if (stmt != null) stmt.close();
             }
             upgradeVersion = 35;
         }
@@ -391,15 +393,16 @@
 
         if (upgradeVersion == 37) {
             db.beginTransaction();
+            SQLiteStatement stmt = null;
             try {
-                SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                         + " VALUES(?,?);");
                 loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
                         R.string.airplane_mode_toggleable_radios);
-                stmt.close();
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
+                if (stmt != null) stmt.close();
             }
             upgradeVersion = 38;
         }
@@ -440,18 +443,19 @@
              * All animations are now turned on by default!
              */
             db.beginTransaction();
+            SQLiteStatement stmt = null;
             try {
                 db.execSQL("DELETE FROM system WHERE name='"
                         + Settings.System.WINDOW_ANIMATION_SCALE + "'");
                 db.execSQL("DELETE FROM system WHERE name='"
                         + Settings.System.TRANSITION_ANIMATION_SCALE + "'");
-                SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+                stmt = db.compileStatement("INSERT INTO system(name,value)"
                         + " VALUES(?,?);");
                 loadDefaultAnimationSettings(stmt);
-                stmt.close();
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
+                if (stmt != null) stmt.close();
             }
             upgradeVersion = 41;
         }
@@ -461,16 +465,17 @@
              * Initialize newly public haptic feedback setting
              */
             db.beginTransaction();
+            SQLiteStatement stmt = null;
             try {
                 db.execSQL("DELETE FROM system WHERE name='"
                         + Settings.System.HAPTIC_FEEDBACK_ENABLED + "'");
-                SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+                stmt = db.compileStatement("INSERT INTO system(name,value)"
                         + " VALUES(?,?);");
                 loadDefaultHapticSettings(stmt);
-                stmt.close();
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
+                if (stmt != null) stmt.close();
             }
             upgradeVersion = 42;
         }
@@ -480,15 +485,16 @@
              * Initialize new notification pulse setting
              */
             db.beginTransaction();
+            SQLiteStatement stmt = null;
             try {
-                SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+                stmt = db.compileStatement("INSERT INTO system(name,value)"
                         + " VALUES(?,?);");
                 loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
                         R.bool.def_notification_pulse);
-                stmt.close();
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
+                if (stmt != null) stmt.close();
             }
             upgradeVersion = 43;
         }
@@ -498,15 +504,16 @@
              * This upgrade stores bluetooth volume separately from voice volume
              */
             db.beginTransaction();
+            SQLiteStatement stmt = null;
             try {
-                SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+                stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                         + " VALUES(?,?);");
                 loadSetting(stmt, Settings.System.VOLUME_BLUETOOTH_SCO,
                         AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
-                stmt.close();
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
+                if (stmt != null) stmt.close();
             }
             upgradeVersion = 44;
         }
@@ -585,14 +592,15 @@
             * New settings for new user interface noises.
             */
            db.beginTransaction();
+           SQLiteStatement stmt = null;
            try {
-                SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+                stmt = db.compileStatement("INSERT INTO system(name,value)"
                         + " VALUES(?,?);");
                 loadUISoundEffectsSettings(stmt);
-                stmt.close();
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
+                if (stmt != null) stmt.close();
             }
 
            upgradeVersion = 50;
@@ -603,15 +611,16 @@
             * New settings for set install location UI.
             */
            db.beginTransaction();
+           SQLiteStatement stmt = null;
            try {
-                SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+                stmt = db.compileStatement("INSERT INTO system(name,value)"
                         + " VALUES(?,?);");
                 loadBooleanSetting(stmt, Settings.System.SET_INSTALL_LOCATION,
                         R.bool.set_install_location);
-                stmt.close();
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
+                if (stmt != null) stmt.close();
             }
 
            upgradeVersion = 51;
@@ -637,15 +646,16 @@
         if (upgradeVersion == 52) {
             // new vibration/silent mode settings
             db.beginTransaction();
+            SQLiteStatement stmt = null;
             try {
-                SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+                stmt = db.compileStatement("INSERT INTO system(name,value)"
                         + " VALUES(?,?);");
                 loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
                         R.bool.def_vibrate_in_silent);
-                stmt.close();
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
+                if (stmt != null) stmt.close();
             }
 
             upgradeVersion = 53;
@@ -656,15 +666,16 @@
              * New settings for set install location UI.
              */
             db.beginTransaction();
+            SQLiteStatement stmt = null;
             try {
-                 SQLiteStatement stmt = db.compileStatement("INSERT INTO system(name,value)"
+                 stmt = db.compileStatement("INSERT INTO system(name,value)"
                          + " VALUES(?,?);");
                  loadIntegerSetting(stmt, Settings.System.DEFAULT_INSTALL_LOCATION,
                          R.integer.def_install_location);
-                 stmt.close();
                  db.setTransactionSuccessful();
              } finally {
                  db.endTransaction();
+                 if (stmt != null) stmt.close();
              }
 
             upgradeVersion = 54;
@@ -844,47 +855,50 @@
      * @param db the database to insert the volume levels into
      */
     private void loadVolumeLevels(SQLiteDatabase db) {
-        SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
-                + " VALUES(?,?);");
-
-        loadSetting(stmt, Settings.System.VOLUME_MUSIC,
-                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
-        loadSetting(stmt, Settings.System.VOLUME_RING,
-                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_RING]);
-        loadSetting(stmt, Settings.System.VOLUME_SYSTEM,
-                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]);
-        loadSetting(
-                stmt,
-                Settings.System.VOLUME_VOICE,
-                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]);
-        loadSetting(stmt, Settings.System.VOLUME_ALARM,
-                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_ALARM]);
-        loadSetting(
-                stmt,
-                Settings.System.VOLUME_NOTIFICATION,
-                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_NOTIFICATION]);
-        loadSetting(
-                stmt,
-                Settings.System.VOLUME_BLUETOOTH_SCO,
-                AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
-
-        loadSetting(stmt, Settings.System.MODE_RINGER,
-                AudioManager.RINGER_MODE_NORMAL);
-
-        loadVibrateSetting(db, false);
-
-        // By default, only the ring/notification and system streams are affected
-        loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED,
-                (1 << AudioManager.STREAM_RING) | (1 << AudioManager.STREAM_NOTIFICATION) |
-                (1 << AudioManager.STREAM_SYSTEM) | (1 << AudioManager.STREAM_SYSTEM_ENFORCED));
-
-        loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED,
-                ((1 << AudioManager.STREAM_MUSIC) |
-                 (1 << AudioManager.STREAM_RING) |
-                 (1 << AudioManager.STREAM_NOTIFICATION) |
-                 (1 << AudioManager.STREAM_SYSTEM)));
-
-        stmt.close();
+        SQLiteStatement stmt = null;
+        try {
+            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+                    + " VALUES(?,?);");
+    
+            loadSetting(stmt, Settings.System.VOLUME_MUSIC,
+                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
+            loadSetting(stmt, Settings.System.VOLUME_RING,
+                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_RING]);
+            loadSetting(stmt, Settings.System.VOLUME_SYSTEM,
+                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]);
+            loadSetting(
+                    stmt,
+                    Settings.System.VOLUME_VOICE,
+                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]);
+            loadSetting(stmt, Settings.System.VOLUME_ALARM,
+                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_ALARM]);
+            loadSetting(
+                    stmt,
+                    Settings.System.VOLUME_NOTIFICATION,
+                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_NOTIFICATION]);
+            loadSetting(
+                    stmt,
+                    Settings.System.VOLUME_BLUETOOTH_SCO,
+                    AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
+    
+            loadSetting(stmt, Settings.System.MODE_RINGER,
+                    AudioManager.RINGER_MODE_NORMAL);
+    
+            loadVibrateSetting(db, false);
+    
+            // By default, only the ring/notification and system streams are affected
+            loadSetting(stmt, Settings.System.MODE_RINGER_STREAMS_AFFECTED,
+                    (1 << AudioManager.STREAM_RING) | (1 << AudioManager.STREAM_NOTIFICATION) |
+                    (1 << AudioManager.STREAM_SYSTEM) | (1 << AudioManager.STREAM_SYSTEM_ENFORCED));
+    
+            loadSetting(stmt, Settings.System.MUTE_STREAMS_AFFECTED,
+                    ((1 << AudioManager.STREAM_MUSIC) |
+                     (1 << AudioManager.STREAM_RING) |
+                     (1 << AudioManager.STREAM_NOTIFICATION) |
+                     (1 << AudioManager.STREAM_SYSTEM)));
+        } finally {
+            if (stmt != null) stmt.close();
+        }
     }
 
     private void loadVibrateSetting(SQLiteDatabase db, boolean deleteOld) {
@@ -892,17 +906,21 @@
             db.execSQL("DELETE FROM system WHERE name='" + Settings.System.VIBRATE_ON + "'");
         }
 
-        SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
-                + " VALUES(?,?);");
-
-        // Vibrate off by default for ringer, on for notification
-        int vibrate = 0;
-        vibrate = AudioService.getValueForVibrateSetting(vibrate,
-                AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_ON);
-        vibrate = AudioService.getValueForVibrateSetting(vibrate,
-                AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
-        loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);
-        stmt.close();
+        SQLiteStatement stmt = null;
+        try {
+            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+                    + " VALUES(?,?);");
+    
+            // Vibrate off by default for ringer, on for notification
+            int vibrate = 0;
+            vibrate = AudioService.getValueForVibrateSetting(vibrate,
+                    AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_ON);
+            vibrate = AudioService.getValueForVibrateSetting(vibrate,
+                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
+            loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);
+        } finally {
+            if (stmt != null) stmt.close();
+        }
     }
 
     private void loadSettings(SQLiteDatabase db) {
@@ -911,69 +929,72 @@
     }
 
     private void loadSystemSettings(SQLiteDatabase db) {
-        SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
-                + " VALUES(?,?);");
-
-        loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
-                R.bool.def_dim_screen);
-        loadSetting(stmt, Settings.System.STAY_ON_WHILE_PLUGGED_IN,
-                "1".equals(SystemProperties.get("ro.kernel.qemu")) ? 1 : 0);
-        loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
-                R.integer.def_screen_off_timeout);
-
-        // Set default cdma emergency tone
-        loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0);
-
-        // Set default cdma call auto retry
-        loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0);
-
-        // Set default cdma DTMF type
-        loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
-
-        // Set default hearing aid
-        loadSetting(stmt, Settings.System.HEARING_AID, 0);
-
-        // Set default tty mode
-        loadSetting(stmt, Settings.System.TTY_MODE, 0);
-
-        loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON,
-                R.bool.def_airplane_mode_on);
-
-        loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS,
-                R.string.def_airplane_mode_radios);
-
-        loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
-                R.string.airplane_mode_toggleable_radios);
-
-        loadBooleanSetting(stmt, Settings.System.AUTO_TIME,
-                R.bool.def_auto_time); // Sync time to NITZ
-
-        loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
-                R.integer.def_screen_brightness);
-
-        loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
-                R.bool.def_screen_brightness_automatic_mode);
-
-        loadDefaultAnimationSettings(stmt);
-
-        loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
-                R.bool.def_accelerometer_rotation);
-
-        loadDefaultHapticSettings(stmt);
-
-        loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
-                R.bool.def_notification_pulse);
-        loadBooleanSetting(stmt, Settings.System.SET_INSTALL_LOCATION,
-                R.bool.set_install_location);
-        loadIntegerSetting(stmt, Settings.System.DEFAULT_INSTALL_LOCATION,
-                R.integer.def_install_location);
-
-        loadUISoundEffectsSettings(stmt);
-
-        loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
-                R.bool.def_vibrate_in_silent);
-
-        stmt.close();
+        SQLiteStatement stmt = null;
+        try {
+            stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
+                    + " VALUES(?,?);");
+    
+            loadBooleanSetting(stmt, Settings.System.DIM_SCREEN,
+                    R.bool.def_dim_screen);
+            loadSetting(stmt, Settings.System.STAY_ON_WHILE_PLUGGED_IN,
+                    "1".equals(SystemProperties.get("ro.kernel.qemu")) ? 1 : 0);
+            loadIntegerSetting(stmt, Settings.System.SCREEN_OFF_TIMEOUT,
+                    R.integer.def_screen_off_timeout);
+    
+            // Set default cdma emergency tone
+            loadSetting(stmt, Settings.System.EMERGENCY_TONE, 0);
+    
+            // Set default cdma call auto retry
+            loadSetting(stmt, Settings.System.CALL_AUTO_RETRY, 0);
+    
+            // Set default cdma DTMF type
+            loadSetting(stmt, Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, 0);
+    
+            // Set default hearing aid
+            loadSetting(stmt, Settings.System.HEARING_AID, 0);
+    
+            // Set default tty mode
+            loadSetting(stmt, Settings.System.TTY_MODE, 0);
+    
+            loadBooleanSetting(stmt, Settings.System.AIRPLANE_MODE_ON,
+                    R.bool.def_airplane_mode_on);
+    
+            loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_RADIOS,
+                    R.string.def_airplane_mode_radios);
+    
+            loadStringSetting(stmt, Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS,
+                    R.string.airplane_mode_toggleable_radios);
+    
+            loadBooleanSetting(stmt, Settings.System.AUTO_TIME,
+                    R.bool.def_auto_time); // Sync time to NITZ
+    
+            loadIntegerSetting(stmt, Settings.System.SCREEN_BRIGHTNESS,
+                    R.integer.def_screen_brightness);
+    
+            loadBooleanSetting(stmt, Settings.System.SCREEN_BRIGHTNESS_MODE,
+                    R.bool.def_screen_brightness_automatic_mode);
+    
+            loadDefaultAnimationSettings(stmt);
+    
+            loadBooleanSetting(stmt, Settings.System.ACCELEROMETER_ROTATION,
+                    R.bool.def_accelerometer_rotation);
+    
+            loadDefaultHapticSettings(stmt);
+    
+            loadBooleanSetting(stmt, Settings.System.NOTIFICATION_LIGHT_PULSE,
+                    R.bool.def_notification_pulse);
+            loadBooleanSetting(stmt, Settings.System.SET_INSTALL_LOCATION,
+                    R.bool.set_install_location);
+            loadIntegerSetting(stmt, Settings.System.DEFAULT_INSTALL_LOCATION,
+                    R.integer.def_install_location);
+    
+            loadUISoundEffectsSettings(stmt);
+    
+            loadBooleanSetting(stmt, Settings.System.VIBRATE_IN_SILENT,
+                    R.bool.def_vibrate_in_silent);
+        } finally {
+            if (stmt != null) stmt.close();
+        }
     }
 
     private void loadUISoundEffectsSettings(SQLiteStatement stmt) {
@@ -1014,79 +1035,82 @@
     }
 
     private void loadSecureSettings(SQLiteDatabase db) {
-        SQLiteStatement stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
-                + " VALUES(?,?);");
-
-        loadBooleanSetting(stmt, Settings.Secure.BLUETOOTH_ON,
-                R.bool.def_bluetooth_on);
-
-        // Data roaming default, based on build
-        loadSetting(stmt, Settings.Secure.DATA_ROAMING,
-                "true".equalsIgnoreCase(
-                        SystemProperties.get("ro.com.android.dataroaming",
-                                "false")) ? 1 : 0);
-
-        loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
-                R.bool.def_install_non_market_apps);
-
-        loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
-                R.string.def_location_providers_allowed);
-
-        loadBooleanSetting(stmt, Settings.Secure.ASSISTED_GPS_ENABLED,
-                R.bool.assisted_gps_enabled);
-
-        loadIntegerSetting(stmt, Settings.Secure.NETWORK_PREFERENCE,
-                R.integer.def_network_preference);
-
-        loadBooleanSetting(stmt, Settings.Secure.USB_MASS_STORAGE_ENABLED,
-                R.bool.def_usb_mass_storage_enabled);
-
-        loadBooleanSetting(stmt, Settings.Secure.WIFI_ON,
-                R.bool.def_wifi_on);
-        loadBooleanSetting(stmt, Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
-                R.bool.def_networks_available_notification_on);
-
-        String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
-        if (!TextUtils.isEmpty(wifiWatchList)) {
-            loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
+        SQLiteStatement stmt = null;
+        try {
+            stmt = db.compileStatement("INSERT OR IGNORE INTO secure(name,value)"
+                    + " VALUES(?,?);");
+    
+            loadBooleanSetting(stmt, Settings.Secure.BLUETOOTH_ON,
+                    R.bool.def_bluetooth_on);
+    
+            // Data roaming default, based on build
+            loadSetting(stmt, Settings.Secure.DATA_ROAMING,
+                    "true".equalsIgnoreCase(
+                            SystemProperties.get("ro.com.android.dataroaming",
+                                    "false")) ? 1 : 0);
+    
+            loadBooleanSetting(stmt, Settings.Secure.INSTALL_NON_MARKET_APPS,
+                    R.bool.def_install_non_market_apps);
+    
+            loadStringSetting(stmt, Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
+                    R.string.def_location_providers_allowed);
+    
+            loadBooleanSetting(stmt, Settings.Secure.ASSISTED_GPS_ENABLED,
+                    R.bool.assisted_gps_enabled);
+    
+            loadIntegerSetting(stmt, Settings.Secure.NETWORK_PREFERENCE,
+                    R.integer.def_network_preference);
+    
+            loadBooleanSetting(stmt, Settings.Secure.USB_MASS_STORAGE_ENABLED,
+                    R.bool.def_usb_mass_storage_enabled);
+    
+            loadBooleanSetting(stmt, Settings.Secure.WIFI_ON,
+                    R.bool.def_wifi_on);
+            loadBooleanSetting(stmt, Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
+                    R.bool.def_networks_available_notification_on);
+    
+            String wifiWatchList = SystemProperties.get("ro.com.android.wifi-watchlist");
+            if (!TextUtils.isEmpty(wifiWatchList)) {
+                loadSetting(stmt, Settings.Secure.WIFI_WATCHDOG_WATCH_LIST, wifiWatchList);
+            }
+    
+            // Set the preferred network mode to 0 = Global, CDMA default
+            int type = SystemProperties.getInt("ro.telephony.default_network",
+                    RILConstants.PREFERRED_NETWORK_MODE);
+            loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE, type);
+    
+            // Enable or disable Cell Broadcast SMS
+            loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS,
+                    RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
+    
+            // Set the preferred cdma subscription to 0 = Subscription from RUIM, when available
+            loadSetting(stmt, Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION,
+                    RILConstants.PREFERRED_CDMA_SUBSCRIPTION);
+    
+            // Don't do this.  The SystemServer will initialize ADB_ENABLED from a
+            // persistent system property instead.
+            //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
+    
+            // Allow mock locations default, based on build
+            loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
+                    "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);
+    
+            loadSecure35Settings(stmt);
+    
+            loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
+                    R.bool.def_mount_play_notification_snd);
+    
+            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
+                    R.bool.def_mount_ums_autostart);
+    
+            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
+                    R.bool.def_mount_ums_prompt);
+    
+            loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
+                    R.bool.def_mount_ums_notify_enabled);
+        } finally {
+            if (stmt != null) stmt.close();
         }
-
-        // Set the preferred network mode to 0 = Global, CDMA default
-        int type = SystemProperties.getInt("ro.telephony.default_network",
-                RILConstants.PREFERRED_NETWORK_MODE);
-        loadSetting(stmt, Settings.Secure.PREFERRED_NETWORK_MODE, type);
-
-        // Enable or disable Cell Broadcast SMS
-        loadSetting(stmt, Settings.Secure.CDMA_CELL_BROADCAST_SMS,
-                RILConstants.CDMA_CELL_BROADCAST_SMS_DISABLED);
-
-        // Set the preferred cdma subscription to 0 = Subscription from RUIM, when available
-        loadSetting(stmt, Settings.Secure.PREFERRED_CDMA_SUBSCRIPTION,
-                RILConstants.PREFERRED_CDMA_SUBSCRIPTION);
-
-        // Don't do this.  The SystemServer will initialize ADB_ENABLED from a
-        // persistent system property instead.
-        //loadSetting(stmt, Settings.Secure.ADB_ENABLED, 0);
-
-        // Allow mock locations default, based on build
-        loadSetting(stmt, Settings.Secure.ALLOW_MOCK_LOCATION,
-                "1".equals(SystemProperties.get("ro.allow.mock.location")) ? 1 : 0);
-
-        loadSecure35Settings(stmt);
-
-        loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
-                R.bool.def_mount_play_notification_snd);
-
-        loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
-                R.bool.def_mount_ums_autostart);
-
-        loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_PROMPT,
-                R.bool.def_mount_ums_prompt);
-
-        loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
-                R.bool.def_mount_ums_notify_enabled);
-
-        stmt.close();
     }
 
     private void loadSecure35Settings(SQLiteStatement stmt) {
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index a4703de..10920fa 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -100,6 +100,7 @@
         public static final int OpFailedMediaCorrupt           = 403;
         public static final int OpFailedVolNotMounted          = 404;
         public static final int OpFailedStorageBusy            = 405;
+        public static final int OpFailedStorageNotFound        = 406;
 
         /*
          * 600 series - Unsolicited broadcasts.
@@ -1290,21 +1291,22 @@
         waitForReady();
         warnOnNotMounted();
 
-        ArrayList<String> rsp = mConnector.doCommand("asec path " + id);
-
-        for (String line : rsp) {
-            String []tok = line.split(" ");
+        try {
+            ArrayList<String> rsp = mConnector.doCommand(String.format("asec path %s", id));
+            String []tok = rsp.get(0).split(" ");
             int code = Integer.parseInt(tok[0]);
-            if (code == VoldResponseCode.AsecPathResult) {
-                return tok[1];
+            if (code != VoldResponseCode.AsecPathResult) {
+                throw new IllegalStateException(String.format("Unexpected response code %d", code));
+            }
+            return tok[1];
+        } catch (NativeDaemonConnectorException e) {
+            int code = e.getCode();
+            if (code == VoldResponseCode.OpFailedStorageNotFound) {
+                throw new IllegalArgumentException(String.format("Container '%s' not found", id));
             } else {
-                Log.e(TAG, String.format("Unexpected response code %d", code));
-                return "";
+                throw new IllegalStateException(String.format("Unexpected response code %d", code));
             }
         }
-
-        Log.e(TAG, "Got an empty response");
-        return "";
     }
 
     public void finishMediaUpdate() {
diff --git a/services/java/com/android/server/NativeDaemonConnector.java b/services/java/com/android/server/NativeDaemonConnector.java
index 39c847a..08d7ce6 100644
--- a/services/java/com/android/server/NativeDaemonConnector.java
+++ b/services/java/com/android/server/NativeDaemonConnector.java
@@ -48,6 +48,8 @@
     private String                mSocket;
     private INativeDaemonConnectorCallbacks mCallbacks;
 
+    private final int BUFFER_SIZE = 4096;
+
     class ResponseCode {
         public static final int ActionInitiated                = 100;
 
@@ -87,7 +89,7 @@
     }
 
     private void listenToSocket() throws IOException {
-       LocalSocket socket = null;
+        LocalSocket socket = null;
 
         try {
             socket = new LocalSocket();
@@ -100,13 +102,13 @@
             InputStream inputStream = socket.getInputStream();
             mOutputStream = socket.getOutputStream();
 
-            byte[] buffer = new byte[4096];
+            byte[] buffer = new byte[BUFFER_SIZE];
+            int start = 0;
 
             while (true) {
-                int count = inputStream.read(buffer);
+                int count = inputStream.read(buffer, start, BUFFER_SIZE - start);
                 if (count < 0) break;
 
-                int start = 0;
                 for (int i = 0; i < count; i++) {
                     if (buffer[i] == 0) {
                         String event = new String(buffer, start, i - start);
@@ -139,6 +141,13 @@
                         start = i + 1;
                     }
                 }
+                if (start != count) {
+                    final int remaining = BUFFER_SIZE - start;
+                    System.arraycopy(buffer, start, buffer, 0, remaining);
+                    start = remaining;
+                } else {
+                    start = 0;
+                }
             }
         } catch (IOException ex) {
             Slog.e(TAG, "Communications error", ex);
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index f9e1963..53415c7 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -4001,6 +4001,8 @@
                             changedPermission = true;
                             gp.grantedPermissions.add(perm);
                             gp.gids = appendInts(gp.gids, bp.gids);
+                        } else if (!ps.haveGids) {
+                            gp.gids = appendInts(gp.gids, bp.gids);
                         }
                     } else {
                         Slog.w(TAG, "Not granting permission " + perm
@@ -4038,6 +4040,7 @@
             // changed.
             ps.permissionsFixed = true;
         }
+        ps.haveGids = true;
     }
     
     private final class ActivityIntentResolver
@@ -6926,7 +6929,8 @@
                     pw.print("    timeStamp="); pw.println(ps.getTimeStampStr());
                     pw.print("    signatures="); pw.println(ps.signatures);
                     pw.print("    permissionsFixed="); pw.print(ps.permissionsFixed);
-                            pw.print(" pkgFlags=0x"); pw.print(Integer.toHexString(ps.pkgFlags));
+                            pw.print(" haveGids="); pw.println(ps.haveGids);
+                    pw.print("    pkgFlags=0x"); pw.print(Integer.toHexString(ps.pkgFlags));
                             pw.print(" installStatus="); pw.print(ps.installStatus);
                             pw.print(" enabled="); pw.println(ps.enabled);
                     if (ps.disabledComponents.size() > 0) {
@@ -7548,6 +7552,7 @@
         PackageSignatures signatures = new PackageSignatures();
 
         boolean permissionsFixed;
+        boolean haveGids;
 
         /* Explicitly disabled components */
         HashSet<String> disabledComponents = new HashSet<String>(0);
@@ -7621,6 +7626,7 @@
             timeStampString = base.timeStampString;
             signatures = base.signatures;
             permissionsFixed = base.permissionsFixed;
+            haveGids = base.haveGids;
             disabledComponents = base.disabledComponents;
             enabledComponents = base.enabledComponents;
             enabled = base.enabled;
@@ -9572,11 +9578,10 @@
        if (doGc) {
            Runtime.getRuntime().gc();
        }
-       // Delete any stale containers if needed.
+       // List stale containers.
        if (removeCids != null) {
            for (String cid : removeCids) {
-               Log.i(TAG, "Destroying stale container : " + cid);
-               PackageHelper.destroySdDir(cid);
+               Log.w(TAG, "Container " + cid + " is stale");
            }
        }
    }
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index 166b6b6..5e1b82f 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -91,7 +91,6 @@
     private static final String DNS_DEFAULT_SERVER2 = "4.2.2.2";
 
     private boolean mDunRequired;  // configuration info - must use DUN apn on 3g
-    private boolean mUseHiPri;
 
     private HierarchicalStateMachine mTetherMasterSM;
 
@@ -1052,13 +1051,12 @@
                 return false;
             }
             protected int turnOnMobileConnection() {
-                Log.d(TAG, "turnonMobileConnection with mUseHiPri="+mUseHiPri);
                 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
                 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
                 int retValue = Phone.APN_REQUEST_FAILED;
                 try {
                     retValue = service.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
-                            (mUseHiPri ? Phone.FEATURE_ENABLE_HIPRI : Phone.FEATURE_ENABLE_DUN),
+                            (mDunRequired ? Phone.FEATURE_ENABLE_DUN : Phone.FEATURE_ENABLE_HIPRI),
                             new Binder());
                 } catch (Exception e) {
                 }
@@ -1083,8 +1081,8 @@
                             IConnectivityManager.Stub.asInterface(b);
                     try {
                         service.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
-                                (mUseHiPri ? Phone.FEATURE_ENABLE_HIPRI :
-                                             Phone.FEATURE_ENABLE_DUN));
+                                (mDunRequired? Phone.FEATURE_ENABLE_DUN :
+                                             Phone.FEATURE_ENABLE_HIPRI));
                     } catch (Exception e) {
                         return false;
                     }
@@ -1175,57 +1173,51 @@
                 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
                 IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b);
                 mConnectionRequested = false;
-                mUseHiPri = false;
                 Log.d(TAG, "chooseUpstreamType(" + tryCell + "),  dunRequired ="
                         + mDunRequired + ", iface=" + iface);
-                if (mDunRequired) {
-                    // check if Dun is on
+                if (iface != null) {
                     try {
-                        NetworkInfo info = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_DUN);
-                        if (info.isConnected()) {
-                            Log.d(TAG, "setting dun ifacename =" + iface);
-                            notifyTetheredOfNewIface(iface);
-                            // even if we're already connected - it may be somebody else's
-                            // refcount, so add our own
-                            turnOnMobileConnection();
-                        }
-                    } catch (RemoteException e) {
-                        Log.e(TAG, "RemoteException calling ConnectivityManager");
-                        notifyTetheredOfNewIface(null);
-                    }
-                    if (tryCell == TRY_TO_SETUP_MOBILE_CONNECTION) {
-                        turnOnMobileConnection();
-                    }
-                } else {
-                    if (iface == null) {
-                        if (tryCell == TRY_TO_SETUP_MOBILE_CONNECTION) {
-                            Log.d(TAG, "turning on hipri");
-                            mUseHiPri = true;
-                            turnOnMobileConnection(); // try to turn on hipri
-                        }
-
-                    } else {
-                        try {
+                        if (mDunRequired) {
+                            // check if Dun is on - we can use that
+                            NetworkInfo info = cm.getNetworkInfo(
+                                    ConnectivityManager.TYPE_MOBILE_DUN);
+                            if (info.isConnected()) {
+                                Log.d(TAG, "setting dun ifacename =" + iface);
+                                // even if we're already connected - it may be somebody else's
+                                // refcount, so add our own
+                                turnOnMobileConnection();
+                            } else {
+                                // verify the iface is not the default mobile - can't use that!
+                                info = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
+                                if (info.isConnected()) {
+                                    iface = null; // can't accept this one
+                                }
+                            }
+                        } else {
                             Log.d(TAG, "checking if hipri brought us this connection");
                             NetworkInfo info = cm.getNetworkInfo(
                                     ConnectivityManager.TYPE_MOBILE_HIPRI);
                             if (info.isConnected()) {
                                 Log.d(TAG, "yes - hipri in use");
-                                mUseHiPri = true;
+                                // even if we're already connected - it may be sombody else's
+                                // refcount, so add our own
                                 turnOnMobileConnection();
                             }
-                        } catch (RemoteException e) {
-                            Log.e(TAG, "RemoteException calling ConnectivityManager");
                         }
-                        // we don't require Dun and have an iface that satisfies, so use it
-                        Log.d(TAG, "setting non-dun iface =" + iface);
-                        notifyTetheredOfNewIface(iface);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "RemoteException calling ConnectivityManager " + e);
+                        iface = null;
                     }
                 }
-                if (iface == null) {
+                // may have been set to null in the if above
+                if (iface == null ) {
+                    if (tryCell == TRY_TO_SETUP_MOBILE_CONNECTION) {
+                        turnOnMobileConnection();
+                    }
                     // wait for things to settle and retry
                     sendMessageDelayed(CMD_RETRY_UPSTREAM, UPSTREAM_SETTLE_TIME_MS);
                 }
+                notifyTetheredOfNewIface(iface);
             }
             protected void notifyTetheredOfNewIface(String ifaceName) {
                 Log.d(TAG, "notifying tethered with iface =" + ifaceName);
@@ -1240,7 +1232,6 @@
         class InitialState extends TetherMasterUtilState {
             @Override
             public void enter() {
-                mUseHiPri = false;
                 mConnectionRequested = false;
             }
             @Override
diff --git a/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java b/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java
index f2f7743..fa7b9ff 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/AppCacheTest.java
@@ -136,9 +136,7 @@
         if(localLOGV || TRACKING) Log.i(TAG, "blks3="+blks3);
         verifyTestFiles1(cacheDir, "testtmpdir", 5);
     }
-    
-    // TODO: flaky test
-    // @LargeTest
+
     public void testFreeApplicationCacheSomeFiles() throws Exception {
         StatFs st = new StatFs("/data");
         long blks1 = getFreeStorageBlks(st);
diff --git a/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java b/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java
index 9aed363..9a75047 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java
@@ -259,6 +259,17 @@
         }
     }
 
+    public void testNonExistPath() {
+        IMountService ms = getMs();
+        try {
+            String path = ms.getSecureContainerPath("jparks.broke.it");
+            failStr(path);
+        } catch (IllegalArgumentException e) {
+        } catch (Exception e) {
+            failStr(e);
+        }
+    }
+
     public void testUnmountBusyContainer() {
         IMountService ms = getMs();
         try {
diff --git a/tests/LocationTracker/src/com/android/locationtracker/TrackerService.java b/tests/LocationTracker/src/com/android/locationtracker/TrackerService.java
index 5b75653..e2332bf 100644
--- a/tests/LocationTracker/src/com/android/locationtracker/TrackerService.java
+++ b/tests/LocationTracker/src/com/android/locationtracker/TrackerService.java
@@ -193,11 +193,11 @@
     }
 
     private boolean doDebugLogging() {
-        return getPreferences().getBoolean(DEBUG_PREF, true);
+        return getPreferences().getBoolean(DEBUG_PREF, false);
     }
 
     private boolean trackSignalStrength() {
-        return getPreferences().getBoolean(SIGNAL_PREF, true);
+        return getPreferences().getBoolean(SIGNAL_PREF, false);
     }
 
     private float getLocationMinDistance() {