Merge "Fix issue 2416481: Support Voice Dialer over BT SCO."
diff --git a/api/current.xml b/api/current.xml
index 701586e..e6f3788 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -87668,6 +87668,17 @@
  visibility="public"
 >
 </field>
+<field name="TYPE_WIMAX"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="6"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 </class>
 <class name="Credentials"
  extends="java.lang.Object"
@@ -143010,6 +143021,17 @@
  visibility="public"
 >
 </field>
+<field name="NETWORK_TYPE_IDEN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="11"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="NETWORK_TYPE_UMTS"
  type="int"
  transient="false"
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 654ee68..b8ba3f6 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -389,9 +389,10 @@
     int cachesize = 0;
 
         /* count the source apk as code -- but only if it's not
-         * on the /system partition
+         * on the /system partition and its not on the sdcard.
          */
-    if (strncmp(apkpath, "/system", 7) != 0) {
+    if (strncmp(apkpath, "/system", 7) != 0 &&
+            strncmp(apkpath, SDCARD_DIR_PREFIX, 7) != 0) {
         if (stat(apkpath, &s) == 0) {
             codesize += stat_size(&s);
         }
@@ -403,17 +404,6 @@
             codesize += stat_size(&s);
         }
     }
-
-        /* count the source apk as code -- but only if it's not
-         * installed on the sdcard
-         */
-    if (strncmp(apkpath, SDCARD_DIR_PREFIX, 7) != 0) {
-        if (stat(apkpath, &s) == 0) {
-            codesize += stat_size(&s);
-        }
-    }
-
-
         /* count the cached dexfile as code */
     if (!create_cache_path(path, apkpath)) {
         if (stat(path, &s) == 0) {
diff --git a/cmds/keystore/keystore_get.h b/cmds/keystore/keystore_get.h
index 8330f8e..141f69b 100644
--- a/cmds/keystore/keystore_get.h
+++ b/cmds/keystore/keystore_get.h
@@ -32,9 +32,11 @@
 #endif
 
 /* This function is provided for native components to get values from keystore.
- * Users are required to link against libcutils. The lengths of keys and values
- * are limited to KEYSTORE_MESSAGE_SIZE. This function returns the length of
- * the requested value or -1 if something goes wrong. */
+ * Users are required to link against libcutils. Keys are values are 8-bit safe.
+ * The first two arguments are the key and its length. The third argument
+ * specifies the buffer to store the retrieved value, which must be an array of
+ * KEYSTORE_MESSAGE_SIZE bytes. This function returns the length of the value or
+ * -1 if an error happens. */
 static int keystore_get(const char *key, int length, char *value)
 {
     uint8_t bytes[2] = {length >> 8, length};
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 5e2c61e..6658842 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -47,7 +47,7 @@
     struct timeval tv;
     gettimeofday(&tv, NULL);
 
-    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000;
+    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
 }
 
 static void playSource(OMXClient *client, const sp<MediaSource> &source) {
@@ -434,7 +434,11 @@
         sp<DataSource> dataSource;
         if (!strncasecmp("http://", filename, 7)) {
             dataSource = new HTTPDataSource(filename);
-            dataSource = new CachingDataSource(dataSource, 64 * 1024, 10);
+            if (((HTTPDataSource *)dataSource.get())->connect() != OK) {
+                fprintf(stderr, "failed to connect to HTTP server.\n");
+                return -1;
+            }
+            dataSource = new CachingDataSource(dataSource, 32 * 1024, 20);
         } else {
             dataSource = new FileSource(filename);
         }
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 6d0a266..16b603c 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -1699,7 +1699,7 @@
                 }
             }
         } else {
-            Account[] accounts = getAccounts(null /* type */);
+            Account[] accounts = getAccountsByType(null /* type */);
             fout.println("Accounts: " + accounts.length);
             for (Account account : accounts) {
                 fout.println("  " + account);
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index f364def..0909952 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -266,7 +266,7 @@
     }
 
     private void dismissDialog() {
-        if (mDecor == null || !mShowing || mDecor.getWindowToken() == null) {
+        if (mDecor == null || !mShowing) {
             return;
         }
 
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index ebc64d7..add99d7 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -483,7 +483,7 @@
         int textId = mSearchable.getSearchButtonText(); 
         if (isBrowserSearch()){
             iconLabel = getContext().getResources()
-                    .getDrawable(com.android.internal.R.drawable.ic_btn_search_play);
+                    .getDrawable(com.android.internal.R.drawable.ic_btn_search_go);
         } else if (textId != 0) {
             textLabel = mActivityContext.getResources().getString(textId);  
         } else {
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 625b120..86224c5d 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1654,10 +1654,17 @@
         Intent intent = new Intent(INTENT_ACTION_GLOBAL_SEARCH);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         intent.setComponent(globalSearchActivity);
-        // TODO: Always pass name of calling package as an extra?
-        if (appSearchData != null) {
-            intent.putExtra(APP_DATA, appSearchData);
+        // Make sure that we have a Bundle to put source in
+        if (appSearchData == null) {
+            appSearchData = new Bundle();
+        } else {
+            appSearchData = new Bundle(appSearchData);
         }
+        // Set source to package name of app that starts global search, if not set already.
+        if (!appSearchData.containsKey("source")) {
+            appSearchData.putString("source", mContext.getPackageName());
+        }
+        intent.putExtra(APP_DATA, appSearchData);
         if (!TextUtils.isEmpty(initialQuery)) {
             intent.putExtra(QUERY, initialQuery);
         }
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 85769a6..df48f04 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -416,6 +416,9 @@
     }
 
     private void initializeSyncAdapter(Account account, String authority) {
+        if (Log.isLoggable(TAG, Log.VERBOSE)) {
+            Log.v(TAG, "initializeSyncAdapter: " + account + ", authority " + authority);
+        }
         SyncAdapterType syncAdapterType = SyncAdapterType.newKey(authority, account.type);
         RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
                 mSyncAdapters.getServiceInfo(syncAdapterType);
@@ -427,9 +430,11 @@
         Intent intent = new Intent();
         intent.setAction("android.content.SyncAdapter");
         intent.setComponent(syncAdapterInfo.componentName);
-        mContext.bindService(intent, new InitializerServiceConnection(account, authority, mContext,
+        if (!mContext.bindService(intent, new InitializerServiceConnection(account, authority, mContext,
                 mMainHandler),
-                Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND);
+                Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND)) {
+            Log.w(TAG, "initializeSyncAdapter: failed to bind to " + intent);
+        }
     }
 
     private static class InitializerServiceConnection implements ServiceConnection {
@@ -452,6 +457,9 @@
             try {
                 if (!mInitialized) {
                     mInitialized = true;
+                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
+                        Log.v(TAG, "calling initialize: " + mAccount + ", authority " + mAuthority);
+                    }
                     ISyncAdapter.Stub.asInterface(service).initialize(mAccount, mAuthority);
                 }
             } catch (RemoteException e) {
@@ -1307,7 +1315,6 @@
         // it if sync is still failing
         private boolean mErrorNotificationInstalled = false;
         private volatile CountDownLatch mReadyToRunLatch = new CountDownLatch(1);
-
         public void onBootCompleted() {
             mBootCompleted = true;
             if (mReadyToRunLatch != null) {
@@ -1603,7 +1610,9 @@
             RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo =
                     mSyncAdapters.getServiceInfo(syncAdapterType);
             if (syncAdapterInfo == null) {
-                Log.d(TAG, "can't find a sync adapter for " + syncAdapterType);
+                Log.d(TAG, "can't find a sync adapter for " + syncAdapterType
+                        + ", removing settings for it");
+                mSyncStorageEngine.removeAuthority(op.account, op.authority);
                 runStateIdle();
                 return;
             }
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 240da72..03e606f 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -121,6 +121,9 @@
 
     private static final boolean SYNC_ENABLED_DEFAULT = false;
 
+    // the version of the accounts xml file format
+    private static final int ACCOUNTS_VERSION = 1;
+
     public static class PendingOperation {
         final Account account;
         final int syncSource;
@@ -640,6 +643,12 @@
         }
     }
 
+    public void removeAuthority(Account account, String authority) {
+        synchronized (mAuthorities) {
+            removeAuthorityLocked(account, authority);
+        }
+    }
+
     public AuthorityInfo getAuthority(int authorityId) {
         synchronized (mAuthorities) {
             return mAuthorities.get(authorityId);
@@ -1269,6 +1278,15 @@
         return authority;
     }
 
+    private void removeAuthorityLocked(Account account, String authorityName) {
+        AccountInfo accountInfo = mAccounts.get(account);
+        if (accountInfo != null) {
+            if (accountInfo.authorities.remove(authorityName) != null) {
+                writeAccountInfoLocked();
+            }
+        }
+    }
+
     public SyncStatusInfo getOrCreateSyncStatus(AuthorityInfo authority) {
         synchronized (mAuthorities) {
             return getOrCreateSyncStatusLocked(authority.ident);
@@ -1322,6 +1340,7 @@
      * Read all account information back in to the initial engine state.
      */
     private void readAccountInfoLocked() {
+        boolean writeNeeded = false;
         FileInputStream fis = null;
         try {
             fis = mAccountInfoFile.openRead();
@@ -1336,6 +1355,16 @@
             if ("accounts".equals(tagName)) {
                 String listen = parser.getAttributeValue(
                         null, "listen-for-tickles");
+                String versionString = parser.getAttributeValue(null, "version");
+                int version;
+                try {
+                    version = (versionString == null) ? 0 : Integer.parseInt(versionString);
+                } catch (NumberFormatException e) {
+                    version = 0;
+                }
+                if (version < ACCOUNTS_VERSION) {
+                    writeNeeded = true;
+                }
                 mMasterSyncAutomatically = listen == null
                             || Boolean.parseBoolean(listen);
                 eventType = parser.next();
@@ -1346,7 +1375,7 @@
                         tagName = parser.getName();
                         if (parser.getDepth() == 2) {
                             if ("authority".equals(tagName)) {
-                                authority = parseAuthority(parser);
+                                authority = parseAuthority(parser, version);
                                 periodicSync = null;
                             }
                         } else if (parser.getDepth() == 3) {
@@ -1364,9 +1393,11 @@
             }
         } catch (XmlPullParserException e) {
             Log.w(TAG, "Error reading accounts", e);
+            return;
         } catch (java.io.IOException e) {
             if (fis == null) Log.i(TAG, "No initial accounts");
             else Log.w(TAG, "Error reading accounts", e);
+            return;
         } finally {
             if (fis != null) {
                 try {
@@ -1375,9 +1406,13 @@
                 }
             }
         }
+
+        if (writeNeeded) {
+            writeAccountInfoLocked();
+        }
     }
 
-    private AuthorityInfo parseAuthority(XmlPullParser parser) {
+    private AuthorityInfo parseAuthority(XmlPullParser parser, int version) {
         AuthorityInfo authority = null;
         int id = -1;
         try {
@@ -1406,8 +1441,14 @@
                 if (DEBUG_FILE) Log.v(TAG, "Creating entry");
                 authority = getOrCreateAuthorityLocked(
                         new Account(accountName, accountType), authorityName, id, false);
-                // clear this since we will read these later on
-                authority.periodicSyncs.clear();
+                // If the version is 0 then we are upgrading from a file format that did not
+                // know about periodic syncs. In that case don't clear the list since we
+                // want the default, which is a daily periodioc sync.
+                // Otherwise clear out this default list since we will populate it later with
+                // the periodic sync descriptions that are read from the configuration file.
+                if (version > 0) {
+                    authority.periodicSyncs.clear();
+                }
             }
             if (authority != null) {
                 authority.enabled = enabled == null || Boolean.parseBoolean(enabled);
@@ -1443,6 +1484,7 @@
         }
         final Pair<Bundle, Long> periodicSync = Pair.create(extras, period);
         authority.periodicSyncs.add(periodicSync);
+
         return periodicSync;
     }
 
@@ -1491,6 +1533,7 @@
             out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
 
             out.startTag(null, "accounts");
+            out.attribute(null, "version", Integer.toString(ACCOUNTS_VERSION));
             if (!mMasterSyncAutomatically) {
                 out.attribute(null, "listen-for-tickles", "false");
             }
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 271f477..e1fbe48 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -439,6 +439,15 @@
     public static final int INSTALL_FAILED_INVALID_INSTALL_LOCATION = -19;
 
     /**
+     * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+     * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+     * the new package couldn't be installed in the specified install
+     * location because the media is not available.
+     * @hide
+     */
+    public static final int INSTALL_FAILED_MEDIA_UNAVAILABLE = -20;
+
+    /**
      * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
      * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
      * if the parser was given a path that is not a file, or does not end with the expected
@@ -586,6 +595,14 @@
     public static final int MOVE_FAILED_INVALID_LOCATION = -5;
 
     /**
+     * Error code that is passed to the {@link IPackageMoveObserver} by
+     * {@link #movePackage(android.net.Uri, IPackageMoveObserver)}
+     * if the specified package cannot be moved to the specified location.
+     * @hide
+     */
+    public static final int MOVE_FAILED_INTERNAL_ERROR = -6;
+
+    /**
      * Flag parameter for {@link #movePackage} to indicate that
      * the package should be moved to internal storage if its
      * been installed on external media.
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index b232ff9..e6f9bed 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -852,7 +852,11 @@
         lock();
         try {
             closeClosable();
-            releaseReference();
+            // close this database instance - regardless of its reference count value
+            onAllReferencesReleased();
+            // set path to null, to cause bad stuff to happen if this object is reused without
+            // being opened first
+            mPath = null;
         } finally {
             unlock();
         }
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
index f29b69f..7f484ff 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -58,11 +58,10 @@
     }
 
     /**
-     * Execute this SQL statement and return the ID of the most
-     * recently inserted row.  The SQL statement should probably be an
-     * INSERT for this to be a useful call.
+     * Execute this SQL statement and return the ID of the row inserted due to this call.
+     * The SQL statement should be an INSERT for this to be a useful call.
      *
-     * @return the row ID of the last row inserted.
+     * @return the row ID of the last row inserted, if this insert is successful. -1 otherwise.
      *
      * @throws android.database.SQLException If the SQL string is invalid for
      *         some reason
@@ -75,7 +74,7 @@
         try {
             native_execute();
             mDatabase.logTimeStat(mSql, timeStart);
-            return mDatabase.lastInsertRow();
+            return (mDatabase.lastChangeCount() > 0) ? mDatabase.lastInsertRow() : -1;
         } finally {
             releaseReference();
             mDatabase.unlock();
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a6668e7..280ded6 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -184,9 +184,15 @@
      * will route over this interface if a default route exists.
      */
     public static final int TYPE_MOBILE_HIPRI = 5;
-    /** {@hide} */
+    /**
+     * The Default WiMAX data connection.  When active, all data traffic
+     * will use this connection by default.  Should not coexist with other
+     * default connections.
+     */
+    public static final int TYPE_WIMAX       = 6;
+    /** {@hide} TODO: Need to adjust this for WiMAX. */
     public static final int MAX_RADIO_TYPE   = TYPE_WIFI;
-    /** {@hide} */
+    /** {@hide} TODO: Need to adjust this for WiMAX. */
     public static final int MAX_NETWORK_TYPE = TYPE_MOBILE_HIPRI;
 
     public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index d1d8b0a..afe4191 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -19,6 +19,7 @@
 
 import android.net.InterfaceConfiguration;
 import android.net.INetworkManagementEventObserver;
+import android.net.wifi.WifiConfiguration;
 
 /**
  * @hide
@@ -166,7 +167,7 @@
     /**
      * Start Wifi Access Point
      */
-    void startAccessPoint();
+    void startAccessPoint(in WifiConfiguration wifiConfig, String intf);
 
     /**
      * Stop Wifi Access Point
diff --git a/core/java/android/pim/vcard/VCardEntryCommitter.java b/core/java/android/pim/vcard/VCardEntryCommitter.java
index 2f99e4a..59a2baf 100644
--- a/core/java/android/pim/vcard/VCardEntryCommitter.java
+++ b/core/java/android/pim/vcard/VCardEntryCommitter.java
@@ -58,12 +58,6 @@
         mTimeToCommit += System.currentTimeMillis() - start;
     }
 
-    // TODO: Compatibility function to not break the build. Will be removed shortly
-    @Deprecated
-    public Uri getLastCreatedUri() {
-        return mCreatedUris.size() == 0 ? null : mCreatedUris.get(mCreatedUris.size() - 1);
-    }
-
     /**
      * Returns the list of created Uris. This list should not be modified by the caller as it is
      * not a clone.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 503d8b8d..66f340e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2502,6 +2502,27 @@
         public static final String WIFI_AP_ON = "wifi_ap_on";
 
         /**
+         * AP SSID
+         *
+         * @hide
+         */
+        public static final String WIFI_AP_SSID = "wifi_ap_ssid";
+
+        /**
+         * AP security
+         *
+         * @hide
+         */
+        public static final String WIFI_AP_SECURITY = "wifi_ap_security";
+
+        /**
+         * AP passphrase
+         *
+         * @hide
+         */
+        public static final String WIFI_AP_PASSWD = "wifi_ap_passwd";
+
+        /**
          * The acceptable packet loss percentage (range 0 - 100) before trying
          * another AP on the same network.
          */
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 1c0d55f..af42ce0 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -62,6 +62,10 @@
     private int mLoadType;
     private boolean mFirstLayoutDone = true;
     private boolean mCommitted = true;
+    // Flag for blocking messages. This is used during destroy() so
+    // that if the UI thread posts any messages after the message
+    // queue has been cleared,they are ignored.
+    private boolean mBlockMessages = false;
 
     // Is this frame the main frame?
     private boolean mIsMainFrame;
@@ -383,6 +387,7 @@
     public void destroy() {
         mOrientationListener.disable();
         nativeDestroyFrame();
+        mBlockMessages = true;
         removeCallbacksAndMessages(null);
     }
 
@@ -392,6 +397,9 @@
      */
     @Override
     public void handleMessage(Message msg) {
+        if (mBlockMessages) {
+            return;
+        }
         switch (msg.what) {
             case FRAME_COMPLETED: {
                 if (mSettings.getSavePassword() && hasPasswordField()) {
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index a013a9b..4f2830b 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -252,6 +252,13 @@
         // 32-bit reads and writes.
         switch (msg.what) {
             case PAGE_STARTED:
+                // every time we start a new page, we want to reset the
+                // WebView certificate:
+                // if the new site is secure, we will reload it and get a
+                // new certificate set;
+                // if the new site is not secure, the certificate must be
+                // null, and that will be the case
+                mWebView.setCertificate(null);
                 if (mWebViewClient != null) {
                     mWebViewClient.onPageStarted(mWebView,
                             msg.getData().getString("url"),
diff --git a/core/java/android/webkit/FrameLoader.java b/core/java/android/webkit/FrameLoader.java
index 303e417..906264a 100644
--- a/core/java/android/webkit/FrameLoader.java
+++ b/core/java/android/webkit/FrameLoader.java
@@ -262,9 +262,13 @@
         CacheLoader cacheLoader =
                 new CacheLoader(mListener, result);
         mListener.setCacheLoader(cacheLoader);
-        // Load the cached file in a separate thread
-        WebViewWorker.getHandler().obtainMessage(
-                WebViewWorker.MSG_ADD_STREAMLOADER, cacheLoader).sendToTarget();
+        if (mListener.isSynchronous()) {
+            cacheLoader.load();
+        } else {
+            // Load the cached file in a separate thread
+            WebViewWorker.getHandler().obtainMessage(
+                    WebViewWorker.MSG_ADD_STREAMLOADER, cacheLoader).sendToTarget();
+        }
     }
 
     /*
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 4bdab0a..a23a4ce 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -656,10 +656,14 @@
                 // ask for it, so make sure we have a valid CacheLoader
                 // before calling it.
                 if (mCacheLoader != null) {
-                    // Load the cached file in a separate thread
-                    WebViewWorker.getHandler().obtainMessage(
-                            WebViewWorker.MSG_ADD_STREAMLOADER, mCacheLoader)
-                            .sendToTarget();
+                    if (isSynchronous()) {
+                        mCacheLoader.load();
+                    } else {
+                        // Load the cached file in a separate thread
+                        WebViewWorker.getHandler().obtainMessage(
+                                WebViewWorker.MSG_ADD_STREAMLOADER, mCacheLoader)
+                                .sendToTarget();
+                    }
                     mFromCache = true;
                     if (DebugFlags.LOAD_LISTENER) {
                         Log.v(LOGTAG, "LoadListener cache load url=" + url());
@@ -718,10 +722,14 @@
                     Log.v(LOGTAG, "FrameLoader: HTTP URL in cache " +
                             "and usable: " + url());
                 }
-                // Load the cached file in a separate thread
-                WebViewWorker.getHandler().obtainMessage(
-                        WebViewWorker.MSG_ADD_STREAMLOADER, mCacheLoader)
-                        .sendToTarget();
+                if (isSynchronous()) {
+                    mCacheLoader.load();
+                } else {
+                    // Load the cached file in a separate thread
+                    WebViewWorker.getHandler().obtainMessage(
+                            WebViewWorker.MSG_ADD_STREAMLOADER, mCacheLoader)
+                            .sendToTarget();
+                }
                 mFromCache = true;
                 return true;
             }
diff --git a/core/java/android/webkit/ViewManager.java b/core/java/android/webkit/ViewManager.java
index 47e7791..4e0e081 100644
--- a/core/java/android/webkit/ViewManager.java
+++ b/core/java/android/webkit/ViewManager.java
@@ -16,6 +16,7 @@
 
 package android.webkit;
 
+import android.view.SurfaceView;
 import android.view.View;
 import android.widget.AbsoluteLayout;
 
@@ -27,6 +28,9 @@
     private boolean mHidden;
     private boolean mReadyToDraw;
 
+    // Threshold at which a surface is prevented from further increasing in size
+    private final int MAX_SURFACE_THRESHOLD;
+
     class ChildView {
         int x;
         int y;
@@ -34,6 +38,11 @@
         int height;
         View mView; // generic view to show
 
+        /* set to true if the view is a surface and it has exceeded the pixel
+           threshold specified in MAX_SURFACE_THRESHOLD.
+         */
+        boolean isFixedSize = false;
+
         ChildView() {
         }
 
@@ -49,15 +58,15 @@
                 return;
             }
             setBounds(x, y, width, height);
-            final AbsoluteLayout.LayoutParams lp =
-                    new AbsoluteLayout.LayoutParams(ctvD(width), ctvD(height),
-                            ctvX(x), ctvY(y));
+
             mWebView.mPrivateHandler.post(new Runnable() {
                 public void run() {
                     // This method may be called multiple times. If the view is
                     // already attached, just set the new LayoutParams,
                     // otherwise attach the view and add it to the list of
                     // children.
+                    AbsoluteLayout.LayoutParams lp = computeLayout(ChildView.this);
+
                     if (mView.getParent() != null) {
                         mView.setLayoutParams(lp);
                     } else {
@@ -67,7 +76,7 @@
             });
         }
 
-        void attachViewOnUIThread(AbsoluteLayout.LayoutParams lp) {
+        private void attachViewOnUIThread(AbsoluteLayout.LayoutParams lp) {
             mWebView.addView(mView, lp);
             mChildren.add(this);
             if (!mReadyToDraw) {
@@ -86,7 +95,7 @@
             });
         }
 
-        void removeViewOnUIThread() {
+        private void removeViewOnUIThread() {
             mWebView.removeView(mView);
             mChildren.remove(this);
         }
@@ -94,6 +103,14 @@
 
     ViewManager(WebView w) {
         mWebView = w;
+
+        int pixelArea = w.getResources().getDisplayMetrics().widthPixels *
+                        w.getResources().getDisplayMetrics().heightPixels;
+        /* set the threshold to be 275% larger than the screen size. The
+           percentage is simply an estimation and is not based on anything but
+           basic trial-and-error tests run on multiple devices.
+         */
+        MAX_SURFACE_THRESHOLD = (int)(pixelArea * 2.75);
     }
 
     ChildView createView() {
@@ -125,16 +142,37 @@
         return mWebView.contentToViewY(val);
     }
 
-    void scaleAll() {
-        for (ChildView v : mChildren) {
-            View view = v.mView;
-            AbsoluteLayout.LayoutParams lp =
-                    (AbsoluteLayout.LayoutParams) view.getLayoutParams();
+    /**
+     * This should only be called from the UI thread.
+     */
+    private AbsoluteLayout.LayoutParams computeLayout(ChildView v) {
+
+        // if the surface has exceed a predefined threshold then fix the size
+        // of the surface.
+        if (!v.isFixedSize && (v.width * v.height) > MAX_SURFACE_THRESHOLD
+                && v.mView instanceof SurfaceView) {
+            ((SurfaceView)v.mView).getHolder().setFixedSize(v.width, v.height);
+            v.isFixedSize = true;
+        }
+
+        AbsoluteLayout.LayoutParams lp =
+            (AbsoluteLayout.LayoutParams) v.mView.getLayoutParams();
+
+        if (lp == null)
+            lp = new AbsoluteLayout.LayoutParams(ctvD(v.width), ctvD(v.height),
+                    ctvX(v.x), ctvY(v.y));
+        else {
             lp.width = ctvD(v.width);
             lp.height = ctvD(v.height);
             lp.x = ctvX(v.x);
             lp.y = ctvY(v.y);
-            view.setLayoutParams(lp);
+        }
+        return lp;
+    }
+
+    void scaleAll() {
+        for (ChildView v : mChildren) {
+            v.mView.setLayoutParams(computeLayout(v));
         }
     }
 
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 52bc8be1..3a34fb4 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1608,13 +1608,6 @@
     }
 
     private void goBackOrForward(int steps, boolean ignoreSnapshot) {
-        // every time we go back or forward, we want to reset the
-        // WebView certificate:
-        // if the new site is secure, we will reload it and get a
-        // new certificate set;
-        // if the new site is not secure, the certificate must be
-        // null, and that will be the case
-        mCertificate = null;
         if (steps != 0) {
             clearTextEntry(false);
             mWebViewCore.sendMessage(EventHub.GO_BACK_FORWARD, steps,
@@ -3858,7 +3851,6 @@
                 || keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT) {
             if (nativeFocusIsPlugin()) {
                 mShiftIsPressed = false;
-                return true;
             } else if (commitCopy()) {
                 return true;
             }
@@ -5761,11 +5753,11 @@
                     contentToViewY(docY + docHeight / 2) - viewHeight / 2,
                     true, 0);
         } else {
-            int oldScreenX = contentToViewX(docX) - mScrollX;
-            int rectViewX = (int) (docX * scale);
-            int rectViewWidth = (int) (docWidth * scale);
-            int newMaxWidth = (int) (mContentWidth * scale);
-            int newScreenX = (viewWidth - rectViewWidth) / 2;
+            float oldScreenX = docX * mActualScale - mScrollX;
+            float rectViewX = docX * scale;
+            float rectViewWidth = docWidth * scale;
+            float newMaxWidth = mContentWidth * scale;
+            float newScreenX = (viewWidth - rectViewWidth) / 2;
             // pin the newX to the WebView
             if (newScreenX > rectViewX) {
                 newScreenX = rectViewX;
@@ -5774,12 +5766,12 @@
             }
             mZoomCenterX = (oldScreenX * scale - newScreenX * mActualScale)
                     / (scale - mActualScale);
-            int oldScreenY = contentToViewY(docY) - mScrollY;
-            int rectViewY = (int) (docY * scale) + getTitleHeight();
-            int rectViewHeight = (int) (docHeight * scale);
-            int newMaxHeight = (int) (mContentHeight * scale)
-                    + getTitleHeight();
-            int newScreenY = (viewHeight - rectViewHeight) / 2;
+            float oldScreenY = docY * mActualScale + getTitleHeight()
+                    - mScrollY;
+            float rectViewY = docY * scale + getTitleHeight();
+            float rectViewHeight = docHeight * scale;
+            float newMaxHeight = mContentHeight * scale + getTitleHeight();
+            float newScreenY = (viewHeight - rectViewHeight) / 2;
             // pin the newY to the WebView
             if (newScreenY > rectViewY) {
                 newScreenY = rectViewY;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index a07397f..ec7424ba 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1988,7 +1988,6 @@
                 }
             }
         }
-        mLastTouchMode = isInTouchMode ? TOUCH_MODE_ON : TOUCH_MODE_OFF;
     }
 
     @Override
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 65f7cdb..9537ba0 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -17,11 +17,10 @@
 package android.widget;
 
 import android.content.Context;
-import android.content.res.Configuration;
 import android.content.res.TypedArray;
+import android.database.DataSetObserver;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable.Orientation;
 import android.text.Editable;
 import android.text.Selection;
 import android.text.TextUtils;
@@ -131,10 +130,11 @@
 
     private boolean mBlockCompletion;
 
-    private AutoCompleteTextView.ListSelectorHider mHideSelector;
+    private ListSelectorHider mHideSelector;
     private Runnable mShowDropDownRunnable;
 
-    private AutoCompleteTextView.PassThroughClickListener mPassThroughClickListener;
+    private PassThroughClickListener mPassThroughClickListener;
+    private PopupDataSetObserver mObserver;
 
     public AutoCompleteTextView(Context context) {
         this(context, null);
@@ -220,14 +220,6 @@
     }
 
     /**
-     * Sets this to be single line; a separate method so
-     * MultiAutoCompleteTextView can skip this.
-     */
-    /* package */ void finishInit() {
-        setSingleLine();
-    }
-
-    /**
      * <p>Sets the optional hint text that is displayed at the bottom of the
      * the matching list.  This can be used as a cue to the user on how to
      * best use the list, or to provide extra information.</p>
@@ -450,7 +442,7 @@
     public boolean isDropDownDismissedOnCompletion() {
         return mDropDownDismissedOnCompletion;
     }
-    
+
     /**
      * Sets whether the drop-down is dismissed when a suggestion is clicked. This is 
      * true by default.
@@ -592,10 +584,16 @@
      * @see android.widget.ListAdapter
      */
     public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
+        if (mObserver == null) {
+            mObserver = new PopupDataSetObserver();
+        } else if (mAdapter != null) {
+            mAdapter.unregisterDataSetObserver(mObserver);
+        }
         mAdapter = adapter;
         if (mAdapter != null) {
             //noinspection unchecked
             mFilter = ((Filterable) mAdapter).getFilter();
+            adapter.registerDataSetObserver(mObserver);
         } else {
             mFilter = null;
         }
@@ -611,8 +609,7 @@
                 && !mDropDownAlwaysVisible) {
             // special case for the back key, we do not even try to send it
             // to the drop down list but instead, consume it immediately
-            if (event.getAction() == KeyEvent.ACTION_DOWN
-                    && event.getRepeatCount() == 0) {
+            if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) {
                 getKeyDispatcherState().startTracking(event, this);
                 return true;
             } else if (event.getAction() == KeyEvent.ACTION_UP) {
@@ -660,10 +657,19 @@
                                     && keyCode != KeyEvent.KEYCODE_DPAD_CENTER))) {
                 int curIndex = mDropDownList.getSelectedItemPosition();
                 boolean consumed;
+
                 final boolean below = !mPopup.isAboveAnchor();
-                if ((below && keyCode == KeyEvent.KEYCODE_DPAD_UP && curIndex <= 0) ||
-                        (!below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN && curIndex >=
-                        mDropDownList.getAdapter().getCount() - 1)) {
+
+                final ListAdapter adapter = mDropDownList.getAdapter();
+                final boolean allEnabled = adapter.areAllItemsEnabled();
+
+                final int firstItem = allEnabled ? 0 :
+                        mDropDownList.lookForSelectablePosition(0, true);
+                final int lastItem = allEnabled ? adapter.getCount() - 1 :
+                        mDropDownList.lookForSelectablePosition(adapter.getCount() - 1, false);
+
+                if ((below && keyCode == KeyEvent.KEYCODE_DPAD_UP && curIndex <= firstItem) ||
+                        (!below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN && curIndex >= lastItem)) {
                     // When the selection is at the top, we block the key
                     // event to prevent focus from moving.
                     clearListSelection();
@@ -703,11 +709,11 @@
                     if (below && keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
                         // when the selection is at the bottom, we block the
                         // event to avoid going to the next focusable widget
-                        Adapter adapter = mDropDownList.getAdapter();
-                        if (adapter != null && curIndex == adapter.getCount() - 1) {
+                        if (curIndex == lastItem) {
                             return true;
                         }
-                    } else if (!below && keyCode == KeyEvent.KEYCODE_DPAD_UP && curIndex == 0) {
+                    } else if (!below && keyCode == KeyEvent.KEYCODE_DPAD_UP &&
+                            curIndex == firstItem) {
                         return true;
                     }
                 }
@@ -860,16 +866,6 @@
         return ListView.INVALID_POSITION;
     }
 
-
-    /**
-     * @hide
-     * @return {@link android.widget.ListView#getChildCount()} of the drop down if it is showing,
-     *         otherwise 0.
-     */
-    protected int getDropDownChildCount() {
-        return mDropDownList == null ? 0 : mDropDownList.getChildCount();
-    }
-
     /**
      * <p>Starts filtering the content of the drop down list. The filtering
      * pattern is the content of the edit box. Subclasses should override this
@@ -970,25 +966,7 @@
             mBlockCompletion = false;
         }
     }
-    
-    /**
-     * Like {@link #setTextKeepState(CharSequence)}, except that it can disable filtering.
-     *
-     * @param filter If <code>false</code>, no filtering will be performed
-     *        as a result of this call.
-     * 
-     * @hide Pending API council approval.
-     */
-    public void setTextKeepState(CharSequence text, boolean filter) {
-        if (filter) {
-            setTextKeepState(text);
-        } else {
-            mBlockCompletion = true;
-            setTextKeepState(text);
-            mBlockCompletion = false;
-        }
-    }
-    
+
     /**
      * <p>Performs the text completion by replacing the current text by the
      * selected item. Subclasses should override this method to avoid replacing
@@ -1517,24 +1495,6 @@
             return view;
         }
 
-        /**
-         * <p>Returns the top padding of the currently selected view.</p>
-         *
-         * @return the height of the top padding for the selection
-         */
-        public int getSelectionPaddingTop() {
-            return mSelectionTopPadding;
-        }
-
-        /**
-         * <p>Returns the bottom padding of the currently selected view.</p>
-         *
-         * @return the height of the bottom padding for the selection
-         */
-        public int getSelectionPaddingBottom() {
-            return mSelectionBottomPadding;
-        }
-
         @Override
         public boolean isInTouchMode() {
             // WARNING: Please read the comment where mListSelectionHidden is declared
@@ -1632,5 +1592,23 @@
             if (mWrapped != null) mWrapped.onClick(v);
         }
     }
-    
+
+    private class PopupDataSetObserver extends DataSetObserver {
+        @Override
+        public void onChanged() {
+            if (isPopupShowing()) {
+                // This will resize the popup to fit the new adapter's content
+                showDropDown();
+            }
+        }
+
+        @Override
+        public void onInvalidated() {
+            if (!mDropDownAlwaysVisible) {
+                // There's no data to display so make sure we're not showing
+                // the drop down and its list
+                dismissDropDown();
+            }
+        }
+    }
 }
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index c81a907..c77416b 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -769,8 +769,8 @@
             } else if (ScaleType.CENTER == mScaleType) {
                 // Center bitmap in view, no scaling.
                 mDrawMatrix = mMatrix;
-                mDrawMatrix.setTranslate((vwidth - dwidth) * 0.5f,
-                                         (vheight - dheight) * 0.5f);
+                mDrawMatrix.setTranslate((int) ((vwidth - dwidth) * 0.5f + 0.5f),
+                                         (int) ((vheight - dheight) * 0.5f + 0.5f));
             } else if (ScaleType.CENTER_CROP == mScaleType) {
                 mDrawMatrix = mMatrix;
 
@@ -786,7 +786,7 @@
                 }
 
                 mDrawMatrix.setScale(scale, scale);
-                mDrawMatrix.postTranslate(dx, dy);
+                mDrawMatrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
             } else if (ScaleType.CENTER_INSIDE == mScaleType) {
                 mDrawMatrix = mMatrix;
                 float scale;
@@ -800,8 +800,8 @@
                             (float) vheight / (float) dheight);
                 }
                 
-                dx = (vwidth - dwidth * scale) * 0.5f;
-                dy = (vheight - dheight * scale) * 0.5f;
+                dx = (int) ((vwidth - dwidth * scale) * 0.5f + 0.5f);
+                dy = (int) ((vheight - dheight * scale) * 0.5f + 0.5f);
 
                 mDrawMatrix.setScale(scale, scale);
                 mDrawMatrix.postTranslate(dx, dy);
diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl
index fd1fd58..badabb0 100755
--- a/core/java/com/android/internal/app/IMediaContainerService.aidl
+++ b/core/java/com/android/internal/app/IMediaContainerService.aidl
@@ -27,4 +27,5 @@
     boolean copyResource(in Uri packageURI,
                 in ParcelFileDescriptor outStream);
     PackageInfoLite getMinimalPackageInfo(in Uri fileUri);
+    boolean checkFreeStorage(boolean external, in Uri fileUri);
 }
\ No newline at end of file
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index 80efca4..4d0a9e0 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -38,6 +38,7 @@
     public static final int RECOMMEND_FAILED_INVALID_APK = -2;
     public static final int RECOMMEND_FAILED_INVALID_LOCATION = -3;
     public static final int RECOMMEND_FAILED_ALREADY_EXISTS = -4;
+    public static final int RECOMMEND_MEDIA_UNAVAILABLE = -5;
     private static final boolean localLOGV = true;
     private static final String TAG = "PackageHelper";
     // App installation location settings values
@@ -70,7 +71,7 @@
 
         try {
             int rc = mountService.createSecureContainer(
-                    cid, mbLen, "vfat", sdEncKey, uid);
+                    cid, mbLen, "fat", sdEncKey, uid);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.e(TAG, "Failed to create secure container " + cid);
                 return null;
diff --git a/core/java/com/android/internal/content/SelectionBuilder.java b/core/java/com/android/internal/content/SelectionBuilder.java
index 0e29411..b194756 100644
--- a/core/java/com/android/internal/content/SelectionBuilder.java
+++ b/core/java/com/android/internal/content/SelectionBuilder.java
@@ -47,7 +47,7 @@
      * Append the given selection clause to the internal state. Each clause is
      * surrounded with parenthesis and combined using {@code AND}.
      */
-    public SelectionBuilder append(String selection, String... selectionArgs) {
+    public SelectionBuilder append(String selection, Object... selectionArgs) {
         if (TextUtils.isEmpty(selection)) {
             if (selectionArgs != null && selectionArgs.length > 0) {
                 throw new IllegalArgumentException(
@@ -63,8 +63,12 @@
         }
 
         mSelection.append("(").append(selection).append(")");
-        for (String arg : selectionArgs) {
-            mSelectionArgs.add(arg);
+        if (selectionArgs != null) {
+            for (Object arg : selectionArgs) {
+                // TODO: switch to storing direct Object instances once
+                // http://b/2464440 is fixed
+                mSelectionArgs.add(String.valueOf(arg));
+            }
         }
 
         return this;
diff --git a/core/java/com/android/internal/view/menu/IconMenuView.java b/core/java/com/android/internal/view/menu/IconMenuView.java
index bba2ee2..beb57ba 100644
--- a/core/java/com/android/internal/view/menu/IconMenuView.java
+++ b/core/java/com/android/internal/view/menu/IconMenuView.java
@@ -179,6 +179,10 @@
      */
     private void layoutItems(int width) {
         int numItems = getChildCount();
+        if (numItems == 0) {
+            mLayoutNumRows = 0;
+            return;
+        }
         
         // Start with the least possible number of rows
         int curNumRows =
@@ -470,15 +474,18 @@
         
         // Get the desired height of the icon menu view (last row of items does
         // not have a divider below)
+        final int layoutNumRows = mLayoutNumRows;
         final int desiredHeight = (mRowHeight + mHorizontalDividerHeight) *
-                mLayoutNumRows - mHorizontalDividerHeight;
+                layoutNumRows - mHorizontalDividerHeight;
         
         // Maximum possible width and desired height
         setMeasuredDimension(measuredWidth,
                 resolveSize(desiredHeight, heightMeasureSpec));
 
         // Position the children
-        positionChildren(mMeasuredWidth, mMeasuredHeight);
+        if (layoutNumRows > 0) {
+            positionChildren(mMeasuredWidth, mMeasuredHeight);
+        }
     }
 
 
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index efd025a..9b7f487 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -47,6 +47,7 @@
 public class LockPatternUtils {
 
     private static final String TAG = "LockPatternUtils";
+    private static final boolean LDEBUG = false;
 
     private static final String LOCK_PATTERN_FILE = "/system/gesture.key";
     private static final String LOCK_PASSWORD_FILE = "/system/password.key";
@@ -126,7 +127,6 @@
     public LockPatternUtils(Context context) {
         mContext = context;
         mContentResolver = context.getContentResolver();
-        mDevicePolicyManager = getDevicePolicyManager();
         // Initialize the location of gesture lock file
         if (sLockPatternFilename == null) {
             sLockPatternFilename = android.os.Environment.getDataDirectory()
diff --git a/core/jni/android_database_SQLiteDatabase.cpp b/core/jni/android_database_SQLiteDatabase.cpp
index fb93014..4e8d05b 100644
--- a/core/jni/android_database_SQLiteDatabase.cpp
+++ b/core/jni/android_database_SQLiteDatabase.cpp
@@ -349,7 +349,7 @@
         goto done;
     }
 
-    dbLocale = (rowCount >= 1) ? meta[1 * colCount + 0] : NULL;
+    dbLocale = (rowCount >= 1) ? meta[colCount] : NULL;
 
     if (dbLocale != NULL && !strcmp(dbLocale, locale8)) {
         // database locale is the same as the desired locale; set up the collators and go
@@ -360,7 +360,8 @@
 
     if ((flags & OPEN_READONLY)) {
         // read-only database, so we're going to have to put up with whatever we got
-        err = register_localized_collators(handle, dbLocale ? dbLocale : locale8, UTF16_STORAGE);
+        // For registering new index. Not for modifing the read-only database.
+        err = register_localized_collators(handle, locale8, UTF16_STORAGE);
         if (err != SQLITE_OK) throw_sqlite3_exception(env, handle);
         goto done;
     }
@@ -373,7 +374,7 @@
         goto done;
     }
 
-    err = register_localized_collators(handle, dbLocale ? dbLocale : locale8, UTF16_STORAGE);
+    err = register_localized_collators(handle, locale8, UTF16_STORAGE);
     if (err != SQLITE_OK) {
         LOGE("register_localized_collators() failed setting locale\n");
         throw_sqlite3_exception(env, handle);
diff --git a/core/res/res/drawable-hdpi/ic_btn_search_go.png b/core/res/res/drawable-hdpi/ic_btn_search_go.png
new file mode 100644
index 0000000..8a3a402
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_btn_search_go.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_btn_search_play.png b/core/res/res/drawable-hdpi/ic_btn_search_play.png
deleted file mode 100644
index fb1b974..0000000
--- a/core/res/res/drawable-hdpi/ic_btn_search_play.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_tether_active.png b/core/res/res/drawable-hdpi/stat_sys_tether_active.png
deleted file mode 100755
index 4c14c07..0000000
--- a/core/res/res/drawable-hdpi/stat_sys_tether_active.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_tether_general.png b/core/res/res/drawable-hdpi/stat_sys_tether_general.png
index e43fbae..c42b00c 100644
--- a/core/res/res/drawable-hdpi/stat_sys_tether_general.png
+++ b/core/res/res/drawable-hdpi/stat_sys_tether_general.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_btn_search_go.png b/core/res/res/drawable-mdpi/ic_btn_search_go.png
new file mode 100644
index 0000000..0ed9e8e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_btn_search_go.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_btn_search_play.png b/core/res/res/drawable-mdpi/ic_btn_search_play.png
deleted file mode 100644
index dc25dae..0000000
--- a/core/res/res/drawable-mdpi/ic_btn_search_play.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_tether_active.png b/core/res/res/drawable-mdpi/stat_sys_tether_active.png
deleted file mode 100644
index 2d0da4c..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_tether_active.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_tether_general.png b/core/res/res/drawable-mdpi/stat_sys_tether_general.png
index efb64ad..3688803 100644
--- a/core/res/res/drawable-mdpi/stat_sys_tether_general.png
+++ b/core/res/res/drawable-mdpi/stat_sys_tether_general.png
Binary files differ
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 584fe25..bf7425f 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2013,6 +2013,8 @@
         <item quantity="one">Open Wi-Fi network available</item>
         <item quantity="other">Open Wi-Fi networks available</item>
     </plurals>
+    <!-- Do not translate. Default access point SSID used for tethering -->
+    <string name="wifi_tether_configure_ssid_default" translatable="false">AndroidAP</string>
 
     <!-- Name of the dialog that lets the user choose an accented character to insert -->
     <string name="select_character">Insert character</string>
diff --git a/core/tests/coretests/src/android/content/SyncStorageEngineTest.java b/core/tests/coretests/src/android/content/SyncStorageEngineTest.java
index 1505a7c..7028d1a 100644
--- a/core/tests/coretests/src/android/content/SyncStorageEngineTest.java
+++ b/core/tests/coretests/src/android/content/SyncStorageEngineTest.java
@@ -16,6 +16,8 @@
 
 package android.content;
 
+import com.android.internal.os.AtomicFile;
+
 import android.test.AndroidTestCase;
 import android.test.RenamingDelegatingContext;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -26,6 +28,7 @@
 
 import java.util.List;
 import java.io.File;
+import java.io.FileOutputStream;
 
 public class SyncStorageEngineTest extends AndroidTestCase {
 
@@ -193,6 +196,109 @@
         assertEquals(1, engine.getIsSyncable(account1, authority2));
         assertEquals(0, engine.getIsSyncable(account2, authority2));
     }
+
+    @SmallTest
+    public void testAuthorityParsing() throws Exception {
+        final Account account = new Account("account1", "type1");
+        final String authority1 = "auth1";
+        final String authority2 = "auth2";
+        final String authority3 = "auth3";
+        final Bundle extras = new Bundle();
+        PeriodicSync sync1 = new PeriodicSync(account, authority1, extras, (long) (60 * 60 * 24));
+        PeriodicSync sync2 = new PeriodicSync(account, authority2, extras, (long) (60 * 60 * 24));
+        PeriodicSync sync3 = new PeriodicSync(account, authority3, extras, (long) (60 * 60 * 24));
+        PeriodicSync sync1s = new PeriodicSync(account, authority1, extras, 1000);
+        PeriodicSync sync2s = new PeriodicSync(account, authority2, extras, 1000);
+        PeriodicSync sync3s = new PeriodicSync(account, authority3, extras, 1000);
+
+        MockContentResolver mockResolver = new MockContentResolver();
+
+        final TestContext testContext = new TestContext(mockResolver, getContext());
+        SyncStorageEngine engine = SyncStorageEngine.newTestInstance(testContext);
+
+        byte[] accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<accounts>\n"
+                + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n"
+                + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n"
+                + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n"
+                + "</accounts>\n").getBytes();
+
+        File syncDir = new File(new File(testContext.getFilesDir(), "system"), "sync");
+        syncDir.mkdirs();
+        AtomicFile accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
+        FileOutputStream fos = accountInfoFile.startWrite();
+        fos.write(accountsFileData);
+        accountInfoFile.finishWrite(fos);
+
+        engine.clearAndReadState();
+
+        List<PeriodicSync> syncs = engine.getPeriodicSyncs(account, authority1);
+        assertEquals(1, syncs.size());
+        assertEquals(sync1, syncs.get(0));
+
+        syncs = engine.getPeriodicSyncs(account, authority2);
+        assertEquals(1, syncs.size());
+        assertEquals(sync2, syncs.get(0));
+
+        syncs = engine.getPeriodicSyncs(account, authority3);
+        assertEquals(1, syncs.size());
+        assertEquals(sync3, syncs.get(0));
+
+        accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<accounts version=\"1\">\n"
+                + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\" />\n"
+                + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\" />\n"
+                + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\" />\n"
+                + "</accounts>\n").getBytes();
+
+        accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
+        fos = accountInfoFile.startWrite();
+        fos.write(accountsFileData);
+        accountInfoFile.finishWrite(fos);
+
+        engine.clearAndReadState();
+
+        syncs = engine.getPeriodicSyncs(account, authority1);
+        assertEquals(0, syncs.size());
+
+        syncs = engine.getPeriodicSyncs(account, authority2);
+        assertEquals(0, syncs.size());
+
+        syncs = engine.getPeriodicSyncs(account, authority3);
+        assertEquals(0, syncs.size());
+
+        accountsFileData = ("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
+                + "<accounts version=\"1\">\n"
+                + "<authority id=\"0\" account=\"account1\" type=\"type1\" authority=\"auth1\">\n"
+                + "<periodicSync period=\"1000\" />\n"
+                + "</authority>"
+                + "<authority id=\"1\" account=\"account1\" type=\"type1\" authority=\"auth2\">\n"
+                + "<periodicSync period=\"1000\" />\n"
+                + "</authority>"
+                + "<authority id=\"2\" account=\"account1\" type=\"type1\" authority=\"auth3\">\n"
+                + "<periodicSync period=\"1000\" />\n"
+                + "</authority>"
+                + "</accounts>\n").getBytes();
+
+        accountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
+        fos = accountInfoFile.startWrite();
+        fos.write(accountsFileData);
+        accountInfoFile.finishWrite(fos);
+
+        engine.clearAndReadState();
+
+        syncs = engine.getPeriodicSyncs(account, authority1);
+        assertEquals(1, syncs.size());
+        assertEquals(sync1s, syncs.get(0));
+
+        syncs = engine.getPeriodicSyncs(account, authority2);
+        assertEquals(1, syncs.size());
+        assertEquals(sync2s, syncs.get(0));
+
+        syncs = engine.getPeriodicSyncs(account, authority3);
+        assertEquals(1, syncs.size());
+        assertEquals(sync3s, syncs.get(0));
+    }
 }
 
 class TestContext extends ContextWrapper {
diff --git a/core/tests/coretests/src/android/database/DatabaseGeneralTest.java b/core/tests/coretests/src/android/database/DatabaseGeneralTest.java
index ab142c9..656029d 100644
--- a/core/tests/coretests/src/android/database/DatabaseGeneralTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseGeneralTest.java
@@ -16,15 +16,12 @@
 
 package android.database;
 
+import static android.database.DatabaseUtils.InsertHelper.TABLE_INFO_PRAGMA_COLUMNNAME_INDEX;
+import static android.database.DatabaseUtils.InsertHelper.TABLE_INFO_PRAGMA_DEFAULT_INDEX;
 import android.content.ContentValues;
 import android.content.Context;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.CharArrayBuffer;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteStatement;
-import android.os.Environment;
 import android.os.Handler;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
@@ -33,18 +30,14 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
-import java.io.File;
-import java.io.UnsupportedEncodingException;
-import java.text.Collator;
-import java.util.Arrays;
-
 import junit.framework.Assert;
-import junit.framework.TestCase;
 
-import static android.database.DatabaseUtils.InsertHelper.TABLE_INFO_PRAGMA_COLUMNNAME_INDEX;
-import static android.database.DatabaseUtils.InsertHelper.TABLE_INFO_PRAGMA_DEFAULT_INDEX;
+import java.io.File;
+import java.util.Arrays;
+import java.util.Locale;
 
 public class DatabaseGeneralTest extends AndroidTestCase implements PerformanceTestCase {
+    private static final String TAG = "DatabaseGeneralTest";
 
     private static final String sString1 = "this is a test";
     private static final String sString2 = "and yet another test";
@@ -1029,4 +1022,91 @@
             fail("unexpected, of course");
         }
     }
+
+    /**
+     * This test is available only when the platform has a locale with the language "ja".
+     * It finishes without failure when it is not available.  
+     */
+    @MediumTest
+    public void testCollateLocalizedForJapanese() throws Exception {
+        final String testName = "DatabaseGeneralTest#testCollateLocalizedForJapanese()";
+        final Locale[] localeArray = Locale.getAvailableLocales();
+        final String japanese = Locale.JAPANESE.getLanguage();
+        final String english = Locale.ENGLISH.getLanguage();
+        Locale japaneseLocale = null;
+        Locale englishLocale = null;
+        for (Locale locale : localeArray) {
+            if (locale != null) {
+                final String language = locale.getLanguage();
+                if (language == null) {
+                    continue;
+                } else if (language.equals(japanese)) {
+                    japaneseLocale = locale;
+                } else if (language.equals(english)) {
+                    englishLocale = locale;
+                }
+            }
+            
+            if (japaneseLocale != null && englishLocale != null) {
+                break;
+            }
+        }
+
+        if (japaneseLocale == null || englishLocale == null) {
+            Log.d(TAG, testName + "n is silently skipped since " +
+                    (englishLocale == null ?
+                            (japaneseLocale == null ?
+                                    "Both English and Japanese locales do not exist." :
+                                    "English locale does not exist.") :
+                            (japaneseLocale == null ?
+                                    "Japanese locale does not exist." :
+                                    "...why?")));
+            return;
+        }
+
+        Locale originalLocale = Locale.getDefault();
+        try {
+
+            final String dbName = "collate_localized_test";
+            mDatabase.execSQL("CREATE TABLE " + dbName + " (" +
+                    "_id INTEGER PRIMARY KEY, " +
+                    "s TEXT COLLATE LOCALIZED) ");
+            DatabaseUtils.InsertHelper ih =
+                new DatabaseUtils.InsertHelper(mDatabase, dbName);
+            ContentValues cv = new ContentValues();
+
+            cv = new ContentValues();  //
+            cv.put("s", "\uFF75\uFF77\uFF85\uFF9C");  // O-ki-na-wa in half-width Katakana
+            ih.insert(cv);
+
+            cv = new ContentValues();  //
+            cv.put("s", "\u306B\u307B\u3093");  // Ni-ho-n in Hiragana
+            ih.insert(cv);
+
+            cv = new ContentValues();  //
+            cv.put("s", "\u30A2\u30E1\u30EA\u30AB");  // A-me-ri-ca in hull-width Katakana
+            ih.insert(cv);            
+
+            // Assume setLocale() does REINDEX and an English locale does not consider
+            // Japanese-specific LOCALIZED order.
+            Locale.setDefault(englishLocale);
+            Locale.setDefault(japaneseLocale);
+
+            Cursor cur = mDatabase.rawQuery(
+                    "SELECT * FROM " + dbName + " ORDER BY s", null);
+            assertTrue(cur.moveToFirst());
+            assertEquals("\u30A2\u30E1\u30EA\u30AB", cur.getString(1));
+            assertTrue(cur.moveToNext());
+            assertEquals("\uFF75\uFF77\uFF85\uFF9C", cur.getString(1));
+            assertTrue(cur.moveToNext());
+            assertEquals("\u306B\u307B\u3093", cur.getString(1));
+        } finally {
+            if (originalLocale != null) {
+                try {
+                    Locale.setDefault(originalLocale);
+                } catch (Exception e) {
+                }
+            }
+        }
+    }    
 }
diff --git a/core/tests/coretests/src/android/os/MemoryFileTest.java b/core/tests/coretests/src/android/os/MemoryFileTest.java
index 1f7ee26..009a0e2 100644
--- a/core/tests/coretests/src/android/os/MemoryFileTest.java
+++ b/core/tests/coretests/src/android/os/MemoryFileTest.java
@@ -42,7 +42,8 @@
     /**
      * Keep allocating new files till the system purges them.
      */
-    @LargeTest
+    // Flaky test - temporarily suppress from large suite for now
+    // @LargeTest
     public void testPurge() throws Exception {
         List<MemoryFile> files = new ArrayList<MemoryFile>();
         try {
diff --git a/docs/html/guide/topics/graphics/index.jd b/docs/html/guide/topics/graphics/index.jd
index e1158be..92771a8 100644
--- a/docs/html/guide/topics/graphics/index.jd
+++ b/docs/html/guide/topics/graphics/index.jd
@@ -56,7 +56,7 @@
 draw your graphics into a View when you want to display a static graphic or predefined animation, within 
 an otherwise static application. Read <a href="#draw-to-view">Simple Graphics Inside a View</a>.</li>
 
-<p>Option "b," drawing to a Canvas, is better when you're application needs to regularly re-draw itself.
+<p>Option "b," drawing to a Canvas, is better when your application needs to regularly re-draw itself.
 Basically, any video game should be drawing to the Canvas on its own. However, there's more than 
 one way to do this: </p>
 <ul>
@@ -117,7 +117,7 @@
 
 <h3 id="on-view">On a View</h3>
 
-<p>If you're application does not require a significant amount of processing or 
+<p>If your application does not require a significant amount of processing or
 frame-rate speed (perhaps for a chess game, a snake game, 
 or another slowly-animated application), then you should consider creating a custom View component
 and drawing with a Canvas in <code>{@link android.view.View#onDraw(Canvas) View.onDraw()}</code>. 
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 24c2f46..d58c711 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -167,7 +167,7 @@
     status_t setupMPEG4EncoderParameters();
     status_t setupAVCEncoderParameters();
 
-    void setVideoOutputFormat(
+    status_t setVideoOutputFormat(
             const char *mime, OMX_U32 width, OMX_U32 height);
 
     void setImageOutputFormat(
@@ -220,6 +220,8 @@
 
     void dumpPortStatus(OMX_U32 portIndex);
 
+    status_t configureCodec(const sp<MetaData> &meta);
+
     static uint32_t getComponentQuirks(const char *componentName);
 
     static void findMatchingCodecs(
diff --git a/libs/rs/scriptc/rs_math.rsh b/libs/rs/scriptc/rs_math.rsh
new file mode 100644
index 0000000..613c7ca
--- /dev/null
+++ b/libs/rs/scriptc/rs_math.rsh
@@ -0,0 +1,287 @@
+// Float ops
+
+extern float __attribute__((overloadable)) abs(float);
+extern float2 __attribute__((overloadable)) abs(float2);
+extern float3 __attribute__((overloadable)) abs(float3);
+extern float4 __attribute__((overloadable)) abs(float4);
+extern float8 __attribute__((overloadable)) abs(float8);
+extern float16 __attribute__((overloadable)) abs(float16);
+
+extern float __attribute__((overloadable)) acos(float);
+extern float2 __attribute__((overloadable)) acos(float2);
+extern float3 __attribute__((overloadable)) acos(float3);
+extern float4 __attribute__((overloadable)) acos(float4);
+extern float8 __attribute__((overloadable)) acos(float8);
+extern float16 __attribute__((overloadable)) acos(float16);
+
+extern float __attribute__((overloadable)) asin(float);
+extern float2 __attribute__((overloadable)) asin(float2);
+extern float3 __attribute__((overloadable)) asin(float3);
+extern float4 __attribute__((overloadable)) asin(float4);
+extern float8 __attribute__((overloadable)) asin(float8);
+extern float16 __attribute__((overloadable)) asin(float16);
+
+extern float __attribute__((overloadable)) atan(float);
+extern float2 __attribute__((overloadable)) atan(float2);
+extern float3 __attribute__((overloadable)) atan(float3);
+extern float4 __attribute__((overloadable)) atan(float4);
+extern float8 __attribute__((overloadable)) atan(float8);
+extern float16 __attribute__((overloadable)) atan(float16);
+
+extern float __attribute__((overloadable)) atan2(float, float);
+extern float2 __attribute__((overloadable)) atan2(float2, float2);
+extern float3 __attribute__((overloadable)) atan2(float3, float3);
+extern float4 __attribute__((overloadable)) atan2(float4, float4);
+extern float8 __attribute__((overloadable)) atan2(float8, float8);
+extern float16 __attribute__((overloadable)) atan2(float16, float16);
+
+extern float __attribute__((overloadable)) ceil(float);
+extern float2 __attribute__((overloadable)) ceil(float2);
+extern float3 __attribute__((overloadable)) ceil(float3);
+extern float4 __attribute__((overloadable)) ceil(float4);
+extern float8 __attribute__((overloadable)) ceil(float8);
+extern float16 __attribute__((overloadable)) ceil(float16);
+
+extern float __attribute__((overloadable)) clamp(float, float, float);
+extern float2 __attribute__((overloadable)) clamp(float2, float2, float2);
+extern float3 __attribute__((overloadable)) clamp(float3, float3, float3);
+extern float4 __attribute__((overloadable)) clamp(float4, float4, float4);
+extern float8 __attribute__((overloadable)) clamp(float8, float8, float8);
+extern float16 __attribute__((overloadable)) clamp(float16, float16, float16);
+extern float __attribute__((overloadable)) clamp(float, float, float);
+extern float2 __attribute__((overloadable)) clamp(float2, float, float);
+extern float3 __attribute__((overloadable)) clamp(float3, float, float);
+extern float4 __attribute__((overloadable)) clamp(float4, float, float);
+extern float8 __attribute__((overloadable)) clamp(float8, float, float);
+extern float16 __attribute__((overloadable)) clamp(float16, float, float);
+
+extern float __attribute__((overloadable)) copysign(float, float);
+extern float2 __attribute__((overloadable)) copysign(float2, float2);
+extern float3 __attribute__((overloadable)) copysign(float3, float3);
+extern float4 __attribute__((overloadable)) copysign(float4, float4);
+extern float8 __attribute__((overloadable)) copysign(float8, float8);
+extern float16 __attribute__((overloadable)) copysign(float16, float16);
+
+extern float __attribute__((overloadable)) cos(float);
+extern float2 __attribute__((overloadable)) cos(float2);
+extern float3 __attribute__((overloadable)) cos(float3);
+extern float4 __attribute__((overloadable)) cos(float4);
+extern float8 __attribute__((overloadable)) cos(float8);
+extern float16 __attribute__((overloadable)) cos(float16);
+
+extern float __attribute__((overloadable)) degrees(float);
+extern float2 __attribute__((overloadable)) degrees(float2);
+extern float3 __attribute__((overloadable)) degrees(float3);
+extern float4 __attribute__((overloadable)) degrees(float4);
+extern float8 __attribute__((overloadable)) degrees(float8);
+extern float16 __attribute__((overloadable)) degrees(float16);
+
+extern float __attribute__((overloadable)) exp(float);
+extern float2 __attribute__((overloadable)) exp(float2);
+extern float3 __attribute__((overloadable)) exp(float3);
+extern float4 __attribute__((overloadable)) exp(float4);
+extern float8 __attribute__((overloadable)) exp(float8);
+extern float16 __attribute__((overloadable)) exp(float16);
+
+extern float __attribute__((overloadable)) exp2(float);
+extern float2 __attribute__((overloadable)) exp2(float2);
+extern float3 __attribute__((overloadable)) exp2(float3);
+extern float4 __attribute__((overloadable)) exp2(float4);
+extern float8 __attribute__((overloadable)) exp2(float8);
+extern float16 __attribute__((overloadable)) exp2(float16);
+
+extern float __attribute__((overloadable)) exp10(float);
+extern float2 __attribute__((overloadable)) exp10(float2);
+extern float3 __attribute__((overloadable)) exp10(float3);
+extern float4 __attribute__((overloadable)) exp10(float4);
+extern float8 __attribute__((overloadable)) exp10(float8);
+extern float16 __attribute__((overloadable)) exp10(float16);
+
+extern float __attribute__((overloadable)) fabs(float);
+extern float2 __attribute__((overloadable)) fabs(float2);
+extern float3 __attribute__((overloadable)) fabs(float3);
+extern float4 __attribute__((overloadable)) fabs(float4);
+extern float8 __attribute__((overloadable)) fabs(float8);
+extern float16 __attribute__((overloadable)) fabs(float16);
+
+extern float __attribute__((overloadable)) floor(float);
+extern float2 __attribute__((overloadable)) floor(float2);
+extern float3 __attribute__((overloadable)) floor(float3);
+extern float4 __attribute__((overloadable)) floor(float4);
+extern float8 __attribute__((overloadable)) floor(float8);
+extern float16 __attribute__((overloadable)) floor(float16);
+
+extern float __attribute__((overloadable)) fmax(float, float);
+extern float2 __attribute__((overloadable)) fmax(float2, float2);
+extern float3 __attribute__((overloadable)) fmax(float3, float3);
+extern float4 __attribute__((overloadable)) fmax(float4, float4);
+extern float8 __attribute__((overloadable)) fmax(float8, float8);
+extern float16 __attribute__((overloadable)) fmax(float16, float16);
+extern float2 __attribute__((overloadable)) fmax(float2, float);
+extern float3 __attribute__((overloadable)) fmax(float3, float);
+extern float4 __attribute__((overloadable)) fmax(float4, float);
+extern float8 __attribute__((overloadable)) fmax(float8, float);
+extern float16 __attribute__((overloadable)) fmax(float16, float);
+
+extern float __attribute__((overloadable)) fmin(float, float);
+extern float2 __attribute__((overloadable)) fmin(float2, float2);
+extern float3 __attribute__((overloadable)) fmin(float3, float3);
+extern float4 __attribute__((overloadable)) fmin(float4, float4);
+extern float8 __attribute__((overloadable)) fmin(float8, float8);
+extern float16 __attribute__((overloadable)) fmin(float16, float16);
+extern float2 __attribute__((overloadable)) fmin(float2, float);
+extern float3 __attribute__((overloadable)) fmin(float3, float);
+extern float4 __attribute__((overloadable)) fmin(float4, float);
+extern float8 __attribute__((overloadable)) fmin(float8, float);
+extern float16 __attribute__((overloadable)) fmin(float16, float);
+
+extern float __attribute__((overloadable)) fmod(float, float);
+extern float2 __attribute__((overloadable)) fmod(float2, float2);
+extern float3 __attribute__((overloadable)) fmod(float3, float3);
+extern float4 __attribute__((overloadable)) fmod(float4, float4);
+extern float8 __attribute__((overloadable)) fmod(float8, float8);
+extern float16 __attribute__((overloadable)) fmod(float16, float16);
+
+extern float __attribute__((overloadable)) log(float);
+extern float2 __attribute__((overloadable)) log(float2);
+extern float3 __attribute__((overloadable)) log(float3);
+extern float4 __attribute__((overloadable)) log(float4);
+extern float8 __attribute__((overloadable)) log(float8);
+extern float16 __attribute__((overloadable)) log(float16);
+
+extern float __attribute__((overloadable)) log2(float);
+extern float2 __attribute__((overloadable)) log2(float2);
+extern float3 __attribute__((overloadable)) log2(float3);
+extern float4 __attribute__((overloadable)) log2(float4);
+extern float8 __attribute__((overloadable)) log2(float8);
+extern float16 __attribute__((overloadable)) log2(float16);
+
+extern float __attribute__((overloadable)) log10(float);
+extern float2 __attribute__((overloadable)) log10(float2);
+extern float3 __attribute__((overloadable)) log10(float3);
+extern float4 __attribute__((overloadable)) log10(float4);
+extern float8 __attribute__((overloadable)) log10(float8);
+extern float16 __attribute__((overloadable)) log10(float16);
+
+extern float __attribute__((overloadable)) max(float, float);
+extern float2 __attribute__((overloadable)) max(float2, float2);
+extern float3 __attribute__((overloadable)) max(float3, float3);
+extern float4 __attribute__((overloadable)) max(float4, float4);
+extern float8 __attribute__((overloadable)) max(float8, float8);
+extern float16 __attribute__((overloadable)) max(float16, float16);
+
+extern float __attribute__((overloadable)) min(float, float);
+extern float2 __attribute__((overloadable)) min(float2, float2);
+extern float3 __attribute__((overloadable)) min(float3, float3);
+extern float4 __attribute__((overloadable)) min(float4, float4);
+extern float8 __attribute__((overloadable)) min(float8, float8);
+extern float16 __attribute__((overloadable)) min(float16, float16);
+
+extern float __attribute__((overloadable)) mix(float, float, float);
+extern float2 __attribute__((overloadable)) mix(float2, float2, float2);
+extern float3 __attribute__((overloadable)) mix(float3, float3, float3);
+extern float4 __attribute__((overloadable)) mix(float4, float4, float4);
+extern float8 __attribute__((overloadable)) mix(float8, float8, float8);
+extern float16 __attribute__((overloadable)) mix(float16, float16, float16);
+extern float __attribute__((overloadable)) mix(float, float, float);
+extern float2 __attribute__((overloadable)) mix(float2, float2, float);
+extern float3 __attribute__((overloadable)) mix(float3, float3, float);
+extern float4 __attribute__((overloadable)) mix(float4, float4, float);
+extern float8 __attribute__((overloadable)) mix(float8, float8, float);
+extern float16 __attribute__((overloadable)) mix(float16, float16, float);
+
+extern float __attribute__((overloadable)) pow(float, float);
+extern float2 __attribute__((overloadable)) pow(float2, float2);
+extern float3 __attribute__((overloadable)) pow(float3, float3);
+extern float4 __attribute__((overloadable)) pow(float4, float4);
+extern float8 __attribute__((overloadable)) pow(float8, float8);
+extern float16 __attribute__((overloadable)) pow(float16, float16);
+
+extern float __attribute__((overloadable)) radians(float);
+extern float2 __attribute__((overloadable)) radians(float2);
+extern float3 __attribute__((overloadable)) radians(float3);
+extern float4 __attribute__((overloadable)) radians(float4);
+extern float8 __attribute__((overloadable)) radians(float8);
+extern float16 __attribute__((overloadable)) radians(float16);
+
+extern float __attribute__((overloadable)) rint(float);
+extern float2 __attribute__((overloadable)) rint(float2);
+extern float3 __attribute__((overloadable)) rint(float3);
+extern float4 __attribute__((overloadable)) rint(float4);
+extern float8 __attribute__((overloadable)) rint(float8);
+extern float16 __attribute__((overloadable)) rint(float16);
+
+extern float __attribute__((overloadable)) round(float);
+extern float2 __attribute__((overloadable)) round(float2);
+extern float3 __attribute__((overloadable)) round(float3);
+extern float4 __attribute__((overloadable)) round(float4);
+extern float8 __attribute__((overloadable)) round(float8);
+extern float16 __attribute__((overloadable)) round(float16);
+
+extern float __attribute__((overloadable)) rsqrt(float);
+extern float2 __attribute__((overloadable)) rsqrt(float2);
+extern float3 __attribute__((overloadable)) rsqrt(float3);
+extern float4 __attribute__((overloadable)) rsqrt(float4);
+extern float8 __attribute__((overloadable)) rsqrt(float8);
+extern float16 __attribute__((overloadable)) rsqrt(float16);
+
+extern float __attribute__((overloadable)) sign(float);
+extern float2 __attribute__((overloadable)) sign(float2);
+extern float3 __attribute__((overloadable)) sign(float3);
+extern float4 __attribute__((overloadable)) sign(float4);
+extern float8 __attribute__((overloadable)) sign(float8);
+extern float16 __attribute__((overloadable)) sign(float16);
+
+extern float __attribute__((overloadable)) sin(float);
+extern float2 __attribute__((overloadable)) sin(float2);
+extern float3 __attribute__((overloadable)) sin(float3);
+extern float4 __attribute__((overloadable)) sin(float4);
+extern float8 __attribute__((overloadable)) sin(float8);
+extern float16 __attribute__((overloadable)) sin(float16);
+
+extern float __attribute__((overloadable)) sqrt(float);
+extern float2 __attribute__((overloadable)) sqrt(float2);
+extern float3 __attribute__((overloadable)) sqrt(float3);
+extern float4 __attribute__((overloadable)) sqrt(float4);
+extern float8 __attribute__((overloadable)) sqrt(float8);
+extern float16 __attribute__((overloadable)) sqrt(float16);
+
+extern float __attribute__((overloadable)) tan(float);
+extern float2 __attribute__((overloadable)) tan(float2);
+extern float3 __attribute__((overloadable)) tan(float3);
+extern float4 __attribute__((overloadable)) tan(float4);
+extern float8 __attribute__((overloadable)) tan(float8);
+extern float16 __attribute__((overloadable)) tan(float16);
+
+extern float __attribute__((overloadable)) trunc(float);
+extern float2 __attribute__((overloadable)) trunc(float2);
+extern float3 __attribute__((overloadable)) trunc(float3);
+extern float4 __attribute__((overloadable)) trunc(float4);
+extern float8 __attribute__((overloadable)) trunc(float8);
+extern float16 __attribute__((overloadable)) trunc(float16);
+
+
+
+
+
+
+// Int ops
+
+extern int __attribute__((overloadable)) abs(int);
+extern int2 __attribute__((overloadable)) abs(int2);
+extern int3 __attribute__((overloadable)) abs(int3);
+extern int4 __attribute__((overloadable)) abs(int4);
+extern int8 __attribute__((overloadable)) abs(int8);
+extern int16 __attribute__((overloadable)) abs(int16);
+
+
+
+/*
+extern float modf(float, float);
+extern float randf(float);
+extern float randf2(float, float);
+extern float fracf(float);
+extern float lerpf(float, float, float);
+extern float mapf(float, float, float, float, float);
+*/
+
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
new file mode 100644
index 0000000..ae1acdb
--- /dev/null
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -0,0 +1,71 @@
+
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+//typedef long int64_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+//typedef long uint64_t;
+
+typedef uint8_t uchar;
+typedef uint16_t ushort;
+typedef uint32_t uint;
+//typedef uint64_t ulong;
+
+typedef void * rs_element;
+typedef void * rs_type;
+typedef void * rs_allocation;
+typedef void * rs_sampler;
+typedef void * rs_script;
+typedef void * rs_mesh;
+typedef void * rs_program_fragment;
+typedef void * rs_program_vertex;
+typedef void * rs_program_raster;
+typedef void * rs_program_store;
+
+typedef float float2 __attribute__((ext_vector_type(2)));
+typedef float float3 __attribute__((ext_vector_type(3)));
+typedef float float4 __attribute__((ext_vector_type(4)));
+typedef float float8 __attribute__((ext_vector_type(8)));
+typedef float float16 __attribute__((ext_vector_type(16)));
+
+typedef uchar uchar2 __attribute__((ext_vector_type(2)));
+typedef uchar uchar3 __attribute__((ext_vector_type(3)));
+typedef uchar uchar4 __attribute__((ext_vector_type(4)));
+typedef uchar uchar8 __attribute__((ext_vector_type(8)));
+typedef uchar uchar16 __attribute__((ext_vector_type(16)));
+
+typedef ushort ushort2 __attribute__((ext_vector_type(2)));
+typedef ushort ushort3 __attribute__((ext_vector_type(3)));
+typedef ushort ushort4 __attribute__((ext_vector_type(4)));
+typedef ushort ushort8 __attribute__((ext_vector_type(8)));
+typedef ushort ushort16 __attribute__((ext_vector_type(16)));
+
+typedef uint uint2 __attribute__((ext_vector_type(2)));
+typedef uint uint3 __attribute__((ext_vector_type(3)));
+typedef uint uint4 __attribute__((ext_vector_type(4)));
+typedef uint uint8 __attribute__((ext_vector_type(8)));
+typedef uint uint16 __attribute__((ext_vector_type(16)));
+
+typedef char char2 __attribute__((ext_vector_type(2)));
+typedef char char3 __attribute__((ext_vector_type(3)));
+typedef char char4 __attribute__((ext_vector_type(4)));
+typedef char char8 __attribute__((ext_vector_type(8)));
+typedef char char16 __attribute__((ext_vector_type(16)));
+
+typedef short short2 __attribute__((ext_vector_type(2)));
+typedef short short3 __attribute__((ext_vector_type(3)));
+typedef short short4 __attribute__((ext_vector_type(4)));
+typedef short short8 __attribute__((ext_vector_type(8)));
+typedef short short16 __attribute__((ext_vector_type(16)));
+
+typedef int int2 __attribute__((ext_vector_type(2)));
+typedef int int3 __attribute__((ext_vector_type(3)));
+typedef int int4 __attribute__((ext_vector_type(4)));
+typedef int int8 __attribute__((ext_vector_type(8)));
+typedef int int16 __attribute__((ext_vector_type(16)));
+
+
+
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 7ca7875..4dc4a15 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -465,44 +465,61 @@
         // for composition later in the loop
         return;
     }
-    
+
+    // ouch, this really should never happen
+    if (uint32_t(buf)>=NUM_BUFFERS) {
+        LOGE("retireAndLock() buffer index (%d) out of range", buf);
+        mPostedDirtyRegion.clear();
+        return;
+    }
+
     // we retired a buffer, which becomes the new front buffer
     mFrontBufferIndex = buf;
 
     // get the dirty region
     sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
-    const Region dirty(lcblk->getDirtyRegion(buf));
-    mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
+    if (newFrontBuffer != NULL) {
+        // compute the posted region
+        const Region dirty(lcblk->getDirtyRegion(buf));
+        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
 
-    const Layer::State& front(drawingState());
-    if (newFrontBuffer->getWidth()  == front.requested_w &&
-        newFrontBuffer->getHeight() == front.requested_h)
-    {
-        if ((front.w != front.requested_w) ||
-            (front.h != front.requested_h))
+        // update the layer size and release freeze-lock
+        const Layer::State& front(drawingState());
+        if (newFrontBuffer->getWidth()  == front.requested_w &&
+            newFrontBuffer->getHeight() == front.requested_h)
         {
-            // Here we pretend the transaction happened by updating the
-            // current and drawing states. Drawing state is only accessed
-            // in this thread, no need to have it locked
-            Layer::State& editDraw(mDrawingState);
-            editDraw.w = editDraw.requested_w;
-            editDraw.h = editDraw.requested_h;
+            if ((front.w != front.requested_w) ||
+                (front.h != front.requested_h))
+            {
+                // Here we pretend the transaction happened by updating the
+                // current and drawing states. Drawing state is only accessed
+                // in this thread, no need to have it locked
+                Layer::State& editDraw(mDrawingState);
+                editDraw.w = editDraw.requested_w;
+                editDraw.h = editDraw.requested_h;
 
-            // We also need to update the current state so that we don't
-            // end-up doing too much work during the next transaction.
-            // NOTE: We actually don't need hold the transaction lock here
-            // because State::w and State::h are only accessed from
-            // this thread
-            Layer::State& editTemp(currentState());
-            editTemp.w = editDraw.w;
-            editTemp.h = editDraw.h;
+                // We also need to update the current state so that we don't
+                // end-up doing too much work during the next transaction.
+                // NOTE: We actually don't need hold the transaction lock here
+                // because State::w and State::h are only accessed from
+                // this thread
+                Layer::State& editTemp(currentState());
+                editTemp.w = editDraw.w;
+                editTemp.h = editDraw.h;
 
-            // recompute visible region
-            recomputeVisibleRegions = true;
+                // recompute visible region
+                recomputeVisibleRegions = true;
+            }
+
+            // we now have the correct size, unfreeze the screen
+            mFreezeLock.clear();
         }
-
-        // we now have the correct size, unfreeze the screen
-        mFreezeLock.clear();
+    } else {
+        // this should not happen unless we ran out of memory while
+        // allocating the buffer. we're hoping that things will get back
+        // to normal the next time the app tries to draw into this buffer.
+        // meanwhile, pretend the screen didn't update.
+        mPostedDirtyRegion.clear();
     }
 
     if (lcblk->getQueuedCount()) {
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index 140f10c..efbc77a 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -214,7 +214,6 @@
     if ((front.w != temp.w) || (front.h != temp.h)) {
         // invalidate and recompute the visible regions if needed
         flags |= Layer::eVisibleRegion;
-        this->contentDirty = true;
     }
 
     if (temp.sequence != front.sequence) {
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index a6e5644..62ec839 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -157,11 +157,11 @@
     
     /**
      * setCoveredRegion - called when the covered region changes. The covered
-     * region correspond to any area of the surface that is covered 
+     * region corresponds to any area of the surface that is covered
      * (transparently or not) by another surface.
      */
     virtual void setCoveredRegion(const Region& coveredRegion);
-    
+
     /**
      * validateVisibility - cache a bunch of things
      */
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 26ee285..0722fda 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -674,6 +674,8 @@
 {
     const GraphicPlane& plane(graphicPlane(0));
     const Transform& planeTransform(plane.transform());
+    const DisplayHardware& hw(plane.displayHardware());
+    const Region screenRegion(hw.bounds());
 
     Region aboveOpaqueLayers;
     Region aboveCoveredLayers;
@@ -689,31 +691,56 @@
         // start with the whole surface at its current location
         const Layer::State& s(layer->drawingState());
 
-        // handle hidden surfaces by setting the visible region to empty
+        /*
+         * opaqueRegion: area of a surface that is fully opaque.
+         */
         Region opaqueRegion;
+
+        /*
+         * visibleRegion: area of a surface that is visible on screen
+         * and not fully transparent. This is essentially the layer's
+         * footprint minus the opaque regions above it.
+         * Areas covered by a translucent surface are considered visible.
+         */
         Region visibleRegion;
+
+        /*
+         * coveredRegion: area of a surface that is covered by all
+         * visible regions above it (which includes the translucent areas).
+         */
         Region coveredRegion;
+
+
+        // handle hidden surfaces by setting the visible region to empty
         if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
             const bool translucent = layer->needsBlending();
             const Rect bounds(layer->visibleBounds());
             visibleRegion.set(bounds);
-            coveredRegion = visibleRegion;
+            visibleRegion.andSelf(screenRegion);
+            if (!visibleRegion.isEmpty()) {
+                // Remove the transparent area from the visible region
+                if (translucent) {
+                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
+                }
 
-            // Remove the transparent area from the visible region
-            if (translucent) {
-                visibleRegion.subtractSelf(layer->transparentRegionScreen);
-            }
-
-            // compute the opaque region
-            if (s.alpha==255 && !translucent && layer->getOrientation()>=0) {
-                // the opaque region is the visible region
-                opaqueRegion = visibleRegion;
+                // compute the opaque region
+                const int32_t layerOrientation = layer->getOrientation();
+                if (s.alpha==255 && !translucent &&
+                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
+                    // the opaque region is the layer's footprint
+                    opaqueRegion = visibleRegion;
+                }
             }
         }
 
+        // Clip the covered region to the visible region
+        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
+
+        // Update aboveCoveredLayers for next (lower) layer
+        aboveCoveredLayers.orSelf(visibleRegion);
+
         // subtract the opaque region covered by the layers above us
         visibleRegion.subtractSelf(aboveOpaqueLayers);
-        coveredRegion.andSelf(aboveCoveredLayers);
 
         // compute this layer's dirty region
         if (layer->contentDirty) {
@@ -724,19 +751,30 @@
             layer->contentDirty = false;
         } else {
             /* compute the exposed region:
-             *    exposed = what's VISIBLE and NOT COVERED now 
-             *    but was COVERED before
+             *   the exposed region consists of two components:
+             *   1) what's VISIBLE now and was COVERED before
+             *   2) what's EXPOSED now less what was EXPOSED before
+             *
+             * note that (1) is conservative, we start with the whole
+             * visible region but only keep what used to be covered by
+             * something -- which mean it may have been exposed.
+             *
+             * (2) handles areas that were not covered by anything but got
+             * exposed because of a resize.
              */
-            dirty = (visibleRegion - coveredRegion) & layer->coveredRegionScreen;
+            const Region newExposed = visibleRegion - coveredRegion;
+            const Region oldVisibleRegion = layer->visibleRegionScreen;
+            const Region oldCoveredRegion = layer->coveredRegionScreen;
+            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
+            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
         }
         dirty.subtractSelf(aboveOpaqueLayers);
 
         // accumulate to the screen dirty region
         dirtyRegion.orSelf(dirty);
 
-        // Update aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer
+        // Update aboveOpaqueLayers for next (lower) layer
         aboveOpaqueLayers.orSelf(opaqueRegion);
-        aboveCoveredLayers.orSelf(visibleRegion);
         
         // Store the visible region is screen space
         layer->setVisibleRegion(visibleRegion);
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index 43762e7..843a8fd 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -58,7 +58,7 @@
 
     int pathRemaining = PATH_MAX - pathLength;
     strcpy(pathBuffer, path);
-    if (pathLength > 0 && pathBuffer[pathLength - 1]) {
+    if (pathLength > 0 && pathBuffer[pathLength - 1] != '/') {
         pathBuffer[pathLength] = '/';
         pathBuffer[pathLength + 1] = 0;
         --pathRemaining;
diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp
index 2a16d26..0fea72e 100644
--- a/media/libstagefright/AMRExtractor.cpp
+++ b/media/libstagefright/AMRExtractor.cpp
@@ -222,7 +222,7 @@
     ssize_t n = mDataSource->readAt(mOffset, &header, 1);
 
     if (n < 1) {
-        return ERROR_IO;
+        return ERROR_END_OF_STREAM;
     }
 
     if (header & 0x83) {
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 10b7be3..164df72 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -624,8 +624,6 @@
 }
 
 bool AwesomePlayer::isPlaying() const {
-    Mutex::Autolock autoLock(mLock);
-
     return mFlags & PLAYING;
 }
 
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 974413d2..9a092d5 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -366,7 +366,6 @@
 
     sp<OMXCodecObserver> observer = new OMXCodecObserver;
     IOMX::node_id node = 0;
-    success = false;
 
     const char *componentName;
     for (size_t i = 0; i < matchingCodecs.size(); ++i) {
@@ -389,22 +388,27 @@
         if (err == OK) {
             LOGV("Successfully allocated OMX node '%s'", componentName);
 
-            success = true;
-            break;
+            sp<OMXCodec> codec = new OMXCodec(
+                    omx, node, getComponentQuirks(componentName),
+                    createEncoder, mime, componentName,
+                    source);
+
+            observer->setCodec(codec);
+
+            err = codec->configureCodec(meta);
+
+            if (err == OK) {
+                return codec;
+            }
+
+            LOGV("Failed to configure codec '%s'", componentName);
         }
     }
 
-    if (!success) {
-        return NULL;
-    }
+    return NULL;
+}
 
-    sp<OMXCodec> codec = new OMXCodec(
-            omx, node, getComponentQuirks(componentName),
-            createEncoder, mime, componentName,
-            source);
-
-    observer->setCodec(codec);
-
+status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
     uint32_t type;
     const void *data;
     size_t size;
@@ -417,7 +421,7 @@
         esds.getCodecSpecificInfo(
                 &codec_specific_data, &codec_specific_data_size);
 
-        codec->addCodecSpecificData(
+        addCodecSpecificData(
                 codec_specific_data, codec_specific_data_size);
     } else if (meta->findData(kKeyAVCC, &type, &data, &size)) {
         // Parse the AVCDecoderConfigurationRecord
@@ -453,7 +457,7 @@
 
             CHECK(size >= length);
 
-            codec->addCodecSpecificData(ptr, length);
+            addCodecSpecificData(ptr, length);
 
             ptr += length;
             size -= length;
@@ -473,7 +477,7 @@
 
             CHECK(size >= length);
 
-            codec->addCodecSpecificData(ptr, length);
+            addCodecSpecificData(ptr, length);
 
             ptr += length;
             size -= length;
@@ -482,44 +486,49 @@
         LOGV("AVC profile = %d (%s), level = %d",
              (int)profile, AVCProfileToString(profile), (int)level / 10);
 
-        if (!strcmp(componentName, "OMX.TI.Video.Decoder")
+        if (!strcmp(mComponentName, "OMX.TI.Video.Decoder")
             && (profile != kAVCProfileBaseline || level > 39)) {
             // This stream exceeds the decoder's capabilities. The decoder
             // does not handle this gracefully and would clobber the heap
             // and wreak havoc instead...
 
             LOGE("Profile and/or level exceed the decoder's capabilities.");
-            return NULL;
+            return ERROR_UNSUPPORTED;
         }
     }
 
-    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
-        codec->setAMRFormat(false /* isWAMR */);
+    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mMIME)) {
+        setAMRFormat(false /* isWAMR */);
     }
-    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
-        codec->setAMRFormat(true /* isWAMR */);
+    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mMIME)) {
+        setAMRFormat(true /* isWAMR */);
     }
-    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
+    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mMIME)) {
         int32_t numChannels, sampleRate;
         CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
         CHECK(meta->findInt32(kKeySampleRate, &sampleRate));
 
-        codec->setAACFormat(numChannels, sampleRate);
+        setAACFormat(numChannels, sampleRate);
     }
-    if (!strncasecmp(mime, "video/", 6)) {
+    if (!strncasecmp(mMIME, "video/", 6)) {
         int32_t width, height;
         bool success = meta->findInt32(kKeyWidth, &width);
         success = success && meta->findInt32(kKeyHeight, &height);
         CHECK(success);
 
-        if (createEncoder) {
-            codec->setVideoInputFormat(mime, width, height);
+        if (mIsEncoder) {
+            setVideoInputFormat(mMIME, width, height);
         } else {
-            codec->setVideoOutputFormat(mime, width, height);
+            status_t err = setVideoOutputFormat(
+                    mMIME, width, height);
+
+            if (err != OK) {
+                return err;
+            }
         }
     }
-    if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_JPEG)
-        && !strcmp(componentName, "OMX.TI.JPEG.decode")) {
+    if (!strcasecmp(mMIME, MEDIA_MIMETYPE_IMAGE_JPEG)
+        && !strcmp(mComponentName, "OMX.TI.JPEG.decode")) {
         OMX_COLOR_FORMATTYPE format =
             OMX_COLOR_Format32bitARGB8888;
             // OMX_COLOR_FormatYUV420PackedPlanar;
@@ -537,23 +546,23 @@
         CHECK(success);
         CHECK(compressedSize > 0);
 
-        codec->setImageOutputFormat(format, width, height);
-        codec->setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
+        setImageOutputFormat(format, width, height);
+        setJPEGInputFormat(width, height, (OMX_U32)compressedSize);
     }
 
     int32_t maxInputSize;
     if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
-        codec->setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
+        setMinBufferSize(kPortIndexInput, (OMX_U32)maxInputSize);
     }
 
-    if (!strcmp(componentName, "OMX.TI.AMR.encode")
-        || !strcmp(componentName, "OMX.TI.WBAMR.encode")) {
-        codec->setMinBufferSize(kPortIndexOutput, 8192);  // XXX
+    if (!strcmp(mComponentName, "OMX.TI.AMR.encode")
+        || !strcmp(mComponentName, "OMX.TI.WBAMR.encode")) {
+        setMinBufferSize(kPortIndexOutput, 8192);  // XXX
     }
 
-    codec->initOutputFormat(meta);
+    initOutputFormat(meta);
 
-    return codec;
+    return OK;
 }
 
 void OMXCodec::setMinBufferSize(OMX_U32 portIndex, OMX_U32 size) {
@@ -902,7 +911,7 @@
     return OK;
 }
 
-void OMXCodec::setVideoOutputFormat(
+status_t OMXCodec::setVideoOutputFormat(
         const char *mime, OMX_U32 width, OMX_U32 height) {
     CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height);
 
@@ -918,9 +927,13 @@
         CHECK(!"Should not be here. Not a supported video mime type.");
     }
 
-    setVideoPortFormatType(
+    status_t err = setVideoPortFormatType(
             kPortIndexInput, compressionFormat, OMX_COLOR_FormatUnused);
 
+    if (err != OK) {
+        return err;
+    }
+
 #if 1
     {
         OMX_VIDEO_PARAM_PORTFORMATTYPE format;
@@ -944,7 +957,10 @@
         err = mOMX->setParameter(
                 mNode, OMX_IndexParamVideoPortFormat,
                 &format, sizeof(format));
-        CHECK_EQ(err, OK);
+
+        if (err != OK) {
+            return err;
+        }
     }
 #endif
 
@@ -954,7 +970,7 @@
 
     OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
 
-    status_t err = mOMX->getParameter(
+    err = mOMX->getParameter(
             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
 
     CHECK_EQ(err, OK);
@@ -977,7 +993,10 @@
 
     err = mOMX->setParameter(
             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, OK);
+
+    if (err != OK) {
+        return err;
+    }
 
     ////////////////////////////////////////////////////////////////////////////
 
@@ -999,7 +1018,8 @@
 
     err = mOMX->setParameter(
             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
-    CHECK_EQ(err, OK);
+
+    return err;
 }
 
 OMXCodec::OMXCodec(
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 16a2a10..b263238 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -275,6 +275,7 @@
     size_t utf8len = 0;
     for (size_t i = 0; i < size; ++i) {
         if (data[i] == '\0') {
+            size = i;
             break;
         } else if (data[i] < 0x80) {
             ++utf8len;
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 2458d2a..c1a010c 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -25,6 +25,7 @@
 
 #include <binder/IMemory.h>
 #include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaErrors.h>
 
 namespace android {
 
@@ -105,7 +106,14 @@
 }
 
 static status_t StatusFromOMXError(OMX_ERRORTYPE err) {
-    return (err == OMX_ErrorNone) ? OK : UNKNOWN_ERROR;
+    switch (err) {
+        case OMX_ErrorNone:
+            return OK;
+        case OMX_ErrorUnsupportedSetting:
+            return ERROR_UNSUPPORTED;
+        default:
+            return UNKNOWN_ERROR;
+    }
 }
 
 status_t OMXNodeInstance::freeNode(OMXMaster *master) {
diff --git a/obex/javax/obex/ServerRequestHandler.java b/obex/javax/obex/ServerRequestHandler.java
index d93e5b6..0882572 100644
--- a/obex/javax/obex/ServerRequestHandler.java
+++ b/obex/javax/obex/ServerRequestHandler.java
@@ -197,6 +197,13 @@
     }
 
     /**
+     * Called when a ABORT request is received.
+     */
+    public int onAbort(HeaderSet request, HeaderSet reply) {
+        return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
+    }
+
+    /**
      * Called when a PUT request is received.
      * <P>
      * If this method is not implemented by the class that extends this class,
diff --git a/obex/javax/obex/ServerSession.java b/obex/javax/obex/ServerSession.java
index 503d440..a4b9759 100644
--- a/obex/javax/obex/ServerSession.java
+++ b/obex/javax/obex/ServerSession.java
@@ -115,6 +115,9 @@
                     case ObexHelper.OBEX_OPCODE_SETPATH:
                         handleSetPathRequest();
                         break;
+                    case ObexHelper.OBEX_OPCODE_ABORT:
+                        handleAbortRequest();
+                        break;
 
                     case -1:
                         done = true;
@@ -145,6 +148,35 @@
     }
 
     /**
+     * Handles a ABORT request from a client. This method will read the rest of
+     * the request from the client. Assuming the request is valid, it will
+     * create a <code>HeaderSet</code> object to pass to the
+     * <code>ServerRequestHandler</code> object. After the handler processes the
+     * request, this method will create a reply message to send to the server.
+     *
+     * @throws IOException if an error occurred at the transport layer
+     */
+    private void handleAbortRequest() throws IOException {
+        int code = ResponseCodes.OBEX_HTTP_OK;
+        HeaderSet request = new HeaderSet();
+        HeaderSet reply = new HeaderSet();
+
+        int length = mInput.read();
+        length = (length << 8) + mInput.read();
+        if (length > ObexHelper.MAX_PACKET_SIZE_INT) {
+            code = ResponseCodes.OBEX_HTTP_REQ_TOO_LARGE;
+        } else {
+            for (int i = 3; i < length; i++) {
+                mInput.read();
+            }
+            code = mListener.onAbort(request, reply);
+            Log.v(TAG, "onAbort request handler return value- " + code);
+            code = validateResponseCode(code);
+        }
+        sendResponse(code, null);
+    }
+
+    /**
      * Handles a PUT request from a client. This method will provide a
      * <code>ServerOperation</code> object to the request handler. The
      * <code>ServerOperation</code> object will handle the rest of the request.
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index 882cbc5..3f029a6 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -977,15 +977,22 @@
          * @return false if the context has been lost.
          */
         public boolean swap() {
-            mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
+            if (! mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
 
-            /*
-             * Always check for EGL_CONTEXT_LOST, which means the context
-             * and all associated data were lost (For instance because
-             * the device went to sleep). We need to sleep until we
-             * get a new surface.
-             */
-            return mEgl.eglGetError() != EGL11.EGL_CONTEXT_LOST;
+                /*
+                 * Check for EGL_CONTEXT_LOST, which means the context
+                 * and all associated data were lost (For instance because
+                 * the device went to sleep). We need to sleep until we
+                 * get a new surface.
+                 */
+                int error = mEgl.eglGetError();
+                if (error == EGL11.EGL_CONTEXT_LOST) {
+                    return false;
+                } else {
+                    throwEglException("eglSwapBuffers", error);
+                }
+            }
+            return true;
         }
 
         public void destroySurface() {
@@ -1010,7 +1017,11 @@
         }
 
         private void throwEglException(String function) {
-            throw new RuntimeException(function + " failed: " + mEgl.eglGetError());
+            throwEglException(function, mEgl.eglGetError());
+        }
+
+        private void throwEglException(String function, int error) {
+            throw new RuntimeException(function + " failed: " + error);
         }
 
         EGL10 mEgl;
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 145e25e..89b3e1f 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -650,6 +650,7 @@
     if (dp->refs > 0) {
         if (major != NULL) *major = VERSION_MAJOR;
         if (minor != NULL) *minor = VERSION_MINOR;
+        dp->refs++;
         return EGL_TRUE;
     }
     
@@ -755,8 +756,10 @@
     }
 
     // this is specific to Android, display termination is ref-counted.
-    if (dp->refs > 1)
+    if (dp->refs > 1) {
+        dp->refs--;
         return EGL_TRUE;
+    }
 
     EGLBoolean res = EGL_FALSE;
     for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index c6b617d..77d11cc 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -24,7 +24,6 @@
 import android.content.pm.PackageInfoLite;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageParser;
-import android.content.pm.PackageParser.Package;
 import android.net.Uri;
 import android.os.Environment;
 import android.os.IBinder;
@@ -45,7 +44,6 @@
 import java.io.InputStream;
 
 import android.os.FileUtils;
-import android.os.storage.IMountService;
 import android.provider.Settings;
 
 /*
@@ -130,26 +128,21 @@
             ret.packageName = pkg.packageName;
             ret.installLocation = pkg.installLocation;
             // Nuke the parser reference right away and force a gc
-            Runtime.getRuntime().gc();
             packageParser = null;
+            Runtime.getRuntime().gc();
             if (pkg == null) {
                 Log.w(TAG, "Failed to parse package");
                 ret.recommendedInstallLocation = PackageHelper.RECOMMEND_FAILED_INVALID_APK;
                 return ret;
             }
             ret.packageName = pkg.packageName;
-            int loc = recommendAppInstallLocation(pkg.installLocation, archiveFilePath);
-            if (loc == PackageManager.INSTALL_EXTERNAL) {
-                ret.recommendedInstallLocation =  PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
-            } else if (loc == ERR_LOC) {
-                Log.i(TAG, "Failed to install insufficient storage");
-                ret.recommendedInstallLocation =  PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
-            } else {
-                // Implies install on internal storage.
-                ret.recommendedInstallLocation =  PackageHelper.RECOMMEND_INSTALL_INTERNAL;
-            }
+            ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation, archiveFilePath);
             return ret;
         }
+
+        public boolean checkFreeStorage(boolean external, Uri fileUri) {
+            return checkFreeStorageInner(external, fileUri);
+        }
     };
 
     public DefaultContainerService() {
@@ -190,6 +183,12 @@
     }
 
     private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName) {
+        // Make sure the sdcard is mounted.
+        String status = Environment.getExternalStorageState();
+        if (!status.equals(Environment.MEDIA_MOUNTED)) {
+            Log.w(TAG, "Make sure sdcard is mounted.");
+            return null;
+        }
         // Create new container at newCachePath
         String codePath = packageURI.getPath();
         File codeFile = new File(codePath);
@@ -313,11 +312,13 @@
         // Else install on internal NAND flash, unless space on NAND is less than 10%
         String status = Environment.getExternalStorageState();
         long availSDSize = -1;
+        boolean mediaAvailable = false;
         if (status.equals(Environment.MEDIA_MOUNTED)) {
             StatFs sdStats = new StatFs(
                     Environment.getExternalStorageDirectory().getPath());
             availSDSize = (long)sdStats.getAvailableBlocks() *
                     (long)sdStats.getBlockSize();
+            mediaAvailable = true;
         }
         StatFs internalStats = new StatFs(Environment.getDataDirectory().getPath());
         long totalInternalSize = (long)internalStats.getBlockCount() *
@@ -337,7 +338,8 @@
         long reqInternalSize = 0;
         boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
         boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalSize);
-        boolean fitsOnSd = (reqInstallSize < availSDSize) && intThresholdOk &&
+        boolean fitsOnSd = mediaAvailable && (reqInstallSize < availSDSize)
+                 && intThresholdOk &&
                 (reqInternalSize < availInternalSize);
         boolean fitsOnInt = intThresholdOk && intAvailOk;
 
@@ -377,21 +379,58 @@
         }
         if (!auto) {
             if (installOnlyOnSd) {
-                return fitsOnSd ? PackageManager.INSTALL_EXTERNAL : ERR_LOC;
+                if (fitsOnSd) {
+                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
+                }
+                if (!mediaAvailable) {
+                    return PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE;
+                }
+                return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
             } else if (installOnlyInternal){
                 // Check on internal flash
-                return fitsOnInt ? 0 : ERR_LOC;
+                return fitsOnInt ?  PackageHelper.RECOMMEND_INSTALL_INTERNAL :
+                    PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
             }
         }
         // Try to install internally
         if (fitsOnInt) {
-            return 0;
+            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
         }
         // Try the sdcard now.
         if (fitsOnSd) {
-            return PackageManager.INSTALL_EXTERNAL;
+            return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
         }
         // Return error code
-        return ERR_LOC;
+        return PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
+    }
+
+    private boolean checkFreeStorageInner(boolean external, Uri packageURI) {
+        File apkFile = new File(packageURI.getPath());
+        long size = apkFile.length();
+        if (external) {
+            String status = Environment.getExternalStorageState();
+            long availSDSize = -1;
+            if (status.equals(Environment.MEDIA_MOUNTED)) {
+                StatFs sdStats = new StatFs(
+                        Environment.getExternalStorageDirectory().getPath());
+                availSDSize = (long)sdStats.getAvailableBlocks() *
+                (long)sdStats.getBlockSize();
+            }
+            return availSDSize > size;
+        }
+        StatFs internalStats = new StatFs(Environment.getDataDirectory().getPath());
+        long totalInternalSize = (long)internalStats.getBlockCount() *
+        (long)internalStats.getBlockSize();
+        long availInternalSize = (long)internalStats.getAvailableBlocks() *
+        (long)internalStats.getBlockSize();
+
+        double pctNandFree = (double)availInternalSize / (double)totalInternalSize;
+        // To make final copy
+        long reqInstallSize = size;
+        // For dex files. Just ignore and fail when extracting. Max limit of 2Gig for now.
+        long reqInternalSize = 0;
+        boolean intThresholdOk = (pctNandFree >= LOW_NAND_FLASH_TRESHOLD);
+        boolean intAvailOk = ((reqInstallSize + reqInternalSize) < availInternalSize);
+        return intThresholdOk && intAvailOk;
     }
 }
diff --git a/packages/TtsService/src/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
index cd46c05..cece94e 100755
--- a/packages/TtsService/src/android/tts/SynthProxy.java
+++ b/packages/TtsService/src/android/tts/SynthProxy.java
@@ -36,9 +36,9 @@
     // Such a huge filter gain is justified by how much energy in the low frequencies is "wasted" at
     // the output of the synthesis. The low shelving filter removes it, leaving room for
     // amplification.
-    private final static float PICO_FILTER_GAIN = 4.0f; // linear gain
-    private final static float PICO_FILTER_LOWSHELF_ATTENUATION = -16.0f; // in dB
-    private final static float PICO_FILTER_TRANSITION_FREQ = 1000.0f;     // in Hz
+    private final static float PICO_FILTER_GAIN = 5.0f; // linear gain
+    private final static float PICO_FILTER_LOWSHELF_ATTENUATION = -18.0f; // in dB
+    private final static float PICO_FILTER_TRANSITION_FREQ = 1100.0f;     // in Hz
     private final static float PICO_FILTER_SHELF_SLOPE = 1.0f;            // Q
 
     //
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index d4d5336..d50f5910 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -29,6 +29,8 @@
 import android.os.storage.IMountShutdownObserver;
 import android.os.storage.StorageResultCode;
 import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
 import android.os.IBinder;
@@ -49,6 +51,8 @@
 class MountService extends IMountService.Stub
         implements INativeDaemonConnectorCallbacks {
     private static final boolean LOCAL_LOGD = false;
+    private static final boolean DEBUG_UNMOUNT = false;
+    private static final boolean DEBUG_EVENTS = false;
     
     private static final String TAG = "MountService";
 
@@ -154,6 +158,7 @@
         }
 
         void handleFinished() {
+            if (DEBUG_UNMOUNT) Log.i(TAG, "Unmounting " + path);
             doUnmountVolume(path, true);
         }
     }
@@ -193,28 +198,37 @@
         }
     }
 
-    final private Handler mHandler = new Handler() {
+    class MountServiceHandler extends Handler {
         ArrayList<UnmountCallBack> mForceUnmounts = new ArrayList<UnmountCallBack>();
         boolean mRegistered = false;
 
+        MountServiceHandler(Looper l) {
+            super(l);
+        }
+
         void registerReceiver() {
             mRegistered = true;
+            if (DEBUG_UNMOUNT) Log.i(TAG, "Registering receiver");
             mContext.registerReceiver(mPmReceiver, mPmFilter);
         }
 
         void unregisterReceiver() {
             mRegistered = false;
+            if (DEBUG_UNMOUNT) Log.i(TAG, "Unregistering receiver");
             mContext.unregisterReceiver(mPmReceiver);
         }
 
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case H_UNMOUNT_PM_UPDATE: {
+                    if (DEBUG_UNMOUNT) Log.i(TAG, "H_UNMOUNT_PM_UPDATE");
                     UnmountCallBack ucb = (UnmountCallBack) msg.obj;
                     mForceUnmounts.add(ucb);
+                    if (DEBUG_UNMOUNT) Log.i(TAG, " registered = " + mRegistered);
                     // Register only if needed.
                     if (!mRegistered) {
                         registerReceiver();
+                        if (DEBUG_UNMOUNT) Log.i(TAG, "Updating external media status");
                         boolean hasExtPkgs = mPms.updateExternalMediaStatus(false);
                         if (!hasExtPkgs) {
                             // Unregister right away
@@ -224,6 +238,7 @@
                     break;
                 }
                 case H_UNMOUNT_PM_DONE: {
+                    if (DEBUG_UNMOUNT) Log.i(TAG, "H_UNMOUNT_PM_DONE");
                     // Unregister now.
                     if (mRegistered) {
                         unregisterReceiver();
@@ -280,6 +295,7 @@
                     break;
                 }
                 case H_UNMOUNT_MS : {
+                    if (DEBUG_UNMOUNT) Log.i(TAG, "H_UNMOUNT_MS");
                     UnmountCallBack ucb = (UnmountCallBack) msg.obj;
                     ucb.handleFinished();
                     break;
@@ -287,6 +303,8 @@
             }
         }
     };
+    final private HandlerThread mHandlerThread;
+    final private Handler mHandler;
 
     private void waitForReady() {
         while (mReady == false) {
@@ -385,7 +403,12 @@
             Log.w(TAG, String.format("Duplicate state transition (%s -> %s)", mLegacyState, state));
             return;
         }
-
+        // Update state on PackageManager
+        if (Environment.MEDIA_UNMOUNTED.equals(state)) {
+            mPms.updateExternalMediaStatus(false);
+        } else if (Environment.MEDIA_MOUNTED.equals(state)) {
+            mPms.updateExternalMediaStatus(true);
+        }
         String oldState = mLegacyState;
         mLegacyState = state;
 
@@ -448,6 +471,7 @@
                         }
                     }
                     if (state != null) {
+                        if (DEBUG_EVENTS) Log.i(TAG, "Updating valid state " + state);
                         updatePublicVolumeState(path, state);
                     }
                 } catch (Exception e) {
@@ -476,6 +500,18 @@
     public boolean onEvent(int code, String raw, String[] cooked) {
         Intent in = null;
 
+        if (DEBUG_EVENTS) {
+            StringBuilder builder = new StringBuilder();
+            builder.append("onEvent::");
+            builder.append(" raw= " + raw);
+            if (cooked != null) {
+                builder.append(" cooked = " );
+                for (String str : cooked) {
+                    builder.append(" " + str);
+                }
+            }
+            Log.i(TAG, builder.toString());
+        }
         if (code == VoldResponseCode.VolumeStateChange) {
             /*
              * One of the volumes we're managing has changed state.
@@ -533,18 +569,22 @@
                     return true;
                 }
                 /* Send the media unmounted event first */
+                if (DEBUG_EVENTS) Log.i(TAG, "Sending unmounted event first");
                 updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
                 in = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, Uri.parse("file://" + path));
                 mContext.sendBroadcast(in);
 
+                if (DEBUG_EVENTS) Log.i(TAG, "Sending media removed");
                 updatePublicVolumeState(path, Environment.MEDIA_REMOVED);
                 in = new Intent(Intent.ACTION_MEDIA_REMOVED, Uri.parse("file://" + path));
             } else if (code == VoldResponseCode.VolumeBadRemoval) {
+                if (DEBUG_EVENTS) Log.i(TAG, "Sending unmounted event first");
                 /* Send the media unmounted event first */
                 updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
                 in = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, Uri.parse("file://" + path));
                 mContext.sendBroadcast(in);
 
+                if (DEBUG_EVENTS) Log.i(TAG, "Sending media bad removal");
                 updatePublicVolumeState(path, Environment.MEDIA_BAD_REMOVAL);
                 in = new Intent(Intent.ACTION_MEDIA_BAD_REMOVAL, Uri.parse("file://" + path));
             } else {
@@ -556,12 +596,13 @@
 
         if (in != null) {
             mContext.sendBroadcast(in);
-	}
-       return true;
+        }
+        return true;
     }
 
     private void notifyVolumeStateChange(String label, String path, int oldState, int newState) {
         String vs = getVolumeState(path);
+        if (DEBUG_EVENTS) Log.i(TAG, "notifyVolumeStateChanged::" + vs);
 
         Intent in = null;
 
@@ -583,29 +624,31 @@
                     Environment.MEDIA_BAD_REMOVAL) && !vs.equals(
                             Environment.MEDIA_NOFS) && !vs.equals(
                                     Environment.MEDIA_UNMOUNTABLE) && !getUmsEnabling()) {
+                if (DEBUG_EVENTS) Log.i(TAG, "updating volume state for media bad removal nofs and unmountable");
                 updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
                 in = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, Uri.parse("file://" + path));
             }
         } else if (newState == VolumeState.Pending) {
         } else if (newState == VolumeState.Checking) {
+            if (DEBUG_EVENTS) Log.i(TAG, "updating volume state checking");
             updatePublicVolumeState(path, Environment.MEDIA_CHECKING);
             in = new Intent(Intent.ACTION_MEDIA_CHECKING, Uri.parse("file://" + path));
         } else if (newState == VolumeState.Mounted) {
+            if (DEBUG_EVENTS) Log.i(TAG, "updating volume state mounted");
             updatePublicVolumeState(path, Environment.MEDIA_MOUNTED);
-            // Update media status on PackageManagerService to mount packages on sdcard
-            mPms.updateExternalMediaStatus(true);
             in = new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + path));
             in.putExtra("read-only", false);
         } else if (newState == VolumeState.Unmounting) {
-            mPms.updateExternalMediaStatus(false);
             in = new Intent(Intent.ACTION_MEDIA_EJECT, Uri.parse("file://" + path));
         } else if (newState == VolumeState.Formatting) {
         } else if (newState == VolumeState.Shared) {
+            if (DEBUG_EVENTS) Log.i(TAG, "Updating volume state media mounted");
             /* Send the media unmounted event first */
             updatePublicVolumeState(path, Environment.MEDIA_UNMOUNTED);
             in = new Intent(Intent.ACTION_MEDIA_UNMOUNTED, Uri.parse("file://" + path));
             mContext.sendBroadcast(in);
 
+            if (DEBUG_EVENTS) Log.i(TAG, "Updating media shared");
             updatePublicVolumeState(path, Environment.MEDIA_SHARED);
             in = new Intent(Intent.ACTION_MEDIA_SHARED, Uri.parse("file://" + path));
             if (LOCAL_LOGD) Log.d(TAG, "Sending ACTION_MEDIA_SHARED intent");
@@ -649,6 +692,7 @@
     private int doMountVolume(String path) {
         int rc = StorageResultCode.OperationSucceeded;
 
+        if (DEBUG_EVENTS) Log.i(TAG, "doMountVolume: Mouting " + path);
         try {
             mConnector.doCommand(String.format("volume mount %s", path));
         } catch (NativeDaemonConnectorException e) {
@@ -663,6 +707,7 @@
                  */
                 rc = StorageResultCode.OperationFailedNoMedia;
             } else if (code == VoldResponseCode.OpFailedMediaBlank) {
+                if (DEBUG_EVENTS) Log.i(TAG, " updating volume state :: media nofs");
                 /*
                  * Media is blank or does not contain a supported filesystem
                  */
@@ -670,6 +715,7 @@
                 in = new Intent(Intent.ACTION_MEDIA_NOFS, Uri.parse("file://" + path));
                 rc = StorageResultCode.OperationFailedMediaBlank;
             } else if (code == VoldResponseCode.OpFailedMediaCorrupt) {
+                if (DEBUG_EVENTS) Log.i(TAG, "updating volume state media corrupt");
                 /*
                  * Volume consistency check failed
                  */
@@ -850,6 +896,10 @@
         mContext.registerReceiver(mBroadcastReceiver,
                 new IntentFilter(Intent.ACTION_BOOT_COMPLETED), null, null);
 
+        mHandlerThread = new HandlerThread("MountService");
+        mHandlerThread.start();
+        mHandler = new MountServiceHandler(mHandlerThread.getLooper());
+
         /*
          * Vold does not run in the simulator, so pretend the connector thread
          * ran and did its thing.
@@ -1028,6 +1078,16 @@
         validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
         waitForReady();
 
+        String volState = getVolumeState(path);
+        if (DEBUG_UNMOUNT) Log.i(TAG, "Unmounting " + path + " force = " + force);
+        if (Environment.MEDIA_UNMOUNTED.equals(volState) ||
+                Environment.MEDIA_REMOVED.equals(volState) ||
+                Environment.MEDIA_SHARED.equals(volState) ||
+                Environment.MEDIA_UNMOUNTABLE.equals(volState)) {
+            // Media already unmounted or cannot be unmounted.
+            // TODO return valid return code when adding observer call back.
+            return;
+        }
         UnmountCallBack ucb = new UnmountCallBack(path, force);
         mHandler.sendMessage(mHandler.obtainMessage(H_UNMOUNT_PM_UPDATE, ucb));
     }
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index aa9ced8..b114ca2 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -26,10 +26,13 @@
 import android.net.Uri;
 import android.net.InterfaceConfiguration;
 import android.net.INetworkManagementEventObserver;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.os.INetworkManagementService;
 import android.os.Handler;
 import android.os.SystemProperties;
 import android.text.TextUtils;
+import android.util.Log;
 import android.util.Slog;
 import java.util.ArrayList;
 import java.util.StringTokenizer;
@@ -457,14 +460,38 @@
         throw new IllegalStateException("Got an empty response");
     }
 
-    public void startAccessPoint()
+    public void startAccessPoint(WifiConfiguration wifiConfig, String intf)
              throws IllegalStateException {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
         mContext.enforceCallingOrSelfPermission(
             android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
-        mConnector.doCommand(String.format("softap set"));
-        mConnector.doCommand(String.format("softap start"));
+        mConnector.doCommand(String.format("softap stop " + intf));
+        mConnector.doCommand(String.format("softap fwreload " + intf + " AP"));
+        mConnector.doCommand(String.format("softap start " + intf));
+        if (wifiConfig == null) {
+            mConnector.doCommand(String.format("softap set " + intf + " wl0.1"));
+        } else {
+            /**
+             * softap set arg1 arg2 arg3 [arg4 arg5 arg6 arg7 arg8]
+             * argv1 - wlan interface
+             * argv2 - softap interface
+             * argv3 - SSID
+             * argv4 - Security
+             * argv5 - Key
+             * argv6 - Channel
+             * argv7 - Preamble
+             * argv8 - Max SCB
+             *
+             * TODO: get a configurable softap interface from driver
+             */
+            String str = String.format("softap set " + intf + " wl0.1 %s %s %s", wifiConfig.SSID,
+                                       wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK) ?
+                                       "wpa2-psk" : "open",
+                                       wifiConfig.preSharedKey);
+            mConnector.doCommand(str);
+        }
+        mConnector.doCommand(String.format("softap startap"));
     }
 
     public void stopAccessPoint() throws IllegalStateException {
@@ -472,7 +499,7 @@
                 android.Manifest.permission.CHANGE_NETWORK_STATE, "NetworkManagementService");
         mContext.enforceCallingOrSelfPermission(
             android.Manifest.permission.CHANGE_WIFI_STATE, "NetworkManagementService");
-        mConnector.doCommand("softap stop");
+        mConnector.doCommand("softap stopap");
     }
 
 }
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 139c05f..818e99e 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -4613,6 +4613,12 @@
             return pkgLite.recommendedInstallLocation;
         }
 
+        /*
+         * Invoke remote method to get package information and install
+         * location values. Override install location based on default
+         * policy if needed and then create install arguments based
+         * on the install location.
+         */
         public void handleStartCopy() throws RemoteException {
             int ret = PackageManager.INSTALL_SUCCEEDED;
             boolean fwdLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
@@ -4624,9 +4630,7 @@
             } else {
                 // Remote call to find out default install location
                 PackageInfoLite pkgLite = mContainerService.getMinimalPackageInfo(packageURI);
-                int loc = installLocationPolicy(pkgLite, flags);
-                // Use install location to create InstallArgs and temporary
-                // install location
+                int loc = pkgLite.recommendedInstallLocation;
                 if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION){
                     ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
                 } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS){
@@ -4635,7 +4639,11 @@
                     ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
                 } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
                     ret = PackageManager.INSTALL_FAILED_INVALID_APK;
+                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
+                  ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
                 } else {
+                    // Override with defaults if needed.
+                    loc = installLocationPolicy(pkgLite, flags);
                     // Override install location with flags
                     if ((flags & PackageManager.INSTALL_EXTERNAL) == 0){
                         if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
@@ -4701,6 +4709,12 @@
         }
 
         public void handleStartCopy() throws RemoteException {
+            mRet = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+            // Check for storage space on target medium
+            if (!targetArgs.checkFreeStorage(mContainerService)) {
+                Log.w(TAG, "Insufficient storage to install");
+                return;
+            }
             // Create the file args now.
             mRet = targetArgs.copyApk(mContainerService, false);
             targetArgs.doPreInstall(mRet);
@@ -4714,15 +4728,20 @@
                     builder.append(" target : ");
                     builder.append(targetArgs.getCodePath());
                 }
-                Log.i(TAG, "Posting move MCS_UNBIND for " + builder.toString());
+                Log.i(TAG, builder.toString());
             }
         }
 
         @Override
         void handleReturnCode() {
             targetArgs.doPostInstall(mRet);
-            // TODO invoke pending move
-            processPendingMove(this, mRet);
+            int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
+            if (mRet == PackageManager.INSTALL_SUCCEEDED) {
+                currentStatus = PackageManager.MOVE_SUCCEEDED;
+            } else if (mRet == PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE){
+                currentStatus = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+            }
+            processPendingMove(this, currentStatus);
         }
 
         @Override
@@ -4782,6 +4801,7 @@
         // Need installer lock especially for dex file removal.
         abstract void cleanUpResourcesLI();
         abstract boolean doPostDeleteLI(boolean delete);
+        abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException;
     }
 
     class FileInstallArgs extends InstallArgs {
@@ -4812,6 +4832,10 @@
             resourceFileName = getResourcePathFromCodePath();
         }
 
+        boolean  checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
+            return imcs.checkFreeStorage(false, packageURI);
+        }
+
         String getCodePath() {
             return codeFileName;
         }
@@ -5013,6 +5037,10 @@
             cid = getTempContainerId();
         }
 
+        boolean  checkFreeStorage(IMediaContainerService imcs) throws RemoteException {
+            return imcs.checkFreeStorage(true, packageURI);
+        }
+
         int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
             if (temp) {
                 createCopyFile();
@@ -9109,6 +9137,9 @@
    public boolean updateExternalMediaStatus(final boolean mediaStatus) {
        final boolean ret;
        synchronized (mPackages) {
+           Log.i(TAG, "Updating external media status from " +
+                   (mMediaMounted ? "mounted" : "unmounted") + " to " +
+                   (mediaStatus ? "mounted" : "unmounted"));
            if (DEBUG_SD_INSTALL) Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" +
                    mediaStatus+", mMediaMounted=" + mMediaMounted);
            if (mediaStatus == mMediaMounted) {
@@ -9117,6 +9148,14 @@
            mMediaMounted = mediaStatus;
            Set<String> appList = mSettings.findPackagesWithFlag(ApplicationInfo.FLAG_EXTERNAL_STORAGE);
            ret = appList != null && appList.size() > 0;
+           if (DEBUG_SD_INSTALL) {
+               if (appList != null) {
+                   for (String app : appList) {
+                       Log.i(TAG, "Should enable " + app + " on sdcard");
+                   }
+               }
+           }
+           if (DEBUG_SD_INSTALL)  Log.i(TAG, "updateExternalMediaStatus returning " + ret);
        }
        // Queue up an async operation since the package installation may take a little while.
        mHandler.post(new Runnable() {
@@ -9134,6 +9173,7 @@
        // enabled or disabled.
        final String list[] = PackageHelper.getSecureContainerList();
        if (list == null || list.length == 0) {
+           Log.i(TAG, "No secure containers on sdcard");
            return;
        }
 
@@ -9141,16 +9181,6 @@
        int num = 0;
        HashSet<String> removeCids = new HashSet<String>();
        HashMap<SdInstallArgs, String> processCids = new HashMap<SdInstallArgs, String>();
-       /*HashMap<String, String> cidPathMap = new HashMap<String, String>();
-       // Don't hold any locks when getting cache paths
-       for (String cid : list) {
-           String cpath = PackageHelper.getSdDir(cid);
-           if (cpath == null) {
-               removeCids.add(cid);
-           } else {
-               cidPathMap.put(cid, cpath);
-           }
-       }*/
        synchronized (mPackages) {
            for (String cid : list) {
                SdInstallArgs args = new SdInstallArgs(cid);
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 37a3cdf..5bd23f4 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -20,7 +20,6 @@
 import android.app.ActivityManagerNative;
 import android.app.AlarmManager;
 import android.app.IActivityManager;
-import android.app.KeyguardManager;
 import android.app.IUiModeManager;
 import android.app.Notification;
 import android.app.NotificationManager;
@@ -103,7 +102,6 @@
     private LocationManager mLocationManager;
     private Location mLocation;
     private StatusBarManager mStatusBarManager;
-    private KeyguardManager.KeyguardLock mKeyguardLock;
     private final PowerManager.WakeLock mWakeLock;
 
     // The broadcast receiver which receives the result of the ordered broadcast sent when
@@ -347,24 +345,6 @@
     void setCarModeLocked(boolean enabled) {
         if (mCarModeEnabled != enabled) {
             mCarModeEnabled = enabled;
-
-            // Disable keyguard when in car mode
-            if (mKeyguardLock == null) {
-                KeyguardManager km =
-                        (KeyguardManager)mContext.getSystemService(Context.KEYGUARD_SERVICE);
-                if (km != null) {
-                    mKeyguardLock = km.newKeyguardLock(TAG);
-                }
-            }
-            if (mKeyguardLock != null) {
-                long ident = Binder.clearCallingIdentity();
-                if (enabled) {
-                    mKeyguardLock.disableKeyguard();
-                } else {
-                    mKeyguardLock.reenableKeyguard();
-                }
-                Binder.restoreCallingIdentity(ident);
-            }
         }
     }
 
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 97a4329..4eb529c 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -46,6 +46,7 @@
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.SupplicantState;
+import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.ConnectivityManager;
 import android.net.InterfaceConfiguration;
 import android.net.NetworkStateTracker;
@@ -81,6 +82,7 @@
 import com.android.internal.app.IBatteryStats;
 import android.app.backup.IBackupManager;
 import com.android.server.am.BatteryStatsService;
+import com.android.internal.R;
 
 /**
  * WifiService handles remote WiFi operation requests by implementing
@@ -105,6 +107,8 @@
     private boolean mDeviceIdle;
     private int mPluggedType;
 
+    private enum DriverAction {DRIVER_UNLOAD, NO_DRIVER_UNLOAD};
+
     // true if the user enabled Wifi while in airplane mode
     private boolean mAirplaneModeOverwridden;
 
@@ -271,11 +275,9 @@
      */
     public void startWifi() {
         boolean wifiEnabled = getPersistedWifiEnabled();
-        boolean wifiAPEnabled = wifiEnabled ? false : getPersistedWifiApEnabled();
         Slog.i(TAG, "WifiService starting up with Wi-Fi " +
                 (wifiEnabled ? "enabled" : "disabled"));
         setWifiEnabledBlocking(wifiEnabled, false, Process.myUid());
-        setWifiApEnabledBlocking(wifiAPEnabled, true, Process.myUid(), null);
     }
 
     private void updateTetherState(ArrayList<String> available, ArrayList<String> tethered) {
@@ -297,28 +299,22 @@
                     try {
                         ifcg = service.getInterfaceConfig(intf);
                         if (ifcg != null) {
-                            /* IP/netmask: 169.254.2.1/255.255.255.0 */
-                            ifcg.ipAddr = (169 << 24) + (254 << 16) + (2 << 8) + 1;
+                            /* IP/netmask: 169.254.2.2/255.255.255.0 */
+                            ifcg.ipAddr = (169 << 24) + (254 << 16) + (2 << 8) + 2;
                             ifcg.netmask = (255 << 24) + (255 << 16) + (255 << 8) + 0;
                             ifcg.interfaceFlags = "up";
 
                             service.setInterfaceConfig(intf, ifcg);
                         }
                     } catch (Exception e) {
-                        /**
-                         * TODO: Add broadcast to indicate tether failed
-                         */
                         Slog.e(TAG, "Error configuring interface " + intf + ", :" + e);
+                        setWifiApEnabledState(WIFI_AP_STATE_FAILED, 0, DriverAction.DRIVER_UNLOAD);
                         return;
                     }
 
-                    /**
-                     * TODO: Add broadcast to indicate tether failed
-                     */
-                    if(mCm.tether(intf) == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
-                        Slog.d(TAG, "Tethered "+intf);
-                    } else {
+                    if(mCm.tether(intf) != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
                         Slog.e(TAG, "Error tethering "+intf);
+                        setWifiApEnabledState(WIFI_AP_STATE_FAILED, 0, DriverAction.DRIVER_UNLOAD);
                     }
                     break;
                 }
@@ -434,7 +430,7 @@
         setWifiEnabledState(enable ? WIFI_STATE_ENABLING : WIFI_STATE_DISABLING, uid);
 
         if ((mWifiApState == WIFI_AP_STATE_ENABLED) && enable) {
-            setWifiApEnabledBlocking(false, true, Process.myUid(), null);
+            setWifiApEnabledBlocking(false, Process.myUid(), null);
         }
 
         if (enable) {
@@ -581,21 +577,6 @@
         return mWifiStateTracker.reassociate();
     }
 
-    private boolean getPersistedWifiApEnabled() {
-        final ContentResolver cr = mContext.getContentResolver();
-        try {
-            return Settings.Secure.getInt(cr, Settings.Secure.WIFI_AP_ON) == 1;
-        } catch (Settings.SettingNotFoundException e) {
-            Settings.Secure.putInt(cr, Settings.Secure.WIFI_AP_ON, 0);
-            return false;
-        }
-    }
-
-    private void persistWifiApEnabled(boolean enabled) {
-      final ContentResolver cr = mContext.getContentResolver();
-      Settings.Secure.putInt(cr, Settings.Secure.WIFI_AP_ON, enabled ? 1 : 0);
-    }
-
     /**
      * see {@link android.net.wifi.WifiManager#startAccessPoint(WifiConfiguration)}
      * @param wifiConfig SSID, security and channel details as
@@ -621,46 +602,101 @@
         return true;
     }
 
+    public WifiConfiguration getWifiApConfiguration() {
+        final ContentResolver cr = mContext.getContentResolver();
+        WifiConfiguration wifiConfig = new WifiConfiguration();
+        int authType;
+        try {
+            wifiConfig.SSID = Settings.Secure.getString(cr, Settings.Secure.WIFI_AP_SSID);
+            if (wifiConfig.SSID == null)
+                return null;
+            authType = Settings.Secure.getInt(cr, Settings.Secure.WIFI_AP_SECURITY);
+            wifiConfig.allowedKeyManagement.set(authType);
+            wifiConfig.preSharedKey = Settings.Secure.getString(cr, Settings.Secure.WIFI_AP_PASSWD);
+            return wifiConfig;
+        } catch (Settings.SettingNotFoundException e) {
+            Slog.e(TAG,"AP settings not found, returning");
+            return null;
+        }
+    }
+
+    private void persistApConfiguration(WifiConfiguration wifiConfig) {
+        final ContentResolver cr = mContext.getContentResolver();
+        boolean isWpa;
+        if (wifiConfig == null)
+            return;
+        Settings.Secure.putString(cr, Settings.Secure.WIFI_AP_SSID, wifiConfig.SSID);
+        isWpa = wifiConfig.allowedKeyManagement.get(KeyMgmt.WPA_PSK);
+        Settings.Secure.putInt(cr,
+                               Settings.Secure.WIFI_AP_SECURITY,
+                               isWpa ? KeyMgmt.WPA_PSK : KeyMgmt.NONE);
+        if (isWpa)
+            Settings.Secure.putString(cr, Settings.Secure.WIFI_AP_PASSWD, wifiConfig.preSharedKey);
+    }
+
     /**
      * Enables/disables Wi-Fi AP synchronously. The driver is loaded
      * and soft access point configured as a single operation.
      * @param enable {@code true} to turn Wi-Fi on, {@code false} to turn it off.
-     * @param persist {@code true} if the setting should be persisted.
      * @param uid The UID of the process making the request.
-     * @param config The WifiConfiguration for AP
+     * @param wifiConfig The WifiConfiguration for AP
      * @return {@code true} if the operation succeeds (or if the existing state
      *         is the same as the requested state)
      */
-    /**
-     * TODO: persist needs to go away in WifiService
-     * This will affect all persist related functions
-     * for Access Point
-     */
     private boolean setWifiApEnabledBlocking(boolean enable,
-                        boolean persist, int uid, WifiConfiguration wifiConfig) {
+                                int uid, WifiConfiguration wifiConfig) {
         final int eventualWifiApState = enable ? WIFI_AP_STATE_ENABLED : WIFI_AP_STATE_DISABLED;
 
         if (mWifiApState == eventualWifiApState) {
-            return true;
+            /* Configuration changed on a running access point */
+            if(enable && (wifiConfig != null)) {
+                try {
+                    persistApConfiguration(wifiConfig);
+                    nwService.stopAccessPoint();
+                    nwService.startAccessPoint(wifiConfig, mWifiStateTracker.getInterfaceName());
+                    return true;
+                } catch(Exception e) {
+                    Slog.e(TAG, "Exception in nwService during AP restart");
+                    setWifiApEnabledState(WIFI_AP_STATE_FAILED, uid, DriverAction.DRIVER_UNLOAD);
+                    return false;
+                }
+            } else {
+                return true;
+            }
         }
 
-        setWifiApEnabledState(enable ? WIFI_AP_STATE_ENABLING : WIFI_AP_STATE_DISABLING, uid);
-
-        if (enable && (mWifiStateTracker.getWifiState() == WIFI_STATE_ENABLED)) {
-            setWifiEnabledBlocking(false, true, Process.myUid());
-        }
+        setWifiApEnabledState(enable ? WIFI_AP_STATE_ENABLING :
+                                       WIFI_AP_STATE_DISABLING, uid, DriverAction.NO_DRIVER_UNLOAD);
 
         if (enable) {
+
+            /**
+             * Disable client mode for starting AP
+             */
+            if (mWifiStateTracker.getWifiState() == WIFI_STATE_ENABLED) {
+                setWifiEnabledBlocking(false, true, Process.myUid());
+            }
+
+            /* Use default config if there is no existing config */
+            if (wifiConfig == null && ((wifiConfig = getWifiApConfiguration()) == null)) {
+                wifiConfig = new WifiConfiguration();
+                wifiConfig.SSID = mContext.getString(R.string.wifi_tether_configure_ssid_default);
+                wifiConfig.allowedKeyManagement.set(KeyMgmt.NONE);
+            }
+            persistApConfiguration(wifiConfig);
+
             if (!mWifiStateTracker.loadDriver()) {
                 Slog.e(TAG, "Failed to load Wi-Fi driver for AP mode");
-                setWifiApEnabledState(WIFI_AP_STATE_FAILED, uid);
+                setWifiApEnabledState(WIFI_AP_STATE_FAILED, uid, DriverAction.NO_DRIVER_UNLOAD);
                 return false;
             }
 
             try {
-                nwService.startAccessPoint();
+                nwService.startAccessPoint(wifiConfig, mWifiStateTracker.getInterfaceName());
             } catch(Exception e) {
                 Slog.e(TAG, "Exception in startAccessPoint()");
+                setWifiApEnabledState(WIFI_AP_STATE_FAILED, uid, DriverAction.DRIVER_UNLOAD);
+                return false;
             }
 
         } else {
@@ -669,20 +705,18 @@
                 nwService.stopAccessPoint();
             } catch(Exception e) {
                 Slog.e(TAG, "Exception in stopAccessPoint()");
+                setWifiApEnabledState(WIFI_AP_STATE_FAILED, uid, DriverAction.DRIVER_UNLOAD);
+                return false;
             }
 
             if (!mWifiStateTracker.unloadDriver()) {
                 Slog.e(TAG, "Failed to unload Wi-Fi driver for AP mode");
-                setWifiApEnabledState(WIFI_AP_STATE_FAILED, uid);
+                setWifiApEnabledState(WIFI_AP_STATE_FAILED, uid, DriverAction.NO_DRIVER_UNLOAD);
                 return false;
             }
         }
 
-        // Success!
-        if (persist) {
-            persistWifiApEnabled(enable);
-        }
-        setWifiApEnabledState(eventualWifiApState, uid);
+        setWifiApEnabledState(eventualWifiApState, uid, DriverAction.NO_DRIVER_UNLOAD);
         return true;
     }
 
@@ -699,9 +733,16 @@
         return mWifiApState;
     }
 
-    private void setWifiApEnabledState(int wifiAPState, int uid) {
+    private void setWifiApEnabledState(int wifiAPState, int uid, DriverAction flag) {
         final int previousWifiApState = mWifiApState;
 
+        /**
+         * Unload the driver if going to a failed state
+         */
+        if ((mWifiApState == WIFI_AP_STATE_FAILED) && (flag == DriverAction.DRIVER_UNLOAD)) {
+            mWifiStateTracker.unloadDriver();
+        }
+
         long ident = Binder.clearCallingIdentity();
         try {
             if (wifiAPState == WIFI_AP_STATE_ENABLED) {
@@ -959,8 +1000,7 @@
          */
         int netId = config.networkId;
         boolean newNetwork = netId == -1;
-        boolean doReconfig;
-        int currentPriority;
+        boolean doReconfig = false;
         // networkId of -1 means we want to create a new network
         synchronized (mWifiStateTracker) {
             if (newNetwork) {
@@ -972,17 +1012,6 @@
                     return -1;
                 }
                 doReconfig = true;
-            } else {
-                String priorityVal = mWifiStateTracker.getNetworkVariable(
-                                            netId, WifiConfiguration.priorityVarName);
-                currentPriority = -1;
-                if (!TextUtils.isEmpty(priorityVal)) {
-                    try {
-                        currentPriority = Integer.parseInt(priorityVal);
-                    } catch (NumberFormatException ignore) {
-                    }
-                }
-                doReconfig = currentPriority != config.priority;
             }
             mNeedReconfig = mNeedReconfig || doReconfig;
         }
@@ -1706,7 +1735,7 @@
     private void sendAccessPointMessage(boolean enable, WifiConfiguration wifiConfig, int uid) {
         Message.obtain(mWifiHandler,
                 (enable ? MESSAGE_START_ACCESS_POINT : MESSAGE_STOP_ACCESS_POINT),
-                0, uid, wifiConfig).sendToTarget();
+                uid, 0, wifiConfig).sendToTarget();
     }
 
     private void updateWifiState() {
@@ -1853,15 +1882,13 @@
 
                 case MESSAGE_START_ACCESS_POINT:
                     setWifiApEnabledBlocking(true,
-                                             msg.arg1 == 1,
-                                             msg.arg2,
+                                             msg.arg1,
                                              (WifiConfiguration) msg.obj);
                     break;
 
                 case MESSAGE_STOP_ACCESS_POINT:
                     setWifiApEnabledBlocking(false,
-                                             msg.arg1 == 1,
-                                             msg.arg2,
+                                             msg.arg1,
                                              (WifiConfiguration) msg.obj);
                     sWakeLock.release();
                     break;
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java
index d5f2c1d..e43b12e 100644
--- a/services/java/com/android/server/status/StatusBarService.java
+++ b/services/java/com/android/server/status/StatusBarService.java
@@ -1502,7 +1502,7 @@
         Drawable bg;
 
         /// ---------- Tracking View --------------
-        pixelFormat = PixelFormat.TRANSLUCENT;
+        pixelFormat = PixelFormat.RGBX_8888;
         bg = mTrackingView.getBackground();
         if (bg != null) {
             pixelFormat = bg.getOpacity();
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a6b1d93..ae5b1de 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -389,6 +389,8 @@
     public static final int NETWORK_TYPE_HSUPA = 9;
     /** Current network is HSPA */
     public static final int NETWORK_TYPE_HSPA = 10;
+    /** Current network is iDen */
+    public static final int NETWORK_TYPE_IDEN = 11;
 
     /**
      * Returns a constant indicating the radio technology (network type)
diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
index 8c8b00c..a06a13b 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
@@ -72,8 +72,8 @@
 public class PackageManagerTests extends AndroidTestCase {
     private static final boolean localLOGV = true;
     public static final String TAG="PackageManagerTests";
-    public final long MAX_WAIT_TIME=120*1000;
-    public final long WAIT_TIME_INCR=20*1000;
+    public final long MAX_WAIT_TIME = 25*1000;
+    public final long WAIT_TIME_INCR = 5*1000;
     private static final String SECURE_CONTAINERS_PREFIX = "/mnt/asec";
     private static final int APP_INSTALL_AUTO = PackageHelper.APP_INSTALL_AUTO;
     private static final int APP_INSTALL_DEVICE = PackageHelper.APP_INSTALL_INTERNAL;
@@ -378,39 +378,50 @@
     private InstallParams installFromRawResource(String outFileName,
             int rawResId, int flags, boolean cleanUp, boolean fail, int result,
             int expInstallLocation) {
+        PackageManager pm = mContext.getPackageManager();
         File filesDir = mContext.getFilesDir();
         File outFile = new File(filesDir, outFileName);
         Uri packageURI = getInstallablePackage(rawResId, outFile);
         PackageParser.Package pkg = parsePackage(packageURI);
         assertNotNull(pkg);
-        InstallParams ip = null;
-        // Make sure the package doesn't exist
-        getPm().deletePackage(pkg.packageName, null, 0);
-        // Clean up the containers as well
-        clearSecureContainersForPkg(pkg.packageName);
-        try {
+        if ((flags & PackageManager.INSTALL_REPLACE_EXISTING) == 0) {
+            // Make sure the package doesn't exist
             try {
-                if (fail) {
-                    assertTrue(invokeInstallPackageFail(packageURI, flags,
-                            pkg.packageName, result));
-                    assertNotInstalled(pkg.packageName);
-                } else {
-                    InstallReceiver receiver = new InstallReceiver(pkg.packageName);
-                    assertTrue(invokeInstallPackage(packageURI, flags,
-                            pkg.packageName, receiver));
-                    // Verify installed information
-                    assertInstall(pkg, flags, expInstallLocation);
-                    ip = new InstallParams(pkg, outFileName, packageURI);
-                }
+                ApplicationInfo appInfo = pm.getApplicationInfo(pkg.packageName,
+                        PackageManager.GET_UNINSTALLED_PACKAGES);
+                GenericReceiver receiver = new DeleteReceiver(pkg.packageName);
+                invokeDeletePackage(packageURI, 0,
+                        pkg.packageName, receiver);
+            } catch (NameNotFoundException e1) {
             } catch (Exception e) {
-                failStr("Failed with exception : " + e);
+                failStr(e);
+            }
+            // Clean up the containers as well
+            clearSecureContainersForPkg(pkg.packageName);
+        }
+        InstallParams ip = null;
+        try {
+            if (fail) {
+                assertTrue(invokeInstallPackageFail(packageURI, flags,
+                        pkg.packageName, result));
+                assertNotInstalled(pkg.packageName);
+            } else {
+                InstallReceiver receiver = new InstallReceiver(pkg.packageName);
+                assertTrue(invokeInstallPackage(packageURI, flags,
+                        pkg.packageName, receiver));
+                // Verify installed information
+                assertInstall(pkg, flags, expInstallLocation);
+                ip = new InstallParams(pkg, outFileName, packageURI);
             }
             return ip;
+        } catch (Exception e) {
+            failStr("Failed with exception : " + e);
         } finally {
             if (cleanUp) {
                 cleanUpInstall(ip);
             }
         }
+        return ip;
     }
 
     @MediumTest
@@ -820,7 +831,7 @@
         try {
             // Wait on observer
             synchronized(observer) {
-                getMs().unmountVolume(path, false);
+                getMs().unmountVolume(path, true);
                 long waitTime = 0;
                 while((!observer.isDone()) && (waitTime < MAX_WAIT_TIME) ) {
                     observer.wait(WAIT_TIME_INCR);
@@ -949,14 +960,21 @@
                 PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
     }
 
-    private void replaceManifestLocation(int iFlags, int rFlags) {
+    /*
+     * Install a package on internal flash via PackageManager install flag. Replace
+     * the package via flag to install on sdcard. Make sure the new flag overrides
+     * the old install location.
+     */
+    public void testReplaceFlagInternalSdcard() {
+        int iFlags = 0;
+        int rFlags = PackageManager.INSTALL_EXTERNAL;
         InstallParams ip = sampleInstallFromRawResource(iFlags, false);
         GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
         int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
         try {
             assertEquals(invokeInstallPackage(ip.packageURI, replaceFlags,
                     ip.pkg.packageName, receiver), true);
-            assertInstall(ip.pkg, replaceFlags, ip.pkg.installLocation);
+            assertInstall(ip.pkg, rFlags, ip.pkg.installLocation);
         } catch (Exception e) {
             failStr("Failed with exception : " + e);
         } finally {
@@ -964,12 +982,26 @@
         }
     }
 
-    public void testReplaceFlagInternalSdcard() {
-        replaceManifestLocation(0, PackageManager.INSTALL_EXTERNAL);
-    }
-
+    /*
+     * Install a package on sdcard via PackageManager install flag. Replace
+     * the package with no flags or manifest option and make sure the old
+     * install location is retained.
+     */
     public void testReplaceFlagSdcardInternal() {
-        replaceManifestLocation(PackageManager.INSTALL_EXTERNAL, 0);
+        int iFlags = PackageManager.INSTALL_EXTERNAL;
+        int rFlags = 0;
+        InstallParams ip = sampleInstallFromRawResource(iFlags, false);
+        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
+        int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
+        try {
+            assertEquals(invokeInstallPackage(ip.packageURI, replaceFlags,
+                    ip.pkg.packageName, receiver), true);
+            assertInstall(ip.pkg, iFlags, ip.pkg.installLocation);
+        } catch (Exception e) {
+            failStr("Failed with exception : " + e);
+        } finally {
+            cleanUpInstall(ip);
+        }
     }
 
     public void testManifestInstallLocationReplaceInternalSdcard() {
@@ -984,7 +1016,7 @@
         int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
         try {
             InstallParams rp = installFromRawResource("install.apk", rApk,
-                    rFlags, false,
+                    replaceFlags, false,
                     false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
             assertInstall(rp.pkg, replaceFlags, rp.pkg.installLocation);
         } catch (Exception e) {
@@ -1002,11 +1034,10 @@
         InstallParams ip = installFromRawResource("install.apk", iApk,
                 iFlags, false,
                 false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
-        GenericReceiver receiver = new ReplaceReceiver(ip.pkg.packageName);
         int replaceFlags = rFlags | PackageManager.INSTALL_REPLACE_EXISTING;
         try {
             InstallParams rp = installFromRawResource("install.apk", rApk,
-                    rFlags, false,
+                    replaceFlags, false,
                     false, -1, PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL);
             assertInstall(rp.pkg, replaceFlags, ip.pkg.installLocation);
         } catch (Exception e) {
@@ -1211,6 +1242,56 @@
         moveFromRawResource(PackageManager.INSTALL_EXTERNAL, PackageManager.MOVE_INTERNAL,
                 PackageManager.MOVE_SUCCEEDED);
     }
+
+    /*
+     * Test that an install error code is returned when media is unmounted
+     * and package installed on sdcard via package manager flag.
+     */
+    public void testInstallSdcardUnmount() {
+        boolean origState = getMediaState();
+        try {
+            // Unmount sdcard
+            assertTrue(unmountMedia());
+            // Try to install and make sure an error code is returned.
+            assertNull(installFromRawResource("install.apk", R.raw.install,
+                    PackageManager.INSTALL_EXTERNAL, false,
+                    true, PackageManager.INSTALL_FAILED_CONTAINER_ERROR,
+                    PackageInfo.INSTALL_LOCATION_AUTO));
+        } finally {
+            // Restore original media state
+            if (origState) {
+                mountMedia();
+            } else {
+                unmountMedia();
+            }
+        }
+    }
+
+    /*
+    * Unmount sdcard. Try installing an app with manifest option to install
+    * on sdcard. Make sure it gets installed on internal flash.
+    */
+   public void testInstallManifestSdcardUnmount() {
+       boolean origState = getMediaState();
+       try {
+           // Unmount sdcard
+           assertTrue(unmountMedia());
+           // Try to install and make sure an error code is returned.
+           assertNotNull(installFromRawResource("install.apk", R.raw.install_loc_sdcard,
+                   0, false,
+                   false, -1,
+                   PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY));
+       } finally {
+           // Restore original media state
+           if (origState) {
+               mountMedia();
+           } else {
+               unmountMedia();
+           }
+       }
+   }
+
+   /*---------- Recommended install location tests ----*/
     /*
      * TODO's
      * check version numbers for upgrades
diff --git a/tests/BrowserTestPlugin/jni/main.cpp b/tests/BrowserTestPlugin/jni/main.cpp
index 87ddbc4..402a7e2 100644
--- a/tests/BrowserTestPlugin/jni/main.cpp
+++ b/tests/BrowserTestPlugin/jni/main.cpp
@@ -142,7 +142,7 @@
     if (browser->version >= 14) {
     instance->pdata = browser->createobject (instance, getPluginClass());
     obj = static_cast<PluginObject*>(instance->pdata);
-    bzero(obj, sizeof(*obj));
+    memset(obj, 0, sizeof(*obj));
     } else {
         return NPERR_GENERIC_ERROR;
     }
diff --git a/tests/framework-tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java b/tests/framework-tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java
index fd05fed..1e57bd2 100644
--- a/tests/framework-tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java
+++ b/tests/framework-tests/src/com/android/internal/policy/impl/LockPatternKeyguardViewTest.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import com.android.internal.telephony.IccCard;
+import android.content.res.Configuration;
 import android.test.AndroidTestCase;
 import android.view.View;
 import android.view.KeyEvent;
@@ -39,8 +40,6 @@
     private static class MockUpdateMonitor extends KeyguardUpdateMonitor {
 
         public IccCard.State simState = IccCard.State.READY;
-        public boolean inPortrait = false;
-        public boolean keyboardOpen = false;
 
         private MockUpdateMonitor(Context context) {
             super(context);
@@ -50,26 +49,6 @@
         public IccCard.State getSimState() {
             return simState;
         }
-
-        @Override
-        public boolean isInPortrait() {
-            return inPortrait;
-        }
-
-        @Override
-        public boolean isKeyboardOpen() {
-            return keyboardOpen;
-        }
-
-        @Override
-        boolean queryInPortrait() {
-            return inPortrait;
-        }
-
-        @Override
-        boolean queryKeyboardOpen() {
-            return keyboardOpen;
-        }
     }
 
     private static class MockLockPatternUtils extends LockPatternUtils {
@@ -115,7 +94,7 @@
         public boolean needsInput() {
             return false;
         }
-        
+
         /** {@inheritDoc} */
         public void onPause() {
             mOnPauseCount++;
@@ -202,7 +181,7 @@
         }
 
         public void keyguardDoneDrawing() {
-            
+
         }
 
         public int getPokeWakelockCount() {
@@ -293,7 +272,7 @@
 
         // should have poked the wakelock to turn on the screen
         assertEquals(1, mKeyguardViewCallback.getPokeWakelockCount());
-        
+
         // shouldn't be any additional views created
         assertEquals(1, mLPKV.getInjectedLockScreens().size());
         assertEquals(1, mLPKV.getInjectedUnlockScreens().size());
@@ -317,7 +296,7 @@
         assertEquals(1, lockScreen.getOnResumeCount());
 
         // simulate screen asking to be recreated
-        mLPKV.mKeyguardScreenCallback.recreateMe();
+        mLPKV.mKeyguardScreenCallback.recreateMe(new Configuration());
 
         // should have been recreated
         assertEquals(2, mLPKV.getInjectedLockScreens().size());
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index d833e33..5fd44b1 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -81,5 +81,7 @@
     boolean setWifiApEnabled(in WifiConfiguration wifiConfig, boolean enable);
 
     int getWifiApEnabledState();
+
+    WifiConfiguration getWifiApConfiguration();
 }
 
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 9ef8ba1..970d5fc 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -810,6 +810,20 @@
     }
 
     /**
+     * Gets the Wi-Fi AP Configuration.
+     * @return AP details in WifiConfiguration
+     *
+     * @hide Dont open yet
+     */
+    public WifiConfiguration getWifiApConfiguration() {
+        try {
+            return mService.getWifiApConfiguration();
+        } catch (RemoteException e) {
+            return null;
+        }
+    }
+
+    /**
      * Allows an application to keep the Wi-Fi radio awake.
      * Normally the Wi-Fi radio may turn off when the user has not used the device in a while.
      * Acquiring a WifiLock will keep the radio on until the lock is released.  Multiple