Merge "Remove BT routes when BT is turned off" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index 299a33c..eb7891a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -27271,8 +27271,8 @@
     method public boolean isSpeaking();
     method public int playEarcon(java.lang.String, int, android.os.Bundle, java.lang.String);
     method public deprecated int playEarcon(java.lang.String, int, java.util.HashMap<java.lang.String, java.lang.String>);
-    method public int playSilence(long, int, java.lang.String);
     method public deprecated int playSilence(long, int, java.util.HashMap<java.lang.String, java.lang.String>);
+    method public int playSilentUtterance(long, int, java.lang.String);
     method public int setAudioAttributes(android.media.AudioAttributes);
     method public deprecated int setEngineByPackageName(java.lang.String);
     method public int setLanguage(java.util.Locale);
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index e659b2b..08923119 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -397,6 +397,31 @@
     }
 }
 
+// Parse a color represented as an HTML-style 'RRGGBB' string: each pair of
+// characters in str is a hex number in [0, 255], which are converted to
+// floating point values in the range [0.0, 1.0] and placed in the
+// corresponding elements of color.
+//
+// If the input string isn't valid, parseColor returns false and color is
+// left unchanged.
+static bool parseColor(const char str[7], float color[3]) {
+    float tmpColor[3];
+    for (int i = 0; i < 3; i++) {
+        int val = 0;
+        for (int j = 0; j < 2; j++) {
+            val *= 16;
+            char c = str[2*i + j];
+            if      (c >= '0' && c <= '9') val += c - '0';
+            else if (c >= 'A' && c <= 'F') val += (c - 'A') + 10;
+            else if (c >= 'a' && c <= 'f') val += (c - 'a') + 10;
+            else                           return false;
+        }
+        tmpColor[i] = static_cast<float>(val) / 255.0f;
+    }
+    memcpy(color, tmpColor, sizeof(tmpColor));
+    return true;
+}
+
 bool BootAnimation::movie()
 {
     ZipEntryRO desc = mZip->findEntryByName("desc.txt");
@@ -427,20 +452,28 @@
         const char* l = line.string();
         int fps, width, height, count, pause;
         char path[ANIM_ENTRY_NAME_MAX];
+        char color[7] = "000000"; // default to black if unspecified
+
         char pathType;
         if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
-            //LOGD("> w=%d, h=%d, fps=%d", width, height, fps);
+            // ALOGD("> w=%d, h=%d, fps=%d", width, height, fps);
             animation.width = width;
             animation.height = height;
             animation.fps = fps;
         }
-        else if (sscanf(l, " %c %d %d %s", &pathType, &count, &pause, path) == 4) {
-            //LOGD("> type=%c, count=%d, pause=%d, path=%s", pathType, count, pause, path);
+        else if (sscanf(l, " %c %d %d %s #%6s", &pathType, &count, &pause, path, color) >= 4) {
+            // ALOGD("> type=%c, count=%d, pause=%d, path=%s, color=%s", pathType, count, pause, path, color);
             Animation::Part part;
             part.playUntilComplete = pathType == 'c';
             part.count = count;
             part.pause = pause;
             part.path = path;
+            if (!parseColor(color, part.backgroundColor)) {
+                ALOGE("> invalid color '#%s'", color);
+                part.backgroundColor[0] = 0.0f;
+                part.backgroundColor[1] = 0.0f;
+                part.backgroundColor[2] = 0.0f;
+            }
             animation.parts.add(part);
         }
 
@@ -526,6 +559,12 @@
             if(exitPending() && !part.playUntilComplete)
                 break;
 
+            glClearColor(
+                    part.backgroundColor[0],
+                    part.backgroundColor[1],
+                    part.backgroundColor[2],
+                    1.0f);
+
             for (size_t j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) {
                 const Animation::Frame& frame(part.frames[j]);
                 nsecs_t lastFrame = systemTime();
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index ba1c507..72cd62b 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -71,6 +71,7 @@
             String8 path;
             SortedVector<Frame> frames;
             bool playUntilComplete;
+            float backgroundColor[3];
         };
         int fps;
         int width;
diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
index 3b41359..a7ea89c 100644
--- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
+++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java
@@ -328,6 +328,7 @@
         resetJpegSurfaceFormats(mCallbackOutputs);
         mPreviewOutputs.clear();
         mCallbackOutputs.clear();
+        mJpegSurfaceIds.clear();
         mPreviewTexture = null;
 
         int facing = mCharacteristics.get(CameraCharacteristics.LENS_FACING);
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index ba71605..362afba 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -17,6 +17,7 @@
 package android.os;
 
 import android.util.Log;
+import android.util.Slog;
 import com.android.internal.util.FastPrintWriter;
 
 import java.io.FileDescriptor;
@@ -48,7 +49,7 @@
      * of classes can potentially create leaks.
      */
     private static final boolean FIND_POTENTIAL_LEAKS = false;
-    private static final String TAG = "Binder";
+    static final String TAG = "Binder";
 
     /**
      * Control whether dump() calls are allowed.
@@ -385,7 +386,14 @@
             super.finalize();
         }
     }
-    
+
+    static void checkParcel(Parcel parcel, String msg) {
+        if (parcel.dataSize() >= 800*1024) {
+            // Trying to send > 800k, this is way too much
+            Slog.wtfStack(TAG, msg + parcel.dataSize());
+        }
+    }
+
     private native final void init();
     private native final void destroy();
 
@@ -424,6 +432,7 @@
             reply.writeException(re);
             res = true;
         }
+        checkParcel(reply, "Unreasonably large binder reply buffer: ");
         reply.recycle();
         data.recycle();
         return res;
@@ -433,13 +442,18 @@
 final class BinderProxy implements IBinder {
     public native boolean pingBinder();
     public native boolean isBinderAlive();
-    
+
     public IInterface queryLocalInterface(String descriptor) {
         return null;
     }
-    
+
+    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
+        Binder.checkParcel(data, "Unreasonably large binder buffer: ");
+        return transactNative(code, data, reply, flags);
+    }
+
     public native String getInterfaceDescriptor() throws RemoteException;
-    public native boolean transact(int code, Parcel data, Parcel reply,
+    public native boolean transactNative(int code, Parcel data, Parcel reply,
             int flags) throws RemoteException;
     public native void linkToDeath(DeathRecipient recipient, int flags)
             throws RemoteException;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 440b1ec..ec4a53e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -978,6 +978,19 @@
     public static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
 
     /**
+     * Activity Extra: The device identifier to act upon.
+     * <p>
+     * This can be passed as an extra field in an Activity Intent with a single
+     * InputDeviceIdentifier. This field is used by some activities to jump straight into the
+     * settings for the given device.
+     * <p>
+     * Example: The {@link #INPUT_METHOD_SETTINGS} intent opens the keyboard layout dialog for the
+     * given device.
+     * @hide
+     */
+    public static final String EXTRA_INPUT_DEVICE_IDENTIFIER = "input_device_identifier";
+
+    /**
      * @hide
      * Activity Extra: Enable or disable Airplane Mode.
      * <p>
diff --git a/core/java/android/speech/tts/SynthesisRequest.java b/core/java/android/speech/tts/SynthesisRequest.java
index d41aa67..6262fcb 100644
--- a/core/java/android/speech/tts/SynthesisRequest.java
+++ b/core/java/android/speech/tts/SynthesisRequest.java
@@ -61,7 +61,7 @@
 
     /**
      * Gets the text which should be synthesized.
-     * @deprecated As of API level 20, replaced by {@link #getCharSequenceText}.
+     * @deprecated As of API level 21, replaced by {@link #getCharSequenceText}.
      */
     @Deprecated
     public String getText() {
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index 120c9e3..c59ca8a 100644
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -575,7 +575,7 @@
          * @see TextToSpeech#synthesizeToFile(String, java.util.HashMap, String)
          * @see TextToSpeech#getFeatures(java.util.Locale)
          *
-         * @deprecated Starting from API level 20, to select network synthesis, call
+         * @deprecated Starting from API level 21, to select network synthesis, call
          * ({@link TextToSpeech#getVoices()}, find a suitable network voice
          * ({@link Voice#isNetworkConnectionRequired()}) and pass it
          * to {@link TextToSpeech#setVoice(Voice)}).
@@ -593,7 +593,7 @@
          * @see TextToSpeech#synthesizeToFile(String, java.util.HashMap, String)
          * @see TextToSpeech#getFeatures(java.util.Locale)
 
-         * @deprecated Starting from API level 20, to select embedded synthesis, call
+         * @deprecated Starting from API level 21, to select embedded synthesis, call
          * ({@link TextToSpeech#getVoices()}, find a suitable embedded voice
          * ({@link Voice#isNetworkConnectionRequired()}) and pass it
          * to {@link TextToSpeech#setVoice(Voice)}).
@@ -1015,7 +1015,7 @@
      *
      * @return Code indicating success or failure. See {@link #ERROR} and {@link #SUCCESS}.
      *
-     * @deprecated As of API level 20, replaced by
+     * @deprecated As of API level 21, replaced by
      *         {@link #addEarcon(String, File)}.
      */
     @Deprecated
@@ -1124,7 +1124,7 @@
      *            engine named "com.svox.pico" if it is being used.
      *
      * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the speak operation.
-     * @deprecated As of API level 20, replaced by
+     * @deprecated As of API level 21, replaced by
      *         {@link #speak(CharSequence, int, Bundle, String)}.
      */
     @Deprecated
@@ -1194,7 +1194,7 @@
      *            engine named "com.svox.pico" if it is being used.
      *
      * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playEarcon operation.
-     * @deprecated As of API level 20, replaced by
+     * @deprecated As of API level 21, replaced by
      *         {@link #playEarcon(String, int, Bundle, String)}.
      */
     @Deprecated
@@ -1218,9 +1218,9 @@
      * @param queueMode {@link #QUEUE_ADD} or {@link #QUEUE_FLUSH}.
      * @param utteranceId An unique identifier for this request.
      *
-     * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playSilence operation.
+     * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playSilentUtterance operation.
      */
-    public int playSilence(final long durationInMs, final int queueMode,
+    public int playSilentUtterance(final long durationInMs, final int queueMode,
             final String utteranceId) {
         return runAction(new Action<Integer>() {
             @Override
@@ -1228,7 +1228,7 @@
                 return service.playSilence(getCallerIdentity(), durationInMs,
                                            queueMode, utteranceId);
             }
-        }, ERROR, "playSilence");
+        }, ERROR, "playSilentUtterance");
     }
 
     /**
@@ -1252,13 +1252,13 @@
      *            engine named "com.svox.pico" if it is being used.
      *
      * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the playSilence operation.
-     * @deprecated As of API level 20, replaced by
-     *         {@link #playSilence(long, int, String)}.
+     * @deprecated As of API level 21, replaced by
+     *         {@link #playSilentUtterance(long, int, String)}.
      */
     @Deprecated
     public int playSilence(final long durationInMs, final int queueMode,
             final HashMap<String, String> params) {
-        return playSilence(durationInMs, queueMode,
+        return playSilentUtterance(durationInMs, queueMode,
                            params == null ? null : params.get(Engine.KEY_PARAM_UTTERANCE_ID));
     }
 
@@ -1276,7 +1276,7 @@
      *
      * @param locale The locale to query features for.
      * @return Set instance. May return {@code null} on error.
-     * @deprecated As of API level 20, please use voices. In order to query features of the voice,
+     * @deprecated As of API level 21, please use voices. In order to query features of the voice,
      * call {@link #getVoices()} to retrieve the list of available voices and
      * {@link Voice#getFeatures()} to retrieve the set of features.
      */
@@ -1421,7 +1421,7 @@
      *
      * @return language, country (if any) and variant (if any) used by the client stored in a
      *     Locale instance, or {@code null} on error.
-     * @deprecated As of API Level 20, use <code>getDefaultVoice().getLocale()</code> ({@link
+     * @deprecated As of API level 21, use <code>getDefaultVoice().getLocale()</code> ({@link
      *   #getDefaultVoice()})
      */
     @Deprecated
@@ -1476,7 +1476,7 @@
 
                 String variant = loc.getVariant();
 
-                // As of API level 20, setLanguage is implemented using setVoice.
+                // As of API level 21, setLanguage is implemented using setVoice.
                 // (which, in the default implementation, will call loadLanguage on the service
                 // interface).
 
@@ -1535,7 +1535,7 @@
      * @return language, country (if any) and variant (if any) used by the client stored in a
      *     Locale instance, or {@code null} on error.
      *
-     * @deprecated As of API level 20, please use <code>getVoice().getLocale()</code>
+     * @deprecated As of API level 21, please use <code>getVoice().getLocale()</code>
      * ({@link #getVoice()}).
      */
     @Deprecated
@@ -1831,7 +1831,7 @@
      *            something like "/sdcard/myappsounds/mysound.wav".
      *
      * @return {@link #ERROR} or {@link #SUCCESS} of <b>queuing</b> the synthesizeToFile operation.
-     * @deprecated As of API level 20, replaced by
+     * @deprecated As of API level 21, replaced by
      *         {@link #synthesizeToFile(CharSequence, Bundle, File, String)}.
      */
     @Deprecated
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 079467a..9bb7f02 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -91,7 +91,7 @@
  * The first three methods are siblings of the {@link #onGetLanguage},
  * {@link #onIsLanguageAvailable} and {@link #onLoadLanguage} methods. The last one,
  * {@link #onGetDefaultVoiceNameFor(String, String, String)} is a link between locale and voice
- * based methods. Since API level 20 {@link TextToSpeech#setLanguage} is implemented by
+ * based methods. Since API level 21 {@link TextToSpeech#setLanguage} is implemented by
  * calling {@link TextToSpeech#setVoice} with the voice returned by
  * {@link #onGetDefaultVoiceNameFor(String, String, String)}.
  *
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 946a3f7..c855e57 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -81,7 +81,7 @@
 
     /**
      * Intermediate density for screens that sit somewhere between
-     * {@link #DENSITY_XXHIGH} (480 dpi) and {@link #DENSITY_XXXHIGH} (560 dpi).
+     * {@link #DENSITY_XXHIGH} (480 dpi) and {@link #DENSITY_XXXHIGH} (640 dpi).
      * This is not a density that applications should target, instead relying
      * on the system to scale their {@link #DENSITY_XXXHIGH} assets for them.
      */
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index a283b91..baa133d 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -889,7 +889,13 @@
                     }
                 }
             } else {
-                AccessibilityNodeInfo root = provider.createAccessibilityNodeInfo(virtualViewId);
+                final AccessibilityNodeInfo root;
+                if (virtualViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+                    root = provider.createAccessibilityNodeInfo(virtualViewId);
+                } else {
+                    root = provider.createAccessibilityNodeInfo(
+                            AccessibilityNodeProvider.HOST_VIEW_ID);
+                }
                 if (root != null) {
                     outInfos.add(root);
                     if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 2b8b4dc..0439168 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1493,11 +1493,11 @@
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(AbsListView.class.getName());
         if (isEnabled()) {
-            if (getFirstVisiblePosition() > 0) {
+            if (canScrollUp()) {
                 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
                 info.setScrollable(true);
             }
-            if (getLastVisiblePosition() < getCount() - 1) {
+            if (canScrollDown()) {
                 info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
                 info.setScrollable(true);
             }
@@ -2203,38 +2203,46 @@
 
     void updateScrollIndicators() {
         if (mScrollUp != null) {
-            boolean canScrollUp;
-            // 0th element is not visible
-            canScrollUp = mFirstPosition > 0;
-
-            // ... Or top of 0th element is not visible
-            if (!canScrollUp) {
-                if (getChildCount() > 0) {
-                    View child = getChildAt(0);
-                    canScrollUp = child.getTop() < mListPadding.top;
-                }
-            }
-
-            mScrollUp.setVisibility(canScrollUp ? View.VISIBLE : View.INVISIBLE);
+            mScrollUp.setVisibility(canScrollUp() ? View.VISIBLE : View.INVISIBLE);
         }
 
         if (mScrollDown != null) {
-            boolean canScrollDown;
-            int count = getChildCount();
-
-            // Last item is not visible
-            canScrollDown = (mFirstPosition + count) < mItemCount;
-
-            // ... Or bottom of the last element is not visible
-            if (!canScrollDown && count > 0) {
-                View child = getChildAt(count - 1);
-                canScrollDown = child.getBottom() > mBottom - mListPadding.bottom;
-            }
-
-            mScrollDown.setVisibility(canScrollDown ? View.VISIBLE : View.INVISIBLE);
+            mScrollDown.setVisibility(canScrollDown() ? View.VISIBLE : View.INVISIBLE);
         }
     }
 
+    private boolean canScrollUp() {
+        boolean canScrollUp;
+        // 0th element is not visible
+        canScrollUp = mFirstPosition > 0;
+
+        // ... Or top of 0th element is not visible
+        if (!canScrollUp) {
+            if (getChildCount() > 0) {
+                View child = getChildAt(0);
+                canScrollUp = child.getTop() < mListPadding.top;
+            }
+        }
+
+        return canScrollUp;
+    }
+
+    private boolean canScrollDown() {
+        boolean canScrollDown;
+        int count = getChildCount();
+
+        // Last item is not visible
+        canScrollDown = (mFirstPosition + count) < mItemCount;
+
+        // ... Or bottom of the last element is not visible
+        if (!canScrollDown && count > 0) {
+            View child = getChildAt(count - 1);
+            canScrollDown = child.getBottom() > mBottom - mListPadding.bottom;
+        }
+
+        return canScrollDown;
+    }
+
     @Override
     @ViewDebug.ExportedProperty
     public View getSelectedView() {
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 22600de..5685ad7 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -128,7 +128,10 @@
                 com.android.internal.R.string.whichSendApplicationNamed),
         DEFAULT(null,
                 com.android.internal.R.string.whichApplication,
-                com.android.internal.R.string.whichApplicationNamed);
+                com.android.internal.R.string.whichApplicationNamed),
+        HOME(Intent.ACTION_MAIN,
+                com.android.internal.R.string.whichHomeApplication,
+                com.android.internal.R.string.whichHomeApplicationNamed);
 
         public final String action;
         public final int titleRes;
@@ -142,7 +145,7 @@
 
         public static ActionTitle forAction(String action) {
             for (ActionTitle title : values()) {
-                if (action != null && action.equals(title.action)) {
+                if (title != HOME && action != null && action.equals(title.action)) {
                     return title;
                 }
             }
@@ -165,26 +168,19 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         // Use a specialized prompt when we're handling the 'Home' app startActivity()
-        final int titleResource;
         final Intent intent = makeMyIntent();
         final Set<String> categories = intent.getCategories();
         if (Intent.ACTION_MAIN.equals(intent.getAction())
                 && categories != null
                 && categories.size() == 1
                 && categories.contains(Intent.CATEGORY_HOME)) {
-            titleResource = com.android.internal.R.string.whichHomeApplication;
-
             // Note: this field is not set to true in the compatibility version.
             mResolvingHome = true;
-        } else {
-            titleResource = 0;
         }
 
         setSafeForwardingMode(true);
 
-        onCreate(savedInstanceState, intent,
-                titleResource != 0 ? getResources().getText(titleResource) : null, titleResource,
-                null, null, true);
+        onCreate(savedInstanceState, intent, null, 0, null, null, true);
     }
 
     /**
@@ -336,7 +332,7 @@
     }
 
     protected CharSequence getTitleForAction(String action, int defaultTitleRes) {
-        final ActionTitle title = ActionTitle.forAction(action);
+        final ActionTitle title = mResolvingHome ? ActionTitle.HOME : ActionTitle.forAction(action);
         final boolean named = mAdapter.hasFilteredItem();
         if (title == ActionTitle.DEFAULT && defaultTitleRes != 0) {
             return getString(defaultTitleRes);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 1a2d6ce..85b58aa 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -780,9 +780,9 @@
      */
     public void saveLockPassword(String password, int quality, boolean isFallback, int userHandle) {
         try {
-            getLockSettings().setLockPassword(password, userHandle);
             DevicePolicyManager dpm = getDevicePolicyManager();
             if (!TextUtils.isEmpty(password)) {
+                getLockSettings().setLockPassword(password, userHandle);
                 int computedQuality = computePasswordQuality(password);
 
                 if (userHandle == UserHandle.USER_OWNER) {
@@ -860,6 +860,7 @@
                 setString(PASSWORD_HISTORY_KEY, passwordHistory, userHandle);
             } else {
                 // Empty password
+                getLockSettings().setLockPassword(null, userHandle);
                 if (userHandle == UserHandle.USER_OWNER) {
                     // Set the encryption password to default.
                     updateEncryptionPassword(StorageManager.CRYPT_TYPE_DEFAULT, null);
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 81e887d..2dbd382 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -1239,7 +1239,7 @@
     {"pingBinder",          "()Z", (void*)android_os_BinderProxy_pingBinder},
     {"isBinderAlive",       "()Z", (void*)android_os_BinderProxy_isBinderAlive},
     {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
-    {"transact",            "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
+    {"transactNative",      "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
     {"linkToDeath",         "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
     {"unlinkToDeath",       "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
     {"destroy",             "()V", (void*)android_os_BinderProxy_destroy},
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fd4b40f..9fc7801 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3440,7 +3440,10 @@
          and a previously used application is known. -->
     <string name="whichSendApplicationNamed">Share with %1$s</string>
     <!-- Title of intent resolver dialog when selecting a HOME application to run. -->
-    <string name="whichHomeApplication">Select a home app</string>
+    <string name="whichHomeApplication">Select a Home app</string>
+    <!-- Title of intent resolver dialog when selecting a HOME application to run
+         and a previously used application is known. -->
+    <string name="whichHomeApplicationNamed">Use %1$s as Home</string>
     <!-- Option to always use the selected application resolution in the future. See the "Complete action using" dialog title-->
     <string name="alwaysUse">Use by default for this action.</string>
     <!-- Title of the list of alternate options to complete an action shown when the
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2620c27..72f756a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2067,4 +2067,5 @@
   <java-symbol type="bool" name="config_restart_radio_on_pdp_fail_regular_deactivation" />
   <java-symbol type="array" name="networks_not_clear_data" />
   <java-symbol type="bool" name="config_switch_phone_on_voice_reg_state_change" />
+  <java-symbol type="string" name="whichHomeApplicationNamed" />
 </resources>
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index f0a2072..e9e475c 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -289,7 +289,7 @@
                         + " mPopupImmediately: " + mPopupImmediately
                         + " mInEmergency: " + getInEmergency());
 
-        if (getLocationEnabled() && !getInEmergency()) {
+        if (!getLocationEnabled() && !getInEmergency()) {
             // Location is currently disabled, ignore all NI requests.
             try {
                 mNetInitiatedListener.sendNiResponse(notif.notificationId,
diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 1de8a8b..3e5919f 100644
--- a/media/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
@@ -141,26 +141,31 @@
 
         final ServiceConnection thisConnection = mServiceConnection = new MediaServiceConnection();
 
+        boolean bound = false;
         try {
-            mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
+            if (mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE)) {
+                bound = true;
+            }
         } catch (Exception ex) {
             Log.e(TAG, "Failed binding to service " + mServiceComponent);
+        }
 
+        if (!bound) {
             // Tell them that it didn't work.  We are already on the main thread,
             // but we don't want to do callbacks inside of connect().  So post it,
             // and then check that we are on the same ServiceConnection.  We know
             // we won't also get an onServiceConnected or onServiceDisconnected,
             // so we won't be doing double callbacks.
             mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        // Ensure that nobody else came in or tried to connect again.
-                        if (thisConnection == mServiceConnection) {
-                            forceCloseConnection();
-                            mCallback.onConnectionFailed();
-                        }
+                @Override
+                public void run() {
+                    // Ensure that nobody else came in or tried to connect again.
+                    if (thisConnection == mServiceConnection) {
+                        forceCloseConnection();
+                        mCallback.onConnectionFailed();
                     }
-                });
+                }
+            });
         }
 
         if (DBG) {
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 8267846..13170ad 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -244,6 +244,6 @@
     <integer name="zen_toast_animation_duration">500</integer>
 
     <!-- Zen toast visibility duration -->
-    <integer name="zen_toast_visible_duration">2000</integer>
+    <integer name="zen_toast_visible_duration">500</integer>
 </resources>
 
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 8e603ba..0d393bf 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -412,7 +412,7 @@
                 if (mCurrView != null) {
                     float delta = getPos(ev) - mInitialTouchPos;
                     float absDelta = Math.abs(delta);
-                    if (absDelta >= mFalsingThreshold) {
+                    if (absDelta >= getFalsingThreshold()) {
                         mTouchAboveFalsingThreshold = true;
                     }
                     // don't let items that can't be dismissed be dragged more than
@@ -466,6 +466,11 @@
         return true;
     }
 
+    private int getFalsingThreshold() {
+        float factor = mCallback.getFalsingThresholdFactor();
+        return (int) (mFalsingThreshold * factor);
+    }
+
     public interface Callback {
         View getChildAtPosition(MotionEvent ev);
 
@@ -489,6 +494,11 @@
          * @return if true, prevents the default alpha fading.
          */
         boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress);
+
+        /**
+         * @return The factor the falsing threshold should be multiplied with
+         */
+        float getFalsingThresholdFactor();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
index bdb0ad3..330333a 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsHorizontalScrollView.java
@@ -196,6 +196,11 @@
         return false;
     }
 
+    @Override
+    public float getFalsingThresholdFactor() {
+        return 1.0f;
+    }
+
     public void dismissChild(View v) {
         mSwipeHelper.dismissChild(v, 0);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
index 47c096f..1e247be 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsVerticalScrollView.java
@@ -204,6 +204,11 @@
         return false;
     }
 
+    @Override
+    public float getFalsingThresholdFactor() {
+        return 1.0f;
+    }
+
     public void dismissChild(View v) {
         mSwipeHelper.dismissChild(v, 0);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
index a9c701a..6653254 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -303,8 +303,12 @@
     }
 
     private boolean isBelowFalsingThreshold() {
-        return Math.abs(mTranslation) < Math.abs(mTranslationOnDown)
-                + mMinTranslationAmount;
+        return Math.abs(mTranslation) < Math.abs(mTranslationOnDown) + getMinTranslationAmount();
+    }
+
+    private int getMinTranslationAmount() {
+        float factor = mCallback.getAffordanceFalsingFactor();
+        return (int) (mMinTranslationAmount * factor);
     }
 
     private void fling(float vel, final boolean snapBack) {
@@ -339,14 +343,14 @@
         translation = rightSwipePossible() ? translation : Math.max(0, translation);
         translation = leftSwipePossible() ? translation : Math.min(0, translation);
         float absTranslation = Math.abs(translation);
-        if (absTranslation > Math.abs(mTranslationOnDown) + mMinTranslationAmount ||
+        if (absTranslation > Math.abs(mTranslationOnDown) + getMinTranslationAmount() ||
                 mMotionPerformedByUser) {
             mMotionPerformedByUser = true;
         }
         if (translation != mTranslation || isReset) {
             KeyguardAffordanceView targetView = translation > 0 ? mLeftIcon : mRightIcon;
             KeyguardAffordanceView otherView = translation > 0 ? mRightIcon : mLeftIcon;
-            float alpha = absTranslation / mMinTranslationAmount;
+            float alpha = absTranslation / getMinTranslationAmount();
 
             // We interpolate the alpha of the other icons to 0
             float fadeOutAlpha = SWIPE_RESTING_ALPHA_AMOUNT * (1.0f - alpha);
@@ -482,5 +486,10 @@
         View getLeftPreview();
 
         View getRightPreview();
+
+        /**
+         * @return The factor the minimum swipe amount should be multiplied with.
+         */
+        float getAffordanceFalsingFactor();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 80e9663..2efa84a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -706,7 +706,7 @@
             case MotionEvent.ACTION_MOVE:
                 final float h = y - mInitialTouchY;
                 setQsExpansion(h + mInitialHeightOnTouch);
-                if (h >= mQsFalsingThreshold) {
+                if (h >= getFalsingThreshold()) {
                     mQsTouchAboveFalsingThreshold = true;
                 }
                 trackMovement(event);
@@ -732,6 +732,11 @@
         }
     }
 
+    private int getFalsingThreshold() {
+        float factor = mStatusBar.isScreenOnComingFromTouch() ? 1.5f : 1.0f;
+        return (int) (mQsFalsingThreshold * factor);
+    }
+
     @Override
     public void onOverscrolled(float lastTouchX, float lastTouchY, int amount) {
         if (mIntercepting && shouldQuickSettingsIntercept(lastTouchX, lastTouchY,
@@ -1633,6 +1638,11 @@
     }
 
     @Override
+    public float getAffordanceFalsingFactor() {
+        return mStatusBar.isScreenOnComingFromTouch() ? 1.5f : 1.0f;
+    }
+
+    @Override
     protected float getPeekHeight() {
         if (mNotificationStackScroller.getNotGoneChildCount() > 0) {
             return mNotificationStackScroller.getPeekHeight();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index 7f155a1d..84216a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -316,6 +316,11 @@
     }
 
     @Override
+    public float getFalsingThresholdFactor() {
+        return 1.0f;
+    }
+
+    @Override
     public void onChildDismissed(View v) {
         Log.v(TAG, "User swiped heads up to dismiss");
         mBar.onHeadsUpDismissed();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 67ba8d20..4a20406 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -547,6 +547,11 @@
         return false;
     }
 
+    @Override
+    public float getFalsingThresholdFactor() {
+        return mPhoneStatusBar.isScreenOnComingFromTouch() ? 1.5f : 1.0f;
+    }
+
     public void onBeginDrag(View v) {
         setSwipingInProgress(true);
         mAmbientState.onBeginDrag(v);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index f72b12f..be3fc47 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -759,7 +759,7 @@
     }
 
     int getActiveWindowId() {
-        return mSecurityPolicy.mActiveWindowId;
+        return mSecurityPolicy.getActiveWindowId();
     }
 
     void onTouchInteractionStart() {
@@ -2600,6 +2600,9 @@
                     userState.mInstalledServices.remove(mAccessibilityServiceInfo);
                     userState.mEnabledServices.remove(mComponentName);
                     userState.destroyUiAutomationService();
+                    if (readConfigurationForUserStateLocked(userState)) {
+                        onUserStateChangedLocked(userState);
+                    }
                 }
             }
         }
@@ -2820,7 +2823,7 @@
 
         private int resolveAccessibilityWindowIdLocked(int accessibilityWindowId) {
             if (accessibilityWindowId == AccessibilityNodeInfo.ACTIVE_WINDOW_ID) {
-                return mSecurityPolicy.mActiveWindowId;
+                return mSecurityPolicy.getActiveWindowId();
             }
             return accessibilityWindowId;
         }
@@ -3281,7 +3284,9 @@
 
         public void clearWindowsLocked() {
             List<AccessibilityWindowInfo> windows = Collections.emptyList();
+            final int activeWindowId = mActiveWindowId;
             updateWindowsLocked(windows);
+            mActiveWindowId = activeWindowId;
             mWindows = null;
         }
 
@@ -3494,6 +3499,13 @@
             }
         }
 
+        public int getActiveWindowId() {
+            if (mActiveWindowId == INVALID_WINDOW_ID && !mTouchInteractionInProgress) {
+                mActiveWindowId = getFocusedWindowId();
+            }
+            return mActiveWindowId;
+        }
+
         private void setActiveWindowLocked(int windowId) {
             if (mActiveWindowId != windowId) {
                 mActiveWindowId = windowId;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 8e8e4a6..01e80b7 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2134,7 +2134,8 @@
                     if (!hasCreate) {
                         continue;
                     }
-                    if (proc != null && !proc.persistent && proc.thread != null
+                    // XXX turned off for now until we have more time to get a better policy.
+                    if (false && proc != null && !proc.persistent && proc.thread != null
                             && proc.pid != 0 && proc.pid != ActivityManagerService.MY_PID
                             && proc.setProcState >= ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
                         proc.kill("bound to service " + sr.name.flattenToShortString()
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d2e3d25..4d2fd4c 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -4690,8 +4690,8 @@
     private final void handleAppDiedLocked(ProcessRecord app,
             boolean restarting, boolean allowRestart) {
         int pid = app.pid;
-        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
-        if (!restarting) {
+        boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
+        if (!kept && !restarting) {
             removeLruProcessLocked(app);
             if (pid > 0) {
                 ProcessList.remove(pid);
@@ -4816,6 +4816,14 @@
     }
 
     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
+        // First check if this ProcessRecord is actually active for the pid.
+        synchronized (mPidsSelfLocked) {
+            ProcessRecord curProc = mPidsSelfLocked.get(pid);
+            if (curProc != app) {
+                Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
+                return;
+            }
+        }
 
         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
         synchronized (stats) {
@@ -4833,7 +4841,7 @@
             boolean doOomAdj = doLowMem;
             if (!app.killedByAm) {
                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
-                        + ") has died.");
+                        + ") has died");
                 mAllowLowerMemLevel = true;
             } else {
                 // Note that we always want to do oom adj to update our state with the
@@ -14310,8 +14318,11 @@
      * Main code for cleaning up a process when it has gone away.  This is
      * called both as a result of the process dying, or directly when stopping
      * a process when running in single process mode.
+     *
+     * @return Returns true if the given process has been restarted, so the
+     * app that was passed in must remain on the process lists.
      */
-    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
+    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
             boolean restarting, boolean allowRestart, int index) {
         if (index >= 0) {
             removeLruProcessLocked(app);
@@ -14434,7 +14445,7 @@
         // If the caller is restarting this app, then leave it in its
         // current lists and let the caller take care of it.
         if (restarting) {
-            return;
+            return false;
         }
 
         if (!app.persistent || app.isolated) {
@@ -14470,8 +14481,12 @@
         if (restart && !app.isolated) {
             // We have components that still need to be running in the
             // process, so re-launch it.
+            if (index < 0) {
+                ProcessList.remove(app.pid);
+            }
             mProcessNames.put(app.processName, app.uid, app);
             startProcessLocked(app, "restart", app.processName);
+            return true;
         } else if (app.pid > 0 && app.pid != MY_PID) {
             // Goodbye!
             boolean removed;
@@ -14485,6 +14500,7 @@
             }
             app.setPid(0);
         }
+        return false;
     }
 
     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 7f89947..15dcd44 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -695,6 +695,8 @@
             final int numFullKeyboards = mTempFullKeyboards.size();
             boolean missingLayoutForExternalKeyboard = false;
             boolean missingLayoutForExternalKeyboardAdded = false;
+            boolean multipleMissingLayoutsForExternalKeyboardsAdded = false;
+            InputDevice keyboardMissingLayout = null;
             synchronized (mDataStore) {
                 for (int i = 0; i < numFullKeyboards; i++) {
                     final InputDevice inputDevice = mTempFullKeyboards.get(i);
@@ -704,13 +706,25 @@
                         missingLayoutForExternalKeyboard = true;
                         if (i < numFullKeyboardsAdded) {
                             missingLayoutForExternalKeyboardAdded = true;
+                            if (keyboardMissingLayout == null) {
+                                keyboardMissingLayout = inputDevice;
+                            } else {
+                                multipleMissingLayoutsForExternalKeyboardsAdded = true;
+                            }
                         }
                     }
                 }
             }
             if (missingLayoutForExternalKeyboard) {
                 if (missingLayoutForExternalKeyboardAdded) {
-                    showMissingKeyboardLayoutNotification();
+                    if (multipleMissingLayoutsForExternalKeyboardsAdded) {
+                        // We have more than one keyboard missing a layout, so drop the
+                        // user at the generic input methods page so they can pick which
+                        // one to set.
+                        showMissingKeyboardLayoutNotification(null);
+                    } else {
+                        showMissingKeyboardLayoutNotification(keyboardMissingLayout);
+                    }
                 }
             } else if (mKeyboardLayoutNotificationShown) {
                 hideMissingKeyboardLayoutNotification();
@@ -761,16 +775,17 @@
     }
 
     // Must be called on handler.
-    private void showMissingKeyboardLayoutNotification() {
+    private void showMissingKeyboardLayoutNotification(InputDevice device) {
         if (!mKeyboardLayoutNotificationShown) {
-            if (mKeyboardLayoutIntent == null) {
-                final Intent intent = new Intent("android.settings.INPUT_METHOD_SETTINGS");
-                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                        | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
-                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                mKeyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0,
-                        intent, 0, null, UserHandle.CURRENT);
+            final Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS);
+            if (device != null) {
+                intent.putExtra(Settings.EXTRA_INPUT_DEVICE_IDENTIFIER, device.getIdentifier());
             }
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                    | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
+                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+            final PendingIntent keyboardLayoutIntent = PendingIntent.getActivityAsUser(mContext, 0,
+                    intent, 0, null, UserHandle.CURRENT);
 
             Resources r = mContext.getResources();
             Notification notification = new Notification.Builder(mContext)
@@ -778,7 +793,7 @@
                             R.string.select_keyboard_layout_notification_title))
                     .setContentText(r.getString(
                             R.string.select_keyboard_layout_notification_message))
-                    .setContentIntent(mKeyboardLayoutIntent)
+                    .setContentIntent(keyboardLayoutIntent)
                     .setSmallIcon(R.drawable.ic_settings_language)
                     .setPriority(Notification.PRIORITY_LOW)
                     .setColor(mContext.getResources().getColor(
diff --git a/telecomm/java/android/telecom/RemoteConference.java b/telecomm/java/android/telecom/RemoteConference.java
index 796725b..b18cb96 100644
--- a/telecomm/java/android/telecom/RemoteConference.java
+++ b/telecomm/java/android/telecom/RemoteConference.java
@@ -166,6 +166,20 @@
         }
     }
 
+    public void merge() {
+        try {
+            mConnectionService.mergeConference(mId);
+        } catch (RemoteException e) {
+        }
+    }
+
+    public void swap() {
+        try {
+            mConnectionService.swapConference(mId);
+        } catch (RemoteException e) {
+        }
+    }
+
     public void hold() {
         try {
             mConnectionService.hold(mId);
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index b8c34543..77d3beb 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -3310,6 +3310,19 @@
     , mParentId(entry.mParentId)
     , mPos(entry.mPos) {}
 
+ResourceTable::Entry& ResourceTable::Entry::operator=(const Entry& entry) {
+    mName = entry.mName;
+    mParent = entry.mParent;
+    mType = entry.mType;
+    mItem = entry.mItem;
+    mItemFormat = entry.mItemFormat;
+    mBag = entry.mBag;
+    mNameIndex = entry.mNameIndex;
+    mParentId = entry.mParentId;
+    mPos = entry.mPos;
+    return *this;
+}
+
 status_t ResourceTable::Entry::makeItABag(const SourcePos& sourcePos)
 {
     if (mType == TYPE_BAG) {
@@ -4352,7 +4365,11 @@
                                     String8(entriesToAdd[i].value->getName()).string(),
                                     entriesToAdd[i].key.toString().string());
 
-                    c->addEntry(entriesToAdd[i].key, entriesToAdd[i].value);
+                    sp<Entry> newEntry = t->getEntry(c->getName(),
+                            entriesToAdd[i].value->getPos(),
+                            &entriesToAdd[i].key);
+
+                    *newEntry = *entriesToAdd[i].value;
                 }
             }
         }
diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h
index c548a85..eac5dd3 100644
--- a/tools/aapt/ResourceTable.h
+++ b/tools/aapt/ResourceTable.h
@@ -316,6 +316,7 @@
         { }
 
         Entry(const Entry& entry);
+        Entry& operator=(const Entry& entry);
 
         virtual ~Entry() { }