Merge "Fix the rgb to yuv422sp conversion. The order of uv is different from the original version, but it should be ok as the original Y,Cb,Cr are all incorrect."
diff --git a/api/current.xml b/api/current.xml
index 444b002..96220c6 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -38899,6 +38899,17 @@
  visibility="public"
 >
 </field>
+<field name="EXTRA_PHYSICAL_DOCK_STATE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;android.intent.extra.PHYSICAL_DOCK_STATE&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="EXTRA_REMOTE_INTENT_TOKEN"
  type="java.lang.String"
  transient="false"
@@ -119450,6 +119461,17 @@
  visibility="public"
 >
 </field>
+<field name="OperationFailedStorageBusy"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-7"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="OperationFailedStorageMounted"
  type="int"
  transient="false"
@@ -190965,6 +190987,17 @@
  visibility="public"
 >
 </method>
+<method name="getBlockNetworkLoads"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="getBuiltInZoomControls"
  return="boolean"
  abstract="false"
@@ -191393,6 +191426,19 @@
 <parameter name="flag" type="boolean">
 </parameter>
 </method>
+<method name="setBlockNetworkLoads"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="true"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="flag" type="boolean">
+</parameter>
+</method>
 <method name="setBuiltInZoomControls"
  return="void"
  abstract="false"
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index 4761f98..bf9e07d 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -66,10 +66,10 @@
      * The event types an {@link AccessibilityService} is interested in.
      *
      * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_CLICKED
+     * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_LONG_CLICKED
      * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_FOCUSED
      * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_SELECTED
      * @see android.view.accessibility.AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED
-     * @see android.view.accessibility.AccessibilityEvent#TYPE_ACTIVITY_STARTED
      * @see android.view.accessibility.AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED
      * @see android.view.accessibility.AccessibilityEvent#TYPE_NOTIFICATION_STATE_CHANGED
      */
@@ -115,7 +115,7 @@
         return 0;
     }
 
-    public void writeToParcel(Parcel parcel, int flags) {
+    public void writeToParcel(Parcel parcel, int flagz) {
         parcel.writeInt(eventTypes);
         parcel.writeStringArray(packageNames);
         parcel.writeInt(feedbackType);
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 52cdc74..ce5f1bf 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1690,6 +1690,25 @@
     }
 
     /**
+     * Gets the name of the web search activity.
+     *
+     * @return The name of the default activity for web searches. This activity
+     *         can be used to get web search suggestions. Returns {@code null} if
+     *         there is no default web search activity.
+     *
+     * @hide
+     */
+    public ComponentName getWebSearchActivity() {
+        ComponentName globalSearch = getGlobalSearchActivity();
+        if (globalSearch == null) {
+            return null;
+        }
+        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
+        intent.setPackage(globalSearch.getPackageName());
+        return intent.resolveActivity(mContext.getPackageManager());
+    }
+
+    /**
      * Similar to {@link #startSearch} but actually fires off the search query after invoking
      * the search dialog.  Made available for testing purposes.
      *
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d31b25b..1b0437c 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1815,11 +1815,18 @@
 
     /**
      * Broadcast Action:  A sticky broadcast indicating the phone was docked
-     * or undocked.  Includes the extra
-     * field {@link #EXTRA_DOCK_STATE}, containing the current dock state. It also
-     * includes the boolean extra field {@link #EXTRA_CAR_MODE_ENABLED}, indicating
-     * the state of the car mode.
-     * This is intended for monitoring the current dock state.
+     * or undocked.
+     *
+     * <p>The intent will have the following extra values:
+     * <ul>
+     *   <li><em>{@link #EXTRA_DOCK_STATE}</em> - the current dock
+     *       state, which depends on the state of the car mode.</li>
+     *   <li><em>{@link #EXTRA_PHYSICAL_DOCK_STATE}</em> - the physical dock
+     *       state.</li>
+     *   <li><em>{@link #EXTRA_CAR_MODE_ENABLED}</em> - a boolean indicating the
+     *       state of the car mode.</li>
+     * </ul>
+     * <p>This is intended for monitoring the current dock state.
      * To launch an activity from a dock state change, use {@link #CATEGORY_CAR_DOCK}
      * or {@link #CATEGORY_DESK_DOCK} instead.
      */
@@ -2154,6 +2161,16 @@
     public static final int EXTRA_DOCK_STATE_CAR = 2;
 
     /**
+     * Used as an int extra field in {@link android.content.Intent#ACTION_DOCK_EVENT}
+     * intents to request the physical dock state. Possible values are
+     * {@link android.content.Intent#EXTRA_DOCK_STATE_UNDOCKED},
+     * {@link android.content.Intent#EXTRA_DOCK_STATE_DESK}, or
+     * {@link android.content.Intent#EXTRA_DOCK_STATE_CAR}.
+     */
+    public static final String EXTRA_PHYSICAL_DOCK_STATE =
+            "android.intent.extra.PHYSICAL_DOCK_STATE";
+
+    /**
      * Used as an boolean extra field in {@link android.content.Intent#ACTION_DOCK_EVENT}
      * intents to indicate that the car mode is enabled or not.
      */
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 9ff2e25..4ddb819 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -447,17 +447,6 @@
     }
 
     /**
-     * Returns whether or not sync is enabled.  Sync can be enabled by
-     * setting the system property "ro.config.sync" to the value "yes".
-     * This is normally done at boot time on builds that support sync.
-     * @return true if sync is enabled
-     */
-    private boolean isSyncEnabled() {
-        // Require the precise value "yes" to discourage accidental activation.
-        return "yes".equals(SystemProperties.get("ro.config.sync"));
-    }
-
-    /**
      * Initiate a sync. This can start a sync for all providers
      * (pass null to url, set onlyTicklable to false), only those
      * providers that are marked as ticklable (pass null to url,
@@ -488,13 +477,6 @@
             Bundle extras, long delay, boolean onlyThoseWithUnkownSyncableState) {
         boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
 
-        if (!isSyncEnabled()) {
-            if (isLoggable) {
-                Log.v(TAG, "not syncing because sync is disabled");
-            }
-            return;
-        }
-
         final boolean backgroundDataUsageAllowed = !mBootCompleted ||
                 getConnectivityManager().getBackgroundDataSetting();
 
@@ -922,9 +904,7 @@
     protected void dump(FileDescriptor fd, PrintWriter pw) {
         StringBuilder sb = new StringBuilder();
         dumpSyncState(pw, sb);
-        if (isSyncEnabled()) {
-            dumpSyncHistory(pw, sb);
-        }
+        dumpSyncHistory(pw, sb);
 
         pw.println();
         pw.println("SyncAdapters:");
@@ -940,7 +920,6 @@
     }
 
     protected void dumpSyncState(PrintWriter pw, StringBuilder sb) {
-        pw.print("sync enabled: "); pw.println(isSyncEnabled());
         pw.print("data connected: "); pw.println(mDataConnectionIsConnected);
         pw.print("memory low: "); pw.println(mStorageIsLow);
 
@@ -1456,11 +1435,6 @@
                 boolean backgroundDataUsageAllowed) {
             Account[] accounts = mAccounts;
 
-            // Sync is disabled, drop this operation.
-            if (!isSyncEnabled()) {
-                return false;
-            }
-
             // skip the sync if the account of this operation no longer exists
             if (!ArrayUtils.contains(accounts, account)) {
                 return false;
diff --git a/core/java/android/os/storage/IMountService.aidl b/core/java/android/os/storage/IMountService.aidl
index 816baf3..79a6cfe 100644
--- a/core/java/android/os/storage/IMountService.aidl
+++ b/core/java/android/os/storage/IMountService.aidl
@@ -63,7 +63,7 @@
      * Safely unmount external storage at given mount point.
      * Returns an int consistent with MountServiceResultCode
      */
-    int unmountVolume(String mountPoint);
+    int unmountVolume(String mountPoint, boolean force);
 
     /**
      * Format external storage given a mount point.
@@ -100,7 +100,7 @@
      * NOTE: Ensure all references are released prior to deleting.
      * Returns an int consistent with MountServiceResultCode
      */
-    int destroySecureContainer(String id);
+    int destroySecureContainer(String id, boolean force);
 
     /*
      * Mount a secure container with the specified key and owner UID.
@@ -112,7 +112,7 @@
      * Unount a secure container.
      * Returns an int consistent with MountServiceResultCode
      */
-    int unmountSecureContainer(String id);
+    int unmountSecureContainer(String id, boolean force);
 
     /*
      * Returns true if the specified container is mounted
diff --git a/core/java/android/os/storage/StorageResultCode.java b/core/java/android/os/storage/StorageResultCode.java
index 249bacf..07d95df 100644
--- a/core/java/android/os/storage/StorageResultCode.java
+++ b/core/java/android/os/storage/StorageResultCode.java
@@ -64,4 +64,10 @@
      */
     public static final int OperationFailedStorageMounted     = -6;
 
+    /**
+     * Operation failed: Storage is busy.
+     * @see android.os.storage.StorageManager
+     */
+    public static final int OperationFailedStorageBusy        = -7;
+
 }
diff --git a/core/java/android/pim/RecurrenceSet.java b/core/java/android/pim/RecurrenceSet.java
index bd7924a..5d09fb5 100644
--- a/core/java/android/pim/RecurrenceSet.java
+++ b/core/java/android/pim/RecurrenceSet.java
@@ -48,7 +48,8 @@
      * events table in the CalendarProvider.
      * @param values The values retrieved from the Events table.
      */
-    public RecurrenceSet(ContentValues values) {
+    public RecurrenceSet(ContentValues values)
+            throws EventRecurrence.InvalidFormatException {
         String rruleStr = values.getAsString(Calendar.Events.RRULE);
         String rdateStr = values.getAsString(Calendar.Events.RDATE);
         String exruleStr = values.getAsString(Calendar.Events.EXRULE);
@@ -65,7 +66,8 @@
      * @param cursor The cursor containing the RRULE, RDATE, EXRULE, and EXDATE
      * columns.
      */
-    public RecurrenceSet(Cursor cursor) {
+    public RecurrenceSet(Cursor cursor)
+            throws EventRecurrence.InvalidFormatException {
         int rruleColumn = cursor.getColumnIndex(Calendar.Events.RRULE);
         int rdateColumn = cursor.getColumnIndex(Calendar.Events.RDATE);
         int exruleColumn = cursor.getColumnIndex(Calendar.Events.EXRULE);
@@ -78,12 +80,14 @@
     }
 
     public RecurrenceSet(String rruleStr, String rdateStr,
-                  String exruleStr, String exdateStr) {
+                  String exruleStr, String exdateStr)
+            throws EventRecurrence.InvalidFormatException {
         init(rruleStr, rdateStr, exruleStr, exdateStr);
     }
 
     private void init(String rruleStr, String rdateStr,
-                      String exruleStr, String exdateStr) {
+                      String exruleStr, String exdateStr)
+            throws EventRecurrence.InvalidFormatException {
         if (!TextUtils.isEmpty(rruleStr) || !TextUtils.isEmpty(rdateStr)) {
 
             if (!TextUtils.isEmpty(rruleStr)) {
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 39e5275..662be95 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -916,9 +916,12 @@
     }
 
     /**
-     * Tell the WebView to block network image. This is only checked when
-     * getLoadsImagesAutomatically() is true.
-     * @param flag True if the WebView should block network image
+     * Tell the WebView to block network images. This is only checked when
+     * {@link #getLoadsImagesAutomatically} is true. If you set the value to
+     * false, images will automatically be loaded. Use this api to reduce
+     * bandwidth only. Use {@link #setBlockNetworkLoads} if possible.
+     * @param flag True if the WebView should block network images.
+     * @see #setBlockNetworkLoads
      */
     public synchronized void setBlockNetworkImage(boolean flag) {
         if (mBlockNetworkImage != flag) {
@@ -928,17 +931,21 @@
     }
 
     /**
-     * Return true if the WebView will block network image. The default is false.
-     * @return True if the WebView blocks network image.
+     * Return true if the WebView will block network images. The default is
+     * false.
+     * @return True if the WebView blocks network images.
      */
     public synchronized boolean getBlockNetworkImage() {
         return mBlockNetworkImage;
     }
 
     /**
-     * @hide
-     * Tell the WebView to block all network load requests.
-     * @param flag True if the WebView should block all network loads
+     * Tell the WebView to block all network load requests. If you set the
+     * value to false, you must call {@link android.webkit.WebView#reload} to
+     * fetch remote resources. This flag supercedes the value passed to
+     * {@link #setBlockNetworkImage}.
+     * @param flag True if the WebView should block all network loads.
+     * @see android.webkit.WebView#reload
      */
     public synchronized void setBlockNetworkLoads(boolean flag) {
         if (mBlockNetworkLoads != flag) {
@@ -948,9 +955,8 @@
     }
 
     /**
-     * @hide
-     * Return true if the WebView will block all network loads.
-     * The default is false.
+     * Return true if the WebView will block all network loads. The default is
+     * false.
      * @return True if the WebView blocks all network loads.
      */
     public synchronized boolean getBlockNetworkLoads() {
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9672892..5f5df56 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3088,14 +3088,11 @@
         Rect vBox = contentToViewRect(contentBounds);
         Rect visibleRect = new Rect();
         calcOurVisibleRect(visibleRect);
-        // The IME may have shown, resulting in the textfield being offscreen.
-        // If so, the textfield will be scrolled on screen, so treat it as
-        // though it is on screen.  If it is on screen, place the WebTextView in
-        // its new place, accounting for our new scroll/zoom values.
-        InputMethodManager imm = InputMethodManager.peekInstance();
-        if ((imm != null && imm.isActive(mWebTextView))
-                || (allowIntersect ? Rect.intersects(visibleRect, vBox)
-                : visibleRect.contains(vBox))) {
+        // If the textfield is on screen, place the WebTextView in
+        // its new place, accounting for our new scroll/zoom values,
+        // and adjust its textsize.
+        if (allowIntersect ? Rect.intersects(visibleRect, vBox)
+                : visibleRect.contains(vBox)) {
             mWebTextView.setRect(vBox.left, vBox.top, vBox.width(),
                     vBox.height());
             mWebTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index c428dc0..5308725c 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -16,14 +16,17 @@
 
 package android.widget;
 
+import com.android.internal.R;
+import com.google.android.collect.Lists;
+
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.PixelFormat;
 import android.graphics.Paint;
-import android.graphics.drawable.Drawable;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
@@ -31,16 +34,13 @@
 import android.view.FocusFinder;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
+import android.view.SoundEffectConstants;
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.ViewParent;
-import android.view.SoundEffectConstants;
 import android.view.accessibility.AccessibilityEvent;
 
-import com.google.android.collect.Lists;
-import com.android.internal.R;
-
 import java.util.ArrayList;
 
 /*
@@ -2722,7 +2722,8 @@
 
     /**
      * Determine the distance to the nearest edge of a view in a particular
-     * direciton.
+     * direction.
+     * 
      * @param descendant A descendant of this list.
      * @return The distance, or 0 if the nearest edge is already on screen.
      */
@@ -3307,9 +3308,9 @@
      * Sets the checked state of the specified position. The is only valid if
      * the choice mode has been set to {@link #CHOICE_MODE_SINGLE} or
      * {@link #CHOICE_MODE_MULTIPLE}.
-     *
+     * 
      * @param position The item whose checked state is to be checked
-     * @param value The new checked sate for the item
+     * @param value The new checked state for the item
      */
     public void setItemChecked(int position, boolean value) {
         if (mChoiceMode == CHOICE_MODE_NONE) {
@@ -3392,10 +3393,11 @@
     }
 
     /**
-     * Returns the set of checked items ids. The result is only valid if
-     * the choice mode has not been set to {@link #CHOICE_MODE_SINGLE}.
-     *
-     * @return A new array which contains the id of each checked item in the list.
+     * Returns the set of checked items ids. The result is only valid if the
+     * choice mode has not been set to {@link #CHOICE_MODE_SINGLE}.
+     * 
+     * @return A new array which contains the id of each checked item in the
+     *         list.
      */
     public long[] getCheckItemIds() {
         if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null && mAdapter != null) {
@@ -3404,11 +3406,23 @@
             final long[] ids = new long[count];
             final ListAdapter adapter = mAdapter;
 
+            int checkedCount = 0;
             for (int i = 0; i < count; i++) {
-                ids[i]= adapter.getItemId(states.keyAt(i));
+                if (states.valueAt(i)) {
+                    ids[checkedCount++] = adapter.getItemId(states.keyAt(i));
+                }
             }
 
-            return ids;
+            // Trim array if needed. mCheckStates may contain false values
+            // resulting in checkedCount being smaller than count.
+            if (checkedCount == count) {
+                return ids;
+            } else {
+                final long[] result = new long[checkedCount];
+                System.arraycopy(ids, 0, result, 0, checkedCount);
+
+                return result;
+            }
         }
 
         return new long[0];
diff --git a/core/java/com/android/internal/app/DisableCarModeActivity.java b/core/java/com/android/internal/app/DisableCarModeActivity.java
new file mode 100644
index 0000000..95dc1f9
--- /dev/null
+++ b/core/java/com/android/internal/app/DisableCarModeActivity.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.app.Activity;
+import android.app.IUiModeManager;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+public class DisableCarModeActivity extends Activity {
+    private static final String TAG = "DisableCarModeActivity";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        try {
+            IUiModeManager uiModeManager = IUiModeManager.Stub.asInterface(
+                    ServiceManager.getService("uimode"));
+            uiModeManager.disableCarMode();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to disable car mode", e);
+        }
+        finish();
+    }
+
+}
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index c5b869b..bc7dbf4 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -93,7 +93,7 @@
 
    public static boolean unMountSdDir(String cid) {
     try {
-        int rc = getMountService().unmountSecureContainer(cid);
+        int rc = getMountService().unmountSecureContainer(cid, false);
         if (rc != StorageResultCode.OperationSucceeded) {
             Log.e(TAG, "Failed to unmount " + cid + " with rc " + rc);
             return false;
@@ -148,7 +148,7 @@
 
     public static boolean destroySdDir(String cid) {
         try {
-            int rc = getMountService().destroySecureContainer(cid);
+            int rc = getMountService().destroySecureContainer(cid, false);
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.i(TAG, "Failed to destroy container " + cid);
                 return false;
diff --git a/core/jni/android_database_SQLiteDatabase.cpp b/core/jni/android_database_SQLiteDatabase.cpp
index c197010..26d0e86 100644
--- a/core/jni/android_database_SQLiteDatabase.cpp
+++ b/core/jni/android_database_SQLiteDatabase.cpp
@@ -470,7 +470,7 @@
     if (errcode == SQLITE_DONE) {
         throw_sqlite3_exception(env, errcode, NULL, message);
     } else {
-        char temp[20];
+        char temp[21];
         sprintf(temp, "error code %d", errcode);
         throw_sqlite3_exception(env, errcode, temp, message);
     }
diff --git a/core/jni/android_database_SQLiteProgram.cpp b/core/jni/android_database_SQLiteProgram.cpp
index 32018eb..c247bbd 100644
--- a/core/jni/android_database_SQLiteProgram.cpp
+++ b/core/jni/android_database_SQLiteProgram.cpp
@@ -45,8 +45,8 @@
 
 static void native_compile(JNIEnv* env, jobject object, jstring sqlString)
 {
-    char buf[32];
-    sprintf(buf, "android_database_SQLiteProgram->native_compile() not implemented");
+    char buf[65];
+    strcpy(buf, "android_database_SQLiteProgram->native_compile() not implemented");
     throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
     return;
 }
@@ -152,8 +152,8 @@
 
 static void native_finalize(JNIEnv* env, jobject object)
 {
-    char buf[32];
-    sprintf(buf, "android_database_SQLiteProgram->native_finalize() not implemented");
+    char buf[66];
+    strcpy(buf, "android_database_SQLiteProgram->native_finalize() not implemented");
     throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
     return;
 }
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 4e1ae62..5432efb 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -1122,9 +1122,10 @@
     if (dbus_set_error_from_message(&err, msg)) {
         if (dbus_error_has_name(&err, "org.bluez.Error.AlreadyExists")) {
             result = CREATE_DEVICE_ALREADY_EXISTS;
+        } else {
+            result = CREATE_DEVICE_FAILED;
         }
         LOG_AND_FREE_DBUS_ERROR(&err);
-        result = CREATE_DEVICE_FAILED;
     }
     env->CallVoidMethod(nat->me,
                         method_onCreateDeviceResult,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a27d28f..333db05 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1252,6 +1252,10 @@
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
+        <activity android:name="com.android.internal.app.DisableCarModeActivity"
+                android:theme="@style/Theme.NoDisplay"
+                android:excludeFromRecents="true">
+        </activity>
         <activity android:name="com.android.internal.app.RingtonePickerActivity"
                 android:theme="@style/Theme.Dialog.Alert"
                 android:excludeFromRecents="true"
diff --git a/core/res/res/drawable-hdpi/stat_notify_car_mode.png b/core/res/res/drawable-hdpi/stat_notify_car_mode.png
new file mode 100644
index 0000000..6c51b32
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_notify_car_mode.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_notify_car_mode.png b/core/res/res/drawable-mdpi/stat_notify_car_mode.png
new file mode 100644
index 0000000..c664244
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_notify_car_mode.png
Binary files differ
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 6f34b4f..cdf38b9 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2261,4 +2261,9 @@
     <!-- See TETHER_STOP_DIALOG.  If there was an error disconnect, this is the text. -->
     <string name="tether_stop_error_message">We\'ve encountered a problem turning off Tethering. Please try again.</string>
 
+    <!-- Strings for car mode notification -->
+    <!-- Shown when car mode is enabled -->
+    <string name="car_mode_disable_notification_title">Car mode enabled</string>
+    <string name="car_mode_disable_notification_message">Select to disable car mode.</string>
+
 </resources>
diff --git a/core/tests/coretests/src/android/widget/listview/ListGetCheckItemIdsTest.java b/core/tests/coretests/src/android/widget/listview/ListGetCheckItemIdsTest.java
new file mode 100644
index 0000000..33d61a0
--- /dev/null
+++ b/core/tests/coretests/src/android/widget/listview/ListGetCheckItemIdsTest.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.widget.listview;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+
+import java.util.Arrays;
+
+/**
+ * Testing the ListView getCheckItemIds() method in different situations.
+ */
+public class ListGetCheckItemIdsTest extends ActivityInstrumentationTestCase2<ListSimple> {
+    private ListView mListView;
+
+    public ListGetCheckItemIdsTest() {
+        super(ListSimple.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mListView = getActivity().getListView();
+    }
+
+    private void assertChecked(String message, long... expectedIds) {
+        // Sort the two arrays since we are actually doing a set equality.
+        long[] checkItemIds = mListView.getCheckItemIds();
+        long[] sortedCheckItemsIds = new long[checkItemIds.length];
+        System.arraycopy(checkItemIds, 0, sortedCheckItemsIds, 0, checkItemIds.length);
+        Arrays.sort(sortedCheckItemsIds);
+
+        long[] sortedExpectedIds = new long[expectedIds.length];
+        System.arraycopy(expectedIds, 0, sortedExpectedIds, 0, expectedIds.length);
+        Arrays.sort(sortedExpectedIds);
+
+        assertTrue(message, Arrays.equals(sortedExpectedIds, sortedCheckItemsIds));
+    }
+
+    @MediumTest
+    @UiThreadTest
+    public void testNoneCheck() {
+        mListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
+
+        mListView.setItemChecked(0, true);
+        assertChecked("None check choice has item checked");
+    }
+
+    @MediumTest
+    @UiThreadTest
+    public void testSimpleCheck() {
+        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        assertChecked("Item checked when setting Single mode");
+
+        // Test a check at each position
+        int childCount = mListView.getChildCount();
+        for (int i=0; i<childCount; i++) {
+            mListView.setItemChecked(i, true);
+            assertChecked("Only element " + i + " should be checked", i);
+        }
+
+        // Check an element and uncheck some others
+        for (int i = 0; i < childCount; i++) {
+            mListView.setItemChecked(i, true);
+            mListView.setItemChecked((i - 3 + childCount) % childCount, false);
+            mListView.setItemChecked((i + 1) % childCount, false);
+            assertChecked("Only element " + i + " should be checked", i);
+        }
+    }
+
+    @MediumTest
+    @UiThreadTest
+    public void testMultipleCheck() {
+        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+        assertChecked("Item checked when setting Multiple mode");
+
+        int childCount = mListView.getChildCount();
+        assertTrue("Tests requires at least 4 items", childCount >= 4);
+
+        mListView.setItemChecked(1, true);
+        assertChecked("First element non checked", 1);
+
+        mListView.setItemChecked(3, true);
+        assertChecked("Second element not checked", 1, 3);
+
+        mListView.setItemChecked(0, true);
+        assertChecked("Third element not checked", 0, 1, 3);
+
+        mListView.setItemChecked(2, false);
+        assertChecked("Unchecked element appears checked", 0, 1, 3);
+
+        mListView.setItemChecked(1, false);
+        assertChecked("Unchecked element remains", 0, 3);
+
+        mListView.setItemChecked(2, false);
+        assertChecked("Already unchecked element appears", 0, 3);
+
+        mListView.setItemChecked(3, false);
+        assertChecked("Unchecked 3 remains", 0);
+
+        mListView.setItemChecked(3, false);
+        assertChecked("Twice unchecked 3 remains", 0);
+
+        mListView.setItemChecked(0, false);
+        assertChecked("Checked items after last element unchecked");
+    }
+
+    @MediumTest
+    @UiThreadTest
+    public void testClearChoices() {
+        mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+        mListView.setItemChecked(0, true);
+        mListView.clearChoices();
+        assertChecked("Item checked after SINGLE clear choice");
+
+        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+        int childCount = mListView.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            mListView.setItemChecked(0, i % 3 == 0);
+        }
+        mListView.clearChoices();
+        assertChecked("Item checked after MULTIPLE clear choice");
+    }
+}
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index f201667..43762e7 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -58,7 +58,7 @@
 
     int pathRemaining = PATH_MAX - pathLength;
     strcpy(pathBuffer, path);
-    if (pathBuffer[pathLength - 1] != '/') {
+    if (pathLength > 0 && pathBuffer[pathLength - 1]) {
         pathBuffer[pathLength] = '/';
         pathBuffer[pathLength + 1] = 0;
         --pathRemaining;
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index 12d7ee2..7997cd6 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -99,13 +99,13 @@
                     : AudioSystem::CHANNEL_OUT_MONO,
                 8192, 0, &AudioCallback, this, 0);
 
-        if (mAudioTrack->initCheck() != OK) {
+        if ((err = mAudioTrack->initCheck()) != OK) {
             delete mAudioTrack;
             mAudioTrack = NULL;
 
             mSource->stop();
 
-            return mAudioTrack->initCheck();
+            return err;
         }
 
         mLatencyUs = (int64_t)mAudioTrack->latency() * 1000;
diff --git a/services/java/com/android/server/AccessibilityManagerService.java b/services/java/com/android/server/AccessibilityManagerService.java
index 407983d..3027a92 100644
--- a/services/java/com/android/server/AccessibilityManagerService.java
+++ b/services/java/com/android/server/AccessibilityManagerService.java
@@ -16,8 +16,6 @@
 
 package com.android.server;
 
-import static android.util.Config.LOGV;
-
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.HandlerCaller.SomeArgs;
 
@@ -47,6 +45,7 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.text.TextUtils.SimpleStringSplitter;
+import android.util.Config;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.accessibility.AccessibilityEvent;
@@ -137,10 +136,6 @@
 
         registerPackageChangeAndBootCompletedBroadcastReceiver();
         registerSettingsContentObservers();
-
-        synchronized (mLock) {
-            populateAccessibilityServiceListLocked();
-        }
     }
 
     /**
@@ -155,13 +150,19 @@
             public void onReceive(Context context, Intent intent) {
                 synchronized (mLock) {
                     populateAccessibilityServiceListLocked();
-                    manageServicesLocked();
 
                     if (intent.getAction() == Intent.ACTION_BOOT_COMPLETED) {
+                        // get the accessibility enabled setting on boot
                         mIsEnabled = Settings.Secure.getInt(mContext.getContentResolver(),
                                 Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
-                        updateClientsLocked();
+
+                        // if accessibility is enabled inform our clients we are on
+                        if (mIsEnabled) {
+                            updateClientsLocked();
+                        }
                     }
+
+                    manageServicesLocked();
                 }
             }
         };
@@ -169,7 +170,6 @@
         // package changes
         IntentFilter packageFilter = new IntentFilter();
         packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
-        packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
         packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
         packageFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
         packageFilter.addDataScheme("package");
@@ -409,7 +409,7 @@
 
         try {
             listener.onAccessibilityEvent(event);
-            if (LOGV) {
+            if (Config.DEBUG) {
                 Log.i(LOG_TAG, "Event " + event + " sent to " + listener);
             }
         } catch (RemoteException re) {
@@ -434,7 +434,7 @@
         mServices.remove(service);
         mHandler.removeMessages(service.mId);
 
-        if (LOGV) {
+        if (Config.DEBUG) {
             Log.i(LOG_TAG, "Dead service " + service.mService + " removed");
         }
 
@@ -547,6 +547,7 @@
 
         Map<ComponentName, Service> componentNameToServiceMap = mComponentNameToServiceMap;
         List<Service> services = mServices;
+        boolean isEnabled = mIsEnabled;
 
         for (int i = 0, count = installedServices.size(); i < count; i++) {
             ServiceInfo intalledService = installedServices.get(i);
@@ -554,7 +555,7 @@
                     intalledService.name);
             Service service = componentNameToServiceMap.get(componentName);
 
-            if (enabledServices.contains(componentName)) {
+            if (isEnabled && enabledServices.contains(componentName)) {
                 if (service == null) {
                     new Service(componentName).bind();
                 }
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index b566fb7e..4791718 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -22,8 +22,10 @@
 import android.app.IActivityManager;
 import android.app.IUiModeManager;
 import android.app.KeyguardManager;
-import android.app.StatusBarManager;
+import android.app.Notification;
+import android.app.NotificationManager;
 import android.app.PendingIntent;
+import android.app.StatusBarManager;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.content.ActivityNotFoundException;
@@ -55,6 +57,8 @@
 import android.text.format.Time;
 import android.util.Log;
 
+import com.android.internal.R;
+import com.android.internal.app.DisableCarModeActivity;
 import com.android.internal.widget.LockPatternUtils;
 
 import java.io.FileNotFoundException;
@@ -101,6 +105,7 @@
     private final Context mContext;
 
     private PowerManagerService mPowerManager;
+    private NotificationManager mNotificationManager;
 
     private KeyguardManager.KeyguardLock mKeyguardLock;
     private boolean mKeyguardDisabled;
@@ -125,7 +130,8 @@
 
             // Launch a dock activity
             String category;
-            if (mCarModeEnabled || mDockState == Intent.EXTRA_DOCK_STATE_CAR) {
+            if (mCarModeEnabled) {
+                // Only launch car home when car mode is enabled.
                 category = Intent.CATEGORY_CAR_DOCK;
             } else if (mDockState == Intent.EXTRA_DOCK_STATE_DESK) {
                 category = Intent.CATEGORY_DESK_DOCK;
@@ -332,9 +338,13 @@
                         if (mCarModeEnabled && mDockState != Intent.EXTRA_DOCK_STATE_CAR) {
                             // Pretend to be in DOCK_STATE_CAR.
                             intent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_CAR);
+                        } else if (!mCarModeEnabled && mDockState == Intent.EXTRA_DOCK_STATE_CAR) {
+                            // Pretend to be in DOCK_STATE_UNDOCKED.
+                            intent.putExtra(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
                         } else {
                             intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
                         }
+                        intent.putExtra(Intent.EXTRA_PHYSICAL_DOCK_STATE, mDockState);
                         intent.putExtra(Intent.EXTRA_CAR_MODE_ENABLED, mCarModeEnabled);
 
                         // Check if this is Bluetooth Dock
@@ -462,6 +472,52 @@
         }
     };
 
+    private void adjustStatusBarCarMode() {
+        if (mStatusBarManager == null) {
+            mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
+        }
+
+        // Fear not: StatusBarService manages a list of requests to disable
+        // features of the status bar; these are ORed together to form the
+        // active disabled list. So if (for example) the device is locked and
+        // the status bar should be totally disabled, the calls below will
+        // have no effect until the device is unlocked.
+        if (mStatusBarManager != null) {
+            long ident = Binder.clearCallingIdentity();
+            mStatusBarManager.disable(mCarModeEnabled
+                ? StatusBarManager.DISABLE_NOTIFICATION_TICKER
+                : StatusBarManager.DISABLE_NONE);
+            Binder.restoreCallingIdentity(ident);
+        }
+
+        if (mNotificationManager == null) {
+            mNotificationManager = (NotificationManager)
+                    mContext.getSystemService(Context.NOTIFICATION_SERVICE);
+        }
+
+        if (mNotificationManager != null) {
+            long ident = Binder.clearCallingIdentity();
+            if (mCarModeEnabled) {
+                Intent carModeOffIntent = new Intent(mContext, DisableCarModeActivity.class);
+
+                Notification n = new Notification();
+                n.icon = R.drawable.stat_notify_car_mode;
+                n.defaults = Notification.DEFAULT_LIGHTS;
+                n.flags = Notification.FLAG_ONGOING_EVENT;
+                n.when = 0;
+                n.setLatestEventInfo(
+                        mContext,
+                        mContext.getString(R.string.car_mode_disable_notification_title),
+                        mContext.getString(R.string.car_mode_disable_notification_message),
+                        PendingIntent.getActivity(mContext, 0, carModeOffIntent, 0));
+                mNotificationManager.notify(0, n);
+            } else {
+                mNotificationManager.cancel(0);
+            }
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
     private void setCarMode(boolean enabled) throws RemoteException {
         mCarModeEnabled = enabled;
         if (enabled) {
@@ -475,23 +531,7 @@
             setMode(Configuration.UI_MODE_TYPE_NORMAL,
                     Configuration.UI_MODE_NIGHT_UNDEFINED);
         }
-
-        if (mStatusBarManager == null) {
-            mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
-        }
-
-        // Fear not: StatusBarService manages a list of requests to disable
-        // features of the status bar; these are ORed together to form the
-        // active disabled list. So if (for example) the device is locked and
-        // the status bar should be totally disabled, the calls below will
-        // have no effect until the device is unlocked.
-        if (mStatusBarManager != null) {
-            long ident = Binder.clearCallingIdentity();
-            mStatusBarManager.disable(enabled 
-                ? StatusBarManager.DISABLE_NOTIFICATION_TICKER
-                : StatusBarManager.DISABLE_NONE);
-            Binder.restoreCallingIdentity(ident);
-        }
+        adjustStatusBarCarMode();
     }
 
     private void setMode(int modeType, int modeNight) throws RemoteException {
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 4e2ffa4..d6e23fb 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -97,7 +97,7 @@
         public static final int OpFailedMediaBlank             = 402;
         public static final int OpFailedMediaCorrupt           = 403;
         public static final int OpFailedVolNotMounted          = 404;
-        public static final int OpFailedVolBusy                = 405;
+        public static final int OpFailedStorageBusy            = 405;
 
         /*
          * 600 series - Unsolicited broadcasts.
@@ -142,6 +142,14 @@
             if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
                 mBooted = true;
 
+                /*
+                 * In the simulator, we need to broadcast a volume mounted event
+                 * to make the media scanner run.
+                 */
+                if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
+                    notifyVolumeStateChange(null, "/sdcard", VolumeState.NoMedia, VolumeState.Mounted);
+                    return;
+                }
                 String path = Environment.getExternalStorageDirectory().getPath();
                 if (getVolumeState(path).equals(Environment.MEDIA_UNMOUNTED)) {
                     int rc = doMountVolume(path);
@@ -184,7 +192,7 @@
         String vs = getVolumeState(path);
         if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
             mUmsEnabling = enable; // Override for isUsbMassStorageEnabled()
-            int rc = doUnmountVolume(path);
+            int rc = doUnmountVolume(path, false);
             mUmsEnabling = false; // Clear override
             if (rc != StorageResultCode.OperationSucceeded) {
                 Log.e(TAG, String.format("Failed to unmount before enabling UMS (%d)", rc));
@@ -527,7 +535,7 @@
         return rc;
     }
 
-    private int doUnmountVolume(String path) {
+    private int doUnmountVolume(String path, boolean force) {
         if (!getVolumeState(path).equals(Environment.MEDIA_MOUNTED)) {
             return VoldResponseCode.OpFailedVolNotMounted;
         }
@@ -537,7 +545,8 @@
         // notified that the applications installed on the media will be killed.
         mPms.updateExternalMediaStatus(false);
         try {
-            mConnector.doCommand(String.format("volume unmount %s", path));
+            mConnector.doCommand(String.format(
+                    "volume unmount %s%s", path, (force ? " force" : "")));
             return StorageResultCode.OperationSucceeded;
         } catch (NativeDaemonConnectorException e) {
             // Don't worry about mismatch in PackageManager since the
@@ -545,6 +554,8 @@
             int code = e.getCode();
             if (code == VoldResponseCode.OpFailedVolNotMounted) {
                 return StorageResultCode.OperationFailedStorageNotMounted;
+            } else if (code == VoldResponseCode.OpFailedStorageBusy) {
+                return StorageResultCode.OperationFailedStorageBusy;
             } else {
                 return StorageResultCode.OperationFailedInternalError;
             }
@@ -639,15 +650,6 @@
     public MountService(Context context) {
         mContext = context;
 
-        /*
-         * Vold does not run in the simulator, so fake out a mounted
-         * event to trigger MediaScanner
-         */
-        if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
-            updatePublicVolumeState("/sdcard", Environment.MEDIA_MOUNTED);
-            return;
-        }
-
         // XXX: This will go away soon in favor of IMountServiceObserver
         mPms = (PackageManagerService) ServiceManager.getService("package");
 
@@ -656,6 +658,16 @@
 
         mListeners = new ArrayList<MountServiceBinderListener>();
 
+        /*
+         * Vold does not run in the simulator, so pretend the connector thread
+         * ran and did its thing.
+         */
+        if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
+            mReady = true;
+            mUmsEnabling = true;
+            return;
+        }
+
         mConnector = new NativeDaemonConnector(this, "vold", 10, "VoldConnector");
         mReady = false;
         Thread thread = new Thread(mConnector, NativeDaemonConnector.class.getName());
@@ -733,7 +745,7 @@
             /*
              * If the media is mounted, then gracefully unmount it.
              */
-            if (doUnmountVolume(path) != StorageResultCode.OperationSucceeded) {
+            if (doUnmountVolume(path, true) != StorageResultCode.OperationSucceeded) {
                 Log.e(TAG, "Failed to unmount media for shutdown");
             }
         }
@@ -782,11 +794,11 @@
         return doMountVolume(path);
     }
 
-    public int unmountVolume(String path) {
+    public int unmountVolume(String path, boolean force) {
         validatePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
         waitForReady();
 
-        return doUnmountVolume(path);
+        return doUnmountVolume(path, force);
     }
 
     public int formatVolume(String path) {
@@ -878,16 +890,21 @@
         return rc;
     }
 
-    public int destroySecureContainer(String id) {
+    public int destroySecureContainer(String id, boolean force) {
         validatePermission(android.Manifest.permission.ASEC_DESTROY);
         waitForReady();
         warnOnNotMounted();
 
         int rc = StorageResultCode.OperationSucceeded;
         try {
-            mConnector.doCommand(String.format("asec destroy %s", id));
+            mConnector.doCommand(String.format("asec destroy %s%s", id, (force ? " force" : "")));
         } catch (NativeDaemonConnectorException e) {
-            rc = StorageResultCode.OperationFailedInternalError;
+            int code = e.getCode();
+            if (code == VoldResponseCode.OpFailedStorageBusy) {
+                rc = StorageResultCode.OperationFailedStorageBusy;
+            } else {
+                rc = StorageResultCode.OperationFailedInternalError;
+            }
         }
 
         if (rc == StorageResultCode.OperationSucceeded) {
@@ -928,7 +945,7 @@
         return rc;
     }
 
-    public int unmountSecureContainer(String id) {
+    public int unmountSecureContainer(String id, boolean force) {
         validatePermission(android.Manifest.permission.ASEC_MOUNT_UNMOUNT);
         waitForReady();
         warnOnNotMounted();
@@ -940,11 +957,16 @@
          }
 
         int rc = StorageResultCode.OperationSucceeded;
-        String cmd = String.format("asec unmount %s", id);
+        String cmd = String.format("asec unmount %s%s", id, (force ? " force" : ""));
         try {
             mConnector.doCommand(cmd);
         } catch (NativeDaemonConnectorException e) {
-            rc = StorageResultCode.OperationFailedInternalError;
+            int code = e.getCode();
+            if (code == VoldResponseCode.OpFailedStorageBusy) {
+                rc = StorageResultCode.OperationFailedStorageBusy;
+            } else {
+                rc = StorageResultCode.OperationFailedInternalError;
+            }
         }
 
         if (rc == StorageResultCode.OperationSucceeded) {
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index d41aacf..1015028 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -28,6 +28,7 @@
 import android.net.INetworkManagementEventObserver;
 import android.os.INetworkManagementService;
 import android.os.Handler;
+import android.os.SystemProperties;
 import android.text.TextUtils;
 import android.util.Log;
 import java.util.ArrayList;
@@ -59,6 +60,10 @@
         public static final int TetherStatusResult        = 210;
         public static final int IpFwdStatusResult         = 211;
         public static final int InterfaceGetCfgResult     = 213;
+        public static final int SoftapStatusResult        = 214;
+        public static final int UsbRNDISStatusResult      = 215;
+
+        public static final int InterfaceChange           = 600;
     }
 
     /**
@@ -83,6 +88,10 @@
 
         mObservers = new ArrayList<INetworkManagementEventObserver>();
 
+        if ("simulator".equals(SystemProperties.get("ro.product.device"))) {
+            return;
+        }
+
         mConnector = new NativeDaemonConnector(
                 new NetdCallbackReceiver(), "netd", 10, "NetdConnector");
         Thread thread = new Thread(mConnector, NativeDaemonConnector.class.getName());
@@ -147,12 +156,35 @@
         public void onDaemonConnected() {
             new Thread() {
                 public void run() {
-                    // XXX: Run some tests
                 }
             }.start();
         }
         public boolean onEvent(int code, String raw, String[] cooked) {
-           return false;
+            if (code == NetdResponseCode.InterfaceChange) {
+                /*
+                 * a network interface change occured
+                 * Format: "NNN Iface added <name>"
+                 *         "NNN Iface removed <name>"
+                 *         "NNN Iface changed <name> <up/down>"
+                 */
+                if (cooked.length < 4 || !cooked[1].equals("Iface")) {
+                    throw new IllegalStateException(
+                            String.format("Invalid event from daemon (%s)", raw));
+                }
+                if (cooked[2].equals("added")) {
+                    notifyInterfaceAdded(cooked[3]);
+                    return true;
+                } else if (cooked[2].equals("removed")) {
+                    notifyInterfaceRemoved(cooked[3]);
+                    return true;
+                } else if (cooked[2].equals("changed") && cooked.length == 5) {
+                    notifyInterfaceLinkStatusChanged(cooked[3], cooked[4].equals("up"));
+                    return true;
+                }
+                throw new IllegalStateException(
+                        String.format("Invalid event from daemon (%s)", raw));
+            }
+            return false;
         }
     }
 
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 3ecfd8a..47a58cf 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -4638,11 +4638,12 @@
         if (activity != null && activity.shortComponentName != null) {
             info.append(" (").append(activity.shortComponentName).append(")");
         }
+        info.append("\n");
         if (annotation != null) {
-            info.append("\nReason: ").append(annotation).append("\n");
+            info.append("Reason: ").append(annotation).append("\n");
         }
         if (parent != null && parent != activity) {
-            info.append("\nParent: ").append(parent.shortComponentName);
+            info.append("Parent: ").append(parent.shortComponentName).append("\n");
         }
 
         String cpuInfo = null;
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index 89761a8..2f2cc32 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -29,6 +29,7 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.util.Log;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -267,6 +268,9 @@
                         int[] outId = new int[1];
                         inm.enqueueNotification(localPackageName, localForegroundId,
                                 localForegroundNoti, outId);
+                    } catch (RuntimeException e) {
+                        Log.w(ActivityManagerService.TAG, "Error showing notification for service",
+                            e);
                     } catch (RemoteException e) {
                     }
                 }
@@ -288,6 +292,9 @@
                     }
                     try {
                         inm.cancelNotification(localPackageName, localForegroundId);
+                    } catch (RuntimeException e) {
+                        Log.w(ActivityManagerService.TAG, "Error canceling notification for"
+                            + " service", e);
                     } catch (RemoteException e) {
                     }
                 }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java b/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java
index 7569d7a..bdf397c 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/AsecTests.java
@@ -73,7 +73,7 @@
 
         for (int i = 0; i < containers.length; i++) {
             if (containers[i].startsWith("com.android.unittests.AsecTests.")) {
-                ms.destroySecureContainer(containers[i]);
+                ms.destroySecureContainer(containers[i], true);
             }
         }
     }
@@ -103,7 +103,32 @@
         Assert.assertTrue(isMediaMounted());
         IMountService ms = getMs();
         try {
-            int rc = ms.createSecureContainer("com.android.unittests.AsecTests.testCreateContainer", 4, "fat", "none", 1000);
+            int rc = ms.createSecureContainer("com.android.unittests.AsecTests.testCreateContainer",
+                    4, "fat", "none", android.os.Process.myUid());
+            Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
+        } catch (Exception e) {
+            failStr(e);
+        }
+    }
+
+    public void testCreateZeroSizeContainer() {
+        Assert.assertTrue(isMediaMounted());
+        IMountService ms = getMs();
+        try {
+            int rc = ms.createSecureContainer("com.android.unittests.AsecTests.testCreateZeroSizeContainer",
+                    0, "fat", "none", android.os.Process.myUid());
+            Assert.assertEquals(StorageResultCode.OperationFailedInternalError, rc);
+        } catch (Exception e) {
+            failStr(e);
+        }
+    }
+
+    public void testCreateMinSizeContainer() {
+        Assert.assertTrue(isMediaMounted());
+        IMountService ms = getMs();
+        try {
+            int rc = ms.createSecureContainer("com.android.unittests.AsecTests.testCreateMinSizeContainer",
+                    1, "fat", "none", android.os.Process.myUid());
             Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
         } catch (Exception e) {
             failStr(e);
@@ -114,9 +139,10 @@
         Assert.assertTrue(isMediaMounted());
         IMountService ms = getMs();
         try {
-            int rc = ms.createSecureContainer("com.android.unittests.AsecTests.testDestroyContainer", 4, "fat", "none", 1000);
+            int rc = ms.createSecureContainer("com.android.unittests.AsecTests.testDestroyContainer",
+                    4, "fat", "none", android.os.Process.myUid());
             Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
-            rc = ms.destroySecureContainer("com.android.unittests.AsecTests.testDestroyContainer");
+            rc = ms.destroySecureContainer("com.android.unittests.AsecTests.testDestroyContainer", true);
             Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
         } catch (Exception e) {
             failStr(e);
@@ -128,13 +154,15 @@
         IMountService ms = getMs();
         try {
             int rc = ms.createSecureContainer(
-                    "com.android.unittests.AsecTests.testMountContainer", 4, "fat", "none", 1000);
+                    "com.android.unittests.AsecTests.testMountContainer",
+                            4, "fat", "none", android.os.Process.myUid());
             Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
 
-            rc = ms.unmountSecureContainer("com.android.unittests.AsecTests.testMountContainer");
+            rc = ms.unmountSecureContainer("com.android.unittests.AsecTests.testMountContainer", false);
             Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
 
-            rc = ms.mountSecureContainer("com.android.unittests.AsecTests.testMountContainer", "none", 1000);
+            rc = ms.mountSecureContainer("com.android.unittests.AsecTests.testMountContainer", "none",
+                    android.os.Process.myUid());
             Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
         } catch (Exception e) {
             failStr(e);
@@ -147,10 +175,10 @@
         try {
             int rc = ms.createSecureContainer(
                     "com.android.unittests.AsecTests.testMountBadKey", 4, "fat",
-                            "00000000000000000000000000000000", 1000);
+                            "00000000000000000000000000000000", android.os.Process.myUid());
             Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
 
-            rc = ms.unmountSecureContainer("com.android.unittests.AsecTests.testMountBadKey");
+            rc = ms.unmountSecureContainer("com.android.unittests.AsecTests.testMountBadKey", false);
             Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
 
             rc = ms.mountSecureContainer(
@@ -165,4 +193,52 @@
             failStr(e);
         }
     }
+
+    public void testUnmountBusyContainer() {
+        Assert.assertTrue(isMediaMounted());
+        IMountService ms = getMs();
+        try {
+            int rc = ms.createSecureContainer("com.android.unittests.AsecTests.testUnmountBusyContainer",
+                    4, "fat", "none", android.os.Process.myUid());
+            Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
+
+            String path = ms.getSecureContainerPath("com.android.unittests.AsecTests.testUnmountBusyContainer");
+            Context con = super.getContext();
+
+            File f = new File(path, "reference");
+            FileOutputStream fos = new FileOutputStream(f);
+            rc = ms.unmountSecureContainer("com.android.unittests.AsecTests.testUnmountBusyContainer", false);
+            Assert.assertEquals(StorageResultCode.OperationFailedStorageBusy, rc);
+            fos.close();
+
+            rc = ms.unmountSecureContainer("com.android.unittests.AsecTests.testUnmountBusyContainer", false);
+            Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
+        } catch (Exception e) {
+            failStr(e);
+        }
+    }
+
+    public void testDestroyBusyContainer() {
+        Assert.assertTrue(isMediaMounted());
+        IMountService ms = getMs();
+        try {
+            int rc = ms.createSecureContainer("com.android.unittests.AsecTests.testUnmountBusyContainer",
+                    4, "fat", "none", android.os.Process.myUid());
+            Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
+
+            String path = ms.getSecureContainerPath("com.android.unittests.AsecTests.testUnmountBusyContainer");
+            Context con = super.getContext();
+
+            File f = new File(path, "reference");
+            FileOutputStream fos = new FileOutputStream(f);
+            rc = ms.destroySecureContainer("com.android.unittests.AsecTests.testUnmountBusyContainer", false);
+            Assert.assertEquals(StorageResultCode.OperationFailedStorageBusy, rc);
+            fos.close();
+
+            rc = ms.destroySecureContainer("com.android.unittests.AsecTests.testUnmountBusyContainer", false);
+            Assert.assertEquals(StorageResultCode.OperationSucceeded, rc);
+        } catch (Exception e) {
+            failStr(e);
+        }
+    }
 }
diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
index 8f4d0a1..be9571c 100755
--- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java
@@ -716,7 +716,7 @@
         }
         try {
         String mPath = Environment.getExternalStorageDirectory().toString();
-        int ret = getMs().unmountVolume(mPath);
+        int ret = getMs().unmountVolume(mPath, false);
         return ret == StorageResultCode.OperationSucceeded;
         } catch (RemoteException e) {
             return true;
diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp
index 663a33a..dc442aa 100644
--- a/tools/aapt/AaptAssets.cpp
+++ b/tools/aapt/AaptAssets.cpp
@@ -938,17 +938,17 @@
     uint8_t mask = 0;
     uint8_t value = 0;
     if (strcmp(name, kWildcardName) == 0) {
-        mask = out->MASK_KEYSHIDDEN;
-        value = out->KEYSHIDDEN_ANY;
+        mask = ResTable_config::MASK_KEYSHIDDEN;
+        value = ResTable_config::KEYSHIDDEN_ANY;
     } else if (strcmp(name, "keysexposed") == 0) {
-        mask = out->MASK_KEYSHIDDEN;
-        value = out->KEYSHIDDEN_NO;
+        mask = ResTable_config::MASK_KEYSHIDDEN;
+        value = ResTable_config::KEYSHIDDEN_NO;
     } else if (strcmp(name, "keyshidden") == 0) {
-        mask = out->MASK_KEYSHIDDEN;
-        value = out->KEYSHIDDEN_YES;
+        mask = ResTable_config::MASK_KEYSHIDDEN;
+        value = ResTable_config::KEYSHIDDEN_YES;
     } else if (strcmp(name, "keyssoft") == 0) {
-        mask = out->MASK_KEYSHIDDEN;
-        value = out->KEYSHIDDEN_SOFT;
+        mask = ResTable_config::MASK_KEYSHIDDEN;
+        value = ResTable_config::KEYSHIDDEN_SOFT;
     }
 
     if (mask != 0) {
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index a389bfb..0b531c2 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -382,7 +382,7 @@
         }
         attr.createIfNeeded(outTable);
         if (!attr.hasErrors) {
-            char buf[10];
+            char buf[11];
             sprintf(buf, "%d", l10n_required);
             err = outTable->addBag(attr.sourcePos, myPackage, attr16, attr.ident,
                     String16(""), String16("^l10n"), String16(buf), NULL, NULL);