Merge "Unhide AudioTrack constructor with AudioAttributes, AudioFormat" into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index d9185e5..011fa53 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -84,7 +84,6 @@
     field public static final java.lang.String MANAGE_ACCOUNTS = "android.permission.MANAGE_ACCOUNTS";
     field public static final java.lang.String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS";
     field public static final java.lang.String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS";
-    field public static final java.lang.String MANAGE_VOICEMAIL = "com.android.voicemail.permission.MANAGE_VOICEMAIL";
     field public static final java.lang.String MASTER_CLEAR = "android.permission.MASTER_CLEAR";
     field public static final java.lang.String MEDIA_CONTENT_CONTROL = "android.permission.MEDIA_CONTENT_CONTROL";
     field public static final java.lang.String MODIFY_AUDIO_SETTINGS = "android.permission.MODIFY_AUDIO_SETTINGS";
@@ -94,7 +93,6 @@
     field public static final java.lang.String NFC = "android.permission.NFC";
     field public static final deprecated java.lang.String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
     field public static final java.lang.String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
-    field public static final java.lang.String READ_ALL_VOICEMAIL = "com.android.voicemail.permission.READ_ALL_VOICEMAIL";
     field public static final java.lang.String READ_CALENDAR = "android.permission.READ_CALENDAR";
     field public static final java.lang.String READ_CALL_LOG = "android.permission.READ_CALL_LOG";
     field public static final java.lang.String READ_CONTACTS = "android.permission.READ_CONTACTS";
@@ -110,6 +108,7 @@
     field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
     field public static final java.lang.String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS";
     field public static final java.lang.String READ_USER_DICTIONARY = "android.permission.READ_USER_DICTIONARY";
+    field public static final java.lang.String READ_VOICEMAIL = "com.android.voicemail.permission.READ_VOICEMAIL";
     field public static final java.lang.String REBOOT = "android.permission.REBOOT";
     field public static final java.lang.String RECEIVE_BOOT_COMPLETED = "android.permission.RECEIVE_BOOT_COMPLETED";
     field public static final java.lang.String RECEIVE_MMS = "android.permission.RECEIVE_MMS";
@@ -160,6 +159,7 @@
     field public static final deprecated java.lang.String WRITE_SOCIAL_STREAM = "android.permission.WRITE_SOCIAL_STREAM";
     field public static final java.lang.String WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS";
     field public static final java.lang.String WRITE_USER_DICTIONARY = "android.permission.WRITE_USER_DICTIONARY";
+    field public static final java.lang.String WRITE_VOICEMAIL = "com.android.voicemail.permission.WRITE_VOICEMAIL";
   }
 
   public static final class Manifest.permission_group {
@@ -7751,6 +7751,7 @@
     field public static final java.lang.String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
     field public static final java.lang.String EXTRA_REFERRER = "android.intent.extra.REFERRER";
     field public static final java.lang.String EXTRA_REMOTE_INTENT_TOKEN = "android.intent.extra.remote_intent_token";
+    field public static final java.lang.String EXTRA_REPLACEMENT_EXTRAS = "android.intent.extra.REPLACEMENT_EXTRAS";
     field public static final java.lang.String EXTRA_REPLACING = "android.intent.extra.REPLACING";
     field public static final java.lang.String EXTRA_RESTRICTIONS_BUNDLE = "android.intent.extra.restrictions_bundle";
     field public static final java.lang.String EXTRA_RESTRICTIONS_INTENT = "android.intent.extra.restrictions_intent";
@@ -10898,11 +10899,9 @@
     ctor public Outline(android.graphics.Outline);
     method public boolean canClip();
     method public boolean isEmpty();
-    method public boolean isFilled();
     method public void set(android.graphics.Outline);
     method public void setConvexPath(android.graphics.Path);
     method public void setEmpty();
-    method public void setFilled(boolean);
     method public void setOval(int, int, int, int);
     method public void setOval(android.graphics.Rect);
     method public void setRect(int, int, int, int);
@@ -11648,7 +11647,7 @@
     method public int getMinimumHeight();
     method public int getMinimumWidth();
     method public abstract int getOpacity();
-    method public boolean getOutline(android.graphics.Outline);
+    method public void getOutline(android.graphics.Outline);
     method public boolean getPadding(android.graphics.Rect);
     method public int[] getState();
     method public android.graphics.Region getTransparentRegion();
@@ -11980,7 +11979,7 @@
     method public android.graphics.drawable.shapes.Shape clone() throws java.lang.CloneNotSupportedException;
     method public abstract void draw(android.graphics.Canvas, android.graphics.Paint);
     method public final float getHeight();
-    method public boolean getOutline(android.graphics.Outline);
+    method public void getOutline(android.graphics.Outline);
     method public final float getWidth();
     method public boolean hasAlpha();
     method protected void onResize(float, float);
@@ -14147,7 +14146,6 @@
     method public deprecated void setWiredHeadsetOn(boolean);
     method public deprecated boolean shouldVibrate(int);
     method public void startBluetoothSco();
-    method public void startBluetoothScoVirtualCall();
     method public void stopBluetoothSco();
     method public void unloadSoundEffects();
     method public void unregisterMediaButtonEventReceiver(android.content.ComponentName);
@@ -17529,6 +17527,7 @@
     method public android.net.VpnService.Builder allowBypass();
     method public android.net.VpnService.Builder allowFamily(int);
     method public android.os.ParcelFileDescriptor establish();
+    method public android.net.VpnService.Builder setBlocking(boolean);
     method public android.net.VpnService.Builder setConfigureIntent(android.app.PendingIntent);
     method public android.net.VpnService.Builder setMtu(int);
     method public android.net.VpnService.Builder setSession(java.lang.String);
@@ -28510,7 +28509,6 @@
     method public android.content.ComponentName getComponentName();
     method public java.lang.String getId();
     method public void writeToParcel(android.os.Parcel, int);
-    field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
@@ -28528,6 +28526,7 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int CAPABILITY_CALL_PROVIDER = 2; // 0x2
     field public static final int CAPABILITY_SIM_CALL_MANAGER = 1; // 0x1
+    field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
@@ -29193,6 +29192,7 @@
     method public boolean setCdmaSubscription(int);
     method public void setLine1NumberForDisplay(java.lang.String, java.lang.String);
     method public void setLine1NumberForDisplay(long, java.lang.String, java.lang.String);
+    method public boolean setOperatorBrandOverride(java.lang.String, java.lang.String);
     method public boolean setPreferredNetworkType(int);
     field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
     field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
@@ -34145,7 +34145,6 @@
     method public void setOnLongClickListener(android.view.View.OnLongClickListener);
     method public void setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener);
     method public void setOnTouchListener(android.view.View.OnTouchListener);
-    method public deprecated void setOutline(android.graphics.Outline);
     method public void setOutlineProvider(android.view.ViewOutlineProvider);
     method public void setOverScrollMode(int);
     method public void setPadding(int, int, int, int);
@@ -34698,7 +34697,7 @@
 
   public abstract class ViewOutlineProvider {
     ctor public ViewOutlineProvider();
-    method public abstract boolean getOutline(android.view.View, android.graphics.Outline);
+    method public abstract void getOutline(android.view.View, android.graphics.Outline);
     field public static final android.view.ViewOutlineProvider BACKGROUND;
   }
 
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 5bf8a97..6e7543f 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3175,6 +3175,33 @@
     public static final String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
 
     /**
+     * A Bundle forming a mapping of potential target package names to different extras Bundles
+     * to add to the default intent extras in {@link #EXTRA_INTENT} when used with
+     * {@link #ACTION_CHOOSER}. Each key should be a package name. The package need not
+     * be currently installed on the device.
+     *
+     * <p>An application may choose to provide alternate extras for the case where a user
+     * selects an activity from a predetermined set of target packages. If the activity
+     * the user selects from the chooser belongs to a package with its package name as
+     * a key in this bundle, the corresponding extras for that package will be merged with
+     * the extras already present in the intent at {@link #EXTRA_INTENT}. If a replacement
+     * extra has the same key as an extra already present in the intent it will overwrite
+     * the extra from the intent.</p>
+     *
+     * <p><em>Examples:</em>
+     * <ul>
+     *     <li>An application may offer different {@link #EXTRA_TEXT} to an application
+     *     when sharing with it via {@link #ACTION_SEND}, augmenting a link with additional query
+     *     parameters for that target.</li>
+     *     <li>An application may offer additional metadata for known targets of a given intent
+     *     to pass along information only relevant to that target such as account or content
+     *     identifiers already known to that application.</li>
+     * </ul></p>
+     */
+    public static final String EXTRA_REPLACEMENT_EXTRAS =
+            "android.intent.extra.REPLACEMENT_EXTRAS";
+
+    /**
      * A {@link android.view.KeyEvent} object containing the event that
      * triggered the creation of the Intent it is in.
      */
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 5d61de2..0967fa8 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -568,6 +568,20 @@
         }
 
         /**
+         * Sets the VPN interface's file descriptor to be in blocking/non-blocking mode.
+         *
+         * By default, the file descriptor returned by {@link #establish} is non-blocking.
+         *
+         * @param blocking True to put the descriptor into blocking mode; false for non-blocking.
+         *
+         * @return this {@link Builder} object to facilitate chaining method calls.
+         */
+        public Builder setBlocking(boolean blocking) {
+            // TODO
+            return this;
+        }
+
+        /**
          * Create a VPN interface using the parameters supplied to this
          * builder. The interface works on IP packets, and a file descriptor
          * is returned for the application to access them. Each read
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d6ec30b..bbaf1c1 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2496,6 +2496,12 @@
         public static final String POINTER_SPEED = "pointer_speed";
 
         /**
+         * Whether lock-to-app will be triggered by long-press on recents.
+         * @hide
+         */
+        public static final String LOCK_TO_APP_ENABLED = "lock_to_app_enabled";
+
+        /**
          * Whether lock-to-app will lock the keyguard when exiting.
          * @hide
          */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 8cb7702..a5899de 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -10762,7 +10762,11 @@
         }
     }
 
-    /** Deprecated, pending removal */
+    /**
+     * Deprecated, pending removal
+     *
+     * @hide
+     */
     @Deprecated
     public void setOutline(@Nullable Outline outline) {}
 
@@ -10843,16 +10847,8 @@
             // no provider, remove outline
             mRenderNode.setOutline(null);
         } else {
-            if (mOutlineProvider.getOutline(this, outline)) {
-                if (outline.isEmpty()) {
-                    throw new IllegalStateException("Outline provider failed to build outline");
-                }
-                // provider has provided
-                mRenderNode.setOutline(outline);
-            } else {
-                // provider failed to provide
-                mRenderNode.setOutline(null);
-            }
+            mOutlineProvider.getOutline(this, outline);
+            mRenderNode.setOutline(outline);
         }
 
         notifySubtreeAccessibilityStateChangedIfNeeded();
diff --git a/core/java/android/view/ViewOutlineProvider.java b/core/java/android/view/ViewOutlineProvider.java
index 9c154d5..64624ae 100644
--- a/core/java/android/view/ViewOutlineProvider.java
+++ b/core/java/android/view/ViewOutlineProvider.java
@@ -31,13 +31,11 @@
      */
     public static final ViewOutlineProvider BACKGROUND = new ViewOutlineProvider() {
         @Override
-        public boolean getOutline(View view, Outline outline) {
+        public void getOutline(View view, Outline outline) {
             Drawable background = view.getBackground();
-            if (background == null) {
-                // no background, no outline
-                return false;
+            if (background != null) {
+                background.getOutline(outline);
             }
-            return background.getOutline(outline);
         }
     };
 
@@ -50,8 +48,6 @@
      *
      * @param view The view building the outline.
      * @param outline The empty outline to be populated.
-     * @return true if this View should have an outline, else false. The outline must be
-     *         populated by this method, and non-empty if true is returned.
      */
-    public abstract boolean getOutline(View view, Outline outline);
+    public abstract void getOutline(View view, Outline outline);
 }
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index a1a64f8..780715c 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -22,6 +22,8 @@
 import android.util.Log;
 
 public class ChooserActivity extends ResolverActivity {
+    private Bundle mReplacementExtras;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         Intent intent = getIntent();
@@ -34,14 +36,9 @@
         }
         Intent target = (Intent)targetParcelable;
         if (target != null) {
-            final String action = target.getAction();
-            if (Intent.ACTION_SEND.equals(action) ||
-                    Intent.ACTION_SEND_MULTIPLE.equals(action)) {
-                target.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
-                        Intent.FLAG_ACTIVITY_MULTIPLE_TASK |
-                        Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS);
-            }
+            modifyTargetIntent(target);
         }
+        mReplacementExtras = intent.getBundleExtra(Intent.EXTRA_REPLACEMENT_EXTRAS);
         CharSequence title = intent.getCharSequenceExtra(Intent.EXTRA_TITLE);
         int defaultTitleRes = 0;
         if (title == null) {
@@ -59,17 +56,33 @@
                     return;
                 }
                 final Intent in = (Intent) pa[i];
-                final String action = in.getAction();
-                if (Intent.ACTION_SEND.equals(action) ||
-                        Intent.ACTION_SEND_MULTIPLE.equals(action)) {
-                    in.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
-                            Intent.FLAG_ACTIVITY_MULTIPLE_TASK |
-                            Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS);
-                }
+                modifyTargetIntent(in);
                 initialIntents[i] = in;
             }
         }
         super.onCreate(savedInstanceState, target, title, defaultTitleRes, initialIntents,
                 null, false);
     }
+
+    public Intent getReplacementIntent(String packageName, Intent defIntent) {
+        if (mReplacementExtras != null) {
+            final Bundle replExtras = mReplacementExtras.getBundle(packageName);
+            if (replExtras != null) {
+                final Intent result = new Intent(defIntent);
+                result.putExtras(replExtras);
+                return result;
+            }
+        }
+        return defIntent;
+    }
+
+    private void modifyTargetIntent(Intent in) {
+        final String action = in.getAction();
+        if (Intent.ACTION_SEND.equals(action) ||
+                Intent.ACTION_SEND_MULTIPLE.equals(action)) {
+            in.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
+                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK |
+                    Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS);
+        }
+    }
 }
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 76ce765..fdb305d 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -18,7 +18,6 @@
 
 import android.app.Activity;
 import android.os.AsyncTask;
-import android.util.ArrayMap;
 import android.widget.AbsListView;
 import android.widget.GridView;
 import com.android.internal.R;
@@ -60,6 +59,7 @@
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -428,6 +428,13 @@
         finish();
     }
 
+    /**
+     * Replace me in subclasses!
+     */
+    public Intent getReplacementIntent(String packageName, Intent defIntent) {
+        return defIntent;
+    }
+
     protected void onIntentSelected(ResolveInfo ri, Intent intent, boolean alwaysCheck) {
         if ((mAlwaysUseOption || mAdapter.hasFilteredItem()) && mAdapter.mOrigResolveList != null) {
             // Build a reasonable intent filter, based on what matched.
@@ -807,9 +814,9 @@
 
         public Intent intentForPosition(int position, boolean filtered) {
             DisplayResolveInfo dri = filtered ? getItem(position) : mList.get(position);
-            
-            Intent intent = new Intent(dri.origIntent != null
-                    ? dri.origIntent : mIntent);
+
+            Intent intent = new Intent(dri.origIntent != null ? dri.origIntent :
+                    getReplacementIntent(dri.ri.activityInfo.packageName, mIntent));
             intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT
                     |Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
             ActivityInfo ai = dri.ri.activityInfo;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ba65d63..fc55116 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -677,18 +677,18 @@
         android:description="@string/permdesc_addVoicemail" />
 
     <!-- Allows an application to modify and remove existing voicemails in the system -->
-    <permission android:name="com.android.voicemail.permission.MANAGE_VOICEMAIL"
+    <permission android:name="com.android.voicemail.permission.WRITE_VOICEMAIL"
         android:permissionGroup="android.permission-group.VOICEMAIL"
         android:protectionLevel="dangerous"
-        android:label="@string/permlab_manageVoicemail"
-        android:description="@string/permdesc_manageVoicemail" />
+        android:label="@string/permlab_writeVoicemail"
+        android:description="@string/permdesc_writeVoicemail" />
 
-    <!-- Allows an application to read all the voicemails in the system. -->
-    <permission android:name="com.android.voicemail.permission.READ_ALL_VOICEMAIL"
+    <!-- Allows an application to read voicemails in the system. -->
+    <permission android:name="com.android.voicemail.permission.READ_VOICEMAIL"
         android:permissionGroup="android.permission-group.VOICEMAIL"
         android:protectionLevel="dangerous"
-        android:label="@string/permlab_readAllVoicemail"
-        android:description="@string/permdesc_readAllVoicemail" />
+        android:label="@string/permlab_readVoicemail"
+        android:description="@string/permdesc_readVoicemail" />
 
     <!-- =============================================== -->
     <!-- Permissions for enabling accessibility features -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index f133707..0d9da35 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2983,11 +2983,11 @@
     <!-- Title of an application permission, listed so the user can choose whether
         they want to allow the application to modify and remove voicemails in the user's voicemail
         inbox. [CHAR LIMIT=NONE] -->
-    <string name="permlab_manageVoicemail">manage voicemails</string>
+    <string name="permlab_writeVoicemail">write voicemails</string>
     <!-- Description of an application permission, listed so the user can choose whether
         they want to allow the application to modify and remove voicemails in the user's voicemail
         inbox. [CHAR LIMIT=NONE] -->
-    <string name="permdesc_manageVoicemail">Allows the app to modify and remove messages from your voicemail inbox.</string>
+    <string name="permdesc_writeVoicemail">Allows the app to modify and remove messages from your voicemail inbox.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether
         they want to allow the application to do this. [CHAR LIMIT=NONE] -->
@@ -2999,10 +2999,10 @@
 
     <!-- Title of an application permission, listed so the user can choose whether
         they want to allow the application to do this. [CHAR LIMIT=NONE] -->
-    <string name="permlab_readAllVoicemail">read all voicemail</string>
+    <string name="permlab_readVoicemail">read voicemail</string>
     <!-- Description of an application permission, listed so the user can choose whether
         they want to allow the application to do this. [CHAR LIMIT=NONE] -->
-    <string name="permdesc_readAllVoicemail">Allows the app to read all your voicemails.</string>
+    <string name="permdesc_readVoicemail">Allows the app to read your voicemails.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether
         they want to allow the application to do this. -->
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
index 22dce39..411a3f8 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
@@ -20,6 +20,8 @@
 import android.content.Context;
 import android.os.Bundle;
 
+import junit.framework.Assert;
+
 import java.util.Set;
 
 public class BluetoothInstrumentation extends Instrumentation {
@@ -70,6 +72,8 @@
             getAddress();
         } else if ("getBondedDevices".equals(command)) {
             getBondedDevices();
+        } else if ("enableBtSnoop".equals(command)) {
+            enableBtSnoop();
         } else {
             finish(null);
         }
@@ -112,6 +116,12 @@
         finish(mSuccessResult);
     }
 
+    public void enableBtSnoop() {
+        Assert.assertTrue("failed to enable snoop log",
+                getBluetoothAdapter().configHciSnoopLog(true));
+        finish(mSuccessResult);
+    }
+
     public void finish(Bundle result) {
         if (result == null) {
             result = new Bundle();
diff --git a/docs/html/training/game-controllers/controller-input.jd b/docs/html/training/game-controllers/controller-input.jd
index c9517ba..25fcde4 100644
--- a/docs/html/training/game-controllers/controller-input.jd
+++ b/docs/html/training/game-controllers/controller-input.jd
@@ -39,14 +39,15 @@
 {@link android.app.Activity} or focused {@link android.view.View} (you should
 implement the callbacks for either the {@link android.app.Activity} or
 {@link android.view.View}, but not both): </p>
-
 <ul>
 <li>From {@link android.app.Activity}:
     <ul>
-    <li>{@link android.app.Activity#dispatchGenericMotionEvent(android.view.MotionEvent) dispatchGenericMotionEvent(android.view.MotionEvent)}
+    <li>{@link android.app.Activity#dispatchGenericMotionEvent(android.view.MotionEvent)
+      dispatchGenericMotionEvent(android.view. MotionEvent)}
         <p>Called to process generic motion events such as joystick movements.</p>
     </li>
-    <li>{@link android.app.Activity#dispatchKeyEvent(android.view.KeyEvent) dispatchKeyEvent(android.view.KeyEvent)}
+    <li>{@link android.app.Activity#dispatchKeyEvent(android.view.KeyEvent)
+      dispatchKeyEvent(android.view.KeyEvent)}
         <p>Called to process key events such as a press or release of a
           gamepad or D-pad button.</p>
     </li>
@@ -244,16 +245,18 @@
       and {@link android.view.KeyEvent#KEYCODE_MENU}<sup>*</sup></td>
   </tr>
   <tr>
-    <td>Same as Android <em>Back</em></td>
+    <td>Same as Android <em>Back</em> navigation behavior described in the
+      <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> design
+      guide.</td>
     <td>{@link android.view.KeyEvent#KEYCODE_BACK KEYCODE_BACK}</td>
   </tr>
   <tr>
     <td>Navigate back to a previous item in a menu</td>
-    <td>{@link android.view.KeyEvent#KEYCODE_BUTTON_B BUTTON_B}<sup>**</sup></td>
+    <td>{@link android.view.KeyEvent#KEYCODE_BUTTON_B BUTTON_B}</td>
   </tr>
   <tr>
     <td>Confirm selection, or perform primary game action</td>
-    <td>{@link android.view.KeyEvent#KEYCODE_BUTTON_A BUTTON_A}<sup>**</sup> and
+    <td>{@link android.view.KeyEvent#KEYCODE_BUTTON_A BUTTON_A} and
 {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER DPAD_CENTER}</td>
   </tr>
 </table>
@@ -261,10 +264,6 @@
 <em>* Your game should not rely on the presence of the Start, Select, or Menu
   buttons.</em>
 </p>
-<p>
-<em>** This could be the opposite button (A/B), depending on the locale that
-you are supporting.</em>
-</p>
 
 <p class="note"><strong>Tip: </strong>Consider providing a configuration screen
 in your game to allow users to personalize their own game controller mappings for
@@ -309,41 +308,22 @@
 
     private static boolean isFireKey(int keyCode) {
         // Here we treat Button_A and DPAD_CENTER as the primary action
-        // keys for the game. You may need to switch this to Button_B and
-        // DPAD_CENTER depending on the user expectations for the locale
-        // in which your game runs.
+        // keys for the game.
         return keyCode == KeyEvent.KEYCODE_DPAD_CENTER
                 || keyCode == KeyEvent.KEYCODE_BUTTON_A;
     }
 }
 </pre>
 
-<p>Follow these best practices when handling button presses:</p>
-<ul>
-<li><strong>Provide localized button mappings.</strong> Generally, if your game
-has a primary gameplay action (for example, it fires lasers, lets your avatar
-do a high jump, or confirms an item selection), you should map
-both {@link android.view.KeyEvent#KEYCODE_DPAD_CENTER DPAD_CENTER} and
-{@link android.view.KeyEvent#KEYCODE_BUTTON_A BUTTON_A} to this action. However,
-in some locales, users may expect
-{@link android.view.KeyEvent#KEYCODE_BUTTON_B BUTTON_B} to be the confirm
-button and {@link android.view.KeyEvent#KEYCODE_BUTTON_A BUTTON_A} to be the
-back button instead. If you are supporting these locales, make sure to treat
-the A and B buttons accordingly in your game. To determine the user's locale,
-call the {@link java.util.Locale#getDefault()} method.
-<li><strong>Map {@link android.view.KeyEvent#KEYCODE_BUTTON_A BUTTON_A}
-consistently across different Android versions.</strong> On Android 4.2 (API
+<p class="note"><strong>Note: </strong>On Android 4.2 (API
 level 17) and lower, the system treats
 {@link android.view.KeyEvent#KEYCODE_BUTTON_A BUTTON_A} as the Android
 <em>Back</em> key by default. If your app supports these Android
 versions, make sure to treat
 {@link android.view.KeyEvent#KEYCODE_BUTTON_A BUTTON_A} as the primary game
-action (except in the localization case mentioned
-above). To determine the current Android SDK
+action. To determine the current Android SDK
 version on the device, refer to the
-{@link android.os.Build.VERSION#SDK_INT Build.VERSION.SDK_INT} value.
-</li>
-</ul>
+{@link android.os.Build.VERSION#SDK_INT Build.VERSION.SDK_INT} value.</p>
 
 <h2 id="dpad">Process Directional Pad Input</h2>
 <p>The 4-way directional pad (D-pad) is a common physical control in many game
@@ -424,7 +404,7 @@
             // UP and DOWN direction accordingly.
             else if (Float.compare(yaxis, -1.0f) == 0) {
                 directionPressed =  Dpad.UP;
-            } else if (Float.compare(yaxis, -1.0f) == 0) {
+            } else if (Float.compare(yaxis, 1.0f) == 0) {
                 directionPressed =  Dpad.DOWN;
             }
         }
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
index 4bee554..1709558 100644
--- a/graphics/java/android/graphics/Outline.java
+++ b/graphics/java/android/graphics/Outline.java
@@ -96,6 +96,8 @@
      *
      * A filled outline is assumed, by the drawing system, to fully cover content beneath it,
      * meaning content beneath may be optimized away.
+     *
+     * @hide
      */
     public void setFilled(boolean isFilled) {
         mIsFilled = isFilled;
@@ -103,6 +105,8 @@
 
     /**
      * Returns whether the outline represents a fully opaque area.
+     *
+     * @hide
      */
     public boolean isFilled() {
         return !isEmpty() && mIsFilled;
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 89236ad..acb34c2 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -869,9 +869,8 @@
      *
      * @see android.view.View#setOutlineProvider(android.view.ViewOutlineProvider)
      */
-    public boolean getOutline(@NonNull Outline outline) {
+    public void getOutline(@NonNull Outline outline) {
         outline.setRect(getBounds());
-        return true;
     }
 
     /**
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 771322d..55bc35e 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -126,11 +126,10 @@
     }
 
     @Override
-    public boolean getOutline(@NonNull Outline outline) {
+    public void getOutline(@NonNull Outline outline) {
         if (mCurrDrawable != null) {
-            return mCurrDrawable.getOutline(outline);
+            mCurrDrawable.getOutline(outline);
         }
-        return false;
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 6e9b776..4815586 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -1410,7 +1410,7 @@
     }
 
     @Override
-    public boolean getOutline(Outline outline) {
+    public void getOutline(Outline outline) {
         final GradientState st = mGradientState;
         final Rect bounds = getBounds();
 
@@ -1419,7 +1419,7 @@
                 if (st.mRadiusArray != null) {
                     buildPathIfDirty();
                     outline.setConvexPath(mPath);
-                    return true;
+                    return;
                 }
 
                 float rad = 0;
@@ -1429,10 +1429,10 @@
                             Math.min(bounds.width(), bounds.height()) * 0.5f);
                 }
                 outline.setRoundRect(bounds, rad);
-                return true;
+                return;
             case OVAL:
                 outline.setOval(bounds);
-                return true;
+                return;
             case LINE:
                 // Hairlines (0-width stroke) must have a non-empty outline for
                 // shadows to draw correctly, so we'll use a very small width.
@@ -1443,10 +1443,9 @@
                 final int bottom = (int) Math.ceil(centerY + halfStrokeWidth);
 
                 outline.setRect(bounds.left, top, bounds.right, bottom);
-                return true;
+                return;
             default:
-                // TODO: investigate
-                return false;
+                // TODO: support more complex shapes
         }
     }
 
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index 6db96b6..f6ccbf5 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -316,8 +316,8 @@
     }
 
     @Override
-    public boolean getOutline(@NonNull Outline outline) {
-        return mInsetState.mDrawable.getOutline(outline);
+    public void getOutline(@NonNull Outline outline) {
+        mInsetState.mDrawable.getOutline(outline);
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 8d83c74..073100a 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -603,16 +603,16 @@
      * @return <code>true</code> if an outline is available
      */
     @Override
-    public boolean getOutline(@NonNull Outline outline) {
+    public void getOutline(@NonNull Outline outline) {
         final LayerState state = mLayerState;
         final ChildDrawable[] children = state.mChildren;
         final int N = state.mNum;
         for (int i = 0; i < N; i++) {
-            if (children[i].mDrawable.getOutline(outline)) {
-                return true;
+            children[i].mDrawable.getOutline(outline);
+            if (!outline.isEmpty()) {
+                return;
             }
         }
-        return false;
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index c0110c9..241ec65 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -284,9 +284,9 @@
     }
 
     @Override
-    public boolean getOutline(@NonNull Outline outline) {
+    public void getOutline(@NonNull Outline outline) {
         final Rect bounds = getBounds();
-        if (bounds.isEmpty()) return false;
+        if (bounds.isEmpty()) return;
 
         if (mNinePatchState != null) {
             NinePatch.InsetStruct insets = mNinePatchState.getBitmap().getNinePatchInsets();
@@ -298,10 +298,10 @@
                         bounds.bottom - outlineInsets.bottom,
                         insets.outlineRadius);
                 outline.setFilled(insets.outlineFilled);
-                return true;
+                return;
             }
         }
-        return super.getOutline(outline);
+        super.getOutline(outline);
     }
 
     /**
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index f955f7c..4a1d640 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -497,16 +497,16 @@
      * @return <code>true</code> if an outline is available
      */
     @Override
-    public boolean getOutline(@NonNull Outline outline) {
+    public void getOutline(@NonNull Outline outline) {
         final LayerState state = mLayerState;
         final ChildDrawable[] children = state.mChildren;
         final int N = state.mNum;
         for (int i = 0; i < N; i++) {
-            if (children[i].mId != R.id.mask && children[i].mDrawable.getOutline(outline)) {
-                return true;
+            if (children[i].mId != R.id.mask) {
+                children[i].mDrawable.getOutline(outline);
+                if (!outline.isEmpty()) return;
             }
         }
-        return false;
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 9802529..2bed3b0 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -467,13 +467,10 @@
     }
 
     @Override
-    public boolean getOutline(Outline outline) {
-        if (mShapeState.mShape == null) {
-            // don't publish outline without a shape
-            return false;
+    public void getOutline(Outline outline) {
+        if (mShapeState.mShape != null) {
+            mShapeState.mShape.getOutline(outline);
         }
-
-        return mShapeState.mShape.getOutline(outline);
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/shapes/OvalShape.java b/graphics/java/android/graphics/drawable/shapes/OvalShape.java
index 198dcc1..c9473f0 100644
--- a/graphics/java/android/graphics/drawable/shapes/OvalShape.java
+++ b/graphics/java/android/graphics/drawable/shapes/OvalShape.java
@@ -29,22 +29,18 @@
  */
 public class OvalShape extends RectShape {
 
-    /**
-     * OvalShape constructor.
-     */
     public OvalShape() {}
-    
+
     @Override
     public void draw(Canvas canvas, Paint paint) {
         canvas.drawOval(rect(), paint);
     }
 
     @Override
-    public boolean getOutline(Outline outline) {
+    public void getOutline(Outline outline) {
         final RectF rect = rect();
         outline.setOval((int) Math.ceil(rect.left), (int) Math.ceil(rect.top),
                 (int) Math.floor(rect.right), (int) Math.floor(rect.bottom));
-        return true;
     }
 }
 
diff --git a/graphics/java/android/graphics/drawable/shapes/RectShape.java b/graphics/java/android/graphics/drawable/shapes/RectShape.java
index 2a0256c..04cf293 100644
--- a/graphics/java/android/graphics/drawable/shapes/RectShape.java
+++ b/graphics/java/android/graphics/drawable/shapes/RectShape.java
@@ -29,10 +29,7 @@
  */
 public class RectShape extends Shape {
     private RectF mRect = new RectF();
-    
-    /**
-     * RectShape constructor.
-     */
+
     public RectShape() {}
     
     @Override
@@ -41,11 +38,10 @@
     }
 
     @Override
-    public boolean getOutline(Outline outline) {
+    public void getOutline(Outline outline) {
         final RectF rect = rect();
         outline.setRect((int) Math.ceil(rect.left), (int) Math.ceil(rect.top),
                 (int) Math.floor(rect.right), (int) Math.floor(rect.bottom));
-        return true;
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java b/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java
index a6bb1bb..e5253b8 100644
--- a/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java
+++ b/graphics/java/android/graphics/drawable/shapes/RoundRectShape.java
@@ -80,8 +80,8 @@
     }
 
     @Override
-    public boolean getOutline(Outline outline) {
-        if (mInnerRect != null) return false; // have a hole, can't produce valid outline
+    public void getOutline(Outline outline) {
+        if (mInnerRect != null) return; // have a hole, can't produce valid outline
 
         float radius = 0;
         if (mOuterRadii != null) {
@@ -90,7 +90,7 @@
                 if (mOuterRadii[i] != radius) {
                     // can't call simple constructors, use path
                     outline.setConvexPath(mPath);
-                    return true;
+                    return;
                 }
             }
         }
@@ -99,7 +99,6 @@
         outline.setRoundRect((int) Math.ceil(rect.left), (int) Math.ceil(rect.top),
                 (int) Math.floor(rect.right), (int) Math.floor(rect.bottom),
                 radius);
-        return true;
     }
 
     @Override
diff --git a/graphics/java/android/graphics/drawable/shapes/Shape.java b/graphics/java/android/graphics/drawable/shapes/Shape.java
index 1a20e8b..589fbaa 100644
--- a/graphics/java/android/graphics/drawable/shapes/Shape.java
+++ b/graphics/java/android/graphics/drawable/shapes/Shape.java
@@ -96,12 +96,8 @@
      * Compute the Outline of the shape.
      *
      * The default implementation does not supply an outline.
-     *
-     * @return True if a valid outline has been computed, false otherwise.
      */
-    public boolean getOutline(Outline outline) {
-        return false;
-    }
+    public void getOutline(Outline outline) {}
 
     @Override
     public Shape clone() throws CloneNotSupportedException {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index ef95c11..5dc59f9 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1341,6 +1341,7 @@
     }
 
     /**
+     * @hide
      * Start bluetooth SCO audio connection in virtual call mode.
      * <p>Requires Permission:
      *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
@@ -1368,12 +1369,11 @@
      * <p>Requires Permission:
      *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
      * <p>This method must be called by applications having requested the use of
-     * bluetooth SCO audio with {@link #startBluetoothSco()} or
-     * {@link #startBluetoothScoVirtualCall()} when finished with the SCO connection or
-     * if connection fails.
+     * bluetooth SCO audio with {@link #startBluetoothSco()} when finished with the SCO
+     * connection or if connection fails.
      * @see #startBluetoothSco()
-     * @see #startBluetoothScoVirtualCall()
      */
+    // Also used for connections started with {@link #startBluetoothScoVirtualCall()}
     public void stopBluetoothSco(){
         IAudioService service = getService();
         try {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index b6d7d7e..66e5d14 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -84,7 +84,7 @@
         mContext = context;
         mSystemServicesProxy = new SystemServicesProxy(context);
         mHandler = new Handler();
-        mConfig = RecentsConfiguration.reinitialize(context);
+        mConfig = RecentsConfiguration.reinitialize(context, mSystemServicesProxy);
         mWindowRect = mSystemServicesProxy.getWindowRect();
         mTaskStackBounds = new Rect();
         mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mTaskStackBounds);
@@ -147,7 +147,7 @@
     }
 
     public void onConfigurationChanged(Configuration newConfig) {
-        mConfig = RecentsConfiguration.reinitialize(mContext);
+        mConfig = RecentsConfiguration.reinitialize(mContext, mSystemServicesProxy);
         mConfig.updateOnConfigurationChange();
         mWindowRect = mSystemServicesProxy.getWindowRect();
         mConfig.getTaskStackBounds(mWindowRect.width(), mWindowRect.height(), mTaskStackBounds);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 29a0262..5741f22 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -340,7 +340,8 @@
 
         // Initialize the loader and the configuration
         RecentsTaskLoader.initialize(this);
-        mConfig = RecentsConfiguration.reinitialize(this);
+        mConfig = RecentsConfiguration.reinitialize(this,
+                RecentsTaskLoader.getInstance().getSystemServicesProxy());
 
         // Create the home intent runnable
         Intent homeIntent = new Intent(Intent.ACTION_MAIN, null);
@@ -405,7 +406,8 @@
 
     void onConfigurationChange() {
         // Update RecentsConfiguration
-        mConfig = RecentsConfiguration.reinitialize(this);
+        mConfig = RecentsConfiguration.reinitialize(this,
+                RecentsTaskLoader.getInstance().getSystemServicesProxy());
 
         // Try and start the enter animation (or restart it on configuration changed)
         ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 439765e..a0cab5c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -29,6 +29,7 @@
 import android.view.animation.Interpolator;
 import com.android.systemui.R;
 import com.android.systemui.recents.misc.Console;
+import com.android.systemui.recents.misc.SystemServicesProxy;
 
 
 /** A static Recents configuration for the current context
@@ -109,7 +110,8 @@
     public boolean launchedFromHome;
     public int launchedToTaskId;
 
-    /** Dev options */
+    /** Dev options and global settings */
+    public boolean lockToAppEnabled;
     public boolean developerOptionsEnabled;
     public boolean debugModeEnabled;
 
@@ -127,15 +129,10 @@
                 com.android.internal.R.interpolator.linear_out_slow_in);
         quintOutInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.decelerate_quint);
-
-        // Check if the developer options are enabled
-        ContentResolver cr = context.getContentResolver();
-        developerOptionsEnabled = Settings.Global.getInt(cr,
-                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0;
     }
 
     /** Updates the configuration to the current context */
-    public static RecentsConfiguration reinitialize(Context context) {
+    public static RecentsConfiguration reinitialize(Context context, SystemServicesProxy ssp) {
         if (sInstance == null) {
             sInstance = new RecentsConfiguration(context);
         }
@@ -144,6 +141,7 @@
             sInstance.update(context);
             sPrevConfigurationHashCode = configHashCode;
         }
+        sInstance.updateOnReinitialize(context, ssp);
         return sInstance;
     }
 
@@ -260,6 +258,15 @@
                 appWidgetId).apply();
     }
 
+    /** Updates the states that need to be re-read whenever we re-initialize. */
+    void updateOnReinitialize(Context context, SystemServicesProxy ssp) {
+        // Check if the developer options are enabled
+        developerOptionsEnabled = ssp.getGlobalSetting(context,
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED) != 0;
+        lockToAppEnabled = ssp.getSystemSetting(context,
+                Settings.System.LOCK_TO_APP_ENABLED) != 0;
+    }
+
     /** Called when the configuration has changed, and we want to reset any configuration specific
      * members. */
     public void updateOnConfigurationChange() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index ced4043..5fadc71 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -26,6 +26,7 @@
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -47,6 +48,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.util.Log;
 import android.util.Pair;
 import android.view.Display;
@@ -413,6 +415,22 @@
     }
 
     /**
+     * Returns a global setting.
+     */
+    public int getGlobalSetting(Context context, String setting) {
+        ContentResolver cr = context.getContentResolver();
+        return Settings.Global.getInt(cr, setting, 0);
+    }
+
+    /**
+     * Returns a system setting.
+     */
+    public int getSystemSetting(Context context, String setting) {
+        ContentResolver cr = context.getContentResolver();
+        return Settings.System.getInt(cr, setting, 0);
+    }
+
+    /**
      * Returns the window rect.
      */
     public Rect getWindowRect() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index adf0794..9325947 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -27,6 +27,9 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.UserHandle;
+import android.provider.Settings;
+import android.provider.Settings.SettingNotFoundException;
+
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -340,7 +343,7 @@
             // Create a new task
             Task task = new Task(t.persistentId, (t.id > -1), t.baseIntent, t.affiliatedTaskId,
                     activityLabel, activityIcon, activityColor, t.userId, t.firstActiveTime,
-                    t.lastActiveTime, (i == (taskCount - 1)));
+                    t.lastActiveTime, (i == (taskCount - 1)), config.lockToAppEnabled);
 
             // Preload the specified number of apps
             if (i >= (taskCount - preloadCount)) {
@@ -395,6 +398,7 @@
 
     /** Creates a lightweight stack of the current recent tasks, without thumbnails and icons. */
     public static TaskStack getShallowTaskStack(SystemServicesProxy ssp) {
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
         List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(ssp);
         TaskStack stack = new TaskStack();
 
@@ -405,7 +409,8 @@
             if (info == null) continue;
 
             stack.addTask(new Task(t.persistentId, true, t.baseIntent, t.affiliatedTaskId, null,
-                    null, 0, 0, t.firstActiveTime, t.lastActiveTime, (i == (taskCount - 1))));
+                    null, 0, 0, t.firstActiveTime, t.lastActiveTime, (i == (taskCount - 1)),
+                    config.lockToAppEnabled));
         }
         stack.createAffiliatedGroupings();
         return stack;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 2473352..4cf9235 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -84,7 +84,8 @@
     public boolean useLightOnPrimaryColor;
     public Bitmap thumbnail;
     public boolean isActive;
-    public boolean canLockToTask;
+    public boolean lockToThisTask;
+    public boolean lockToTaskEnabled;
     public int userId;
 
     TaskCallbacks mCb;
@@ -95,7 +96,8 @@
 
     public Task(int id, boolean isActive, Intent intent, int taskAffiliation, String activityTitle,
                 Drawable activityIcon, int colorPrimary, int userId,
-                long firstActiveTime, long lastActiveTime, boolean canLockToTask) {
+                long firstActiveTime, long lastActiveTime, boolean lockToThisTask,
+                boolean lockToTaskEnabled) {
         this.key = new TaskKey(id, intent, userId, firstActiveTime, lastActiveTime);
         this.taskAffiliation = taskAffiliation;
         this.activityLabel = activityTitle;
@@ -104,7 +106,8 @@
         this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(colorPrimary,
                 Color.WHITE) > 3f;
         this.isActive = isActive;
-        this.canLockToTask = canLockToTask;
+        this.lockToThisTask = lockToTaskEnabled && lockToThisTask;
+        this.lockToTaskEnabled = lockToTaskEnabled;
         this.userId = userId;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index 13fbe64..fdc5775 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -17,6 +17,7 @@
 package com.android.systemui.recents.model;
 
 import com.android.systemui.recents.Constants;
+import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.misc.NamedCounter;
 
 import java.util.ArrayList;
@@ -204,10 +205,10 @@
                 removeGroup(group);
             }
             // Update the lock-to-app state
-            t.canLockToTask = false;
+            t.lockToThisTask = false;
             Task newFrontMostTask = getFrontMostTask();
-            if (newFrontMostTask != null) {
-                newFrontMostTask.canLockToTask = true;
+            if (newFrontMostTask != null && newFrontMostTask.lockToTaskEnabled) {
+                newFrontMostTask.lockToThisTask = true;
             }
             if (mCb != null) {
                 // Notify that a task has been removed
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 068cbfe..191dc37 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -356,7 +356,7 @@
         // Disallow touch events from this task view
         tv.setTouchEnabled(false);
         // Hide the footer
-        tv.animateFooterVisibility(false, mSv.mConfig.taskViewLockToAppShortAnimDuration, 0);
+        tv.animateFooterVisibility(false, mSv.mConfig.taskViewLockToAppShortAnimDuration);
         // Disallow parents from intercepting touch events
         final ViewParent parent = mSv.getParent();
         if (parent != null) {
@@ -396,7 +396,7 @@
         // Re-enable touch events from this task view
         tv.setTouchEnabled(true);
         // Restore the footer
-        tv.animateFooterVisibility(true, mSv.mConfig.taskViewLockToAppShortAnimDuration, 0);
+        tv.animateFooterVisibility(true, mSv.mConfig.taskViewLockToAppShortAnimDuration);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 199d3f3..4757c5f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -32,11 +32,9 @@
 import android.view.animation.AccelerateInterpolator;
 import android.widget.FrameLayout;
 import com.android.systemui.R;
-import com.android.systemui.recents.misc.Console;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.model.Task;
-import com.android.systemui.recents.model.TaskStack;
 
 
 /* A task view */
@@ -118,13 +116,12 @@
         setFooterHeight(getFooterHeight());
         setOutlineProvider(new ViewOutlineProvider() {
             @Override
-            public boolean getOutline(View view, Outline outline) {
+            public void getOutline(View view, Outline outline) {
                 // The current height is measured with the footer, so account for the footer height
                 // and the current clip (in the stack)
                 int height = getMeasuredHeight() - mClipFromBottom - mMaxFooterHeight + mFooterHeight;
                 outline.setRoundRect(0, 0, getWidth(), height,
                         mConfig.taskViewRoundedCornerRadiusPx);
-                return true;
             }
         });
     }
@@ -314,7 +311,7 @@
                         mBarView.startEnterRecentsAnimation(0, mEnableThumbnailClip);
                         setVisibility(View.VISIBLE);
                         // Animate the footer into view
-                        animateFooterVisibility(true, mConfig.taskBarEnterAnimDuration, 0);
+                        animateFooterVisibility(true, mConfig.taskBarEnterAnimDuration);
                         // Decrement the post animation trigger
                         ctx.postAnimationTrigger.decrement();
                     }
@@ -363,8 +360,8 @@
                 ctx.postAnimationTrigger.increment();
 
                 // Animate the footer into view
-                animateFooterVisibility(true, mConfig.taskBarEnterAnimDuration,
-                        mConfig.taskBarEnterAnimDelay);
+                animateFooterVisibility(true, mConfig.taskBarEnterAnimDuration
+                );
             } else {
                 mEnableThumbnailClip.run();
             }
@@ -398,14 +395,14 @@
             ctx.postAnimationTrigger.increment();
 
             // Animate the footer into view
-            animateFooterVisibility(true, mConfig.taskViewEnterFromHomeDuration,
-                    mConfig.taskBarEnterAnimDelay);
+            animateFooterVisibility(true, mConfig.taskViewEnterFromHomeDuration
+            );
         } else {
             // Otherwise, just enable the thumbnail clip
             mEnableThumbnailClip.run();
 
             // Animate the footer into view
-            animateFooterVisibility(true, 0, 0);
+            animateFooterVisibility(true, 0);
         }
     }
 
@@ -555,8 +552,8 @@
     }
 
     /** Animates the footer into and out of view. */
-    public void animateFooterVisibility(boolean visible, int duration, int delay) {
-        if (!mTask.canLockToTask) {
+    public void animateFooterVisibility(boolean visible, int duration) {
+        if (!mTask.lockToThisTask) {
             if (mLockToAppButtonView.getVisibility() == View.VISIBLE) {
                 mLockToAppButtonView.setVisibility(View.INVISIBLE);
             }
@@ -684,9 +681,9 @@
         mTask.setCallbacks(this);
         if (getMeasuredWidth() == 0) {
             // If we haven't yet measured, we should just set the footer height with any animation
-            animateFooterVisibility(t.canLockToTask, 0, 0);
+            animateFooterVisibility(t.lockToThisTask, 0);
         } else {
-            animateFooterVisibility(t.canLockToTask, mConfig.taskViewLockToAppLongAnimDuration, 0);
+            animateFooterVisibility(t.lockToThisTask, mConfig.taskViewLockToAppLongAnimDuration);
         }
     }
 
@@ -754,7 +751,7 @@
                         }
                     });
                     // Hide the footer
-                    tv.animateFooterVisibility(false, mConfig.taskViewRemoveAnimDuration, 0);
+                    tv.animateFooterVisibility(false, mConfig.taskViewRemoveAnimDuration);
                 } else if (v == tv || v == mLockToAppButtonView) {
                     mCb.onTaskViewClicked(tv, tv.getTask(), (v == mLockToAppButtonView));
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
index d9719ea..d882a87 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableOutlineView.java
@@ -38,7 +38,7 @@
         mDensity = getResources().getDisplayMetrics().density;
         setOutlineProvider(new ViewOutlineProvider() {
             @Override
-            public boolean getOutline(View view, Outline outline) {
+            public void getOutline(View view, Outline outline) {
                 if (!mCustomOutline) {
                     outline.setRect(0,
                             mClipTopAmount,
@@ -47,7 +47,6 @@
                 } else {
                     outline.setRect(mOutlineRect);
                 }
-                return true;
             }
         });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 3012b13..b2709bc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -148,9 +148,8 @@
         });
         setOutlineProvider(new ViewOutlineProvider() {
             @Override
-            public boolean getOutline(View view, Outline outline) {
+            public void getOutline(View view, Outline outline) {
                 outline.setRect(mClipBounds);
-                return true;
             }
         });
     }
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 d232bc4..f3ff8ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -163,7 +163,7 @@
     private static final ViewOutlineProvider CONTENT_HOLDER_OUTLINE_PROVIDER =
             new ViewOutlineProvider() {
         @Override
-        public boolean getOutline(View view, Outline outline) {
+        public void getOutline(View view, Outline outline) {
             int outlineLeft = view.getPaddingLeft();
             int outlineTop = view.getPaddingTop();
 
@@ -171,7 +171,6 @@
             outline.setRect(outlineLeft, outlineTop,
                     view.getWidth() - outlineLeft - view.getPaddingRight(),
                     view.getHeight() - outlineTop - view.getPaddingBottom());
-            return true;
         }
     };
 
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index caae9f5..3b52baf 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -287,8 +287,8 @@
                 ArraySet<JobStatus> jobs = mJobs.getJobs();
                 for (int i=0; i<jobs.size(); i++) {
                     JobStatus job = jobs.valueAt(i);
-                    for (int j=0; j<mControllers.size(); j++) {
-                        mControllers.get(i).maybeStartTrackingJob(job);
+                    for (int controller=0; controller<mControllers.size(); controller++) {
+                        mControllers.get(controller).maybeStartTrackingJob(job);
                     }
                 }
                 // GO GO GO!
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index 5bf6124..76a826e 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -427,6 +427,12 @@
                         request.getCallId());
                 mAdapter.handleCreateConnectionSuccessful(request);
                 addConnection(request.getCallId(), connection);
+
+                // TODO: onSuccess should pass through the entire state of the connection instead of
+                // having to set it like this afterwards.  Also, it would eliminate the hack of
+                // having to change the request object that we pass back.
+                mConnectionListener.onCallCapabilitiesChanged(
+                        connection, connection.getCallCapabilities());
             }
 
             @Override
diff --git a/telecomm/java/android/telecomm/PhoneAccount.java b/telecomm/java/android/telecomm/PhoneAccount.java
index bb335c3..edfd846 100644
--- a/telecomm/java/android/telecomm/PhoneAccount.java
+++ b/telecomm/java/android/telecomm/PhoneAccount.java
@@ -33,14 +33,6 @@
  * PhoneAccountMetadata.
  */
 public class PhoneAccount implements Parcelable {
-
-    /**
-     * Flag indicating that this {@code PhoneAccount} represents  built-in PSTN SIM subscription.
-     * <p>
-     * Only the android framework can set this capability on a phone account.
-     */
-    public static final int CAPABILITY_SIM_SUBSCRIPTION = 0x4;
-
     private ComponentName mComponentName;
     private String mId;
 
diff --git a/telecomm/java/android/telecomm/PhoneAccountMetadata.java b/telecomm/java/android/telecomm/PhoneAccountMetadata.java
index e5e41ff..8993170 100644
--- a/telecomm/java/android/telecomm/PhoneAccountMetadata.java
+++ b/telecomm/java/android/telecomm/PhoneAccountMetadata.java
@@ -57,6 +57,13 @@
      */
     public static final int CAPABILITY_CALL_PROVIDER = 0x2;
 
+    /**
+     * Flag indicating that this {@code PhoneAccount} represents  built-in PSTN SIM subscription.
+     * <p>
+     * Only the android framework can set this capability on a phone account.
+     */
+    public static final int CAPABILITY_SIM_SUBSCRIPTION = 0x4;
+
     private final PhoneAccount mAccount;
     private final Uri mHandle;
     private final int mCapabilities;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 6e1ee78..9cff765 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2934,6 +2934,34 @@
     }
 
     /**
+     * Override the branding for the input ICCID.
+     *
+     * Once set, whenever the ICCID is inserted into the device, the service
+     * provider name (SPN) and the operator name will both be replaced by the
+     * brand value input. To unset the value, the same function should be
+     * called with a null brand value.
+     *
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+     *  or has to be carrier app - see #hasCarrierPrivileges.
+     *
+     * @param iccId The ICCID of that the branding applies to.
+     * @param brand The brand name to display/set.
+     * @return true if the operation was executed correctly.
+     */
+    public boolean setOperatorBrandOverride(String iccId, String brand) {
+        // TODO: Validate ICCID format.
+        try {
+            return getITelephony().setOperatorBrandOverride(iccId, brand);
+        } catch (RemoteException ex) {
+            Rlog.e(TAG, "setOperatorBrandOverride RemoteException", ex);
+        } catch (NullPointerException ex) {
+            Rlog.e(TAG, "setOperatorBrandOverride NPE", ex);
+        }
+        return false;
+    }
+
+    /**
      * Expose the rest of ITelephony to @SystemApi
      */
 
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d41ceda..435c334 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -706,5 +706,23 @@
      *         not set.
      */
     String getLine1AlphaTagForDisplay(long subId);
+
+    /**
+     * Override the operator branding for the input ICCID.
+     *
+     * Once set, whenever the ICCID is inserted into the device, the service
+     * provider name (SPN) and the operator name will both be replaced by the
+     * brand value input. To unset the value, the same function should be
+     * called with a null brand value.
+     *
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+     *  or has to be carrier app - see #hasCarrierPrivileges.
+     *
+     * @param iccid The ICCID of that the branding applies to.
+     * @param brand The brand name to display/set.
+     * @return true if the operation was executed correctly.
+     */
+    boolean setOperatorBrandOverride(String iccId, String brand);
 }
 
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ClipOutlineActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipOutlineActivity.java
index af448e8e..23bb6b4 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ClipOutlineActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ClipOutlineActivity.java
@@ -25,6 +25,8 @@
 import android.graphics.Path;
 import android.graphics.Rect;
 import android.os.Bundle;
+import android.view.View;
+import android.view.ViewOutlineProvider;
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
@@ -58,11 +60,23 @@
 
     public static class RegionView extends FrameLayout {
         private float mClipPosition = 0.0f;
-        private Outline mOutline = new Outline();
         private Rect mRect = new Rect();
 
         public RegionView(Context c) {
             super(c);
+            setOutlineProvider(new ViewOutlineProvider() {
+
+                @Override
+                public void getOutline(View view, Outline outline) {
+                    int w = getWidth() / 2;
+                    int h = getHeight() / 2;
+
+                    mRect.set(0, 0, w, h);
+                    mRect.offset((int) (mClipPosition * w), getHeight() / 4);
+
+                    outline.setRoundRect(mRect, w / 2);
+                }
+            });
             setClipToOutline(true);
         }
 
@@ -72,14 +86,7 @@
 
         public void setClipPosition(float clipPosition) {
             mClipPosition = clipPosition;
-            int w = getWidth() / 2;
-            int h = getHeight() / 2;
-
-            mRect.set(0, 0, w, h);
-            mRect.offset((int) (clipPosition * w), getHeight() / 4);
-            mOutline.setRoundRect(mRect, w / 2);
-            setOutline(mOutline);
-            invalidate();
+            invalidateOutline();
         }
     }