Merge "Import translations. DO NOT MERGE"
diff --git a/api/current.txt b/api/current.txt
index 4aba4e9..e9b4b89 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5259,6 +5259,7 @@
     method public android.app.Notification.Builder extend(android.app.Notification.Builder);
     method public java.util.List<android.app.Notification.Action> getActions();
     method public android.graphics.Bitmap getBackground();
+    method public java.lang.String getBridgeTag();
     method public int getContentAction();
     method public int getContentIcon();
     method public int getContentIconGravity();
@@ -5277,6 +5278,7 @@
     method public java.util.List<android.app.Notification> getPages();
     method public boolean getStartScrollBottom();
     method public android.app.Notification.WearableExtender setBackground(android.graphics.Bitmap);
+    method public android.app.Notification.WearableExtender setBridgeTag(java.lang.String);
     method public android.app.Notification.WearableExtender setContentAction(int);
     method public android.app.Notification.WearableExtender setContentIcon(int);
     method public android.app.Notification.WearableExtender setContentIconGravity(int);
@@ -22587,8 +22589,8 @@
     method public int getRepeatMode();
     method public android.app.PendingIntent getSessionActivity();
     method public android.media.session.MediaSession.Token getSessionToken();
-    method public boolean getShuffleMode();
     method public android.media.session.MediaController.TransportControls getTransportControls();
+    method public boolean isShuffleModeEnabled();
     method public void registerCallback(android.media.session.MediaController.Callback);
     method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
     method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
@@ -22637,7 +22639,7 @@
     method public void sendCustomAction(java.lang.String, android.os.Bundle);
     method public void setRating(android.media.Rating);
     method public void setRepeatMode(int);
-    method public void setShuffleMode(boolean);
+    method public void setShuffleModeEnabled(boolean);
     method public void skipToNext();
     method public void skipToPrevious();
     method public void skipToQueueItem(long);
@@ -22666,7 +22668,7 @@
     method public void setRatingType(int);
     method public void setRepeatMode(int);
     method public void setSessionActivity(android.app.PendingIntent);
-    method public void setShuffleMode(boolean);
+    method public void setShuffleModeEnabled(boolean);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
@@ -22690,7 +22692,7 @@
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
     method public void onSetRepeatMode(int);
-    method public void onSetShuffleMode(boolean);
+    method public void onSetShuffleModeEnabled(boolean);
     method public void onSkipToNext();
     method public void onSkipToPrevious();
     method public void onSkipToQueueItem(long);
@@ -22752,7 +22754,7 @@
     field public static final long ACTION_SEEK_TO = 256L; // 0x100L
     field public static final long ACTION_SET_RATING = 128L; // 0x80L
     field public static final long ACTION_SET_REPEAT_MODE = 262144L; // 0x40000L
-    field public static final long ACTION_SET_SHUFFLE_MODE = 524288L; // 0x80000L
+    field public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 524288L; // 0x80000L
     field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
     field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
     field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
diff --git a/api/system-current.txt b/api/system-current.txt
index f213e26..4fc0c2b 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5406,6 +5406,7 @@
     method public android.app.Notification.Builder extend(android.app.Notification.Builder);
     method public java.util.List<android.app.Notification.Action> getActions();
     method public android.graphics.Bitmap getBackground();
+    method public java.lang.String getBridgeTag();
     method public int getContentAction();
     method public int getContentIcon();
     method public int getContentIconGravity();
@@ -5424,6 +5425,7 @@
     method public java.util.List<android.app.Notification> getPages();
     method public boolean getStartScrollBottom();
     method public android.app.Notification.WearableExtender setBackground(android.graphics.Bitmap);
+    method public android.app.Notification.WearableExtender setBridgeTag(java.lang.String);
     method public android.app.Notification.WearableExtender setContentAction(int);
     method public android.app.Notification.WearableExtender setContentIcon(int);
     method public android.app.Notification.WearableExtender setContentIconGravity(int);
@@ -24183,8 +24185,8 @@
     method public int getRepeatMode();
     method public android.app.PendingIntent getSessionActivity();
     method public android.media.session.MediaSession.Token getSessionToken();
-    method public boolean getShuffleMode();
     method public android.media.session.MediaController.TransportControls getTransportControls();
+    method public boolean isShuffleModeEnabled();
     method public void registerCallback(android.media.session.MediaController.Callback);
     method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
     method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
@@ -24233,7 +24235,7 @@
     method public void sendCustomAction(java.lang.String, android.os.Bundle);
     method public void setRating(android.media.Rating);
     method public void setRepeatMode(int);
-    method public void setShuffleMode(boolean);
+    method public void setShuffleModeEnabled(boolean);
     method public void skipToNext();
     method public void skipToPrevious();
     method public void skipToQueueItem(long);
@@ -24262,7 +24264,7 @@
     method public void setRatingType(int);
     method public void setRepeatMode(int);
     method public void setSessionActivity(android.app.PendingIntent);
-    method public void setShuffleMode(boolean);
+    method public void setShuffleModeEnabled(boolean);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
@@ -24286,7 +24288,7 @@
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
     method public void onSetRepeatMode(int);
-    method public void onSetShuffleMode(boolean);
+    method public void onSetShuffleModeEnabled(boolean);
     method public void onSkipToNext();
     method public void onSkipToPrevious();
     method public void onSkipToQueueItem(long);
@@ -24348,7 +24350,7 @@
     field public static final long ACTION_SEEK_TO = 256L; // 0x100L
     field public static final long ACTION_SET_RATING = 128L; // 0x80L
     field public static final long ACTION_SET_REPEAT_MODE = 262144L; // 0x40000L
-    field public static final long ACTION_SET_SHUFFLE_MODE = 524288L; // 0x80000L
+    field public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 524288L; // 0x80000L
     field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
     field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
     field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
diff --git a/api/test-current.txt b/api/test-current.txt
index d4a8018..986c416 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5262,6 +5262,7 @@
     method public android.app.Notification.Builder extend(android.app.Notification.Builder);
     method public java.util.List<android.app.Notification.Action> getActions();
     method public android.graphics.Bitmap getBackground();
+    method public java.lang.String getBridgeTag();
     method public int getContentAction();
     method public int getContentIcon();
     method public int getContentIconGravity();
@@ -5280,6 +5281,7 @@
     method public java.util.List<android.app.Notification> getPages();
     method public boolean getStartScrollBottom();
     method public android.app.Notification.WearableExtender setBackground(android.graphics.Bitmap);
+    method public android.app.Notification.WearableExtender setBridgeTag(java.lang.String);
     method public android.app.Notification.WearableExtender setContentAction(int);
     method public android.app.Notification.WearableExtender setContentIcon(int);
     method public android.app.Notification.WearableExtender setContentIconGravity(int);
@@ -22659,8 +22661,8 @@
     method public int getRepeatMode();
     method public android.app.PendingIntent getSessionActivity();
     method public android.media.session.MediaSession.Token getSessionToken();
-    method public boolean getShuffleMode();
     method public android.media.session.MediaController.TransportControls getTransportControls();
+    method public boolean isShuffleModeEnabled();
     method public void registerCallback(android.media.session.MediaController.Callback);
     method public void registerCallback(android.media.session.MediaController.Callback, android.os.Handler);
     method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
@@ -22709,7 +22711,7 @@
     method public void sendCustomAction(java.lang.String, android.os.Bundle);
     method public void setRating(android.media.Rating);
     method public void setRepeatMode(int);
-    method public void setShuffleMode(boolean);
+    method public void setShuffleModeEnabled(boolean);
     method public void skipToNext();
     method public void skipToPrevious();
     method public void skipToQueueItem(long);
@@ -22738,7 +22740,7 @@
     method public void setRatingType(int);
     method public void setRepeatMode(int);
     method public void setSessionActivity(android.app.PendingIntent);
-    method public void setShuffleMode(boolean);
+    method public void setShuffleModeEnabled(boolean);
     field public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1; // 0x1
     field public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 2; // 0x2
   }
@@ -22762,7 +22764,7 @@
     method public void onSeekTo(long);
     method public void onSetRating(android.media.Rating);
     method public void onSetRepeatMode(int);
-    method public void onSetShuffleMode(boolean);
+    method public void onSetShuffleModeEnabled(boolean);
     method public void onSkipToNext();
     method public void onSkipToPrevious();
     method public void onSkipToQueueItem(long);
@@ -22824,7 +22826,7 @@
     field public static final long ACTION_SEEK_TO = 256L; // 0x100L
     field public static final long ACTION_SET_RATING = 128L; // 0x80L
     field public static final long ACTION_SET_REPEAT_MODE = 262144L; // 0x40000L
-    field public static final long ACTION_SET_SHUFFLE_MODE = 524288L; // 0x80000L
+    field public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 524288L; // 0x80000L
     field public static final long ACTION_SKIP_TO_NEXT = 32L; // 0x20L
     field public static final long ACTION_SKIP_TO_PREVIOUS = 16L; // 0x10L
     field public static final long ACTION_SKIP_TO_QUEUE_ITEM = 4096L; // 0x1000L
diff --git a/cmds/media/src/com/android/commands/media/Media.java b/cmds/media/src/com/android/commands/media/Media.java
index 2e9d0d6..0e0ecd0 100644
--- a/cmds/media/src/com/android/commands/media/Media.java
+++ b/cmds/media/src/com/android/commands/media/Media.java
@@ -230,8 +230,8 @@
         }
 
         @Override
-        public void onShuffleModeChanged(boolean shuffleMode) throws RemoteException {
-            System.out.println("onShuffleModeChanged " + shuffleMode);
+        public void onShuffleModeChanged(boolean enabled) throws RemoteException {
+            System.out.println("onShuffleModeChanged " + enabled);
         }
 
         void printUsageMessage() {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 2028572..26c8670 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5834,6 +5834,7 @@
         private static final String KEY_GRAVITY = "gravity";
         private static final String KEY_HINT_SCREEN_TIMEOUT = "hintScreenTimeout";
         private static final String KEY_DISMISSAL_ID = "dismissalId";
+        private static final String KEY_BRIDGE_TAG = "bridgeTag";
 
         // Flags bitwise-ored to mFlags
         private static final int FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE = 0x1;
@@ -5863,6 +5864,7 @@
         private int mGravity = DEFAULT_GRAVITY;
         private int mHintScreenTimeout;
         private String mDismissalId;
+        private String mBridgeTag;
 
         /**
          * Create a {@link android.app.Notification.WearableExtender} with default
@@ -5900,6 +5902,7 @@
                 mGravity = wearableBundle.getInt(KEY_GRAVITY, DEFAULT_GRAVITY);
                 mHintScreenTimeout = wearableBundle.getInt(KEY_HINT_SCREEN_TIMEOUT);
                 mDismissalId = wearableBundle.getString(KEY_DISMISSAL_ID);
+                mBridgeTag = wearableBundle.getString(KEY_BRIDGE_TAG);
             }
         }
 
@@ -5953,6 +5956,9 @@
             if (mDismissalId != null) {
                 wearableBundle.putString(KEY_DISMISSAL_ID, mDismissalId);
             }
+            if (mBridgeTag != null) {
+                wearableBundle.putString(KEY_BRIDGE_TAG, mBridgeTag);
+            }
 
             builder.getExtras().putBundle(EXTRA_WEARABLE_EXTENSIONS, wearableBundle);
             return builder;
@@ -5974,6 +5980,7 @@
             that.mGravity = this.mGravity;
             that.mHintScreenTimeout = this.mHintScreenTimeout;
             that.mDismissalId = this.mDismissalId;
+            that.mBridgeTag = this.mBridgeTag;
             return that;
         }
 
@@ -6462,12 +6469,11 @@
         }
 
         /**
-         * When you post a notification, if you set the dismissal id field, then when that
-         * notification is canceled, notifications on other wearables and the paired Android phone
-         * having that same dismissal id will also be canceled.  Note that this only works if you
-         * have notification bridge mode set to NO_BRIDGING in your Wear app manifest.  See
+         * Sets the dismissal id for this notification. If a notification is posted with a
+         * dismissal id, then when that notification is canceled, notifications on other wearables
+         * and the paired Android phone having that same dismissal id will also be canceled. See
          * <a href="{@docRoot}wear/notifications/index.html">Adding Wearable Features to
-         * Notifications</a> for more information on how to use the bridge mode feature.
+         * Notifications</a> for more information.
          * @param dismissalId the dismissal id of the notification.
          * @return this object for method chaining
          */
@@ -6484,6 +6490,27 @@
             return mDismissalId;
         }
 
+        /**
+         * Sets a bridge tag for this notification. A bridge tag can be set for notifications
+         * posted from a phone to provide finer-grained control on what notifications are bridged
+         * to wearables. See <a href="{@docRoot}wear/notifications/index.html">Adding Wearable
+         * Features to Notifications</a> for more information.
+         * @param bridgeTag the bridge tag of the notification.
+         * @return this object for method chaining
+         */
+        public WearableExtender setBridgeTag(String bridgeTag) {
+            mBridgeTag = bridgeTag;
+            return this;
+        }
+
+        /**
+         * Returns the bridge tag of the notification.
+         * @return the bridge tag or null if not present.
+         */
+        public String getBridgeTag() {
+            return mBridgeTag;
+        }
+
         private void setFlag(int mask, boolean value) {
             if (value) {
                 mFlags |= mask;
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index b0f15b5..a394f35 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -377,6 +377,10 @@
      * The object is intended to provide local information about the drag and drop operation. For
      * example, it can indicate whether the drag and drop operation is a copy or a move.
      * <p>
+     * The local state is available only to views in the activity which has started the drag
+     * operation. In all other activities this method will return null
+     * </p>
+     * <p>
      *  This method returns valid data for all event actions except for {@link #ACTION_DRAG_ENDED}.
      * </p>
      * @return The local state object sent to the system by startDrag().
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 79bdc00..a7337d2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -20657,8 +20657,10 @@
      * @param shadowBuilder A {@link android.view.View.DragShadowBuilder} object for building the
      * drag shadow.
      * @param myLocalState An {@link java.lang.Object} containing local data about the drag and
-     * drop operation. This Object is put into every DragEvent object sent by the system during the
-     * current drag.
+     * drop operation. When dispatching drag events to views in the same activity this object
+     * will be available through {@link android.view.DragEvent#getLocalState()}. Views in other
+     * activities will not have access to this data ({@link android.view.DragEvent#getLocalState()}
+     * will return null).
      * <p>
      * myLocalState is a lightweight mechanism for the sending information from the dragged View
      * to the target Views. For example, it can contain flags that differentiate between a
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 18e2118..e2a2466 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -3750,7 +3750,7 @@
          * how to override the standard click action by adding a custom label:
          * <pre>
          *   AccessibilityAction action = new AccessibilityAction(
-         *           AccessibilityAction.ACTION_ACTION_CLICK, getLocalizedLabel());
+         *           AccessibilityAction.ACTION_CLICK.getId(), getLocalizedLabel());
          *   node.addAction(action);
          * </pre>
          *
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 2956175..18c4ee3 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -151,12 +151,12 @@
     mPixelRef->unref();
 }
 
-Bitmap::Bitmap(void* address, int fd,
+Bitmap::Bitmap(void* address, int fd, size_t mappedSize,
             const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable)
         : mPixelStorageType(PixelStorageType::Ashmem) {
     mPixelStorage.ashmem.address = address;
     mPixelStorage.ashmem.fd = fd;
-    mPixelStorage.ashmem.size = ashmem_get_size_region(fd);
+    mPixelStorage.ashmem.size = mappedSize;
     mPixelRef.reset(new WrappedPixelRef(this, address, info, rowBytes, ctable));
     // Note: this will trigger a call to onStrongRefDestroyed(), but
     // we want the pixel ref to have a ref count of 0 at this point
@@ -1027,7 +1027,7 @@
 
         // Map the pixels in place and take ownership of the ashmem region.
         nativeBitmap = GraphicsJNI::mapAshmemPixelRef(env, bitmap.get(),
-                ctable, dupFd, const_cast<void*>(blob.data()), !isMutable);
+                ctable, dupFd, const_cast<void*>(blob.data()), size, !isMutable);
         SkSafeUnref(ctable);
         if (!nativeBitmap) {
             close(dupFd);
diff --git a/core/jni/android/graphics/Bitmap.h b/core/jni/android/graphics/Bitmap.h
index eadba5c..aaea178 100644
--- a/core/jni/android/graphics/Bitmap.h
+++ b/core/jni/android/graphics/Bitmap.h
@@ -51,8 +51,8 @@
             const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
     Bitmap(void* address, void* context, FreeFunc freeFunc,
             const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable);
-    Bitmap(void* address, int fd, const SkImageInfo& info, size_t rowBytes,
-            SkColorTable* ctable);
+    Bitmap(void* address, int fd, size_t mappedSize, const SkImageInfo& info,
+            size_t rowBytes, SkColorTable* ctable);
 
     const SkImageInfo& info() const;
 
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index b5630d5..c6a51e8 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -613,7 +613,7 @@
         return nullptr;
     }
 
-    android::Bitmap* wrapper = new android::Bitmap(addr, fd, info, rowBytes, ctable);
+    android::Bitmap* wrapper = new android::Bitmap(addr, fd, size, info, rowBytes, ctable);
     wrapper->getSkBitmap(bitmap);
     // since we're already allocated, we lockPixels right away
     // HeapAllocator behaves this way too
@@ -623,7 +623,7 @@
 }
 
 android::Bitmap* GraphicsJNI::mapAshmemPixelRef(JNIEnv* env, SkBitmap* bitmap,
-        SkColorTable* ctable, int fd, void* addr, bool readOnly) {
+        SkColorTable* ctable, int fd, void* addr, size_t size, bool readOnly) {
     const SkImageInfo& info = bitmap->info();
     if (info.colorType() == kUnknown_SkColorType) {
         doThrowIAE(env, "unknown bitmap configuration");
@@ -633,7 +633,8 @@
     if (!addr) {
         // Map existing ashmem region if not already mapped.
         int flags = readOnly ? (PROT_READ) : (PROT_READ | PROT_WRITE);
-        addr = mmap(NULL, ashmem_get_size_region(fd), flags, MAP_SHARED, fd, 0);
+        size = ashmem_get_size_region(fd);
+        addr = mmap(NULL, size, flags, MAP_SHARED, fd, 0);
         if (addr == MAP_FAILED) {
             return nullptr;
         }
@@ -643,7 +644,7 @@
     // attempting to compute our own.
     const size_t rowBytes = bitmap->rowBytes();
 
-    android::Bitmap* wrapper = new android::Bitmap(addr, fd, info, rowBytes, ctable);
+    android::Bitmap* wrapper = new android::Bitmap(addr, fd, size, info, rowBytes, ctable);
     wrapper->getSkBitmap(bitmap);
     if (readOnly) {
         bitmap->pixelRef()->setImmutable();
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 0f04f6d..89636db 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -100,7 +100,7 @@
             SkColorTable* ctable);
 
     static android::Bitmap* mapAshmemPixelRef(JNIEnv* env, SkBitmap* bitmap,
-            SkColorTable* ctable, int fd, void* addr, bool readOnly);
+            SkColorTable* ctable, int fd, void* addr, size_t size, bool readOnly);
 
     /**
      * Given a bitmap we natively allocate a memory block to store the contents
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 2452cfd..cef4784 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -479,6 +479,13 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.view.ScaleGesture" android:label="ScaleGesture">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="android.view.StubbedView" android:label="ViewStub">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/core/tests/coretests/res/layout/scale_gesture.xml b/core/tests/coretests/res/layout/scale_gesture.xml
new file mode 100644
index 0000000..05d408d
--- /dev/null
+++ b/core/tests/coretests/res/layout/scale_gesture.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates use of scale gesture detector to perform pinch to zoom.
+     See corresponding Java code. -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="Hello World!"
+        android:id="@+id/article"
+        android:textSize="12sp"/>
+
+</RelativeLayout>
diff --git a/core/tests/coretests/src/android/view/PinchZoomAction.java b/core/tests/coretests/src/android/view/PinchZoomAction.java
new file mode 100644
index 0000000..78a4b31
--- /dev/null
+++ b/core/tests/coretests/src/android/view/PinchZoomAction.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.view;
+
+import static android.support.test.espresso.core.deps.guava.base.Preconditions.checkNotNull;
+import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom;
+import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
+import static org.hamcrest.Matchers.allOf;
+
+import android.os.SystemClock;
+import android.support.test.espresso.InjectEventSecurityException;
+import android.support.test.espresso.PerformException;
+import android.support.test.espresso.ViewAction;
+import android.support.test.espresso.action.MotionEvents;
+import android.support.test.espresso.action.Swiper;
+import android.support.test.espresso.UiController;
+import android.support.test.espresso.util.HumanReadables;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import javax.annotation.Nullable;
+import org.hamcrest.Matcher;
+
+/**
+ * Pinch and zooms on a View using touch events.
+ * <br>
+ * View constraints:
+ * <ul>
+ * <li>must be displayed on screen
+ * <ul>
+ */
+public class PinchZoomAction implements ViewAction {
+    public static Swiper.Status sendPinchZoomAction(UiController uiController,
+                                                    float[] firstFingerStartCoords,
+                                                    float[] firstFingerEndCoords,
+                                                    float[] secondFingerStartCoords,
+                                                    float[] secondFingerEndCoords,
+                                                    float[] precision) {
+        checkNotNull(uiController);
+        checkNotNull(firstFingerStartCoords);
+        checkNotNull(firstFingerEndCoords);
+        checkNotNull(secondFingerStartCoords);
+        checkNotNull(secondFingerEndCoords);
+        checkNotNull(precision);
+
+        // Specify the touch properties for the finger events.
+        final MotionEvent.PointerProperties pp1 = new MotionEvent.PointerProperties();
+        pp1.id = 0;
+        pp1.toolType = MotionEvent.TOOL_TYPE_FINGER;
+        final MotionEvent.PointerProperties pp2 = new MotionEvent.PointerProperties();
+        pp2.id = 1;
+        pp2.toolType = MotionEvent.TOOL_TYPE_FINGER;
+        MotionEvent.PointerProperties[] pointerProperties =
+                new MotionEvent.PointerProperties[]{pp1, pp2};
+
+        // Specify the motion properties of the two touch points.
+        final MotionEvent.PointerCoords pc1 = new MotionEvent.PointerCoords();
+        pc1.x = firstFingerStartCoords[0];
+        pc1.y = firstFingerStartCoords[1];
+        pc1.pressure = 1;
+        pc1.size = 1;
+        final MotionEvent.PointerCoords pc2 = new MotionEvent.PointerCoords();
+        pc2.x = secondFingerStartCoords[0];
+        pc2.y = secondFingerEndCoords[1];
+        pc2.pressure = 1;
+        pc2.size = 1;
+
+        final long startTime = SystemClock.uptimeMillis();
+        long eventTime = startTime;
+        final MotionEvent.PointerCoords[] pointerCoords = new MotionEvent.PointerCoords[]{pc1, pc2};
+
+        final MotionEvent firstFingerEvent = MotionEvent.obtain(startTime,
+                eventTime, MotionEvent.ACTION_DOWN, 1, pointerProperties, pointerCoords,
+                0, 0, 1, 1, 0, 0, 0, 0);
+
+        eventTime = SystemClock.uptimeMillis();
+        final MotionEvent secondFingerEvent = MotionEvent.obtain(startTime, eventTime,
+                MotionEvent.ACTION_POINTER_DOWN +
+                        (pp2.id << MotionEvent.ACTION_POINTER_INDEX_SHIFT),
+                2, pointerProperties, pointerCoords, 0, 0, 1, 1, 0, 0, 0, 0);
+
+        try {
+            uiController.injectMotionEvent(firstFingerEvent);
+        } catch (InjectEventSecurityException e) {
+            throw new PerformException.Builder()
+                    .withActionDescription("First finger down event")
+                    .withViewDescription("Scale gesture detector")
+                    .withCause(e)
+                    .build();
+        }
+
+        try {
+            uiController.injectMotionEvent(secondFingerEvent);
+        } catch (InjectEventSecurityException e) {
+            throw new PerformException.Builder()
+                    .withActionDescription("Second finger down event")
+                    .withViewDescription("Scale gesture detector")
+                    .withCause(e)
+                    .build();
+        }
+
+        // Specify the coordinates of the two touch points.
+        final float[][] stepsFirstFinger = interpolate(firstFingerStartCoords,
+                firstFingerEndCoords);
+        final float[][] stepsSecondFinger = interpolate(secondFingerStartCoords,
+                secondFingerEndCoords);
+
+        // Loop until the end points of the two fingers are reached.
+        for (int i = 0; i < PINCH_STEP_COUNT; i++) {
+            eventTime = SystemClock.uptimeMillis();
+
+            pc1.x = stepsFirstFinger[i][0];
+            pc1.y = stepsFirstFinger[i][1];
+            pc2.x = stepsSecondFinger[i][0];
+            pc2.y = stepsSecondFinger[i][1];
+
+            final MotionEvent event = MotionEvent.obtain(startTime, eventTime,
+                    MotionEvent.ACTION_MOVE, 2, pointerProperties, pointerCoords,
+                    0, 0, 1, 1, 0, 0, 0, 0);
+
+            try {
+                uiController.injectMotionEvent(event);
+            } catch (InjectEventSecurityException e) {
+                throw new PerformException.Builder()
+                        .withActionDescription("Move event")
+                        .withViewDescription("Scale gesture event")
+                        .withCause(e)
+                        .build();
+            }
+
+           uiController.loopMainThreadForAtLeast(800);
+        }
+
+        eventTime = SystemClock.uptimeMillis();
+
+        // Send the up event for the second finger.
+        final MotionEvent secondFingerUpEvent = MotionEvent.obtain(startTime, eventTime,
+                MotionEvent.ACTION_POINTER_UP, 2, pointerProperties, pointerCoords,
+                0, 0, 1, 1, 0, 0, 0, 0);
+        try {
+            uiController.injectMotionEvent(secondFingerUpEvent);
+        } catch (InjectEventSecurityException e) {
+            throw new PerformException.Builder()
+                    .withActionDescription("Second finger up event")
+                    .withViewDescription("Scale gesture detector")
+                    .withCause(e)
+                    .build();
+        }
+
+        eventTime = SystemClock.uptimeMillis();
+        // Send the up event for the first finger.
+        final MotionEvent firstFingerUpEvent = MotionEvent.obtain(startTime, eventTime,
+                MotionEvent.ACTION_POINTER_UP, 1, pointerProperties, pointerCoords,
+                0, 0, 1, 1, 0, 0, 0, 0);
+        try {
+            uiController.injectMotionEvent(firstFingerUpEvent);
+        } catch (InjectEventSecurityException e) {
+            throw new PerformException.Builder()
+                    .withActionDescription("First finger up event")
+                    .withViewDescription("Scale gesture detector")
+                    .withCause(e)
+                    .build();
+        }
+        return Swiper.Status.SUCCESS;
+    }
+
+    private static float[][] interpolate(float[] start, float[] end) {
+        float[][] res = new float[PINCH_STEP_COUNT][2];
+
+        for (int i = 0; i < PINCH_STEP_COUNT; i++) {
+            res[i][0] = start[0] + (end[0] - start[0]) * i / (PINCH_STEP_COUNT - 1f);
+            res[i][1] = start[1] + (end[1] - start[1]) * i / (PINCH_STEP_COUNT - 1f);
+        }
+
+        return res;
+    }
+
+    /** The number of move events to send for each pinch. */
+    private static final int PINCH_STEP_COUNT = 10;
+
+    private final Class<? extends View> mViewClass;
+    private final float[] mFirstFingerStartCoords;
+    private final float[] mFirstFingerEndCoords;
+    private final float[] mSecondFingerStartCoords;
+    private final float[] mSecondFingerEndCoords;
+
+    public PinchZoomAction(float[] firstFingerStartCoords,
+                           float[] firstFingerEndCoords,
+                           float[] secondFingerStartCoords,
+                           float[] secondFingerEndCoords,
+                           Class<? extends View> viewClass) {
+        mFirstFingerStartCoords = firstFingerStartCoords;
+        mFirstFingerEndCoords = firstFingerEndCoords;
+        mSecondFingerStartCoords = secondFingerStartCoords;
+        mSecondFingerEndCoords = secondFingerEndCoords;
+        mViewClass = viewClass;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Matcher<View> getConstraints() {
+        return allOf(isCompletelyDisplayed(), isAssignableFrom(mViewClass));
+    }
+
+    @Override
+    public void perform(UiController uiController, View view) {
+        checkNotNull(uiController);
+        checkNotNull(view);
+        Swiper.Status status;
+        final float[] precision = {1.0f, 1.0f, 1.0f, 1.0f};
+
+        try {
+            status = sendPinchZoomAction(uiController, this.mFirstFingerStartCoords,
+                this.mFirstFingerEndCoords, this.mSecondFingerStartCoords,
+                this.mSecondFingerEndCoords, precision);
+        } catch (RuntimeException re) {
+            throw new PerformException.Builder()
+                    .withActionDescription(getDescription())
+                    .withViewDescription(HumanReadables.describe(view))
+                    .withCause(re)
+                    .build();
+        }
+        if (status == Swiper.Status.FAILURE) {
+            throw new PerformException.Builder()
+                    .withActionDescription(getDescription())
+                    .withViewDescription(HumanReadables.describe(view))
+                    .withCause(new RuntimeException(getDescription() + " failed"))
+                    .build();
+        }
+    }
+
+    @Override
+    public String getDescription() {
+        return "Pinch Zoom Action";
+    }
+}
diff --git a/core/tests/coretests/src/android/view/ScaleGesture.java b/core/tests/coretests/src/android/view/ScaleGesture.java
new file mode 100644
index 0000000..a954a4a
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ScaleGesture.java
@@ -0,0 +1,58 @@
+/*
+* Copyright (C) 2016 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package android.view;
+
+import com.android.frameworks.coretests.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
+import android.widget.TextView;
+
+public class ScaleGesture extends Activity {
+    private ScaleGestureDetector mScaleGestureDetector;
+    private float mFactor;
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.scale_gesture);
+        mScaleGestureDetector = new ScaleGestureDetector(this, new OnScaleGestureListener());
+        mFactor = 1.0f;
+    }
+
+    public float getScaleFactor() {
+        return mFactor;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        mScaleGestureDetector.onTouchEvent(event);
+        return true;
+    }
+
+    public class OnScaleGestureListener extends SimpleOnScaleGestureListener {
+        @Override
+        public boolean onScale(ScaleGestureDetector detector) {
+            mFactor *= detector.getScaleFactor();
+            return true;
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/view/ScaleGestureDetectorTest.java b/core/tests/coretests/src/android/view/ScaleGestureDetectorTest.java
new file mode 100644
index 0000000..23d0251
--- /dev/null
+++ b/core/tests/coretests/src/android/view/ScaleGestureDetectorTest.java
@@ -0,0 +1,91 @@
+/*
+* Copyright (C) 2016 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package android.view;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.DisplayMetrics;
+import android.view.PinchZoomAction;
+import android.view.ScaleGesture;
+import android.view.WindowManager;
+import android.widget.TextView;
+
+import com.android.frameworks.coretests.R;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.Espresso.onView;
+
+public class ScaleGestureDetectorTest extends ActivityInstrumentationTestCase2<ScaleGesture> {
+    private ScaleGesture mScaleGestureActivity;
+
+    public ScaleGestureDetectorTest() {
+        super("com.android.frameworks.coretests", ScaleGesture.class);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
+        mScaleGestureActivity = getActivity();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    public void testScaleGestureDetector() {
+        // No scaling should have occurred prior to performing pinch zoom action.
+        final float initialScaleFactor = 1.0f;
+        assertEquals(initialScaleFactor, mScaleGestureActivity.getScaleFactor());
+
+        // Specify start and end coordinates, irrespective of device display size.
+        final DisplayMetrics dm = new DisplayMetrics();
+        final WindowManager wm = (WindowManager) (mScaleGestureActivity.getApplicationContext())
+                .getSystemService(Context.WINDOW_SERVICE);
+        wm.getDefaultDisplay().getMetrics(dm);
+        final int displayWidth = dm.widthPixels;
+        final int displayHeight = dm.heightPixels;
+
+        // Obtain coordinates to perform pinch and zoom from the center, to 75% of the display.
+        final int centerX = displayWidth / 2;
+        final int centerY = displayHeight / 2;
+
+        // Offset center coordinates by one, so that the two starting points are different.
+        final float[] firstFingerStartCoords = new float[] {centerX + 1.0f, centerY - 1.0f};
+        final float[] firstFingerEndCoords =
+        new float[] {0.75f * displayWidth, 0.25f * displayHeight};
+        final float[] secondFingerStartCoords = new float[] {centerX - 1.0f, centerY + 1.0f};
+        final float[] secondFingerEndCoords =
+        new float[] {0.25f * displayWidth, 0.75f * displayHeight};
+
+        onView(withId(R.id.article)).perform(new PinchZoomAction(firstFingerStartCoords,
+                firstFingerEndCoords, secondFingerStartCoords, secondFingerEndCoords,
+                TextView.class));
+
+        // Text should have been 'zoomed', meaning scale factor increased.
+        assertTrue(mScaleGestureActivity.getScaleFactor() > initialScaleFactor);
+    }
+}
\ No newline at end of file
diff --git a/docs/html/topic/libraries/testing-support-library/index.jd b/docs/html/topic/libraries/testing-support-library/index.jd
index 941f5c3..3d3c091 100644
--- a/docs/html/topic/libraries/testing-support-library/index.jd
+++ b/docs/html/topic/libraries/testing-support-library/index.jd
@@ -202,7 +202,7 @@
     <li><a href="{@docRoot}reference/android/support/test/filters/SdkSuppress.html">{@code @SdkSupress}</a>:
     Suppresses the test from running on a lower Android API level than the given level. For
     example, to suppress tests on all API levels lower than 18 from running, use the annotation
-    {@code @SDKSupress(minSdkVersion=18)}.
+    {@code @SdkSuppress(minSdkVersion=18)}.
     </li>
 
     <li>{@link android.test.suitebuilder.annotation.SmallTest &#64;SmallTest},
diff --git a/docs/html/training/accessibility/service.jd b/docs/html/training/accessibility/service.jd
index de00db7..25be81e 100755
--- a/docs/html/training/accessibility/service.jd
+++ b/docs/html/training/accessibility/service.jd
@@ -17,7 +17,7 @@
   <li><a href="#create">Create Your Accessibility Service</a></li>
   <li><a href="#configure">Configure Your Accessibility Service</a></li>
   <li><a href="#events">Respond to AccessibilityEvents</a></li>
-  <li><a href="#query">Query the View Heirarchy for More Context</a></li>
+  <li><a href="#query">Query the View Hierarchy for More Context</a></li>
 </ol>
 
 <h2>You should also read</h2>
@@ -200,7 +200,7 @@
 }
 </pre>
 
-<h2 id="query">Query the View Heirarchy for More Context</h2>
+<h2 id="query">Query the View Hierarchy's for More Context</h2>
 <p>This step is optional, but highly useful. The Android platform provides the ability for an
 {@link android.accessibilityservice.AccessibilityService} to query the view
 hierarchy, collecting information about the UI component that generated an event, and
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index a215493..4f3314c 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -46,7 +46,7 @@
     void setExtras(in Bundle extras);
     void setRatingType(int type);
     void setRepeatMode(int repeatMode);
-    void setShuffleMode(boolean shuffleMode);
+    void setShuffleModeEnabled(boolean enabled);
 
     // These commands relate to volume handling
     void setPlaybackToLocal(in AudioAttributes attributes);
diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl
index b3c6d59..2f6e260 100644
--- a/media/java/android/media/session/ISessionCallback.aidl
+++ b/media/java/android/media/session/ISessionCallback.aidl
@@ -47,7 +47,7 @@
     void onSeekTo(long pos);
     void onRate(in Rating rating);
     void onRepeatMode(int repeatMode);
-    void onShuffleMode(boolean shuffleMode);
+    void onShuffleMode(boolean enabled);
     void onCustomAction(String action, in Bundle args);
 
     // These callbacks are for volume handling
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index b73f167..e92758c 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -55,7 +55,7 @@
     Bundle getExtras();
     int getRatingType();
     int getRepeatMode();
-    boolean getShuffleMode();
+    boolean isShuffleModeEnabled();
 
     // These commands are for the TransportControls
     void prepare();
@@ -76,6 +76,6 @@
     void seekTo(long pos);
     void rate(in Rating rating);
     void repeatMode(int repeatMode);
-    void shuffleMode(boolean shuffleMode);
+    void shuffleMode(boolean enabled);
     void sendCustomAction(String action, in Bundle args);
 }
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index ddff1b7..8cbf8e1 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -251,15 +251,15 @@
     }
 
     /**
-     * Get the shuffle mode for this session.
+     * Return whether the shuffle mode is enabled for this session.
      *
-     * @return The latest shuffle mode set to the session, or false if not set.
+     * @return {@code true} if the shuffle mode is enabled, {@code false} if disabled or not set.
      */
-    public boolean getShuffleMode() {
+    public boolean isShuffleModeEnabled() {
         try {
-            return mSessionBinder.getShuffleMode();
+            return mSessionBinder.isShuffleModeEnabled();
         } catch (RemoteException e) {
-            Log.wtf(TAG, "Error calling getShuffleMode.", e);
+            Log.wtf(TAG, "Error calling isShuffleModeEnabled.", e);
             return false;
         }
     }
@@ -625,10 +625,9 @@
         /**
          * Override to handle changes to the shuffle mode.
          *
-         * @param shuffleMode The shuffle mode. {@code true} if _the_ shuffle mode is on,
-         *                    {@code false} otherwise.
+         * @param enabled {@code true} if the shuffle mode is enabled, {@code false} otherwise.
          */
-        public void onShuffleModeChanged(boolean shuffleMode) {
+        public void onShuffleModeChanged(boolean enabled) {
         }
     }
 
@@ -931,13 +930,13 @@
         /**
          * Set the shuffle mode for this session.
          *
-         * @param shuffleMode {@code true} if the shuffle mode is on, {@code false} otherwise.
+         * @param enabled {@code true} to enable the shuffle mode, {@code false} to disable.
          */
-        public void setShuffleMode(boolean shuffleMode) {
+        public void setShuffleModeEnabled(boolean enabled) {
             try {
-                mSessionBinder.shuffleMode(shuffleMode);
+                mSessionBinder.shuffleMode(enabled);
             } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling shuffleQueue.", e);
+                Log.wtf(TAG, "Error calling shuffleMode.", e);
             }
         }
 
@@ -1151,10 +1150,10 @@
         }
 
         @Override
-        public void onShuffleModeChanged(boolean shuffleMode) {
+        public void onShuffleModeChanged(boolean enabled) {
             MediaController controller = mController.get();
             if (controller != null) {
-                controller.postMessage(MSG_UPDATE_SHUFFLE_MODE, shuffleMode, null);
+                controller.postMessage(MSG_UPDATE_SHUFFLE_MODE, enabled, null);
             }
         }
     }
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index cab5d93..84dc93a 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -501,16 +501,16 @@
     /**
      * Set the shuffle mode for this session.
      * <p>
-     * Note that if this method is not called before, {@link MediaController#getShuffleMode}
+     * Note that if this method is not called before, {@link MediaController#isShuffleModeEnabled}
      * will return {@code false}.
      *
-     * @param shuffleMode {@code true} if the shuffle mode is on, {@code false} otherwise.
+     * @param enabled {@code true} to enable the shuffle mode, {@code false} to disable.
      */
-    public void setShuffleMode(boolean shuffleMode) {
+    public void setShuffleModeEnabled(boolean enabled) {
         try {
-            mBinder.setShuffleMode(shuffleMode);
+            mBinder.setShuffleModeEnabled(enabled);
         } catch (RemoteException e) {
-            Log.e(TAG, "Error in setShuffleMode.", e);
+            Log.e(TAG, "Error in setShuffleModeEnabled.", e);
         }
     }
 
@@ -637,8 +637,8 @@
         postToCallback(CallbackMessageHandler.MSG_REPEAT_MODE, repeatMode);
     }
 
-    private void dispatchShuffleMode(boolean shuffleMode) {
-        postToCallback(CallbackMessageHandler.MSG_SHUFFLE_MODE, shuffleMode);
+    private void dispatchShuffleMode(boolean enabled) {
+        postToCallback(CallbackMessageHandler.MSG_SHUFFLE_MODE, enabled);
     }
 
     private void dispatchCustomAction(String action, Bundle args) {
@@ -1024,13 +1024,13 @@
         /**
          * Override to handle the setting of the shuffle mode.
          * <p>
-         * You should call {@link #setShuffleMode} before end of this method in order to notify
-         * the change to the {@link MediaController}, or {@link MediaController#getShuffleMode}
-         * could return an invalid value.
+         * You should call {@link #setShuffleModeEnabled} before the end of this method in order to
+         * notify the change to the {@link MediaController}, or
+         * {@link MediaController#isShuffleModeEnabled} could return an invalid value.
          *
-         * @param shuffleMode true if the shuffle mode is on, false otherwise.
+         * @param enabled true when the shuffle mode is enabled, false otherwise.
          */
-        public void onSetShuffleMode(boolean shuffleMode) {
+        public void onSetShuffleModeEnabled(boolean enabled) {
         }
 
         /**
@@ -1223,10 +1223,10 @@
         }
 
         @Override
-        public void onShuffleMode(boolean shuffleMode) {
+        public void onShuffleMode(boolean enabled) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
-                session.dispatchShuffleMode(shuffleMode);
+                session.dispatchShuffleMode(enabled);
             }
         }
 
@@ -1468,7 +1468,7 @@
                     mCallback.onSetRepeatMode((int) msg.obj);
                     break;
                 case MSG_SHUFFLE_MODE:
-                    mCallback.onSetShuffleMode((boolean) msg.obj);
+                    mCallback.onSetShuffleModeEnabled((boolean) msg.obj);
                     break;
                 case MSG_CUSTOM_ACTION:
                     mCallback.onCustomAction((String) msg.obj, msg.getData());
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 5cdd201..1ea6109 100644
--- a/media/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
@@ -46,7 +46,7 @@
             ACTION_SEEK_TO, ACTION_PLAY_PAUSE, ACTION_PLAY_FROM_MEDIA_ID, ACTION_PLAY_FROM_SEARCH,
             ACTION_SKIP_TO_QUEUE_ITEM, ACTION_PLAY_FROM_URI, ACTION_PREPARE,
             ACTION_PREPARE_FROM_MEDIA_ID, ACTION_PREPARE_FROM_SEARCH, ACTION_PREPARE_FROM_URI,
-            ACTION_SET_REPEAT_MODE, ACTION_SET_SHUFFLE_MODE})
+            ACTION_SET_REPEAT_MODE, ACTION_SET_SHUFFLE_MODE_ENABLED})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Actions {}
 
@@ -184,11 +184,11 @@
     public static final long ACTION_SET_REPEAT_MODE = 1 << 18;
 
     /**
-     * Indicates this session supports the set shuffle mode command.
+     * Indicates this session supports the set shuffle mode enabled command.
      *
      * @see Builder#setActions(long)
      */
-    public static final long ACTION_SET_SHUFFLE_MODE = 1 << 19;
+    public static final long ACTION_SET_SHUFFLE_MODE_ENABLED = 1 << 19;
 
     /**
      * @hide
@@ -467,7 +467,7 @@
      * <li> {@link PlaybackState#ACTION_PREPARE_FROM_SEARCH}</li>
      * <li> {@link PlaybackState#ACTION_PREPARE_FROM_URI}</li>
      * <li> {@link PlaybackState#ACTION_SET_REPEAT_MODE}</li>
-     * <li> {@link PlaybackState#ACTION_SET_SHUFFLE_MODE}</li>
+     * <li> {@link PlaybackState#ACTION_SET_SHUFFLE_MODE_ENABLED}</li>
      * </ul>
      */
     @Actions
@@ -1003,7 +1003,7 @@
          * <li> {@link PlaybackState#ACTION_PREPARE_FROM_SEARCH}</li>
          * <li> {@link PlaybackState#ACTION_PREPARE_FROM_URI}</li>
          * <li> {@link PlaybackState#ACTION_SET_REPEAT_MODE}</li>
-         * <li> {@link PlaybackState#ACTION_SET_SHUFFLE_MODE}</li>
+         * <li> {@link PlaybackState#ACTION_SET_SHUFFLE_MODE_ENABLED}</li>
          * </ul>
          *
          * @param actions The set of actions allowed.
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 2d71ce9..ede6e30 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -108,7 +108,7 @@
     private CharSequence mQueueTitle;
     private int mRatingType;
     private int mRepeatMode;
-    private boolean mShuffleMode;
+    private boolean mShuffleModeEnabled;
     private long mLastActiveTime;
     // End TransportPerformer fields
 
@@ -649,7 +649,7 @@
             for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
                 ISessionControllerCallback cb = mControllerCallbacks.get(i);
                 try {
-                    cb.onShuffleModeChanged(mShuffleMode);
+                    cb.onShuffleModeChanged(mShuffleModeEnabled);
                 } catch (DeadObjectException e) {
                     mControllerCallbacks.remove(i);
                     Log.w(TAG, "Removed dead callback in pushShuffleModeUpdate.", e);
@@ -880,11 +880,11 @@
         }
 
         @Override
-        public void setShuffleMode(boolean shuffleMode) {
+        public void setShuffleModeEnabled(boolean enabled) {
             boolean changed;
             synchronized (mLock) {
-                changed = mShuffleMode != shuffleMode;
-                mShuffleMode = shuffleMode;
+                changed = mShuffleModeEnabled != enabled;
+                mShuffleModeEnabled = enabled;
             }
             if (changed) {
                 mHandler.post(MessageHandler.MSG_UPDATE_SHUFFLE_MODE);
@@ -1115,9 +1115,9 @@
             }
         }
 
-        public void shuffleMode(boolean shuffleMode) {
+        public void shuffleMode(boolean enabled) {
             try {
-                mCb.onShuffleMode(shuffleMode);
+                mCb.onShuffleMode(enabled);
             } catch (RemoteException e) {
                 Slog.e(TAG, "Remote failure in shuffleMode.", e);
             }
@@ -1364,9 +1364,9 @@
         }
 
         @Override
-        public void shuffleMode(boolean shuffleMode) throws RemoteException {
+        public void shuffleMode(boolean enabled) throws RemoteException {
             updateCallingPackage();
-            mSessionCb.shuffleMode(shuffleMode);
+            mSessionCb.shuffleMode(enabled);
         }
 
 
@@ -1419,8 +1419,8 @@
         }
 
         @Override
-        public boolean getShuffleMode() {
-            return mShuffleMode;
+        public boolean isShuffleModeEnabled() {
+            return mShuffleModeEnabled;
         }
 
         @Override
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index b9956c8..788f28d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -225,8 +225,6 @@
     int mAttrType;
 
     static final long PENDING_TRANSACTION_FINISH_WAIT_TIME = 100;
-    long mDeferTransactionUntilFrame = -1;
-    long mDeferTransactionTime = -1;
 
     boolean mForceScaleUntilResize;
 
@@ -1889,35 +1887,10 @@
         if (!mWin.isChildWindow()) {
             return;
         }
-        mDeferTransactionUntilFrame = frameNumber;
-        mDeferTransactionTime = System.currentTimeMillis();
         mSurfaceController.deferTransactionUntil(
                 mWin.getParentWindow().mWinAnimator.mSurfaceController.getHandle(), frameNumber);
     }
 
-    // Defer the current transaction to the frame number of the last saved transaction.
-    // We do this to avoid shooting through an unsynchronized transaction while something is
-    // pending. This is generally fine, as either we will get in on the synchronization,
-    // or SurfaceFlinger will see that the frame has already occured. The only
-    // potential problem is in frame number resets so we reset things with a timeout
-    // every so often to be careful.
-    void deferToPendingTransaction() {
-        if (mDeferTransactionUntilFrame < 0) {
-            return;
-        }
-        final WindowState parentWindow = mWin.getParentWindow();
-        long time = System.currentTimeMillis();
-        if (time > mDeferTransactionTime + PENDING_TRANSACTION_FINISH_WAIT_TIME) {
-            mDeferTransactionTime = -1;
-            mDeferTransactionUntilFrame = -1;
-        } else if (parentWindow != null &&
-                parentWindow.mWinAnimator.hasSurface()) {
-            mSurfaceController.deferTransactionUntil(
-                    mWin.getParentWindow().mWinAnimator.mSurfaceController.getHandle(),
-                    mDeferTransactionUntilFrame);
-        }
-    }
-
     /**
      * Sometimes we need to synchronize the first frame of animation with some external event.
      * To achieve this, we prolong the start of the animation and keep producing the first frame of
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 22f39fb..e03456f 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -739,10 +739,6 @@
 
                 // Moved from updateWindowsAndWallpaperLocked().
                 if (w.mHasSurface) {
-                    // If we have recently synchronized a previous transaction for this
-                    // window ensure we don't push through an unsynchronized one now.
-                    winAnimator.deferToPendingTransaction();
-
                     // Take care of the window being ready to display.
                     final boolean committed = winAnimator.commitFinishDrawingLocked();
                     if (isDefaultDisplay && committed) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 4591fcc..c5e2840 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -591,6 +591,9 @@
         boolean disableTextServices = SystemProperties.getBoolean("config.disable_textservices", false);
         boolean disableSamplingProfiler = SystemProperties.getBoolean("config.disable_samplingprof",
                 false);
+
+        boolean disableConsumerIr = SystemProperties.getBoolean("config.disable_consumerir", false);
+
         boolean isEmulator = SystemProperties.get("ro.kernel.qemu").equals("1");
 
         try {
@@ -646,10 +649,12 @@
             ServiceManager.addService("vibrator", vibrator);
             traceEnd();
 
-            traceBeginAndSlog("StartConsumerIrService");
-            consumerIr = new ConsumerIrService(context);
-            ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);
-            traceEnd();
+            if (!disableConsumerIr) {
+                traceBeginAndSlog("StartConsumerIrService");
+                consumerIr = new ConsumerIrService(context);
+                ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);
+                traceEnd();
+            }
 
             traceBeginAndSlog("StartAlarmManagerService");
             mSystemServiceManager.startService(AlarmManagerService.class);