Merge "ActivityManagerService: Rather than throw an exception, return INVALID_STACK_ID from getWorkspaceId when there is no associated workspace. This leaves the caller free to default."
diff --git a/api/current.txt b/api/current.txt
index 3e1f5a5..68f6f04 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -8881,6 +8881,7 @@
     field public int configChanges;
     field public int documentLaunchMode;
     field public int flags;
+    field public android.content.pm.ActivityInfo.InitialLayout initialLayout;
     field public int launchMode;
     field public int maxRecents;
     field public java.lang.String parentActivityName;
@@ -8894,6 +8895,15 @@
     field public int uiOptions;
   }
 
+  public static final class ActivityInfo.InitialLayout {
+    ctor public ActivityInfo.InitialLayout(int, float, int, float, int);
+    field public final int gravity;
+    field public final int height;
+    field public final float heightFraction;
+    field public final int width;
+    field public final float widthFraction;
+  }
+
   public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
     ctor public ApplicationInfo();
     ctor public ApplicationInfo(android.content.pm.ApplicationInfo);
@@ -18136,7 +18146,7 @@
     method public final int getThumbPixWidth();
   }
 
-  public class MtpObjectInfo.Builder {
+  public static class MtpObjectInfo.Builder {
     ctor public MtpObjectInfo.Builder();
     ctor public MtpObjectInfo.Builder(android.mtp.MtpObjectInfo);
     method public android.mtp.MtpObjectInfo build();
@@ -34141,6 +34151,15 @@
     field public static final int RTL = 1; // 0x1
   }
 
+  public final class LocaleList {
+    ctor public LocaleList();
+    ctor public LocaleList(java.util.Locale[]);
+    method public java.util.Locale get(int);
+    method public java.util.Locale getPrimary();
+    method public boolean isEmpty();
+    method public int size();
+  }
+
   public final class Log {
     method public static int d(java.lang.String, java.lang.String);
     method public static int d(java.lang.String, java.lang.String, java.lang.Throwable);
diff --git a/api/system-current.txt b/api/system-current.txt
index 984d395..bbdc397 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9139,6 +9139,7 @@
     field public int configChanges;
     field public int documentLaunchMode;
     field public int flags;
+    field public android.content.pm.ActivityInfo.InitialLayout initialLayout;
     field public int launchMode;
     field public int maxRecents;
     field public java.lang.String parentActivityName;
@@ -9152,6 +9153,15 @@
     field public int uiOptions;
   }
 
+  public static final class ActivityInfo.InitialLayout {
+    ctor public ActivityInfo.InitialLayout(int, float, int, float, int);
+    field public final int gravity;
+    field public final int height;
+    field public final float heightFraction;
+    field public final int width;
+    field public final float widthFraction;
+  }
+
   public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
     ctor public ApplicationInfo();
     ctor public ApplicationInfo(android.content.pm.ApplicationInfo);
@@ -19649,7 +19659,7 @@
     method public final int getThumbPixWidth();
   }
 
-  public class MtpObjectInfo.Builder {
+  public static class MtpObjectInfo.Builder {
     ctor public MtpObjectInfo.Builder();
     ctor public MtpObjectInfo.Builder(android.mtp.MtpObjectInfo);
     method public android.mtp.MtpObjectInfo build();
@@ -36474,6 +36484,15 @@
     field public static final int RTL = 1; // 0x1
   }
 
+  public final class LocaleList {
+    ctor public LocaleList();
+    ctor public LocaleList(java.util.Locale[]);
+    method public java.util.Locale get(int);
+    method public java.util.Locale getPrimary();
+    method public boolean isEmpty();
+    method public int size();
+  }
+
   public final class Log {
     method public static int d(java.lang.String, java.lang.String);
     method public static int d(java.lang.String, java.lang.String, java.lang.Throwable);
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 1f3ff51..2d825fa 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -64,9 +64,7 @@
  * <p>To get a {@link BluetoothAdapter} representing the local Bluetooth
  * adapter, when running on JELLY_BEAN_MR1 and below, call the
  * static {@link #getDefaultAdapter} method; when running on JELLY_BEAN_MR2 and
- * higher, retrieve it through
- * {@link android.content.Context#getSystemService} with
- * {@link android.content.Context#BLUETOOTH_SERVICE}.
+ * higher, call {@link BluetoothManager#getAdapter}.
  * Fundamentally, this is your starting point for all
  * Bluetooth actions. Once you have the local adapter, you can get a set of
  * {@link BluetoothDevice} objects representing all paired devices with
diff --git a/core/java/android/content/RestrictionEntry.java b/core/java/android/content/RestrictionEntry.java
index ab049ec..0473475 100644
--- a/core/java/android/content/RestrictionEntry.java
+++ b/core/java/android/content/RestrictionEntry.java
@@ -456,7 +456,7 @@
         if (o == this) return true;
         if (!(o instanceof RestrictionEntry)) return false;
         final RestrictionEntry other = (RestrictionEntry) o;
-        if (mType != other.mType || mKey.equals(other.mKey)) {
+        if (mType != other.mType || !mKey.equals(other.mKey)) {
             return false;
         }
         if (mCurrentValues == null && other.mCurrentValues == null
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 43cc63b..876fbf5 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -698,6 +698,8 @@
      */
     public int lockTaskLaunchMode;
 
+    public InitialLayout initialLayout;
+
     public ActivityInfo() {
     }
 
@@ -763,9 +765,14 @@
         }
         pw.println(prefix + "resizeable=" + resizeable + " lockTaskLaunchMode="
                 + lockTaskLaunchModeToString(lockTaskLaunchMode));
+        if (initialLayout != null) {
+            pw.println(prefix + "initialLayout=" + initialLayout.width + "|"
+                    + initialLayout.widthFraction + ", " + initialLayout.height + "|"
+                    + initialLayout.heightFraction + ", " + initialLayout.gravity);
+        }
         super.dumpBack(pw, prefix);
     }
-    
+
     public String toString() {
         return "ActivityInfo{"
             + Integer.toHexString(System.identityHashCode(this))
@@ -793,6 +800,16 @@
         dest.writeInt(maxRecents);
         dest.writeInt(resizeable ? 1 : 0);
         dest.writeInt(lockTaskLaunchMode);
+        if (initialLayout != null) {
+            dest.writeInt(1);
+            dest.writeInt(initialLayout.width);
+            dest.writeFloat(initialLayout.widthFraction);
+            dest.writeInt(initialLayout.height);
+            dest.writeFloat(initialLayout.heightFraction);
+            dest.writeInt(initialLayout.gravity);
+        } else {
+            dest.writeInt(0);
+        }
     }
 
     public static final Parcelable.Creator<ActivityInfo> CREATOR
@@ -822,5 +839,33 @@
         maxRecents = source.readInt();
         resizeable = (source.readInt() == 1);
         lockTaskLaunchMode = source.readInt();
+        if (source.readInt() == 1) {
+            initialLayout = new InitialLayout(source);
+        }
+    }
+
+    public static final class InitialLayout {
+        public InitialLayout(int width, float widthFraction, int height, float heightFraction,
+                int gravity) {
+            this.width = width;
+            this.widthFraction = widthFraction;
+            this.height = height;
+            this.heightFraction = heightFraction;
+            this.gravity = gravity;
+        }
+
+        InitialLayout(Parcel source) {
+            width = source.readInt();
+            widthFraction = source.readFloat();
+            height = source.readInt();
+            heightFraction = source.readFloat();
+            gravity = source.readInt();
+        }
+
+        public final int width;
+        public final float widthFraction;
+        public final int height;
+        public final float heightFraction;
+        public final int gravity;
     }
 }
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 924df1b..6443667 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -50,6 +50,7 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.util.TypedValue;
+import android.view.Gravity;
 
 import com.android.internal.R;
 import com.android.internal.util.ArrayUtils;
@@ -3260,10 +3261,12 @@
                     owner.preferredActivityFilters.add(intent);
                 }
             } else if (parser.getName().equals("meta-data")) {
-                if ((a.metaData=parseMetaData(res, parser, attrs, a.metaData,
+                if ((a.metaData = parseMetaData(res, parser, attrs, a.metaData,
                         outError)) == null) {
                     return null;
                 }
+            } else if (!receiver && parser.getName().equals("initial-layout")) {
+                parseInitialLayout(res, attrs, a);
             } else {
                 if (!RIGID_PARSER) {
                     Slog.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
@@ -3296,6 +3299,43 @@
         return a;
     }
 
+    private void parseInitialLayout(Resources res, AttributeSet attrs, Activity a) {
+        TypedArray sw = res.obtainAttributes(attrs,
+                com.android.internal.R.styleable.AndroidManifestInitialLayout);
+        int width = -1;
+        float widthFraction = -1f;
+        int height = -1;
+        float heightFraction = -1f;
+        final int widthType = sw.getType(
+                com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_width);
+        if (widthType == TypedValue.TYPE_FRACTION) {
+            widthFraction = sw.getFraction(
+                    com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_width,
+                    1, 1, -1);
+        } else if (widthType == TypedValue.TYPE_DIMENSION) {
+            width = sw.getDimensionPixelSize(
+                    com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_width,
+                    -1);
+        }
+        final int heightType = sw.getType(
+                com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_height);
+        if (heightType == TypedValue.TYPE_FRACTION) {
+            heightFraction = sw.getFraction(
+                    com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_height,
+                    1, 1, -1);
+        } else if (heightType == TypedValue.TYPE_DIMENSION) {
+            height = sw.getDimensionPixelSize(
+                    com.android.internal.R.styleable.AndroidManifestInitialLayout_activity_height,
+                    -1);
+        }
+        int gravity = sw.getInt(
+                com.android.internal.R.styleable.AndroidManifestInitialLayout_gravity,
+                Gravity.CENTER);
+        sw.recycle();
+        a.info.initialLayout = new ActivityInfo.InitialLayout(width, widthFraction,
+                height, heightFraction, gravity);
+    }
+
     private Activity parseActivityAlias(Package owner, Resources res,
             XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
             throws XmlPullParserException, IOException {
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index cbd2f78..dfd0f7d 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -145,6 +145,17 @@
         return (!hideSystemUser || id != UserHandle.USER_SYSTEM) && supportsSwitchTo();
     }
 
+    /* @hide */
+    public boolean canHaveProfile() {
+        if (isManagedProfile() || isGuest() || isRestricted()) {
+            return false;
+        }
+        if (UserManager.isSplitSystemUser()) {
+            return id != UserHandle.USER_SYSTEM;
+        }
+        return id == UserHandle.USER_OWNER;
+    }
+
     public UserInfo() {
     }
 
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 7aa9787..a04cdce 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -19,7 +19,9 @@
 
 import android.hardware.camera2.CameraDevice;
 import android.hardware.camera2.utils.HashCodeHelpers;
+import android.hardware.camera2.utils.SurfaceUtils;
 import android.util.Log;
+import android.util.Size;
 import android.view.Surface;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -66,9 +68,7 @@
      *
      */
     public OutputConfiguration(Surface surface) {
-        checkNotNull(surface, "Surface must not be null");
-        mSurface = surface;
-        mRotation = ROTATION_0;
+        this(surface, ROTATION_0);
     }
 
     /**
@@ -94,6 +94,9 @@
         checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
         mSurface = surface;
         mRotation = rotation;
+        mConfiguredSize = SurfaceUtils.getSurfaceSize(surface);
+        mConfiguredFormat = SurfaceUtils.getSurfaceFormat(surface);
+        mConfiguredDataspace = SurfaceUtils.getSurfaceDataspace(surface);
     }
 
     /**
@@ -106,6 +109,9 @@
         checkArgumentInRange(rotation, ROTATION_0, ROTATION_270, "Rotation constant");
         mSurface = surface;
         mRotation = rotation;
+        mConfiguredSize = SurfaceUtils.getSurfaceSize(mSurface);
+        mConfiguredFormat = SurfaceUtils.getSurfaceFormat(mSurface);
+        mConfiguredDataspace = SurfaceUtils.getSurfaceDataspace(mSurface);
     }
 
     /**
@@ -163,8 +169,9 @@
     /**
      * Check if this {@link OutputConfiguration} is equal to another {@link OutputConfiguration}.
      *
-     * <p>Two output configurations are only equal if and only if the underlying surface and
-     * all other configuration parameters are equal. </p>
+     * <p>Two output configurations are only equal if and only if the underlying surfaces, surface
+     * properties (width, height, format, dataspace) when the output configurations are created,
+     * and all other configuration parameters are equal. </p>
      *
      * @return {@code true} if the objects were equal, {@code false} otherwise
      */
@@ -176,7 +183,11 @@
             return true;
         } else if (obj instanceof OutputConfiguration) {
             final OutputConfiguration other = (OutputConfiguration) obj;
-            return (mSurface == other.mSurface && mRotation == other.mRotation);
+            return mSurface == other.mSurface &&
+                   mRotation == other.mRotation &&
+                   mConfiguredSize.equals(other.mConfiguredSize) &&
+                   mConfiguredFormat == other.mConfiguredFormat &&
+                   mConfiguredDataspace == other.mConfiguredDataspace;
         }
         return false;
     }
@@ -192,4 +203,9 @@
     private static final String TAG = "OutputConfiguration";
     private final Surface mSurface;
     private final int mRotation;
+
+    // The size, format, and dataspace of the surface when OutputConfiguration is created.
+    private final Size mConfiguredSize;
+    private final int mConfiguredFormat;
+    private final int mConfiguredDataspace;
 }
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index a6d477f..3bd12c0 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -351,8 +351,12 @@
     public void maybeMarkCapabilitiesRestricted() {
         // If all the capabilities are typically provided by restricted networks, conclude that this
         // network is restricted.
-        if ((mNetworkCapabilities & ~(DEFAULT_CAPABILITIES | RESTRICTED_CAPABILITIES)) == 0)
+        if ((mNetworkCapabilities & ~(DEFAULT_CAPABILITIES | RESTRICTED_CAPABILITIES)) == 0 &&
+                // Must have at least some restricted capabilities, otherwise a request for an
+                // internet-less network will get marked restricted.
+                (mNetworkCapabilities & RESTRICTED_CAPABILITIES) != 0) {
             removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+        }
     }
 
     /**
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index 364c0eb..aeb5d45 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -43,7 +43,7 @@
     UserInfo getPrimaryUser();
     List<UserInfo> getUsers(boolean excludeDying);
     List<UserInfo> getProfiles(int userHandle, boolean enabledOnly);
-    boolean canAddMoreManagedProfiles();
+    boolean canAddMoreManagedProfiles(int userId);
     UserInfo getProfileParent(int userHandle);
     UserInfo getUserInfo(int userHandle);
     long getUserCreationTime(int userHandle);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index aea5123..849f5de 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1024,9 +1024,9 @@
      * @return true if more managed profiles can be added, false if limit has been reached.
      * @hide
      */
-    public boolean canAddMoreManagedProfiles() {
+    public boolean canAddMoreManagedProfiles(int userId) {
         try {
-            return mService.canAddMoreManagedProfiles();
+            return mService.canAddMoreManagedProfiles(userId);
         } catch (RemoteException re) {
             Log.w(TAG, "Could not check if we can add more managed profiles", re);
             return false;
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index ef54d84..6888594 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -341,6 +341,7 @@
         }
 
         String description = null;
+        String derivedFsUuid = fsUuid;
         long mtpReserveSize = 0;
         long maxFileSize = 0;
         int mtpStorageId = StorageVolume.STORAGE_ID_INVALID;
@@ -351,6 +352,7 @@
             final VolumeInfo privateVol = storage.findPrivateForEmulated(this);
             if (privateVol != null) {
                 description = storage.getBestVolumeDescription(privateVol);
+                derivedFsUuid = privateVol.fsUuid;
             }
 
             if (isPrimary()) {
@@ -393,7 +395,7 @@
 
         return new StorageVolume(id, mtpStorageId, userPath, description, isPrimary(), removable,
                 emulated, mtpReserveSize, allowMassStorage, maxFileSize, new UserHandle(userId),
-                fsUuid, envState);
+                derivedFsUuid, envState);
     }
 
     public static int buildStableMtpStorageId(String fsUuid) {
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index db19f7a..6310570 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -118,7 +118,7 @@
     public boolean allowEvents = DEFAULT_ALLOW_EVENTS;
     public int allowCallsFrom = DEFAULT_SOURCE;
     public int allowMessagesFrom = DEFAULT_SOURCE;
-    public int user = UserHandle.USER_OWNER;
+    public int user = UserHandle.USER_SYSTEM;
 
     public ZenRule manualRule;
     public ArrayMap<String, ZenRule> automaticRules = new ArrayMap<>();
diff --git a/core/java/android/util/LocaleList.java b/core/java/android/util/LocaleList.java
new file mode 100644
index 0000000..017735a
--- /dev/null
+++ b/core/java/android/util/LocaleList.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2015 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.util;
+
+import android.annotation.Nullable;
+
+import java.util.HashSet;
+import java.util.Locale;
+
+// TODO: We don't except too many LocaleLists to exist at the same time, and
+// we need access to the data at native level, so we should pass the data
+// down to the native level, create a mapt of every list seen there, take a
+// pointer back, and just keep that pointed in the Java-level object, so
+// things could be copied very quickly.
+
+/**
+ * LocaleList is an immutable list of Locales, typically used to keep an
+ * ordered user preferences for locales.
+ */
+public final class LocaleList {
+    private final Locale[] mList;
+    private static final Locale[] sEmptyList = new Locale[0];
+
+    public Locale get(int location) {
+        return location < mList.length ? mList[location] : null;
+    }
+
+    public Locale getPrimary() {
+        return mList.length == 0 ? null : get(0);
+    }
+
+    public boolean isEmpty() {
+        return mList.length == 0;
+    }
+
+    public int size() {
+        return mList.length;
+    }
+
+    public LocaleList() {
+        mList = sEmptyList;
+    }
+
+    /**
+     * @throws NullPointerException if any of the input locales is <code>null</code>.
+     * @throws IllegalArgumentException if any of the input locales repeat.
+     */
+    public LocaleList(@Nullable Locale[] list) {
+        if (list == null || list.length == 0) {
+            mList = sEmptyList;
+        } else {
+            final Locale[] localeList = new Locale[list.length];
+            final HashSet<Locale> seenLocales = new HashSet<Locale>();
+            for (int i = 0; i < list.length; ++i) {
+                final Locale l = list[i];
+                if (l == null) {
+                    throw new NullPointerException();
+                } else if (seenLocales.contains(l)) {
+                    throw new IllegalArgumentException();
+                } else {
+                    seenLocales.add(l);
+                    localeList[i] = (Locale) l.clone();
+                }
+            }
+            mList = localeList;
+        }
+    }
+}
diff --git a/core/java/android/view/AppTransitionAnimationSpec.aidl b/core/java/android/view/AppTransitionAnimationSpec.aidl
new file mode 100644
index 0000000..8388347
--- /dev/null
+++ b/core/java/android/view/AppTransitionAnimationSpec.aidl
@@ -0,0 +1,20 @@
+/*
+** Copyright 2015, 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;
+
+/** @hide */
+parcelable AppTransitionAnimationSpec;
diff --git a/core/java/android/view/AppTransitionAnimationSpec.java b/core/java/android/view/AppTransitionAnimationSpec.java
new file mode 100644
index 0000000..c6e1989
--- /dev/null
+++ b/core/java/android/view/AppTransitionAnimationSpec.java
@@ -0,0 +1,61 @@
+package android.view;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Holds information about how the next app transition animation should be executed.
+ *
+ * This class is intended to be used with IWindowManager.overridePendingAppTransition* methods when
+ * simple arguments are not enough to describe the animation.
+ *
+ * @hide
+ */
+public class AppTransitionAnimationSpec implements Parcelable {
+    public final int taskId;
+    public final Bitmap bitmap;
+    public final Rect rect;
+
+    public AppTransitionAnimationSpec(int taskId, Bitmap bitmap, Rect rect) {
+        this.taskId = taskId;
+        this.bitmap = bitmap;
+        this.rect = rect;
+    }
+
+    public AppTransitionAnimationSpec(Parcel in) {
+        taskId = in.readInt();
+        bitmap = in.readParcelable(null);
+        rect = in.readParcelable(null);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(taskId);
+        dest.writeParcelable(bitmap, 0 /* flags */);
+        dest.writeParcelable(rect, 0 /* flags */);
+
+    }
+
+    public static final Parcelable.Creator<AppTransitionAnimationSpec> CREATOR
+            = new Parcelable.Creator<AppTransitionAnimationSpec>() {
+        public AppTransitionAnimationSpec createFromParcel(Parcel in) {
+            return new AppTransitionAnimationSpec(in);
+        }
+
+        public AppTransitionAnimationSpec[] newArray(int size) {
+            return new AppTransitionAnimationSpec[size];
+        }
+    };
+
+    @Override
+    public String toString() {
+        return "{taskId: " + taskId + ", bitmap: " + bitmap + ", rect: " + rect + "}";
+    }
+}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 0a4b982..f86adfe 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -39,6 +39,7 @@
 import android.view.InputChannel;
 import android.view.InputDevice;
 import android.view.IInputFilter;
+import android.view.AppTransitionAnimationSpec;
 import android.view.WindowContentFrameStats;
 
 /**
@@ -127,6 +128,16 @@
     void overridePendingAppTransitionAspectScaledThumb(in Bitmap srcThumb, int startX,
             int startY, int targetWidth, int targetHeight, IRemoteCallback startedCallback,
             boolean scaleUp);
+    /**
+     * Overrides animation for app transition that exits from an application to a multi-window
+     * environment and allows specifying transition animation parameters for each window.
+     *
+     * @param specs Array of transition animation descriptions for entering windows.
+     *
+     * @hide
+     */
+    void overridePendingAppTransitionMultiThumb(in AppTransitionAnimationSpec[] specs,
+            IRemoteCallback startedCallback, boolean scaleUp);
     void overridePendingAppTransitionInPlace(String packageName, int anim);
     void executeAppTransition();
     void setAppStartingWindow(IBinder token, String pkg, int theme,
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index cdc196e..197ea09 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -23,6 +23,7 @@
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
+import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Log;
 
@@ -294,6 +295,22 @@
     public void buildLayer() {
     }
 
+    @Override
+    public void setForeground(Drawable foreground) {
+        if (foreground != null) {
+            throw new UnsupportedOperationException(
+                    "TextureView doesn't support displaying a foreground drawable");
+        }
+    }
+
+    @Override
+    public void setBackgroundDrawable(Drawable background) {
+        if (background != null) {
+            throw new UnsupportedOperationException(
+                    "TextureView doesn't support displaying a background drawable");
+        }
+    }
+
     /**
      * Subclasses of TextureView cannot do their own rendering
      * with the {@link Canvas} object.
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index d9faece..5fc8c7a 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -220,7 +220,7 @@
                 result.putExtras(replExtras);
             }
         }
-        if (aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER)
+        if (aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_PARENT)
                 || aInfo.name.equals(IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE)) {
             result = Intent.createChooser(result,
                     getIntent().getCharSequenceExtra(Intent.EXTRA_TITLE));
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 39b66aa..dbec740 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -45,8 +45,8 @@
 
     public static String TAG = "IntentForwarderActivity";
 
-    public static String FORWARD_INTENT_TO_USER_OWNER
-            = "com.android.internal.app.ForwardIntentToUserOwner";
+    public static String FORWARD_INTENT_TO_PARENT
+            = "com.android.internal.app.ForwardIntentToParent";
 
     public static String FORWARD_INTENT_TO_MANAGED_PROFILE
             = "com.android.internal.app.ForwardIntentToManagedProfile";
@@ -60,9 +60,9 @@
         final int targetUserId;
         final int userMessageId;
 
-        if (className.equals(FORWARD_INTENT_TO_USER_OWNER)) {
+        if (className.equals(FORWARD_INTENT_TO_PARENT)) {
             userMessageId = com.android.internal.R.string.forward_intent_to_owner;
-            targetUserId = UserHandle.USER_OWNER;
+            targetUserId = getProfileParent();
         } else if (className.equals(FORWARD_INTENT_TO_MANAGED_PROFILE)) {
             userMessageId = com.android.internal.R.string.forward_intent_to_work;
             targetUserId = getManagedProfile();
@@ -72,7 +72,7 @@
             targetUserId = UserHandle.USER_NULL;
         }
         if (targetUserId == UserHandle.USER_NULL) {
-            // This covers the case where there is no managed profile.
+            // This covers the case where there is no parent / managed profile.
             finish();
             return;
         }
@@ -168,7 +168,7 @@
      */
     private int getManagedProfile() {
         UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
-        List<UserInfo> relatedUsers = userManager.getProfiles(UserHandle.USER_OWNER);
+        List<UserInfo> relatedUsers = userManager.getProfiles(UserHandle.myUserId());
         for (UserInfo userInfo : relatedUsers) {
             if (userInfo.isManagedProfile()) return userInfo.id;
         }
@@ -176,4 +176,19 @@
                 + " has been called, but there is no managed profile");
         return UserHandle.USER_NULL;
     }
+
+    /**
+     * Returns the userId of the profile parent or UserHandle.USER_NULL if there is
+     * no parent.
+     */
+    private int getProfileParent() {
+        UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        UserInfo parent = userManager.getProfileParent(UserHandle.myUserId());
+        if (parent == null) {
+            Slog.wtf(TAG, FORWARD_INTENT_TO_PARENT
+                    + " has been called, but there is no parent");
+            return UserHandle.USER_NULL;
+        }
+        return parent.id;
+    }
 }
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index c1645c3..1e41e63 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -46,6 +46,8 @@
     void cancelPreloadRecentApps();
     void showScreenPinningRequest();
 
+    void showKeyboardShortcutsMenu();
+
     /**
      * Notifies the status bar that an app transition is pending to delay applying some flags with
      * visual impact until {@link #appTransitionReady} is called.
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 7db2cc9..6c957be 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -68,6 +68,8 @@
     void preloadRecentApps();
     void cancelPreloadRecentApps();
 
+    void showKeyboardShortcutsMenu();
+
     /**
      * Notifies the status bar that an app transition is pending to delay applying some flags with
      * visual impact until {@link #appTransitionReady} is called.
diff --git a/core/java/com/android/internal/widget/NonClientDecorView.java b/core/java/com/android/internal/widget/NonClientDecorView.java
index 05711b5..92812f8 100644
--- a/core/java/com/android/internal/widget/NonClientDecorView.java
+++ b/core/java/com/android/internal/widget/NonClientDecorView.java
@@ -20,6 +20,7 @@
 import android.graphics.Rect;
 import android.os.RemoteException;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
 import android.view.View;
 import android.widget.LinearLayout;
 import android.view.ViewGroup;
@@ -63,18 +64,31 @@
     private final int DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP = 20;
     // The height of a window which has not in DIP.
     private final int DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP = 5;
-
     private PhoneWindow mOwner = null;
-    boolean mWindowHasShadow = false;
-    boolean mShowDecor = false;
+    private boolean mWindowHasShadow = false;
+    private boolean mShowDecor = false;
+
+    // True if the window is being dragged.
+    private boolean mDragging = false;
+
+    // The bounds of the window and the absolute mouse pointer coordinates from before we started to
+    // drag the window. They will be used to determine the next window position.
+    private final Rect mWindowOriginalBounds = new Rect();
+    private float mStartDragX;
+    private float mStartDragY;
+    // True when the left mouse button got released while dragging.
+    private boolean mLeftMouseButtonReleased;
+
+    // Avoiding re-creation of Rect's by keeping a temporary window drag bound.
+    private final Rect mWindowDragBounds = new Rect();
 
     // The current focus state of the window for updating the window elevation.
-    boolean mWindowHasFocus = true;
+    private boolean mWindowHasFocus = true;
 
     // Cludge to address b/22668382: Set the shadow size to the maximum so that the layer
     // size calculation takes the shadow size into account. We set the elevation currently
     // to max until the first layout command has been executed.
-    boolean mAllowUpdateElevation = false;
+    private boolean mAllowUpdateElevation = false;
 
     public NonClientDecorView(Context context) {
         super(context);
@@ -103,6 +117,62 @@
         findViewById(R.id.close_window).setOnClickListener(this);
     }
 
+    @Override
+    public boolean onTouchEvent(MotionEvent e) {
+        // Note: There are no mixed events. When a new device gets used (e.g. 1. Mouse, 2. touch)
+        // the old input device events get cancelled first. So no need to remember the kind of
+        // input device we are listening to.
+        switch (e.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                // A drag action is started if we aren't dragging already and the starting event is
+                // either a left mouse button or any other input device.
+                if (!mDragging &&
+                        (e.getToolType(e.getActionIndex()) != MotionEvent.TOOL_TYPE_MOUSE ||
+                                (e.getButtonState() & MotionEvent.BUTTON_PRIMARY) != 0)) {
+                    mDragging = true;
+                    mWindowOriginalBounds.set(getActivityBounds());
+                    mLeftMouseButtonReleased = false;
+                    mStartDragX = e.getRawX();
+                    mStartDragY = e.getRawY();
+                }
+                break;
+
+            case MotionEvent.ACTION_MOVE:
+                if (mDragging && !mLeftMouseButtonReleased) {
+                    if (e.getToolType(e.getActionIndex()) == MotionEvent.TOOL_TYPE_MOUSE &&
+                            (e.getButtonState() & MotionEvent.BUTTON_PRIMARY) == 0) {
+                        // There is no separate mouse button up call and if the user mixes mouse
+                        // button drag actions, we stop dragging once he releases the button.
+                        mLeftMouseButtonReleased = true;
+                        break;
+                    }
+                    mWindowDragBounds.set(mWindowOriginalBounds);
+                    mWindowDragBounds.offset(Math.round(e.getRawX() - mStartDragX),
+                            Math.round(e.getRawY() - mStartDragY));
+                    setActivityBounds(mWindowDragBounds);
+                }
+                break;
+
+            case MotionEvent.ACTION_UP:
+                if (mDragging) {
+                    // Since the window is already where it should be we don't have to do anything
+                    // special at this time.
+                    mDragging = false;
+                    return true;
+                }
+                break;
+
+            case MotionEvent.ACTION_CANCEL:
+                if (mDragging) {
+                    mDragging = false;
+                    setActivityBounds(mWindowOriginalBounds);
+                    return true;
+                }
+                break;
+        }
+        return mDragging;
+    }
+
     /**
      * The phone window configuration has changed and the decor needs to be updated.
      * @param showDecor True if the decor should be shown.
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index c66cdfe..988d13a 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -112,15 +112,15 @@
     }
 
     static jlong init(JNIEnv* env, jobject clazz) {
-        SK_COMPILE_ASSERT(1 <<  0 == SkPaint::kAntiAlias_Flag,          paint_flags_mismatch);
-        SK_COMPILE_ASSERT(1 <<  2 == SkPaint::kDither_Flag,             paint_flags_mismatch);
-        SK_COMPILE_ASSERT(1 <<  3 == SkPaint::kUnderlineText_Flag,      paint_flags_mismatch);
-        SK_COMPILE_ASSERT(1 <<  4 == SkPaint::kStrikeThruText_Flag,     paint_flags_mismatch);
-        SK_COMPILE_ASSERT(1 <<  5 == SkPaint::kFakeBoldText_Flag,       paint_flags_mismatch);
-        SK_COMPILE_ASSERT(1 <<  6 == SkPaint::kLinearText_Flag,         paint_flags_mismatch);
-        SK_COMPILE_ASSERT(1 <<  7 == SkPaint::kSubpixelText_Flag,       paint_flags_mismatch);
-        SK_COMPILE_ASSERT(1 <<  8 == SkPaint::kDevKernText_Flag,        paint_flags_mismatch);
-        SK_COMPILE_ASSERT(1 << 10 == SkPaint::kEmbeddedBitmapText_Flag, paint_flags_mismatch);
+        static_assert(1 <<  0 == SkPaint::kAntiAlias_Flag,          "paint_flags_mismatch");
+        static_assert(1 <<  2 == SkPaint::kDither_Flag,             "paint_flags_mismatch");
+        static_assert(1 <<  3 == SkPaint::kUnderlineText_Flag,      "paint_flags_mismatch");
+        static_assert(1 <<  4 == SkPaint::kStrikeThruText_Flag,     "paint_flags_mismatch");
+        static_assert(1 <<  5 == SkPaint::kFakeBoldText_Flag,       "paint_flags_mismatch");
+        static_assert(1 <<  6 == SkPaint::kLinearText_Flag,         "paint_flags_mismatch");
+        static_assert(1 <<  7 == SkPaint::kSubpixelText_Flag,       "paint_flags_mismatch");
+        static_assert(1 <<  8 == SkPaint::kDevKernText_Flag,        "paint_flags_mismatch");
+        static_assert(1 << 10 == SkPaint::kEmbeddedBitmapText_Flag, "paint_flags_mismatch");
 
         Paint* obj = new Paint();
         defaultSettingsForAndroid(obj);
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp
index f7b5dc2..dbd7c89 100644
--- a/core/jni/android/graphics/Path.cpp
+++ b/core/jni/android/graphics/Path.cpp
@@ -519,6 +519,9 @@
 
 int register_android_graphics_Path(JNIEnv* env) {
     return RegisterMethodsOrDie(env, "android/graphics/Path", methods, NELEM(methods));
+
+    static_assert(0  == SkPath::kCW_Direction,  "direction_mismatch");
+    static_assert(1  == SkPath::kCCW_Direction, "direction_mismatch");
 }
 
 }
diff --git a/core/jni/android/graphics/PorterDuff.cpp b/core/jni/android/graphics/PorterDuff.cpp
index d65864d..fed90a5 100644
--- a/core/jni/android/graphics/PorterDuff.cpp
+++ b/core/jni/android/graphics/PorterDuff.cpp
@@ -33,29 +33,29 @@
 
     static jlong CreateXfermode(JNIEnv* env, jobject, jint modeHandle) {
         // validate that the Java enum values match our expectations
-        SK_COMPILE_ASSERT(0  == SkXfermode::kClear_Mode,    xfermode_mismatch);
-        SK_COMPILE_ASSERT(1  == SkXfermode::kSrc_Mode,      xfermode_mismatch);
-        SK_COMPILE_ASSERT(2  == SkXfermode::kDst_Mode,      xfermode_mismatch);
-        SK_COMPILE_ASSERT(3  == SkXfermode::kSrcOver_Mode,  xfermode_mismatch);
-        SK_COMPILE_ASSERT(4  == SkXfermode::kDstOver_Mode,  xfermode_mismatch);
-        SK_COMPILE_ASSERT(5  == SkXfermode::kSrcIn_Mode,    xfermode_mismatch);
-        SK_COMPILE_ASSERT(6  == SkXfermode::kDstIn_Mode,    xfermode_mismatch);
-        SK_COMPILE_ASSERT(7  == SkXfermode::kSrcOut_Mode,   xfermode_mismatch);
-        SK_COMPILE_ASSERT(8  == SkXfermode::kDstOut_Mode,   xfermode_mismatch);
-        SK_COMPILE_ASSERT(9  == SkXfermode::kSrcATop_Mode,  xfermode_mismatch);
-        SK_COMPILE_ASSERT(10 == SkXfermode::kDstATop_Mode,  xfermode_mismatch);
-        SK_COMPILE_ASSERT(11 == SkXfermode::kXor_Mode,      xfermode_mismatch);
-        SK_COMPILE_ASSERT(16 == SkXfermode::kDarken_Mode,   xfermode_mismatch);
-        SK_COMPILE_ASSERT(17 == SkXfermode::kLighten_Mode,  xfermode_mismatch);
-        SK_COMPILE_ASSERT(13 == SkXfermode::kModulate_Mode, xfermode_mismatch);
-        SK_COMPILE_ASSERT(14 == SkXfermode::kScreen_Mode,   xfermode_mismatch);
-        SK_COMPILE_ASSERT(12 == SkXfermode::kPlus_Mode,     xfermode_mismatch);
-        SK_COMPILE_ASSERT(15 == SkXfermode::kOverlay_Mode,  xfermode_mismatch);
-        
+        static_assert(0  == SkXfermode::kClear_Mode,    "xfermode_mismatch");
+        static_assert(1  == SkXfermode::kSrc_Mode,      "xfermode_mismatch");
+        static_assert(2  == SkXfermode::kDst_Mode,      "xfermode_mismatch");
+        static_assert(3  == SkXfermode::kSrcOver_Mode,  "xfermode_mismatch");
+        static_assert(4  == SkXfermode::kDstOver_Mode,  "xfermode_mismatch");
+        static_assert(5  == SkXfermode::kSrcIn_Mode,    "xfermode_mismatch");
+        static_assert(6  == SkXfermode::kDstIn_Mode,    "xfermode_mismatch");
+        static_assert(7  == SkXfermode::kSrcOut_Mode,   "xfermode_mismatch");
+        static_assert(8  == SkXfermode::kDstOut_Mode,   "xfermode_mismatch");
+        static_assert(9  == SkXfermode::kSrcATop_Mode,  "xfermode_mismatch");
+        static_assert(10 == SkXfermode::kDstATop_Mode,  "xfermode_mismatch");
+        static_assert(11 == SkXfermode::kXor_Mode,      "xfermode_mismatch");
+        static_assert(16 == SkXfermode::kDarken_Mode,   "xfermode_mismatch");
+        static_assert(17 == SkXfermode::kLighten_Mode,  "xfermode_mismatch");
+        static_assert(13 == SkXfermode::kModulate_Mode, "xfermode_mismatch");
+        static_assert(14 == SkXfermode::kScreen_Mode,   "xfermode_mismatch");
+        static_assert(12 == SkXfermode::kPlus_Mode,     "xfermode_mismatch");
+        static_assert(15 == SkXfermode::kOverlay_Mode,  "xfermode_mismatch");
+
         SkXfermode::Mode mode = static_cast<SkXfermode::Mode>(modeHandle);
         return reinterpret_cast<jlong>(SkXfermode::Create(mode));
     }
- 
+
 };
 
 static JNINativeMethod methods[] = {
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 4c920dc..414cbb4 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -358,8 +358,8 @@
     return;
   }
   jsize count = env->GetArrayLength(fdsToClose);
-  jint *ar = env->GetIntArrayElements(fdsToClose, 0);
-  if (!ar) {
+  ScopedIntArrayRO ar(env, fdsToClose);
+  if (ar.get() == NULL) {
       ALOGE("Bad fd array");
       RuntimeAbort(env);
   }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d591f8b..fefd5a7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -786,6 +786,46 @@
         android:protectionLevel="normal"
         android:permissionFlags="hidden"/>
 
+    <!-- @hide We need to keep this around for backwards compatibility -->
+    <permission android:name="android.permission.WRITE_SMS"
+        android:protectionLevel="normal"
+        android:permissionFlags="hidden"/>
+
+    <!-- @hide We need to keep this around for backwards compatibility -->
+    <permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"
+        android:protectionLevel="normal"
+        android:permissionFlags="hidden"/>
+
+    <!-- @hide We need to keep this around for backwards compatibility -->
+    <permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"
+        android:protectionLevel="normal"
+        android:permissionFlags="hidden"/>
+
+    <!-- @hide We need to keep this around for backwards compatibility -->
+    <permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"
+        android:protectionLevel="normal"
+        android:permissionFlags="hidden"/>
+
+    <!-- @hide We need to keep this around for backwards compatibility -->
+    <permission android:name="android.permission.MANAGE_ACCOUNTS"
+        android:protectionLevel="normal"
+        android:permissionFlags="hidden"/>
+
+    <!-- @hide We need to keep this around for backwards compatibility -->
+    <permission android:name="android.permission.USE_CREDENTIALS"
+        android:protectionLevel="normal"
+        android:permissionFlags="hidden"/>
+
+    <!-- @hide We need to keep this around for backwards compatibility -->
+    <permission android:name="android.permission.SUBSCRIBED_FEEDS_READ"
+        android:protectionLevel="normal"
+        android:permissionFlags="hidden"/>
+
+    <!-- @hide We need to keep this around for backwards compatibility -->
+    <permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE"
+        android:protectionLevel="normal"
+        android:permissionFlags="hidden"/>
+
     <!-- ====================================================================== -->
     <!-- INSTALL PERMISSIONS                                                    -->
     <!-- ====================================================================== -->
@@ -2658,7 +2698,7 @@
                 android:exported="true"
                 >
         </activity>
-        <activity-alias android:name="com.android.internal.app.ForwardIntentToUserOwner"
+        <activity-alias android:name="com.android.internal.app.ForwardIntentToParent"
                 android:targetActivity="com.android.internal.app.IntentForwarderActivity"
                 android:exported="true"
                 android:label="@string/user_owner_label">
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 1a45b3a..74fd1ec 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2195,4 +2195,18 @@
       <attr name="name" />
     </declare-styleable>
 
+    <!-- <code>initial-layout</code> tag allows configuring the initial layout for the activity
+         within multi-window environment. -->
+    <declare-styleable name="AndroidManifestInitialLayout" parent="AndroidManifestActivity">
+        <!-- Initial width of the activity. Can be either a fixed value or fraction, in which case
+             the width will be constructed as a fraction of the total available width. -->
+        <attr name="activity_width" format="dimension|fraction" />
+        <!-- Initial height of the activity. Can be either a fixed value or fraction, in which case
+             the height will be constructed as a fraction of the total available height. -->
+        <attr name="activity_height" format="dimension|fraction" />
+        <!-- Where to initially position the activity inside the available space. Uses constants
+             defined in {@link android.view.Gravity}. -->
+        <attr name="gravity" />
+    </declare-styleable>
+
 </resources>
diff --git a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
new file mode 100644
index 0000000..03ae9dc
--- /dev/null
+++ b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
@@ -0,0 +1,494 @@
+/*
+* Copyright (C) 2015 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.animation;
+
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import static android.test.MoreAsserts.assertNotEqual;
+
+public class ValueAnimatorTests extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> {
+    private ValueAnimator a1;
+    private ValueAnimator a2;
+
+    // Tolerance of error in calculations related to duration, frame time, etc. due to frame delay.
+    private final static long TOLERANCE = 100; // ms
+    private final static long POLL_INTERVAL = 100; // ms
+
+    private final static float A1_START_VALUE = 0f;
+    private final static float A1_END_VALUE = 1f;
+    private final static int A2_START_VALUE = 100;
+    private final static int A2_END_VALUE = 200;
+
+    public ValueAnimatorTests() {
+        super(BasicAnimatorActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        a1 = ValueAnimator.ofFloat(A1_START_VALUE, A1_END_VALUE).setDuration(300);
+        a2 = ValueAnimator.ofInt(A2_START_VALUE, A2_END_VALUE).setDuration(500);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        a1 = null;
+        a2 = null;
+    }
+
+    @SmallTest
+    public void testStartDelay() throws Throwable {
+        final ValueAnimator a = ValueAnimator.ofFloat(5f, 20f);
+        assertEquals(a.getStartDelay(), 0);
+        final long delay = 200;
+        a.setStartDelay(delay);
+        assertEquals(a.getStartDelay(), delay);
+
+        final MyUpdateListener listener = new MyUpdateListener();
+        a.addUpdateListener(listener);
+        final long[] startTime = new long[1];
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Test the time between isRunning() and isStarted()
+                assertFalse(a.isStarted());
+                assertFalse(a.isRunning());
+                a.start();
+                startTime[0] = SystemClock.uptimeMillis();
+                assertTrue(a.isStarted());
+                assertFalse(a.isRunning());
+            }
+        });
+
+        Thread.sleep(a.getTotalDuration());
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(listener.wasRunning);
+                assertTrue(listener.firstRunningFrameTime - startTime[0] >= delay);
+            }
+        });
+
+        Thread.sleep(a.getTotalDuration());
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertFalse(a.isStarted());
+            }
+        });
+    }
+
+    @SmallTest
+    public void testListenerCallbacks() throws Throwable {
+        final MyListener l1 = new MyListener();
+        final MyListener l2 = new MyListener();
+        a1.addListener(l1);
+        a2.addListener(l2);
+        a2.setStartDelay(400);
+
+        assertFalse(l1.startCalled);
+        assertFalse(l1.cancelCalled);
+        assertFalse(l1.endCalled);
+        assertFalse(l2.startCalled);
+        assertFalse(l2.cancelCalled);
+        assertFalse(l2.endCalled);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                a1.start();
+                a2.start();
+            }
+        });
+
+        long wait = 0;
+        Thread.sleep(POLL_INTERVAL);
+        wait += POLL_INTERVAL;
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertFalse(l1.cancelCalled);
+                a1.cancel();
+                assertTrue(l1.cancelCalled);
+                assertTrue(l1.endCalled);
+            }
+        });
+
+        while (wait < a2.getStartDelay()) {
+            runTestOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    // Make sure a2's start listener isn't called during start delay.
+                    assertTrue(l1.startCalled);
+                    assertFalse(l2.startCalled);
+                }
+            });
+            Thread.sleep(POLL_INTERVAL);
+            wait += POLL_INTERVAL;
+        }
+
+        long delay = Math.max(a1.getTotalDuration(), a2.getTotalDuration()) + TOLERANCE;
+        Thread.sleep(delay);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // a1 is canceled.
+                assertTrue(l1.startCalled);
+                assertTrue(l1.cancelCalled);
+                assertTrue(l1.endCalled);
+
+                // a2 is supposed to finish normally
+                assertTrue(l2.startCalled);
+                assertFalse(l2.cancelCalled);
+                assertTrue(l2.endCalled);
+            }
+        });
+    }
+
+    @SmallTest
+    public void testIsStarted() throws Throwable {
+        assertFalse(a1.isStarted());
+        assertFalse(a2.isStarted());
+        assertFalse(a1.isRunning());
+        assertFalse(a2.isRunning());
+        final long startDelay = 150;
+        a1.setStartDelay(startDelay);
+        final long[] startTime = new long[1];
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                a1.start();
+                a2.start();
+                startTime[0] = SystemClock.uptimeMillis();
+                assertTrue(a1.isStarted());
+                assertTrue(a2.isStarted());
+            }
+        });
+        long delayMs = 0;
+        while (delayMs < startDelay) {
+            Thread.sleep(POLL_INTERVAL);
+            delayMs += POLL_INTERVAL;
+            runTestOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    if (SystemClock.uptimeMillis() - startTime[0] < startDelay) {
+                        assertFalse(a1.isRunning());
+                    }
+                }
+            });
+        }
+
+        Thread.sleep(startDelay);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(a1.isRunning());
+                assertTrue(a2.isRunning());
+            }
+        });
+
+        long delay = Math.max(a1.getTotalDuration(), a2.getTotalDuration()) * 2;
+        Thread.sleep(delay);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertFalse(a1.isStarted());
+                assertFalse(a1.isRunning());
+                assertFalse(a2.isStarted());
+                assertFalse(a2.isRunning());
+            }
+        });
+    }
+
+    @SmallTest
+    public void testPause() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertFalse(a1.isPaused());
+                assertFalse(a2.isPaused());
+
+                a1.start();
+                a2.start();
+
+                assertFalse(a1.isPaused());
+                assertFalse(a2.isPaused());
+                assertTrue(a1.isStarted());
+                assertTrue(a2.isStarted());
+            }
+        });
+
+        Thread.sleep(POLL_INTERVAL);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(a1.isRunning());
+                assertTrue(a2.isRunning());
+                a1.pause();
+                assertTrue(a1.isPaused());
+                assertFalse(a2.isPaused());
+                assertTrue(a1.isRunning());
+            }
+        });
+
+        Thread.sleep(a2.getTotalDuration());
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // By this time, a2 should have finished, and a1 is still paused
+                assertFalse(a2.isStarted());
+                assertFalse(a2.isRunning());
+                assertTrue(a1.isStarted());
+                assertTrue(a1.isRunning());
+                assertTrue(a1.isPaused());
+
+                a1.resume();
+            }
+        });
+
+        Thread.sleep(POLL_INTERVAL);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(a1.isRunning());
+                assertTrue(a1.isStarted());
+                assertFalse(a1.isPaused());
+            }
+        });
+
+        Thread.sleep(a1.getTotalDuration());
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // a1 should finish by now.
+                assertFalse(a1.isRunning());
+                assertFalse(a1.isStarted());
+                assertFalse(a1.isPaused());
+            }
+        });
+
+    }
+
+    @SmallTest
+    public void testPauseListener() throws Throwable {
+        MyPauseListener l1 = new MyPauseListener();
+        MyPauseListener l2 = new MyPauseListener();
+        a1.addPauseListener(l1);
+        a2.addPauseListener(l2);
+
+        assertFalse(l1.pauseCalled);
+        assertFalse(l1.resumeCalled);
+        assertFalse(l2.pauseCalled);
+        assertFalse(l2.resumeCalled);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                a1.start();
+                a2.start();
+            }
+        });
+
+        Thread.sleep(a1.getTotalDuration() / 2);
+        a1.pause();
+
+        Thread.sleep(a2.getTotalDuration());
+
+        // Only a1's pause listener should be called.
+        assertTrue(l1.pauseCalled);
+        assertFalse(l1.resumeCalled);
+        a1.resume();
+
+        Thread.sleep(a1.getTotalDuration());
+
+        assertTrue(l1.pauseCalled);
+        assertTrue(l1.resumeCalled);
+        assertFalse(l2.pauseCalled);
+        assertFalse(l2.resumeCalled);
+    }
+
+    @SmallTest
+    public void testResume() throws Throwable {
+        final MyUpdateListener l1 = new MyUpdateListener();
+        final long totalDuration = a1.getTotalDuration();
+        a1.addUpdateListener(l1);
+        // Set a longer duration on a1 for this test
+        a1.setDuration(1000);
+        assertTrue(l1.firstRunningFrameTime < 0);
+        assertTrue(l1.lastUpdateTime < 0);
+
+        final long[] lastUpdate = new long[1];
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                a1.start();
+            }
+        });
+
+        Thread.sleep(totalDuration / 2);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertTrue(l1.firstRunningFrameTime > 0);
+                assertTrue(l1.lastUpdateTime > l1.firstRunningFrameTime);
+                lastUpdate[0] = l1.lastUpdateTime;
+                a1.pause();
+            }
+        });
+
+        Thread.sleep(totalDuration);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // There should be no update after pause()
+                assertEquals(lastUpdate[0], l1.lastUpdateTime);
+                a1.resume();
+            }
+        });
+
+        do {
+            Thread.sleep(POLL_INTERVAL);
+            runTestOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    assertTrue(l1.lastUpdateTime > lastUpdate[0]);
+                    lastUpdate[0] = l1.lastUpdateTime;
+                }
+            });
+        } while (!a1.isStarted());
+
+        // Time between pause and resume: totalDuration
+        long entireSpan = totalDuration * 2;
+        long frameDelta = l1.lastUpdateTime - l1.firstRunningFrameTime;
+        assertTrue(Math.abs(entireSpan - frameDelta) < TOLERANCE);
+    }
+
+    @SmallTest
+    public void testEndValue() throws Throwable {
+        final MyListener l1 = new MyListener();
+        a1.addListener(l1);
+
+        final MyListener l2 = new MyListener();
+        a2.addListener(l2);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                a1.start();
+                a2.start();
+            }
+        });
+
+        Thread.sleep(POLL_INTERVAL);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                // Animation has started but not finished, check animated values against end values
+                assertFalse(l1.endCalled);
+                assertFalse(l2.endCalled);
+                assertNotEqual(A1_END_VALUE, a1.getAnimatedValue());
+                assertNotEqual(A1_END_VALUE, a2.getAnimatedValue());
+
+                // Force a2 to end.
+                a2.end();
+            }
+        });
+
+        Thread.sleep(a1.getTotalDuration());
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertFalse(l1.cancelCalled);
+                assertTrue(l1.endCalled);
+                assertFalse(l2.cancelCalled);
+                assertTrue(l2.endCalled);
+
+                // By now a1 should have finished normally and a2 has skipped to the end, check
+                // their end values.
+                assertEquals(A1_END_VALUE, ((Float) (a1.getAnimatedValue())).floatValue());
+                assertEquals(A2_END_VALUE, ((Integer) (a2.getAnimatedValue())).intValue());
+            }
+        });
+    }
+
+    class MyUpdateListener implements ValueAnimator.AnimatorUpdateListener {
+        boolean wasRunning = false;
+        long firstRunningFrameTime = -1;
+        long lastUpdateTime = -1;
+
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            lastUpdateTime = SystemClock.uptimeMillis();
+            if (animation.isRunning() && !wasRunning) {
+                // Delay has passed
+                firstRunningFrameTime = lastUpdateTime;
+                wasRunning = animation.isRunning();
+            }
+        }
+    }
+
+    class MyListener implements Animator.AnimatorListener {
+        boolean startCalled = false;
+        boolean cancelCalled = false;
+        boolean endCalled = false;
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+            startCalled = true;
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            endCalled = true;
+        }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+            cancelCalled = true;
+        }
+
+        @Override
+        public void onAnimationRepeat(Animator animation) {
+
+        }
+    }
+
+    class MyPauseListener implements Animator.AnimatorPauseListener {
+        boolean pauseCalled = false;
+        boolean resumeCalled = false;
+
+        @Override
+        public void onAnimationPause(Animator animation) {
+            pauseCalled = true;
+        }
+
+        @Override
+        public void onAnimationResume(Animator animation) {
+            resumeCalled = true;
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/widget/TextViewTest.java b/core/tests/coretests/src/android/widget/TextViewTest.java
index 0b94f8b..49d9115 100644
--- a/core/tests/coretests/src/android/widget/TextViewTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewTest.java
@@ -18,7 +18,7 @@
 
 import android.app.Activity;
 import android.content.Intent;
-import android.test.AndroidTestCase;
+import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.GetChars;
 import android.text.Selection;
@@ -27,11 +27,15 @@
 /**
  * TextViewTest tests {@link TextView}.
  */
-public class TextViewTest extends AndroidTestCase {
+public class TextViewTest extends ActivityInstrumentationTestCase2<TextViewActivity> {
+
+    public TextViewTest() {
+        super(TextViewActivity.class);
+    }
 
     @SmallTest
     public void testArray() throws Exception {
-        TextView tv = new TextView(mContext);
+        TextView tv = new TextView(getActivity());
 
         char[] c = new char[] { 'H', 'e', 'l', 'l', 'o', ' ',
                                 'W', 'o', 'r', 'l', 'd', '!' };
@@ -59,25 +63,34 @@
         assertEquals('\0', c2[5]);
     }
 
+    @SmallTest
     public void testProcessTextActivityResultNonEditable() {
-        TextView tv = new TextView(mContext);
+        final TextView tv = new TextView(getActivity());
         CharSequence originalText = "This is some text.";
         tv.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, tv.getText().toString());
         tv.setTextIsSelectable(true);
         Selection.setSelection((Spannable) tv.getText(), 0, tv.getText().length());
 
-        CharSequence newText = "Text is replaced.";
-        Intent data = new Intent();
-        data.putExtra(Intent.EXTRA_PROCESS_TEXT, newText);
-        tv.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_OK, data);
+        // We need to run this in the UI thread, as it will create a Toast.
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                CharSequence newText = "Text is replaced.";
+                Intent data = new Intent();
+                data.putExtra(Intent.EXTRA_PROCESS_TEXT, newText);
+                tv.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_OK, data);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
 
         // This is a TextView, which can't be modified. Hence no change should have been made.
         assertEquals(originalText, tv.getText().toString());
     }
 
+    @SmallTest
     public void testProcessTextActivityResultEditable() {
-        EditText tv = new EditText(mContext);
+        EditText tv = new EditText(getActivity());
         CharSequence originalText = "This is some text.";
         tv.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, tv.getText().toString());
@@ -92,8 +105,9 @@
         assertEquals(newText, tv.getText().toString());
     }
 
+    @SmallTest
     public void testProcessTextActivityResultCancel() {
-        EditText tv = new EditText(mContext);
+        EditText tv = new EditText(getActivity());
         CharSequence originalText = "This is some text.";
         tv.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, tv.getText().toString());
@@ -108,8 +122,9 @@
         assertEquals(originalText, tv.getText().toString());
     }
 
+    @SmallTest
     public void testProcessTextActivityNoData() {
-        EditText tv = new EditText(mContext);
+        EditText tv = new EditText(getActivity());
         CharSequence originalText = "This is some text.";
         tv.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, tv.getText().toString());
diff --git a/docs/html/design/media/wear/1-tap-launch.png b/docs/html/design/media/wear/1-tap-launch.png
new file mode 100644
index 0000000..c0c9aca
--- /dev/null
+++ b/docs/html/design/media/wear/1-tap-launch.png
Binary files differ
diff --git a/docs/html/design/media/wear/2-tap-launch.png b/docs/html/design/media/wear/2-tap-launch.png
new file mode 100644
index 0000000..395a3ce
--- /dev/null
+++ b/docs/html/design/media/wear/2-tap-launch.png
Binary files differ
diff --git a/docs/html/design/media/wear/aesthetic.png b/docs/html/design/media/wear/aesthetic.png
new file mode 100644
index 0000000..f6e5f3e
--- /dev/null
+++ b/docs/html/design/media/wear/aesthetic.png
Binary files differ
diff --git a/docs/html/design/media/wear/available_gestures.png b/docs/html/design/media/wear/available_gestures.png
new file mode 100644
index 0000000..677076b
--- /dev/null
+++ b/docs/html/design/media/wear/available_gestures.png
Binary files differ
diff --git a/docs/html/design/media/wear/available_gestures_2x.png b/docs/html/design/media/wear/available_gestures_2x.png
new file mode 100644
index 0000000..eced0c7
--- /dev/null
+++ b/docs/html/design/media/wear/available_gestures_2x.png
Binary files differ
diff --git a/docs/html/design/media/wear/changing-target.png b/docs/html/design/media/wear/changing-target.png
new file mode 100644
index 0000000..427531f
--- /dev/null
+++ b/docs/html/design/media/wear/changing-target.png
Binary files differ
diff --git a/docs/html/design/media/wear/revealing-info.png b/docs/html/design/media/wear/revealing-info.png
new file mode 100644
index 0000000..e419e9f
--- /dev/null
+++ b/docs/html/design/media/wear/revealing-info.png
Binary files differ
diff --git a/docs/html/design/media/wear/toggling-states.png b/docs/html/design/media/wear/toggling-states.png
new file mode 100644
index 0000000..93398e6
--- /dev/null
+++ b/docs/html/design/media/wear/toggling-states.png
Binary files differ
diff --git a/docs/html/design/media/wear/visual_feedback.gif b/docs/html/design/media/wear/visual_feedback.gif
new file mode 100644
index 0000000..e07000a
--- /dev/null
+++ b/docs/html/design/media/wear/visual_feedback.gif
Binary files differ
diff --git a/docs/html/design/wear/watchfaces.jd b/docs/html/design/wear/watchfaces.jd
index e018523..c8c6d5a 100644
--- a/docs/html/design/wear/watchfaces.jd
+++ b/docs/html/design/wear/watchfaces.jd
@@ -288,6 +288,107 @@
 with an actual watch screen before you start coding.</p>
 
 
+<h2 id="interactive">Design Interactive Watch Faces</h2>
+
+<p>Your watch face can respond to a single-tap gesture from the user, as long as
+there’s not another UI element that also responds to that gesture. Some possible use cases for
+interacting with the watch face include:</p>
+
+<ul>
+   <li><strong>Causing an aesthetic change</strong> on the watch face, for example inverting
+         the color scheme.</li>
+   <li><strong>Showing more information</strong> inline on the watch face, for example displaying a
+         detailed step count.</li>
+   <li><strong>Completing an action</strong> inline or in the background, for example starting a
+         timer.</li>
+   <li><strong>Launching a specific activity,</strong> for example a starting a conversation in a
+   messaging application.</li>
+</ul>
+
+<h3 id="ag">Available gestures</h3>
+<p>Only single taps are available. This restriction is important for maintaining clear and
+consistent system interactions, and for making watch face interactions as simple as
+possible: Neither you nor the user should think of watch faces as full-fledged apps. Figure 1
+summarizes the categories of gestures, and their uses.</p>
+
+<img src="{@docRoot}design/media/wear/available_gestures.png"
+srcset="{@docRoot}design/media/wear/available_gestures.png 1x,
+{@docRoot}design/media/wear/available_gestures_2x.png 2x"
+alt="Single tap is the only available gesture." width="740" height="" id="available-gestures" />
+<p class="img-caption">
+  <strong>Figure 1.</strong> Available, reserved, and blocked gestures.
+</p>
+
+As a rule, watch-face interaction should be lightweight, with the user completing their desired
+action within one or two touches.
+
+<h3>Tap targets</h3>
+
+<p>If you want to cause a simple state change on the watch face, such as a purely aesthetic
+change, you can use the entire canvas of the watch face as the tap target.</p>
+
+<p>For a more significant change or action, such as launching an activity or sending a message to a
+friend, it’s important to keep targets smaller, between 48-90 dpi, to avoid false-positive taps.
+There should be a gap between targets of at least 8-16 dpi. For an optimized tappable experience,
+display a maximum of 7 to 9 targets at once.</p>
+
+<h3 id=”areas”>Tap regions</h3>
+
+<p>You can also use different regions of the screen to trigger different changes to the watch face.
+For example, tapping on the entire canvas could toggle states for the entire face. Tapping a specific target
+could produce an inline display of information related to the target. Last, tapping outside the
+target could restore the watch face to its default state.</p>
+
+<div style="float:right;margin-bottom:20px;margin-left:20px">
+  <img src="/design/media/wear/visual_feedback.gif" width="200"
+       height="196" alt="The watch face should show where the user’s finger has made contact." style="margin-top:-10px;margin-left:13px">
+</div>
+
+
+<h3>Visual feedback</h3>
+
+<p>Provide visual feedback when the user’s finger touches down on the watch face. The tap
+event does not trigger until the user lifts their finger, but visual feedback on touchdown helps
+indicate that the system has received the touch, and also helps the user know where the touch
+landed.</p>
+
+<p class=”warning”><strong>Warning:</strong> Do not immediately launch a UI on touchdown. A UI that
+you launch on touchdown conflicts with gestures for interacting with system UI elements including
+the watch face picker, notification stream, settings shade, and app launcher.</p>
+
+<h3>Design examples</h3>
+
+Here are some examples of approaches for interactive watch faces:
+
+<h4>Applying an aesthetic change</h4>
+
+<img src="{@docRoot}design/media/wear/aesthetic.png"
+alt="" width="686" height="" id="descriptive-id" />
+
+<h4>Toggling states</h4>
+
+<img src="{@docRoot}design/media/wear/toggling-states.png"
+alt="" width="686" height="" id="descriptive-id" />
+
+<h4>Changing a targeted UI element</h4>
+
+<img src="{@docRoot}design/media/wear/changing-target.png"
+alt="" width="686" height="" id="descriptive-id" />
+
+<h4>Revealing information inline</h4>
+
+<img src="{@docRoot}design/media/wear/revealing-info.png"
+alt="" width="686" height="" id="descriptive-id" />
+
+<h4>Launching an activity with a single tap</h4>
+
+<img src="{@docRoot}design/media/wear/1-tap-launch.png"
+alt="" width="751" height="" id="descriptive-id" />
+
+<h4>Launching an activity with two taps</h4>
+
+<img src="{@docRoot}design/media/wear/2-tap-launch.png"
+alt="" width="751" height="" id="descriptive-id" />
 
 <h2 id="CompanionApp">Support the Android Wear Companion App</h2>
 
diff --git a/docs/html/reference/android/support/wearable/R.anim.html b/docs/html/reference/android/support/wearable/R.anim.html
index 11d766d..8976afe 100644
--- a/docs/html/reference/android/support/wearable/R.anim.html
+++ b/docs/html/reference/android/support/wearable/R.anim.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1322,6 +1323,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.animator.html b/docs/html/reference/android/support/wearable/R.animator.html
index 9fa6445..7ab63f2 100644
--- a/docs/html/reference/android/support/wearable/R.animator.html
+++ b/docs/html/reference/android/support/wearable/R.animator.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1134,6 +1135,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.attr.html b/docs/html/reference/android/support/wearable/R.attr.html
index 1f043a2..099c981 100644
--- a/docs/html/reference/android/support/wearable/R.attr.html
+++ b/docs/html/reference/android/support/wearable/R.attr.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -697,6 +698,23 @@
           static
           
           int</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#buttonRippleColor">buttonRippleColor</a></td>
+          <td class="jd-descrcol" width="100%">
+            <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+            
+    
+
+          </td>
+      </tr>
+      
+    
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
           <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#circle_border_color">circle_border_color</a></td>
           <td class="jd-descrcol" width="100%">
             <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
@@ -708,7 +726,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -724,7 +742,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -741,7 +759,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -757,7 +775,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -773,7 +791,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -789,7 +807,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -805,7 +823,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -821,6 +839,23 @@
       </tr>
       
     
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#color_sequence">color_sequence</a></td>
+          <td class="jd-descrcol" width="100%">
+            <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+            
+    
+
+          </td>
+      </tr>
+      
+    
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1054,6 +1089,55 @@
           static
           
           int</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#image_circle_percentage">image_circle_percentage</a></td>
+          <td class="jd-descrcol" width="100%">
+            <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+            
+    
+
+          </td>
+      </tr>
+      
+    
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#image_horizontal_offcenter_percentage">image_horizontal_offcenter_percentage</a></td>
+          <td class="jd-descrcol" width="100%">
+            <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+            
+    
+
+          </td>
+      </tr>
+      
+    
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#image_tint">image_tint</a></td>
+          <td class="jd-descrcol" width="100%">
+            <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+            
+    
+
+          </td>
+      </tr>
+      
+    
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
           <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#layout_box">layout_box</a></td>
           <td class="jd-descrcol" width="100%">
             <p>Must be one or more (separated by '|') of the following constant values.
@@ -1064,7 +1148,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1080,7 +1164,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1096,7 +1180,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1112,7 +1196,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1128,7 +1212,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1144,7 +1228,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1160,7 +1244,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1176,7 +1260,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1192,7 +1276,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1208,7 +1292,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1224,13 +1308,13 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
           
           int</nobr></td>
-          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#pressedTranslationZ">pressedTranslationZ</a></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#pressedButtonTranslationZ">pressedButtonTranslationZ</a></td>
           <td class="jd-descrcol" width="100%">
             <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
             
@@ -1240,7 +1324,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1257,23 +1341,6 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
-          <td class="jd-typecol"><nobr>
-          public
-          static
-          
-          int</nobr></td>
-          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html#rippleColor">rippleColor</a></td>
-          <td class="jd-descrcol" width="100%">
-            <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
-or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
-            
-    
-
-          </td>
-      </tr>
-      
-    
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1605,6 +1672,41 @@
 
 
 
+<A NAME="buttonRippleColor"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        buttonRippleColor
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p><p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
 <A NAME="circle_border_color"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -1921,6 +2023,41 @@
 
 
 
+<A NAME="color_sequence"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        color_sequence
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p><p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
 <A NAME="dotColor"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -2457,6 +2594,122 @@
 
 
 
+<A NAME="image_circle_percentage"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        image_circle_percentage
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p><p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
+<A NAME="image_horizontal_offcenter_percentage"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        image_horizontal_offcenter_percentage
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p><p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
+<A NAME="image_tint"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        image_tint
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p><p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
 <A NAME="layout_box"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -2903,7 +3156,7 @@
 
 
 
-<A NAME="pressedTranslationZ"></A>
+<A NAME="pressedButtonTranslationZ"></A>
 
 <div class="jd-details api apilevel-"> 
     <h4 class="jd-details-title">
@@ -2913,7 +3166,7 @@
          
         int
       </span>
-        pressedTranslationZ
+        pressedButtonTranslationZ
     </h4>
       <div class="api-level">
         
@@ -2975,41 +3228,6 @@
 
 
 
-<A NAME="rippleColor"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-        static 
-         
-        int
-      </span>
-        rippleColor
-    </h4>
-      <div class="api-level">
-        
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-    
-
-      
-  <div class="jd-tagdata jd-tagdescr"><p><p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
-or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
-<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
-"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
-</p></div>
-
-    
-    </div>
-</div>
-
-
-
 <A NAME="roundLayout"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -3233,6 +3451,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.color.html b/docs/html/reference/android/support/wearable/R.color.html
index cdfd0a8..07b5e0c 100644
--- a/docs/html/reference/android/support/wearable/R.color.html
+++ b/docs/html/reference/android/support/wearable/R.color.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -2450,6 +2451,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.dimen.html b/docs/html/reference/android/support/wearable/R.dimen.html
index c24ef8d..215b2b3 100644
--- a/docs/html/reference/android/support/wearable/R.dimen.html
+++ b/docs/html/reference/android/support/wearable/R.dimen.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1839,6 +1840,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.drawable.html b/docs/html/reference/android/support/wearable/R.drawable.html
index 167c8ab..c83cd2e 100644
--- a/docs/html/reference/android/support/wearable/R.drawable.html
+++ b/docs/html/reference/android/support/wearable/R.drawable.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1557,6 +1558,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.html b/docs/html/reference/android/support/wearable/R.html
index fd87f79..714f287 100644
--- a/docs/html/reference/android/support/wearable/R.html
+++ b/docs/html/reference/android/support/wearable/R.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="selected api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -717,7 +718,7 @@
          
         
         class</nobr></td>
-      <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></td>
+      <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></td>
       <td class="jd-descrcol" width="100%">
         &nbsp;
         
@@ -734,6 +735,23 @@
          
         
         class</nobr></td>
+      <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></td>
+      <td class="jd-descrcol" width="100%">
+        &nbsp;
+        
+    
+
+      </td>
+    </tr>
+    
+    
+    <tr class="alt-color api apilevel-" >
+      <td class="jd-typecol"><nobr>
+        
+         
+         
+        
+        class</nobr></td>
       <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></td>
       <td class="jd-descrcol" width="100%">
         &nbsp;
@@ -744,7 +762,7 @@
     </tr>
     
     
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
       <td class="jd-typecol"><nobr>
         
          
@@ -761,7 +779,7 @@
     </tr>
     
     
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
       <td class="jd-typecol"><nobr>
         
          
@@ -778,7 +796,7 @@
     </tr>
     
     
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
       <td class="jd-typecol"><nobr>
         
          
@@ -795,7 +813,7 @@
     </tr>
     
     
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
       <td class="jd-typecol"><nobr>
         
          
@@ -812,7 +830,7 @@
     </tr>
     
     
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
       <td class="jd-typecol"><nobr>
         
          
@@ -829,7 +847,7 @@
     </tr>
     
     
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
       <td class="jd-typecol"><nobr>
         
          
@@ -846,7 +864,7 @@
     </tr>
     
     
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
       <td class="jd-typecol"><nobr>
         
          
@@ -863,7 +881,7 @@
     </tr>
     
     
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
       <td class="jd-typecol"><nobr>
         
          
@@ -1283,6 +1301,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.id.html b/docs/html/reference/android/support/wearable/R.id.html
index 2b3db85..c6bad3b 100644
--- a/docs/html/reference/android/support/wearable/R.id.html
+++ b/docs/html/reference/android/support/wearable/R.id.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -2262,6 +2263,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.interpolator.html b/docs/html/reference/android/support/wearable/R.interpolator.html
index ae6cac1..01391a8 100644
--- a/docs/html/reference/android/support/wearable/R.interpolator.html
+++ b/docs/html/reference/android/support/wearable/R.interpolator.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1369,6 +1370,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.layout.html b/docs/html/reference/android/support/wearable/R.layout.html
index 7a87cf2..4987ba7 100644
--- a/docs/html/reference/android/support/wearable/R.layout.html
+++ b/docs/html/reference/android/support/wearable/R.layout.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1275,6 +1276,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.string.html b/docs/html/reference/android/support/wearable/R.string.html
index 3d13614..c8707ef 100644
--- a/docs/html/reference/android/support/wearable/R.string.html
+++ b/docs/html/reference/android/support/wearable/R.string.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1134,6 +1135,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.style.html b/docs/html/reference/android/support/wearable/R.style.html
index 48837d0..38ce308 100644
--- a/docs/html/reference/android/support/wearable/R.style.html
+++ b/docs/html/reference/android/support/wearable/R.style.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -2262,6 +2263,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/R.styleable.html b/docs/html/reference/android/support/wearable/R.styleable.html
index d1e4ca3..e43e070 100644
--- a/docs/html/reference/android/support/wearable/R.styleable.html
+++ b/docs/html/reference/android/support/wearable/R.styleable.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -473,6 +473,7 @@
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+          <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
           <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -614,7 +615,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1137,6 +1138,23 @@
           static
           
           int</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_buttonRippleColor">ActionPage_buttonRippleColor</a></td>
+          <td class="jd-descrcol" width="100%">
+            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#buttonRippleColor">buttonRippleColor</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
+            
+    
+
+          </td>
+      </tr>
+      
+    
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
           <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_imageScaleMode">ActionPage_imageScaleMode</a></td>
           <td class="jd-descrcol" width="100%">
             <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#imageScaleMode">imageScaleMode</a></code>
@@ -1148,7 +1166,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1165,7 +1183,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1182,32 +1200,15 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
-          <td class="jd-typecol"><nobr>
-          public
-          static
-          
-          int</nobr></td>
-          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedTranslationZ">ActionPage_pressedTranslationZ</a></td>
-          <td class="jd-descrcol" width="100%">
-            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedTranslationZ">pressedTranslationZ</a></code>
-          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
-            
-    
-
-          </td>
-      </tr>
-      
-    
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
           
           int</nobr></td>
-          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_rippleColor">ActionPage_rippleColor</a></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedButtonTranslationZ">ActionPage_pressedButtonTranslationZ</a></td>
           <td class="jd-descrcol" width="100%">
-            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#rippleColor">rippleColor</a></code>
+            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedButtonTranslationZ">pressedButtonTranslationZ</a></code>
           attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
             
     
@@ -1390,6 +1391,57 @@
           static
           
           int</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_circle_percentage">CircledImageView_image_circle_percentage</a></td>
+          <td class="jd-descrcol" width="100%">
+            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_circle_percentage">image_circle_percentage</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+            
+    
+
+          </td>
+      </tr>
+      
+    
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_horizontal_offcenter_percentage">CircledImageView_image_horizontal_offcenter_percentage</a></td>
+          <td class="jd-descrcol" width="100%">
+            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_horizontal_offcenter_percentage">image_horizontal_offcenter_percentage</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+            
+    
+
+          </td>
+      </tr>
+      
+    
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_tint">CircledImageView_image_tint</a></td>
+          <td class="jd-descrcol" width="100%">
+            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_tint">image_tint</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+            
+    
+
+          </td>
+      </tr>
+      
+    
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
           <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_shadow_width">CircledImageView_shadow_width</a></td>
           <td class="jd-descrcol" width="100%">
             <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#shadow_width">shadow_width</a></code>
@@ -1401,7 +1453,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1417,7 +1469,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1434,7 +1486,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1451,7 +1503,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1468,7 +1520,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1485,6 +1537,23 @@
       </tr>
       
     
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          
+          int</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_buttonRippleColor">CircularButton_buttonRippleColor</a></td>
+          <td class="jd-descrcol" width="100%">
+            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#buttonRippleColor">buttonRippleColor</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
+            
+    
+
+          </td>
+      </tr>
+      
+    
       <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
@@ -1508,9 +1577,9 @@
           static
           
           int</nobr></td>
-          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedTranslationZ">CircularButton_pressedTranslationZ</a></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedButtonTranslationZ">CircularButton_pressedButtonTranslationZ</a></td>
           <td class="jd-descrcol" width="100%">
-            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedTranslationZ">pressedTranslationZ</a></code>
+            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedButtonTranslationZ">pressedButtonTranslationZ</a></code>
           attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
             
     
@@ -1523,23 +1592,6 @@
           <td class="jd-typecol"><nobr>
           public
           static
-          
-          int</nobr></td>
-          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_rippleColor">CircularButton_rippleColor</a></td>
-          <td class="jd-descrcol" width="100%">
-            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#rippleColor">rippleColor</a></code>
-          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
-            
-    
-
-          </td>
-      </tr>
-      
-    
-      <tr class="alt-color api apilevel-" >
-          <td class="jd-typecol"><nobr>
-          public
-          static
           final
           int[]</nobr></td>
           <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#DelayedConfirmationView">DelayedConfirmationView</a></td>
@@ -1552,7 +1604,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1569,7 +1621,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1585,7 +1637,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1602,7 +1654,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1619,7 +1671,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1636,7 +1688,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1653,7 +1705,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1670,7 +1722,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1687,7 +1739,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1704,7 +1756,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1721,7 +1773,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1738,7 +1790,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1755,7 +1807,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1772,7 +1824,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1789,7 +1841,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1806,10 +1858,43 @@
       </tr>
       
     
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          final
+          int[]</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner">ProgressSpinner</a></td>
+          <td class="jd-descrcol" width="100%">
+            Attributes that can be used with a ProgressSpinner.
+            
+    
+
+          </td>
+      </tr>
+      
+    
       <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
+          
+          int</nobr></td>
+          <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner_color_sequence">ProgressSpinner_color_sequence</a></td>
+          <td class="jd-descrcol" width="100%">
+            <p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#color_sequence">color_sequence</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner">ProgressSpinner</a></code> array.
+            
+    
+
+          </td>
+      </tr>
+      
+    
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
           final
           int[]</nobr></td>
           <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html#WatchViewStub">WatchViewStub</a></td>
@@ -1822,7 +1907,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1839,7 +1924,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1856,7 +1941,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1872,7 +1957,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1889,7 +1974,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1906,7 +1991,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1923,7 +2008,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1940,7 +2025,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1957,7 +2042,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1974,7 +2059,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -1991,7 +2076,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -2008,7 +2093,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -2025,7 +2110,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -2042,7 +2127,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -2059,7 +2144,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -2076,7 +2161,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -2092,7 +2177,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -2109,7 +2194,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
           <td class="jd-typecol"><nobr>
           public
           static
@@ -2875,15 +2960,15 @@
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textColor">android:textColor</a></code></code></td><td></td></tr>
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textStyle">android:textStyle</a></code></code></td><td></td></tr>
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_typeface">android:typeface</a></code></code></td><td></td></tr>
+           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_buttonRippleColor">android.support.wearable:buttonRippleColor</a></code></code></td><td></td></tr>
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_imageScaleMode">android.support.wearable:imageScaleMode</a></code></code></td><td></td></tr>
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_maxTextSize">android.support.wearable:maxTextSize</a></code></code></td><td></td></tr>
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_minTextSize">android.support.wearable:minTextSize</a></code></code></td><td></td></tr>
-           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedTranslationZ">android.support.wearable:pressedTranslationZ</a></code></code></td><td></td></tr>
-           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_rippleColor">android.support.wearable:rippleColor</a></code></code></td><td></td></tr>
+           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedButtonTranslationZ">android.support.wearable:pressedButtonTranslationZ</a></code></code></td><td></td></tr>
            </table></p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">See Also</h5>
-      <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_color">ActionPage_android_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_elevation">ActionPage_android_elevation</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_fontFamily">ActionPage_android_fontFamily</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_gravity">ActionPage_android_gravity</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_lineSpacingExtra">ActionPage_android_lineSpacingExtra</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_lineSpacingMultiplier">ActionPage_android_lineSpacingMultiplier</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_maxLines">ActionPage_android_maxLines</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_src">ActionPage_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_stateListAnimator">ActionPage_android_stateListAnimator</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_text">ActionPage_android_text</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textColor">ActionPage_android_textColor</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textStyle">ActionPage_android_textStyle</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_typeface">ActionPage_android_typeface</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_imageScaleMode">ActionPage_imageScaleMode</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_maxTextSize">ActionPage_maxTextSize</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_minTextSize">ActionPage_minTextSize</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedTranslationZ">ActionPage_pressedTranslationZ</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_rippleColor">ActionPage_rippleColor</a></code></li>
+      <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_color">ActionPage_android_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_elevation">ActionPage_android_elevation</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_fontFamily">ActionPage_android_fontFamily</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_gravity">ActionPage_android_gravity</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_lineSpacingExtra">ActionPage_android_lineSpacingExtra</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_lineSpacingMultiplier">ActionPage_android_lineSpacingMultiplier</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_maxLines">ActionPage_android_maxLines</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_src">ActionPage_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_stateListAnimator">ActionPage_android_stateListAnimator</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_text">ActionPage_android_text</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textColor">ActionPage_android_textColor</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_textStyle">ActionPage_android_textStyle</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_android_typeface">ActionPage_android_typeface</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_buttonRippleColor">ActionPage_buttonRippleColor</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_imageScaleMode">ActionPage_imageScaleMode</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_maxTextSize">ActionPage_maxTextSize</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_minTextSize">ActionPage_minTextSize</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage_pressedButtonTranslationZ">ActionPage_pressedButtonTranslationZ</a></code></li>
       </ul>
   </div>
 
@@ -3309,6 +3394,44 @@
 
 
 
+<A NAME="ActionPage_buttonRippleColor"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        ActionPage_buttonRippleColor
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#buttonRippleColor">buttonRippleColor</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
+
+
+          <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".</p></div>
+
+    
+    </div>
+</div>
+
+
+
 <A NAME="ActionPage_imageScaleMode"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -3436,7 +3559,7 @@
 
 
 
-<A NAME="ActionPage_pressedTranslationZ"></A>
+<A NAME="ActionPage_pressedButtonTranslationZ"></A>
 
 <div class="jd-details api apilevel-"> 
     <h4 class="jd-details-title">
@@ -3446,7 +3569,7 @@
          
         int
       </span>
-        ActionPage_pressedTranslationZ
+        ActionPage_pressedButtonTranslationZ
     </h4>
       <div class="api-level">
         
@@ -3459,7 +3582,7 @@
     
 
       
-  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedTranslationZ">pressedTranslationZ</a></code>
+  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedButtonTranslationZ">pressedButtonTranslationZ</a></code>
           attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
 
 
@@ -3478,44 +3601,6 @@
 
 
 
-<A NAME="ActionPage_rippleColor"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-        static 
-         
-        int
-      </span>
-        ActionPage_rippleColor
-    </h4>
-      <div class="api-level">
-        
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-    
-
-      
-  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#rippleColor">rippleColor</a></code>
-          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ActionPage">ActionPage</a></code> array.
-
-
-          <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
-or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
-<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
-"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".</p></div>
-
-    
-    </div>
-</div>
-
-
-
 <A NAME="BoxInsetLayout_Layout"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -3641,11 +3726,14 @@
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_padding">android.support.wearable:circle_padding</a></code></code></td><td></td></tr>
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius">android.support.wearable:circle_radius</a></code></code></td><td></td></tr>
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius_pressed">android.support.wearable:circle_radius_pressed</a></code></code></td><td></td></tr>
+           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_circle_percentage">android.support.wearable:image_circle_percentage</a></code></code></td><td></td></tr>
+           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_horizontal_offcenter_percentage">android.support.wearable:image_horizontal_offcenter_percentage</a></code></code></td><td></td></tr>
+           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_tint">android.support.wearable:image_tint</a></code></code></td><td></td></tr>
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_shadow_width">android.support.wearable:shadow_width</a></code></code></td><td></td></tr>
            </table></p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">See Also</h5>
-      <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_android_src">CircledImageView_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_border_color">CircledImageView_circle_border_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_border_width">CircledImageView_circle_border_width</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_color">CircledImageView_circle_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_padding">CircledImageView_circle_padding</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius">CircledImageView_circle_radius</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius_pressed">CircledImageView_circle_radius_pressed</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_shadow_width">CircledImageView_shadow_width</a></code></li>
+      <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_android_src">CircledImageView_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_border_color">CircledImageView_circle_border_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_border_width">CircledImageView_circle_border_width</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_color">CircledImageView_circle_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_padding">CircledImageView_circle_padding</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius">CircledImageView_circle_radius</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_circle_radius_pressed">CircledImageView_circle_radius_pressed</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_circle_percentage">CircledImageView_image_circle_percentage</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_horizontal_offcenter_percentage">CircledImageView_image_horizontal_offcenter_percentage</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_image_tint">CircledImageView_image_tint</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView_shadow_width">CircledImageView_shadow_width</a></code></li>
       </ul>
   </div>
 
@@ -3937,6 +4025,131 @@
 
 
 
+<A NAME="CircledImageView_image_circle_percentage"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        CircledImageView_image_circle_percentage
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_circle_percentage">image_circle_percentage</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+
+
+          <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.</p></div>
+
+    
+    </div>
+</div>
+
+
+
+<A NAME="CircledImageView_image_horizontal_offcenter_percentage"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        CircledImageView_image_horizontal_offcenter_percentage
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_horizontal_offcenter_percentage">image_horizontal_offcenter_percentage</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+
+
+          <p>Must be a dimension value, which is a floating point number appended with a unit such as "<code>14.5sp</code>".
+Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
+in (inches), mm (millimeters).
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.</p></div>
+
+    
+    </div>
+</div>
+
+
+
+<A NAME="CircledImageView_image_tint"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        CircledImageView_image_tint
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#image_tint">image_tint</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircledImageView">CircledImageView</a></code> array.
+
+
+          <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
+<p>This may also be a reference to a resource (in the form
+"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
+theme attribute (in the form
+"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
+containing a value of this type.</p></div>
+
+    
+    </div>
+</div>
+
+
+
 <A NAME="CircledImageView_shadow_width"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -4012,13 +4225,13 @@
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_elevation">android:elevation</a></code></code></td><td></td></tr>
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_src">android:src</a></code></code></td><td></td></tr>
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_stateListAnimator">android:stateListAnimator</a></code></code></td><td></td></tr>
+           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_buttonRippleColor">android.support.wearable:buttonRippleColor</a></code></code></td><td></td></tr>
            <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_imageScaleMode">android.support.wearable:imageScaleMode</a></code></code></td><td></td></tr>
-           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedTranslationZ">android.support.wearable:pressedTranslationZ</a></code></code></td><td></td></tr>
-           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_rippleColor">android.support.wearable:rippleColor</a></code></code></td><td></td></tr>
+           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedButtonTranslationZ">android.support.wearable:pressedButtonTranslationZ</a></code></code></td><td></td></tr>
            </table></p></div>
   <div class="jd-tagdata">
       <h5 class="jd-tagtitle">See Also</h5>
-      <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_color">CircularButton_android_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_elevation">CircularButton_android_elevation</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_src">CircularButton_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_stateListAnimator">CircularButton_android_stateListAnimator</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_imageScaleMode">CircularButton_imageScaleMode</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedTranslationZ">CircularButton_pressedTranslationZ</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_rippleColor">CircularButton_rippleColor</a></code></li>
+      <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_color">CircularButton_android_color</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_elevation">CircularButton_android_elevation</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_src">CircularButton_android_src</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_android_stateListAnimator">CircularButton_android_stateListAnimator</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_buttonRippleColor">CircularButton_buttonRippleColor</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_imageScaleMode">CircularButton_imageScaleMode</a></code></li><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton_pressedButtonTranslationZ">CircularButton_pressedButtonTranslationZ</a></code></li>
       </ul>
   </div>
 
@@ -4156,6 +4369,44 @@
 
 
 
+<A NAME="CircularButton_buttonRippleColor"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        CircularButton_buttonRippleColor
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#buttonRippleColor">buttonRippleColor</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
+
+
+          <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".</p></div>
+
+    
+    </div>
+</div>
+
+
+
 <A NAME="CircularButton_imageScaleMode"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -4199,7 +4450,7 @@
 
 
 
-<A NAME="CircularButton_pressedTranslationZ"></A>
+<A NAME="CircularButton_pressedButtonTranslationZ"></A>
 
 <div class="jd-details api apilevel-"> 
     <h4 class="jd-details-title">
@@ -4209,7 +4460,7 @@
          
         int
       </span>
-        CircularButton_pressedTranslationZ
+        CircularButton_pressedButtonTranslationZ
     </h4>
       <div class="api-level">
         
@@ -4222,7 +4473,7 @@
     
 
       
-  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedTranslationZ">pressedTranslationZ</a></code>
+  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#pressedButtonTranslationZ">pressedButtonTranslationZ</a></code>
           attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
 
 
@@ -4241,44 +4492,6 @@
 
 
 
-<A NAME="CircularButton_rippleColor"></A>
-
-<div class="jd-details api apilevel-"> 
-    <h4 class="jd-details-title">
-      <span class="normal">
-        public 
-        static 
-         
-        int
-      </span>
-        CircularButton_rippleColor
-    </h4>
-      <div class="api-level">
-        
-        
-  
-
-      </div>
-    <div class="jd-details-descr">
-      
-    
-
-      
-  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#rippleColor">rippleColor</a></code>
-          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#CircularButton">CircularButton</a></code> array.
-
-
-          <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
-or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
-<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
-"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".</p></div>
-
-    
-    </div>
-</div>
-
-
-
 <A NAME="DelayedConfirmationView"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -4952,6 +5165,87 @@
 
 
 
+<A NAME="ProgressSpinner"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+        final 
+        int[]
+      </span>
+        ProgressSpinner
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Attributes that can be used with a ProgressSpinner.
+           <p>Includes the following attributes:</p>
+           <table>
+           <colgroup align="left" />
+           <colgroup align="left" />
+           <tr><th>Attribute</th><th>Description</th></tr>
+           <tr><td><code><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner_color_sequence">android.support.wearable:color_sequence</a></code></code></td><td></td></tr>
+           </table></p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">See Also</h5>
+      <ul class="nolist"><li><code><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner_color_sequence">ProgressSpinner_color_sequence</a></code></li>
+      </ul>
+  </div>
+
+    
+    </div>
+</div>
+
+
+
+<A NAME="ProgressSpinner_color_sequence"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+        int
+      </span>
+        ProgressSpinner_color_sequence
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p><p>This symbol is the offset where the <code><a href="../../../../reference/android/support/wearable/R.attr.html#color_sequence">color_sequence</a></code>
+          attribute's value can be found in the <code><a href="../../../../reference/android/support/wearable/R.styleable.html#ProgressSpinner">ProgressSpinner</a></code> array.
+
+
+          <p>May be a reference to another resource, in the form "<code>@[+][<i>package</i>:]<i>type</i>:<i>name</i></code>"
+or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>".
+<p>May be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
+"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".</p></div>
+
+    
+    </div>
+</div>
+
+
+
 <A NAME="WatchViewStub"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -5847,6 +6141,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/activity/ConfirmationActivity.html b/docs/html/reference/android/support/wearable/activity/ConfirmationActivity.html
index f7cd613..92bfeca 100644
--- a/docs/html/reference/android/support/wearable/activity/ConfirmationActivity.html
+++ b/docs/html/reference/android/support/wearable/activity/ConfirmationActivity.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -713,7 +713,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -10110,6 +10110,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/activity/WearableActivity.html b/docs/html/reference/android/support/wearable/activity/WearableActivity.html
index 2698dca..6f70f74 100644
--- a/docs/html/reference/android/support/wearable/activity/WearableActivity.html
+++ b/docs/html/reference/android/support/wearable/activity/WearableActivity.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -716,7 +716,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -10513,6 +10513,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/activity/package-summary.html b/docs/html/reference/android/support/wearable/activity/package-summary.html
index 4dd01b7..e3a691a 100644
--- a/docs/html/reference/android/support/wearable/activity/package-summary.html
+++ b/docs/html/reference/android/support/wearable/activity/package-summary.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -542,7 +542,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 
 
 
@@ -654,6 +654,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/companion/WatchFaceCompanion.html b/docs/html/reference/android/support/wearable/companion/WatchFaceCompanion.html
index ce369f2..8174777 100644
--- a/docs/html/reference/android/support/wearable/companion/WatchFaceCompanion.html
+++ b/docs/html/reference/android/support/wearable/companion/WatchFaceCompanion.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -599,7 +599,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1158,6 +1158,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/companion/package-summary.html b/docs/html/reference/android/support/wearable/companion/package-summary.html
index 0447708..7404dcd 100644
--- a/docs/html/reference/android/support/wearable/companion/package-summary.html
+++ b/docs/html/reference/android/support/wearable/companion/package-summary.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -541,7 +541,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 
 
 
@@ -641,6 +641,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/input/RemoteInputConstants.html b/docs/html/reference/android/support/wearable/input/RemoteInputConstants.html
index f3cb90c..35fe2d5 100644
--- a/docs/html/reference/android/support/wearable/input/RemoteInputConstants.html
+++ b/docs/html/reference/android/support/wearable/input/RemoteInputConstants.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -603,7 +603,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1151,6 +1151,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/input/RemoteInputIntent.html b/docs/html/reference/android/support/wearable/input/RemoteInputIntent.html
index 92d90bc..34ae2d5 100644
--- a/docs/html/reference/android/support/wearable/input/RemoteInputIntent.html
+++ b/docs/html/reference/android/support/wearable/input/RemoteInputIntent.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -603,7 +603,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -644,7 +644,7 @@
      new RemoteInput.Builder(KEY_QUICK_REPLY_TEXT).setLabel("Quick reply").build()
  };
  Intent intent = new Intent(ACTION_REMOTE_INPUT);
- intent.putExtra(EXTRA_REMOTE_INPUT, remoteInputs);
+ intent.putExtra(EXTRA_REMOTE_INPUTS, remoteInputs);
  startActivity(intent);
  </pre>
 
@@ -1496,6 +1496,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/input/package-summary.html b/docs/html/reference/android/support/wearable/input/package-summary.html
index 2071e28..314838d 100644
--- a/docs/html/reference/android/support/wearable/input/package-summary.html
+++ b/docs/html/reference/android/support/wearable/input/package-summary.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -542,7 +542,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 
 
 
@@ -653,6 +653,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/media/MediaControlConstants.html b/docs/html/reference/android/support/wearable/media/MediaControlConstants.html
index 42c141b..30ddc45 100644
--- a/docs/html/reference/android/support/wearable/media/MediaControlConstants.html
+++ b/docs/html/reference/android/support/wearable/media/MediaControlConstants.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -602,7 +602,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1370,6 +1370,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/media/package-summary.html b/docs/html/reference/android/support/wearable/media/package-summary.html
index 3310b5a..72dce84 100644
--- a/docs/html/reference/android/support/wearable/media/package-summary.html
+++ b/docs/html/reference/android/support/wearable/media/package-summary.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -541,7 +541,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 
 
 
@@ -641,6 +641,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/package-summary.html b/docs/html/reference/android/support/wearable/package-summary.html
index a8e3db057..a4ef376 100644
--- a/docs/html/reference/android/support/wearable/package-summary.html
+++ b/docs/html/reference/android/support/wearable/package-summary.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -474,6 +474,7 @@
         <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.html">R</a></li>
         <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.anim.html">R.anim</a></li>
         <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.animator.html">R.animator</a></li>
+        <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></li>
         <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></li>
         <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></li>
         <li class="api apilevel-"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></li>
@@ -553,7 +554,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 
 
 
@@ -607,6 +608,17 @@
       
     
       <tr class=" api apilevel-" >
+        <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.array.html">R.array</a></td>
+        <td class="jd-descrcol" width="100%">
+          &nbsp;
+          
+    
+
+        </td>
+      </tr>
+      
+    
+      <tr class="alt-color api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.attr.html">R.attr</a></td>
         <td class="jd-descrcol" width="100%">
           &nbsp;
@@ -617,7 +629,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.color.html">R.color</a></td>
         <td class="jd-descrcol" width="100%">
           &nbsp;
@@ -628,7 +640,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.dimen.html">R.dimen</a></td>
         <td class="jd-descrcol" width="100%">
           &nbsp;
@@ -639,7 +651,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.drawable.html">R.drawable</a></td>
         <td class="jd-descrcol" width="100%">
           &nbsp;
@@ -650,7 +662,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.id.html">R.id</a></td>
         <td class="jd-descrcol" width="100%">
           &nbsp;
@@ -661,7 +673,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.interpolator.html">R.interpolator</a></td>
         <td class="jd-descrcol" width="100%">
           &nbsp;
@@ -672,7 +684,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.layout.html">R.layout</a></td>
         <td class="jd-descrcol" width="100%">
           &nbsp;
@@ -683,7 +695,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.string.html">R.string</a></td>
         <td class="jd-descrcol" width="100%">
           &nbsp;
@@ -694,7 +706,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.style.html">R.style</a></td>
         <td class="jd-descrcol" width="100%">
           &nbsp;
@@ -705,7 +717,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../reference/android/support/wearable/R.styleable.html">R.styleable</a></td>
         <td class="jd-descrcol" width="100%">
           &nbsp;
@@ -785,6 +797,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Attendees.html b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Attendees.html
index ba439b3..794973f 100644
--- a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Attendees.html
+++ b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Attendees.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -602,7 +602,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1063,6 +1063,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Instances.html b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Instances.html
index 70ad4d9..77c3c67 100644
--- a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Instances.html
+++ b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Instances.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -602,7 +602,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1063,6 +1063,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Reminders.html b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Reminders.html
index 752da5e..9dfd7f7 100644
--- a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Reminders.html
+++ b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.Reminders.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -602,7 +602,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1063,6 +1063,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.html b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.html
index 919306b..588ae71 100644
--- a/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.html
+++ b/docs/html/reference/android/support/wearable/provider/WearableCalendarContract.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -611,7 +611,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1265,6 +1265,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/provider/package-summary.html b/docs/html/reference/android/support/wearable/provider/package-summary.html
index f82ce5c..bb4c581 100644
--- a/docs/html/reference/android/support/wearable/provider/package-summary.html
+++ b/docs/html/reference/android/support/wearable/provider/package-summary.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -544,7 +544,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 
 
 
@@ -677,6 +677,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/ActionLabel.html b/docs/html/reference/android/support/wearable/view/ActionLabel.html
index 3716018..f8cb733 100644
--- a/docs/html/reference/android/support/wearable/view/ActionLabel.html
+++ b/docs/html/reference/android/support/wearable/view/ActionLabel.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -684,7 +685,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -12362,6 +12363,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/ActionPage.html b/docs/html/reference/android/support/wearable/view/ActionPage.html
index 268bba1..69c4dfb 100644
--- a/docs/html/reference/android/support/wearable/view/ActionPage.html
+++ b/docs/html/reference/android/support/wearable/view/ActionPage.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -714,7 +715,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -15449,6 +15450,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/BoxInsetLayout.LayoutParams.html b/docs/html/reference/android/support/wearable/view/BoxInsetLayout.LayoutParams.html
index 43097b4..d716836 100644
--- a/docs/html/reference/android/support/wearable/view/BoxInsetLayout.LayoutParams.html
+++ b/docs/html/reference/android/support/wearable/view/BoxInsetLayout.LayoutParams.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -687,7 +688,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -2431,6 +2432,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/BoxInsetLayout.html b/docs/html/reference/android/support/wearable/view/BoxInsetLayout.html
index 5619e75..d315135 100644
--- a/docs/html/reference/android/support/wearable/view/BoxInsetLayout.html
+++ b/docs/html/reference/android/support/wearable/view/BoxInsetLayout.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -725,7 +726,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -15573,6 +15574,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CardFragment.html b/docs/html/reference/android/support/wearable/view/CardFragment.html
index 9437e93..b73c6ca 100644
--- a/docs/html/reference/android/support/wearable/view/CardFragment.html
+++ b/docs/html/reference/android/support/wearable/view/CardFragment.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -679,7 +680,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -4875,6 +4876,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CardFrame.html b/docs/html/reference/android/support/wearable/view/CardFrame.html
index 1beeda2..32224d5 100644
--- a/docs/html/reference/android/support/wearable/view/CardFrame.html
+++ b/docs/html/reference/android/support/wearable/view/CardFrame.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -714,7 +715,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -15930,6 +15931,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CardScrollView.html b/docs/html/reference/android/support/wearable/view/CardScrollView.html
index 0364eb9..a361847 100644
--- a/docs/html/reference/android/support/wearable/view/CardScrollView.html
+++ b/docs/html/reference/android/support/wearable/view/CardScrollView.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -722,7 +723,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -15898,6 +15899,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CircledImageView.html b/docs/html/reference/android/support/wearable/view/CircledImageView.html
index 1c9451b..a2ba3f7 100644
--- a/docs/html/reference/android/support/wearable/view/CircledImageView.html
+++ b/docs/html/reference/android/support/wearable/view/CircledImageView.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -684,7 +685,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -2857,12 +2858,44 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageCirclePercentage(float)">setImageCirclePercentage</a></span>(float percentage)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageDrawable(android.graphics.drawable.Drawable)">setImageDrawable</a></span>(Drawable drawable)</nobr>
         
   </td></tr>
 
 
 	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageHorizontalOffcenterPercentage(float)">setImageHorizontalOffcenterPercentage</a></span>(float percentage)</nobr>
+        
+  </td></tr>
+
+
+	 
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
@@ -2889,7 +2922,7 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setPressed(boolean)">setPressed</a></span>(boolean pressed)</nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageTint(int)">setImageTint</a></span>(int tint)</nobr>
         
   </td></tr>
 
@@ -2905,7 +2938,7 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setProgress(float)">setProgress</a></span>(float progress)</nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setPressed(boolean)">setPressed</a></span>(boolean pressed)</nobr>
         
   </td></tr>
 
@@ -2921,6 +2954,22 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setProgress(float)">setProgress</a></span>(float progress)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setShadowVisibility(float)">setShadowVisibility</a></span>(float shadowVisibility)</nobr>
         
         <div class="jd-descrdiv">
@@ -2934,7 +2983,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -11857,6 +11906,38 @@
 </div>
 
 
+<A NAME="setImageCirclePercentage(float)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setImageCirclePercentage</span>
+      <span class="normal">(float percentage)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    </div>
+</div>
+
+
 <A NAME="setImageDrawable(android.graphics.drawable.Drawable)"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -11889,6 +11970,38 @@
 </div>
 
 
+<A NAME="setImageHorizontalOffcenterPercentage(float)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setImageHorizontalOffcenterPercentage</span>
+      <span class="normal">(float percentage)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    </div>
+</div>
+
+
 <A NAME="setImageResource(int)"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -11921,6 +12034,38 @@
 </div>
 
 
+<A NAME="setImageTint(int)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setImageTint</span>
+      <span class="normal">(int tint)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    </div>
+</div>
+
+
 <A NAME="setPressed(boolean)"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -12330,6 +12475,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CircularButton.html b/docs/html/reference/android/support/wearable/view/CircularButton.html
index edcb3f2..ff626ce 100644
--- a/docs/html/reference/android/support/wearable/view/CircularButton.html
+++ b/docs/html/reference/android/support/wearable/view/CircularButton.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -687,7 +688,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -11986,6 +11987,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/CrossfadeDrawable.html b/docs/html/reference/android/support/wearable/view/CrossfadeDrawable.html
index f346b82..176e532 100644
--- a/docs/html/reference/android/support/wearable/view/CrossfadeDrawable.html
+++ b/docs/html/reference/android/support/wearable/view/CrossfadeDrawable.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -665,7 +666,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -3562,6 +3563,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.DelayedConfirmationListener.html b/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.DelayedConfirmationListener.html
index 6159875..459b683 100644
--- a/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.DelayedConfirmationListener.html
+++ b/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.DelayedConfirmationListener.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -908,6 +909,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.html b/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.html
index 3b61bf0..10e10b9 100644
--- a/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.html
+++ b/docs/html/reference/android/support/wearable/view/DelayedConfirmationView.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -698,7 +699,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -3164,12 +3165,44 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageCirclePercentage(float)">setImageCirclePercentage</a></span>(float percentage)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageDrawable(android.graphics.drawable.Drawable)">setImageDrawable</a></span>(Drawable drawable)</nobr>
         
   </td></tr>
 
 
 	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageHorizontalOffcenterPercentage(float)">setImageHorizontalOffcenterPercentage</a></span>(float percentage)</nobr>
+        
+  </td></tr>
+
+
+	 
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
@@ -3196,7 +3229,7 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setPressed(boolean)">setPressed</a></span>(boolean pressed)</nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setImageTint(int)">setImageTint</a></span>(int tint)</nobr>
         
   </td></tr>
 
@@ -3212,7 +3245,7 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setProgress(float)">setProgress</a></span>(float progress)</nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setPressed(boolean)">setPressed</a></span>(boolean pressed)</nobr>
         
   </td></tr>
 
@@ -3228,6 +3261,22 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setProgress(float)">setProgress</a></span>(float progress)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/CircledImageView.html#setShadowVisibility(float)">setShadowVisibility</a></span>(float shadowVisibility)</nobr>
         
         <div class="jd-descrdiv">
@@ -3241,7 +3290,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -11914,6 +11963,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/DismissOverlayView.html b/docs/html/reference/android/support/wearable/view/DismissOverlayView.html
index f455403..f146daf 100644
--- a/docs/html/reference/android/support/wearable/view/DismissOverlayView.html
+++ b/docs/html/reference/android/support/wearable/view/DismissOverlayView.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -719,7 +720,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -15317,6 +15318,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/DotsPageIndicator.html b/docs/html/reference/android/support/wearable/view/DotsPageIndicator.html
index 006a270..634cf95 100644
--- a/docs/html/reference/android/support/wearable/view/DotsPageIndicator.html
+++ b/docs/html/reference/android/support/wearable/view/DotsPageIndicator.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -705,7 +706,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -13437,6 +13438,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/FragmentGridPagerAdapter.html b/docs/html/reference/android/support/wearable/view/FragmentGridPagerAdapter.html
index 9df4ae7..ed7fecd 100644
--- a/docs/html/reference/android/support/wearable/view/FragmentGridPagerAdapter.html
+++ b/docs/html/reference/android/support/wearable/view/FragmentGridPagerAdapter.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -611,6 +612,9 @@
   
 
 
+  &#124; <a href="#promethods">Protected Methods</a>
+  
+
 
   &#124; <a href="#inhmethods">Inherited Methods</a>
 
@@ -660,7 +664,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -965,6 +969,22 @@
             
             
             
+            Fragment</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/FragmentGridPagerAdapter.html#findExistingFragment(int, int)">findExistingFragment</a></span>(int row, int column)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
@@ -981,7 +1001,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1004,7 +1024,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             abstract
             
@@ -1027,7 +1047,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1050,7 +1070,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1074,7 +1094,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1097,7 +1117,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1126,6 +1146,71 @@
 
 
 
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="promethods" class="jd-sumtable"><tr><th colspan="12">Protected Methods</th></tr>
+
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/FragmentGridPagerAdapter.html#applyItemPosition(java.lang.Object, android.graphics.Point)">applyItemPosition</a></span>(Object object, Point position)</nobr>
+        
+        <div class="jd-descrdiv">
+          Called after <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code> to allow superclasses to update their
+ internal bookkeeping if a subclass has overridden <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/FragmentGridPagerAdapter.html#removeFragment(android.app.Fragment, android.app.FragmentTransaction)">removeFragment</a></span>(Fragment fragment, FragmentTransaction transaction)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/FragmentGridPagerAdapter.html#restoreFragment(android.app.Fragment, android.app.FragmentTransaction)">restoreFragment</a></span>(Fragment fragment, FragmentTransaction transaction)</nobr>
+        
+  </td></tr>
+
+
+
+</table>
+
+
 
 
 
@@ -1157,6 +1242,30 @@
 	 
     <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#applyItemPosition(java.lang.Object, android.graphics.Point)">applyItemPosition</a></span>(Object object, Point position)</nobr>
+        
+        <div class="jd-descrdiv">
+          Called after <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code> to allow superclasses to update their
+ internal bookkeeping if a subclass has overridden <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
             abstract
             
             
@@ -1178,7 +1287,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1201,7 +1310,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1224,7 +1333,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1247,7 +1356,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             abstract
             
@@ -1270,7 +1379,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1293,7 +1402,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1316,7 +1425,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1339,7 +1448,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             abstract
             
@@ -1362,7 +1471,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             abstract
             
@@ -1385,7 +1494,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             abstract
             
@@ -1409,7 +1518,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1433,7 +1542,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1457,7 +1566,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1481,7 +1590,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1504,7 +1613,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1527,7 +1636,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1550,7 +1659,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1573,7 +1682,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1596,7 +1705,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1964,6 +2073,38 @@
 </div>
 
 
+<A NAME="findExistingFragment(int, int)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        Fragment
+      </span>
+      <span class="sympad">findExistingFragment</span>
+      <span class="normal">(int row, int column)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    </div>
+</div>
+
+
 <A NAME="finishUpdate(android.view.ViewGroup)"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -2331,6 +2472,122 @@
 
 <!-- ========= METHOD DETAIL ======== -->
 
+<h2>Protected Methods</h2>
+
+
+
+<A NAME="applyItemPosition(java.lang.Object, android.graphics.Point)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        protected 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">applyItemPosition</span>
+      <span class="normal">(Object object, Point position)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Called after <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code> to allow superclasses to update their
+ internal bookkeeping if a subclass has overridden <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>object</td>
+          <td>Object representing the item passed to <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.</td>
+        </tr>
+        <tr>
+          <th>position</td>
+          <td>position which was returned from <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="removeFragment(android.app.Fragment, android.app.FragmentTransaction)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        protected 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">removeFragment</span>
+      <span class="normal">(Fragment fragment, FragmentTransaction transaction)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    </div>
+</div>
+
+
+<A NAME="restoreFragment(android.app.Fragment, android.app.FragmentTransaction)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        protected 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">restoreFragment</span>
+      <span class="normal">(Fragment fragment, FragmentTransaction transaction)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    </div>
+</div>
+
+
+
 
 
 <!-- ========= END OF CLASS DATA ========= -->
@@ -2389,6 +2646,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridPageOptions.BackgroundListener.html b/docs/html/reference/android/support/wearable/view/GridPageOptions.BackgroundListener.html
index a37d8f8a..1e066c1 100644
--- a/docs/html/reference/android/support/wearable/view/GridPageOptions.BackgroundListener.html
+++ b/docs/html/reference/android/support/wearable/view/GridPageOptions.BackgroundListener.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -853,6 +854,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridPageOptions.html b/docs/html/reference/android/support/wearable/view/GridPageOptions.html
index 56cfa05..8c22582 100644
--- a/docs/html/reference/android/support/wearable/view/GridPageOptions.html
+++ b/docs/html/reference/android/support/wearable/view/GridPageOptions.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -948,6 +949,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridPagerAdapter.html b/docs/html/reference/android/support/wearable/view/GridPagerAdapter.html
index 9876a82..b157c39 100644
--- a/docs/html/reference/android/support/wearable/view/GridPagerAdapter.html
+++ b/docs/html/reference/android/support/wearable/view/GridPagerAdapter.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -600,6 +601,9 @@
   
 
 
+  &#124; <a href="#promethods">Protected Methods</a>
+  
+
 
   &#124; <a href="#inhmethods">Inherited Methods</a>
 
@@ -645,7 +649,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1369,6 +1373,39 @@
 
 
 
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="promethods" class="jd-sumtable"><tr><th colspan="12">Protected Methods</th></tr>
+
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#applyItemPosition(java.lang.Object, android.graphics.Point)">applyItemPosition</a></span>(Object object, Point position)</nobr>
+        
+        <div class="jd-descrdiv">
+          Called after <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code> to allow superclasses to update their
+ internal bookkeeping if a subclass has overridden <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+
+</table>
+
+
 
 
 
@@ -2742,6 +2779,58 @@
 
 <!-- ========= METHOD DETAIL ======== -->
 
+<h2>Protected Methods</h2>
+
+
+
+<A NAME="applyItemPosition(java.lang.Object, android.graphics.Point)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        protected 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">applyItemPosition</span>
+      <span class="normal">(Object object, Point position)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Called after <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code> to allow superclasses to update their
+ internal bookkeeping if a subclass has overridden <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>object</td>
+          <td>Object representing the item passed to <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.</td>
+        </tr>
+        <tr>
+          <th>position</td>
+          <td>position which was returned from <code><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html#getItemPosition(java.lang.Object)">getItemPosition(Object)</a></code>.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
+
 
 
 <!-- ========= END OF CLASS DATA ========= -->
@@ -2800,6 +2889,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridViewPager.LayoutParams.html b/docs/html/reference/android/support/wearable/view/GridViewPager.LayoutParams.html
index 9db55c9..c4d63e22 100644
--- a/docs/html/reference/android/support/wearable/view/GridViewPager.LayoutParams.html
+++ b/docs/html/reference/android/support/wearable/view/GridViewPager.LayoutParams.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -673,7 +674,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1787,6 +1788,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridViewPager.OnAdapterChangeListener.html b/docs/html/reference/android/support/wearable/view/GridViewPager.OnAdapterChangeListener.html
index 1cbec14..fcd6a3d 100644
--- a/docs/html/reference/android/support/wearable/view/GridViewPager.OnAdapterChangeListener.html
+++ b/docs/html/reference/android/support/wearable/view/GridViewPager.OnAdapterChangeListener.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -621,7 +622,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -968,6 +969,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridViewPager.OnPageChangeListener.html b/docs/html/reference/android/support/wearable/view/GridViewPager.OnPageChangeListener.html
index fd81fbe..072f6c5 100644
--- a/docs/html/reference/android/support/wearable/view/GridViewPager.OnPageChangeListener.html
+++ b/docs/html/reference/android/support/wearable/view/GridViewPager.OnPageChangeListener.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -621,7 +622,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1085,6 +1086,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/GridViewPager.html b/docs/html/reference/android/support/wearable/view/GridViewPager.html
index b92720c..3e2179d 100644
--- a/docs/html/reference/android/support/wearable/view/GridViewPager.html
+++ b/docs/html/reference/android/support/wearable/view/GridViewPager.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -717,7 +718,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -16881,6 +16882,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/SimpleAnimatorListener.html b/docs/html/reference/android/support/wearable/view/SimpleAnimatorListener.html
index 454f420..9940f3b 100644
--- a/docs/html/reference/android/support/wearable/view/SimpleAnimatorListener.html
+++ b/docs/html/reference/android/support/wearable/view/SimpleAnimatorListener.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -651,7 +652,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1525,6 +1526,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WatchViewStub.OnLayoutInflatedListener.html b/docs/html/reference/android/support/wearable/view/WatchViewStub.OnLayoutInflatedListener.html
index b05ce34..9492429 100644
--- a/docs/html/reference/android/support/wearable/view/WatchViewStub.OnLayoutInflatedListener.html
+++ b/docs/html/reference/android/support/wearable/view/WatchViewStub.OnLayoutInflatedListener.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -847,6 +848,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WatchViewStub.html b/docs/html/reference/android/support/wearable/view/WatchViewStub.html
index 8fd5fee..170a165 100644
--- a/docs/html/reference/android/support/wearable/view/WatchViewStub.html
+++ b/docs/html/reference/android/support/wearable/view/WatchViewStub.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -725,7 +726,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -15465,6 +15466,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableFrameLayout.LayoutParams.html b/docs/html/reference/android/support/wearable/view/WearableFrameLayout.LayoutParams.html
index 93f4b0d..fb54c95 100644
--- a/docs/html/reference/android/support/wearable/view/WearableFrameLayout.LayoutParams.html
+++ b/docs/html/reference/android/support/wearable/view/WearableFrameLayout.LayoutParams.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -684,7 +685,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -2322,6 +2323,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableFrameLayout.html b/docs/html/reference/android/support/wearable/view/WearableFrameLayout.html
index f2b0df7..e269ab8 100644
--- a/docs/html/reference/android/support/wearable/view/WearableFrameLayout.html
+++ b/docs/html/reference/android/support/wearable/view/WearableFrameLayout.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="selected api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -714,7 +715,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -16352,6 +16353,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.Adapter.html b/docs/html/reference/android/support/wearable/view/WearableListView.Adapter.html
index 9619c5d..0686ff2 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.Adapter.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.Adapter.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -647,7 +648,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1561,6 +1562,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.ClickListener.html b/docs/html/reference/android/support/wearable/view/WearableListView.ClickListener.html
index 84cb188..17431c4 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.ClickListener.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.ClickListener.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -919,6 +920,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.OnCenterProximityListener.html b/docs/html/reference/android/support/wearable/view/WearableListView.OnCenterProximityListener.html
index b2b9246..936a163 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.OnCenterProximityListener.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.OnCenterProximityListener.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -930,6 +931,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.OnCentralPositionChangedListener.html b/docs/html/reference/android/support/wearable/view/WearableListView.OnCentralPositionChangedListener.html
index 66eeac3..c49bbcc 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.OnCentralPositionChangedListener.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.OnCentralPositionChangedListener.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -861,6 +862,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.OnScrollListener.html b/docs/html/reference/android/support/wearable/view/WearableListView.OnScrollListener.html
index de2bcd7..2871600 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.OnScrollListener.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.OnScrollListener.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -602,7 +603,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1065,6 +1066,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.ViewHolder.html b/docs/html/reference/android/support/wearable/view/WearableListView.ViewHolder.html
index b7953d4..270d8d8 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.ViewHolder.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.ViewHolder.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -652,7 +653,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1346,6 +1347,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/WearableListView.html b/docs/html/reference/android/support/wearable/view/WearableListView.html
index eec5c32..7fb9565 100644
--- a/docs/html/reference/android/support/wearable/view/WearableListView.html
+++ b/docs/html/reference/android/support/wearable/view/WearableListView.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -501,6 +501,7 @@
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
           <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -724,7 +725,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -3236,7 +3237,7 @@
             boolean</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#onInterceptTouchEvent(android.view.MotionEvent)">onInterceptTouchEvent</a></span>(MotionEvent event)</nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#isAtTop()">isAtTop</a></span>()</nobr>
         
   </td></tr>
 
@@ -3252,7 +3253,7 @@
             boolean</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
-        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#onTouchEvent(android.view.MotionEvent)">onTouchEvent</a></span>(MotionEvent event)</nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#onInterceptTouchEvent(android.view.MotionEvent)">onInterceptTouchEvent</a></span>(MotionEvent event)</nobr>
         
   </td></tr>
 
@@ -3265,6 +3266,22 @@
             
             
             
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#onTouchEvent(android.view.MotionEvent)">onTouchEvent</a></span>(MotionEvent event)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
@@ -3281,7 +3298,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -3304,7 +3321,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -3327,7 +3344,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -3343,7 +3360,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -3366,7 +3383,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -3390,7 +3407,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -3413,7 +3430,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -3436,6 +3453,22 @@
   </td></tr>
 
 
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html#smoothScrollToPosition(int, android.support.v7.widget.RecyclerView.SmoothScroller)">smoothScrollToPosition</a></span>(int position, RecyclerView.SmoothScroller smoothScroller)</nobr>
+        
+  </td></tr>
+
+
 
 </table>
 
@@ -16613,6 +16646,43 @@
 </div>
 
 
+<A NAME="isAtTop()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        boolean
+      </span>
+      <span class="sympad">isAtTop</span>
+      <span class="normal">()</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Returns</h5>
+      <ul class="nolist"><li>true if the list is scrolled all the way to the top.
+</li></ul>
+  </div>
+
+    </div>
+</div>
+
+
 <A NAME="onInterceptTouchEvent(android.view.MotionEvent)"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -16963,6 +17033,38 @@
 </div>
 
 
+<A NAME="smoothScrollToPosition(int, android.support.v7.widget.RecyclerView.SmoothScroller)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">smoothScrollToPosition</span>
+      <span class="normal">(int position, RecyclerView.SmoothScroller smoothScroller)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    </div>
+</div>
+
+
 
 
 
@@ -17026,6 +17128,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/view/package-summary.html b/docs/html/reference/android/support/wearable/view/package-summary.html
index 28f94db..f76e378 100644
--- a/docs/html/reference/android/support/wearable/view/package-summary.html
+++ b/docs/html/reference/android/support/wearable/view/package-summary.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -502,6 +502,7 @@
         <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridPagerAdapter.html">GridPagerAdapter</a></li>
         <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.html">GridViewPager</a></li>
         <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/GridViewPager.LayoutParams.html">GridViewPager.LayoutParams</a></li>
+        <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></li>
         <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></li>
         <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></li>
         <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></li>
@@ -578,7 +579,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 
 
 
@@ -920,6 +921,17 @@
       
     
       <tr class=" api apilevel-" >
+        <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/ProgressSpinner.html">ProgressSpinner</a></td>
+        <td class="jd-descrcol" width="100%">
+          An indeterminate progress spinner designed for wearables which cycles through colors.&nbsp;
+          
+    
+
+        </td>
+      </tr>
+      
+    
+      <tr class="alt-color api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/SimpleAnimatorListener.html">SimpleAnimatorListener</a></td>
         <td class="jd-descrcol" width="100%">
           Convenience class for listening for Animator events that implements the AnimatorListener
@@ -931,7 +943,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WatchViewStub.html">WatchViewStub</a></td>
         <td class="jd-descrcol" width="100%">
           A WatchViewStub allows for the use of different sub-layouts depending on the
@@ -944,7 +956,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.html">WearableFrameLayout</a></td>
         <td class="jd-descrcol" width="100%">
           WearableFrameLayout works exactly like FrameLayout, except it can have overrides for a round
@@ -956,7 +968,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WearableFrameLayout.LayoutParams.html">WearableFrameLayout.LayoutParams</a></td>
         <td class="jd-descrcol" width="100%">
           Per-child layout information for layouts on wearable devices.&nbsp;
@@ -967,7 +979,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WearableListView.html">WearableListView</a></td>
         <td class="jd-descrcol" width="100%">
           An alternative version of ListView that is optimized for ease of use on small screen wearable
@@ -979,7 +991,7 @@
       </tr>
       
     
-      <tr class="alt-color api apilevel-" >
+      <tr class=" api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WearableListView.Adapter.html">WearableListView.Adapter</a></td>
         <td class="jd-descrcol" width="100%">
           Base class for adapters providing data for the WearableListView.&nbsp;
@@ -990,7 +1002,7 @@
       </tr>
       
     
-      <tr class=" api apilevel-" >
+      <tr class="alt-color api apilevel-" >
         <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/view/WearableListView.ViewHolder.html">WearableListView.ViewHolder</a></td>
         <td class="jd-descrcol" width="100%">
           Wrapper around items displayed in the list view.&nbsp;
@@ -1070,6 +1082,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.Engine.html b/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.Engine.html
index bbae62a..1a7aa76 100644
--- a/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.Engine.html
+++ b/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.Engine.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -466,6 +466,11 @@
 
             <ul>
               
+    <li><h2>Annotations</h2>
+      <ul>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+      </ul>
+    </li>
               
               
     <li><h2>Classes</h2>
@@ -631,7 +636,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -968,6 +973,29 @@
             final
             
             
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#getNotificationCount()">getNotificationCount</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">
+          Returns the total number of notification cards in the stream.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
             Rect</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
@@ -984,7 +1012,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1007,7 +1035,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1030,7 +1058,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1053,7 +1081,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1069,7 +1097,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1085,7 +1113,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1101,7 +1129,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1124,6 +1152,29 @@
 
 
 	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onNotificationCountChanged(int)">onNotificationCountChanged</a></span>(int count)</nobr>
+        
+        <div class="jd-descrdiv">
+          Called when the total number of notification cards in the stream has changed.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
@@ -1180,6 +1231,29 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTapCommand(int, int, int, long)">onTapCommand</a></span>(int tapType, int x, int y, long eventTime)</nobr>
+        
+        <div class="jd-descrdiv">
+          Called when a tap or touch related event occurs.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTimeTick()">onTimeTick</a></span>()</nobr>
         
         <div class="jd-descrdiv">
@@ -1193,7 +1267,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1216,7 +1290,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1239,7 +1313,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2201,6 +2275,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.html b/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.html
index 5dbd8ea..aee337f 100644
--- a/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.html
+++ b/docs/html/reference/android/support/wearable/watchface/CanvasWatchFaceService.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -466,6 +466,11 @@
 
             <ul>
               
+    <li><h2>Annotations</h2>
+      <ul>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+      </ul>
+    </li>
               
               
     <li><h2>Classes</h2>
@@ -694,7 +699,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -952,6 +957,44 @@
     </tr>
     
     
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP">TAP_TYPE_TAP</a></td>
+        <td class="jd-descrcol" width="100%">
+          Used in onTapCommaned to indicate that an "up" event on the watch face has occurred that
+ has not been consumed by another activity.
+          
+    
+
+        </td>
+    </tr>
+    
+    
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH">TAP_TYPE_TOUCH</a></td>
+        <td class="jd-descrcol" width="100%">
+          Used in onTapCommand to indicate a "down" touch event on the watch face.
+          
+    
+
+        </td>
+    </tr>
+    
+    
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL">TAP_TYPE_TOUCH_CANCEL</a></td>
+        <td class="jd-descrcol" width="100%">
+          Used in onTapCaommand to indicate that a previous TAP_TYPE_TOUCH touch event has been
+ canceled.
+          
+    
+
+        </td>
+    </tr>
+    
+    
 </table>
   </div>
 </div>
@@ -6238,6 +6281,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.Engine.html b/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.Engine.html
index 761917877..aba23a6 100644
--- a/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.Engine.html
+++ b/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.Engine.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -466,6 +466,11 @@
 
             <ul>
               
+    <li><h2>Annotations</h2>
+      <ul>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+      </ul>
+    </li>
               
               
     <li><h2>Classes</h2>
@@ -631,7 +636,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1138,6 +1143,29 @@
             final
             
             
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#getNotificationCount()">getNotificationCount</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">
+          Returns the total number of notification cards in the stream.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
             Rect</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
@@ -1154,7 +1182,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1177,7 +1205,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1200,7 +1228,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1223,7 +1251,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1239,7 +1267,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1255,7 +1283,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1271,7 +1299,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1294,6 +1322,29 @@
 
 
 	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onNotificationCountChanged(int)">onNotificationCountChanged</a></span>(int count)</nobr>
+        
+        <div class="jd-descrdiv">
+          Called when the total number of notification cards in the stream has changed.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
@@ -1350,6 +1401,29 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTapCommand(int, int, int, long)">onTapCommand</a></span>(int tapType, int x, int y, long eventTime)</nobr>
+        
+        <div class="jd-descrdiv">
+          Called when a tap or touch related event occurs.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTimeTick()">onTimeTick</a></span>()</nobr>
         
         <div class="jd-descrdiv">
@@ -1363,7 +1437,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1386,7 +1460,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1409,7 +1483,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -2668,6 +2742,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.html b/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.html
index 6371290..1dcc7dd 100644
--- a/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.html
+++ b/docs/html/reference/android/support/wearable/watchface/Gles2WatchFaceService.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -466,6 +466,11 @@
 
             <ul>
               
+    <li><h2>Annotations</h2>
+      <ul>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+      </ul>
+    </li>
               
               
     <li><h2>Classes</h2>
@@ -694,7 +699,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -955,6 +960,44 @@
     </tr>
     
     
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP">TAP_TYPE_TAP</a></td>
+        <td class="jd-descrcol" width="100%">
+          Used in onTapCommaned to indicate that an "up" event on the watch face has occurred that
+ has not been consumed by another activity.
+          
+    
+
+        </td>
+    </tr>
+    
+    
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH">TAP_TYPE_TOUCH</a></td>
+        <td class="jd-descrcol" width="100%">
+          Used in onTapCommand to indicate a "down" touch event on the watch face.
+          
+    
+
+        </td>
+    </tr>
+    
+    
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL">TAP_TYPE_TOUCH_CANCEL</a></td>
+        <td class="jd-descrcol" width="100%">
+          Used in onTapCaommand to indicate that a previous TAP_TYPE_TOUCH touch event has been
+ canceled.
+          
+    
+
+        </td>
+    </tr>
+    
+    
 </table>
   </div>
 </div>
@@ -6241,6 +6284,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/WatchFaceService.Engine.html b/docs/html/reference/android/support/wearable/watchface/WatchFaceService.Engine.html
index 2326386..ad6cc2c 100644
--- a/docs/html/reference/android/support/wearable/watchface/WatchFaceService.Engine.html
+++ b/docs/html/reference/android/support/wearable/watchface/WatchFaceService.Engine.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -466,6 +466,11 @@
 
             <ul>
               
+    <li><h2>Annotations</h2>
+      <ul>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+      </ul>
+    </li>
               
               
     <li><h2>Classes</h2>
@@ -620,7 +625,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -831,6 +836,29 @@
             final
             
             
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#getNotificationCount()">getNotificationCount</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">
+          Returns the total number of notification cards in the stream.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
             Rect</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
@@ -847,7 +875,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -870,7 +898,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -893,7 +921,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -916,7 +944,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -932,7 +960,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -948,7 +976,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -964,7 +992,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -987,6 +1015,29 @@
 
 
 	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onNotificationCountChanged(int)">onNotificationCountChanged</a></span>(int count)</nobr>
+        
+        <div class="jd-descrdiv">
+          Called when the total number of notification cards in the stream has changed.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
     <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
@@ -1043,6 +1094,29 @@
             void</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTapCommand(int, int, int, long)">onTapCommand</a></span>(int tapType, int x, int y, long eventTime)</nobr>
+        
+        <div class="jd-descrdiv">
+          Called when a tap or touch related event occurs.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTimeTick()">onTimeTick</a></span>()</nobr>
         
         <div class="jd-descrdiv">
@@ -1056,7 +1130,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1079,7 +1153,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1102,7 +1176,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1805,6 +1879,39 @@
 </div>
 
 
+<A NAME="getNotificationCount()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+        final 
+         
+         
+        int
+      </span>
+      <span class="sympad">getNotificationCount</span>
+      <span class="normal">()</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Returns the total number of notification cards in the stream.
+</p></div>
+
+    </div>
+</div>
+
+
 <A NAME="getPeekCardPosition()"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -2075,6 +2182,48 @@
 </div>
 
 
+<A NAME="onNotificationCountChanged(int)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">onNotificationCountChanged</span>
+      <span class="normal">(int count)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Called when the total number of notification cards in the stream has changed.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>count</td>
+          <td>total number of the notification cards in the stream
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
 <A NAME="onPeekCardPositionUpdate(android.graphics.Rect)"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -2154,6 +2303,60 @@
 </div>
 
 
+<A NAME="onTapCommand(int, int, int, long)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">onTapCommand</span>
+      <span class="normal">(int tapType, int x, int y, long eventTime)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Called when a tap or touch related event occurs.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>tapType</td>
+          <td>Value representing the event sent to the wallpaper.</td>
+        </tr>
+        <tr>
+          <th>x</td>
+          <td>X coordinate of the event.</td>
+        </tr>
+        <tr>
+          <th>y</td>
+          <td>Y coordinate of the event.</td>
+        </tr>
+        <tr>
+          <th>eventTime</td>
+          <td>The time, in millis, of the event.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
 <A NAME="onTimeTick()"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -2369,6 +2572,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/WatchFaceService.html b/docs/html/reference/android/support/wearable/watchface/WatchFaceService.html
index f566e7e..40cf0a3 100644
--- a/docs/html/reference/android/support/wearable/watchface/WatchFaceService.html
+++ b/docs/html/reference/android/support/wearable/watchface/WatchFaceService.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -466,6 +466,11 @@
 
             <ul>
               
+    <li><h2>Annotations</h2>
+      <ul>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+      </ul>
+    </li>
               
               
     <li><h2>Classes</h2>
@@ -684,7 +689,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -922,6 +927,23 @@
     </tr>
     
     
+    <tr class=" api apilevel-" >
+      <td class="jd-typecol"><nobr>
+        
+         
+         
+        
+        @interface</nobr></td>
+      <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></td>
+      <td class="jd-descrcol" width="100%">
+        &nbsp;
+        
+    
+
+      </td>
+    </tr>
+    
+    
 
 
 
@@ -1005,6 +1027,44 @@
     </tr>
     
     
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP">TAP_TYPE_TAP</a></td>
+        <td class="jd-descrcol" width="100%">
+          Used in onTapCommaned to indicate that an "up" event on the watch face has occurred that
+ has not been consumed by another activity.
+          
+    
+
+        </td>
+    </tr>
+    
+    
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH">TAP_TYPE_TOUCH</a></td>
+        <td class="jd-descrcol" width="100%">
+          Used in onTapCommand to indicate a "down" touch event on the watch face.
+          
+    
+
+        </td>
+    </tr>
+    
+    
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL">TAP_TYPE_TOUCH_CANCEL</a></td>
+        <td class="jd-descrcol" width="100%">
+          Used in onTapCaommand to indicate that a previous TAP_TYPE_TOUCH touch event has been
+ canceled.
+          
+    
+
+        </td>
+    </tr>
+    
+    
 
 </table>
 
@@ -6330,6 +6390,136 @@
 
 
 
+<A NAME="TAP_TYPE_TAP"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+        final 
+        int
+      </span>
+        TAP_TYPE_TAP
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Used in onTapCommaned to indicate that an "up" event on the watch face has occurred that
+ has not been consumed by another activity. A TAP_TYPE_TOUCH will always occur first. This
+ event will not occur if a TAP_TYPE_TOUCH_CANCEL is sent.
+</p></div>
+
+    
+        <div class="jd-tagdata">
+        <span class="jd-tagtitle">Constant Value: </span>
+        <span>
+            
+                2
+                (0x00000002)
+            
+        </span>
+        </div>
+    
+    </div>
+</div>
+
+
+
+<A NAME="TAP_TYPE_TOUCH"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+        final 
+        int
+      </span>
+        TAP_TYPE_TOUCH
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Used in onTapCommand to indicate a "down" touch event on the watch face.
+</p></div>
+
+    
+        <div class="jd-tagdata">
+        <span class="jd-tagtitle">Constant Value: </span>
+        <span>
+            
+                0
+                (0x00000000)
+            
+        </span>
+        </div>
+    
+    </div>
+</div>
+
+
+
+<A NAME="TAP_TYPE_TOUCH_CANCEL"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+        final 
+        int
+      </span>
+        TAP_TYPE_TOUCH_CANCEL
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Used in onTapCaommand to indicate that a previous TAP_TYPE_TOUCH touch event has been
+ canceled. This generally happens when the watch face is touched but then a move or long
+ press occurs.
+</p></div>
+
+    
+        <div class="jd-tagdata">
+        <span class="jd-tagtitle">Constant Value: </span>
+        <span>
+            
+                1
+                (0x00000001)
+            
+        </span>
+        </div>
+    
+    </div>
+</div>
+
+
+
 
 <!-- Fields -->
 
@@ -6484,6 +6674,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html b/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html
index 956e3a8..a5401e5 100644
--- a/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html
+++ b/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -466,6 +466,11 @@
 
             <ul>
               
+    <li><h2>Annotations</h2>
+      <ul>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+      </ul>
+    </li>
               
               
     <li><h2>Classes</h2>
@@ -609,7 +614,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -758,6 +763,29 @@
             <a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html">WatchFaceStyle.Builder</a></nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html#setAcceptsTapEvents(boolean)">setAcceptsTapEvents</a></span>(boolean acceptsTapEvents)</nobr>
+        
+        <div class="jd-descrdiv">
+          Sets whether this watchface accepts tap events.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html">WatchFaceStyle.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
         <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html#setAmbientPeekMode(int)">setAmbientPeekMode</a></span>(int ambientPeekMode)</nobr>
         
         <div class="jd-descrdiv">
@@ -772,7 +800,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -795,7 +823,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -818,7 +846,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -841,7 +869,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -864,7 +892,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -887,7 +915,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -910,7 +938,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -933,7 +961,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -959,7 +987,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1312,6 +1340,53 @@
 </div>
 
 
+<A NAME="setAcceptsTapEvents(boolean)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.Builder.html">WatchFaceStyle.Builder</a>
+      </span>
+      <span class="sympad">setAcceptsTapEvents</span>
+      <span class="normal">(boolean acceptsTapEvents)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Sets whether this watchface accepts tap events. The default is false.
+ <p>
+ Watchfaces that set this <code>true</code> are indicating they are prepared to receive
+ <code><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH">TAP_TYPE_TOUCH</a></code>,
+ <code><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL">TAP_TYPE_TOUCH_CANCEL</a></code>,
+ and <code><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP">TAP_TYPE_TAP</a></code></p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>acceptsTapEvents</td>
+          <td>whether to receive touch events.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
 <A NAME="setAmbientPeekMode(int)"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -1825,6 +1900,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.html b/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.html
index e08608f..70c3851 100644
--- a/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.html
+++ b/docs/html/reference/android/support/wearable/watchface/WatchFaceStyle.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -466,6 +466,11 @@
 
             <ul>
               
+    <li><h2>Annotations</h2>
+      <ul>
+          <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+      </ul>
+    </li>
               
               
     <li><h2>Classes</h2>
@@ -632,7 +637,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 <table class="jd-inheritance-table">
 
 
@@ -1022,6 +1027,29 @@
             
             
             
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceStyle.html#getAcceptsTapEvents()">getAcceptsTapEvents</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">
+          Whether the watchface accepts tap events.
+          
+    
+
+        </div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
             int</nobr>
         </td>
         <td class="jd-linkcol" width="100%"><nobr>
@@ -1039,7 +1067,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1062,7 +1090,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1085,7 +1113,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1108,7 +1136,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1131,7 +1159,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1154,7 +1182,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1177,7 +1205,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1200,7 +1228,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1223,7 +1251,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1247,7 +1275,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1263,7 +1291,7 @@
 
 
 	 
-    <tr class=" api apilevel-" >
+    <tr class="alt-color api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1279,7 +1307,7 @@
 
 
 	 
-    <tr class="alt-color api apilevel-" >
+    <tr class=" api apilevel-" >
         <td class="jd-typecol"><nobr>
             
             
@@ -1706,7 +1734,8 @@
 
       
   <div class="jd-tagdata jd-tagdescr"><p>When this background visibility is selected, the background of the peek card should only be
- shown briefly, and only if the peek card represents an interruptive notification.
+ shown briefly, and only if the peek card represents an interruptive notification. This is the
+ default mode.
 </p></div>
 
     
@@ -1749,7 +1778,7 @@
 
       
   <div class="jd-tagdata jd-tagdescr"><p>When this background visibility is selected, the background of the peek card should always
- be shown. This is the default mode.
+ be shown.
 
  Note that this will obscure your watch face whenever there is a peek card showing.
 </p></div>
@@ -2191,6 +2220,39 @@
 </div>
 
 
+<A NAME="getAcceptsTapEvents()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        boolean
+      </span>
+      <span class="sympad">getAcceptsTapEvents</span>
+      <span class="normal">()</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+    
+
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Whether the watchface accepts tap events.  The default is false.
+</p></div>
+
+    </div>
+</div>
+
+
 <A NAME="getAmbientPeekMode()"></A>
 
 <div class="jd-details api apilevel-"> 
@@ -2705,6 +2767,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/reference/android/support/wearable/watchface/package-summary.html b/docs/html/reference/android/support/wearable/watchface/package-summary.html
index 6853fc4..a654b13 100644
--- a/docs/html/reference/android/support/wearable/watchface/package-summary.html
+++ b/docs/html/reference/android/support/wearable/watchface/package-summary.html
@@ -128,7 +128,7 @@
   var metaTags = [];
   var devsite = false;
 </script>
-<script src="../../../../../assets/js/docs.js?v=5" type="text/javascript"></script>
+<script src="../../../../../assets/js/docs.js?v=6" type="text/javascript"></script>
 
 
 
@@ -467,6 +467,11 @@
 
             <ul>
               
+    <li><h2>Annotations</h2>
+      <ul>
+        <li class="api apilevel-"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></li>
+      </ul>
+    </li>
               
               
     <li><h2>Classes</h2>
@@ -548,7 +553,7 @@
 
 <div id="naMessage"></div>
 
-<div id="jd-content" class="api apilevel-"><p style="border:2px solid #99ccff;padding:12px;margin-top:20px"><strong>Note:</strong> The Wearable Support Library classes under the <code>android.support.wearable</code> package are subject to change. For the full Android API reference, see <a href="/reference/">Reference</a>.</p>
+<div id="jd-content" class="api apilevel-">
 
 
 
@@ -556,6 +561,27 @@
 
 
   
+    <h2>Annotations</h2>
+    <div class="jd-sumtable">
+    
+  
+  <table class="jd-sumtable-expando">
+    
+      <tr class="alt-color api apilevel-" >
+        <td class="jd-linkcol"><a href="../../../../../reference/android/support/wearable/watchface/WatchFaceService.TapType.html">WatchFaceService.TapType</a></td>
+        <td class="jd-descrcol" width="100%">
+          &nbsp;
+          
+    
+
+        </td>
+      </tr>
+      
+    
+  </table>
+
+    </div>
+  
 
 
   
@@ -726,6 +752,7 @@
           <option value="es">Español</option>
           <option value="ja">日本語</option>
           <option value="ko">한국어</option>
+          <option value="pt-br">Português Brasileiro</option>
           <option value="ru">Русский</option>
           <option value="zh-cn">中文(简体)</option>
           <option value="zh-tw">中文(繁體)</option>
diff --git a/docs/html/tools/help/adb.jd b/docs/html/tools/help/adb.jd
index 641d463..2faff4f 100644
--- a/docs/html/tools/help/adb.jd
+++ b/docs/html/tools/help/adb.jd
@@ -420,62 +420,54 @@
 <ol>
 
 <li>
-Connect Android device and adb host computer
+<p>Connect your Android device and adb host computer
 to a common Wi-Fi network accessible to both.
 We have found that not all access points
 are suitable; you may need to use an access point
-whose firewall is configured properly to support adb.
+whose firewall is configured properly to support adb.</p>
+
+<p class="note"><strong>Note: </strong>If you are attempting to connect
+to a Wear device, force it to connect to Wi-Fi by shutting off Bluetooth
+on the phone connected to it.</p>
 </li>
 
 <li>
-Connect the device with USB cable to host.
+Connect the device to the host computer with a USB cable.
 </li>
 
 <li>
-Make sure adb is running in USB mode on host.
-<pre>
-$ adb usb
-restarting in USB mode
-</pre>
-</li>
-
-<li>
-Connect to the device over USB.
-<pre>
-$ adb devices
-List of devices attached
-######## device
-</pre>
-</li>
-
-<li>
-Restart host adb in tcpip mode.
-<pre>
+Set the target device to listen for a TCP/IP connection on port 5555.
+<pre class="no-pretty-print">
 $ adb tcpip 5555
-restarting in TCP mode port: 5555
 </pre>
 </li>
 
 <li>
-Find out the IP address of the Android device:
-Settings -> About tablet -> Status -> IP address.
-Remember the IP address, of the form <code>#.#.#.#</code>.
+Disconnect the USB cable from the target device.
 </li>
 
 <li>
-Connect adb host to device:
-<pre>
-$ adb connect #.#.#.#
-connected to #.#.#.#:5555
+Find the IP address of the Android device. For example, on a Nexus device, you can find
+the IP address at <strong>Settings</strong> &gt; <strong>About tablet</strong>
+(or <strong>About phone</strong>) &gt; <strong>Status</strong> &gt; <strong>IP address</strong>. Or,
+on an Android Wear device, you can find the IP address at <strong>Settings</strong> &gt;
+<strong>Wi-Fi Settings</strong> &gt; <strong>Advanced</strong> &gt; <strong>IP address</strong>.
+</li>
+
+<li>
+Connect to the device, identifying it by IP address.
+<pre class="no-pretty-print">
+$ adb connect &lt;device-ip-address&gt;
 </pre>
 </li>
 
+
 <li>
-Remove USB cable from device, and confirm you can still access device:
-<pre>
+Confirm that your host computer is connected to the target device:
+<pre class="no-pretty-print">
 $ adb devices
 List of devices attached
-#.#.#.#:5555 device
+&lt;device-ip-address&gt;:5555 device
 </pre>
 
 </ol>
@@ -500,10 +492,10 @@
 
 <li>
 Or if that doesn't work, reset your adb host:
-<pre>
+<pre class="no-pretty-print">
 adb kill-server
 </pre>
 and then start over from the beginning.
 </li>
 
-</ol>
\ No newline at end of file
+</ol>
diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs
index 5279969..7cffdd8 100644
--- a/docs/html/training/training_toc.cs
+++ b/docs/html/training/training_toc.cs
@@ -989,6 +989,9 @@
             <a href="<?cs var:toroot ?>training/wearables/watch-faces/information.html">Showing Information in Watch Faces</a>
           </li>
           <li>
+            <a href="<?cs var:toroot ?>training/wearables/watch-faces/interacting.html">Creating Interactive Watch Faces</a>
+          </li>
+          <li>
             <a href="<?cs var:toroot ?>training/wearables/watch-faces/configuration.html">Providing Configuration Activities</a>
           </li>
           <li>
diff --git a/docs/html/training/wearables/watch-faces/index.jd b/docs/html/training/wearables/watch-faces/index.jd
index ec428c1..a329fda 100644
--- a/docs/html/training/wearables/watch-faces/index.jd
+++ b/docs/html/training/wearables/watch-faces/index.jd
@@ -65,6 +65,9 @@
 <dt><a href="{@docRoot}training/wearables/watch-faces/information.html">
 Showing Information in Watch Faces</a></dt>
 <dd>Learn how to incorporate contextual information into your watch face.</dd>
+<dt><a href="{@docRoot}training/wearables/watch-faces/interacting.html">
+Creating Interactive Watch Faces</a></dt>
+<dd>Learn how to enable the user to interact with your watch face.</dd>
 <dt><a href="{@docRoot}training/wearables/watch-faces/configuration.html">
 Providing Configuration Activities</a></dt>
 <dd>Learn how to create watch faces with configurable parameters.</dd>
diff --git a/docs/html/training/wearables/watch-faces/interacting.jd b/docs/html/training/wearables/watch-faces/interacting.jd
new file mode 100644
index 0000000..5a44fde
--- /dev/null
+++ b/docs/html/training/wearables/watch-faces/interacting.jd
@@ -0,0 +1,133 @@
+page.title=Creating Interactive Watch Faces
+
+@jd:body
+
+<div id="tb-wrapper">
+<div id="tb">
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Construct">Construct an Interactive Watch Face</a></li>
+  <li><a href="#Handle">Handle Gestures</a></li>
+</ol>
+<h2>You should also read</h2>
+<ul>
+  <li><a href="{@docRoot}design/wear/watchfaces.html">Watch Faces for Android Wear</a></li>
+</ul>
+<h2>Related Samples</h2>
+  <ul>
+    <li><a href="{@docRoot}samples/WatchFace/index.html">WatchFace</a></li>
+  </ul>
+</div>
+</div>
+
+<p>Your watch's display is more than just a pretty face: Users can  interact with it.
+For example, a user might tap the watch face to learn what song is currently playing, or
+to see the day's agenda. Android Wear allows Android Wear watch faces to accept
+the single-tap gesture at a given location on the watch face, as long as there's not another
+UI element that also responds to that gesture.
+
+<p>This lesson teaches you how to implement an interactive watch face by first constructing the
+watch face style, and then implementing gesture handling.</p>
+
+<p class="note"><strong>Note:</strong> Before beginning development work on your interactive watch
+face, you should be sure to read the <a href="{@docRoot}design/wear/watchfaces.html">Watch Faces for
+Android Wear</a> design guide.
+
+<h2 id="Construct">Handling Tap Events</h2>
+
+<p>When constructing an interactive watch-face style, the first thing the app must do is tell the
+system that the watch face receives <a href="{@docRoot}design/wear/watchfaces.html#ag">tap events</a>.
+The following example shows how to do this:
+
+<pre>
+setWatchFaceStyle(new WatchFaceStyle.Builder(mService)
+    .setAcceptsTapEvents(true)
+    // other style customizations
+    .build());
+</pre>
+
+<p>When the system detects a tap on the watch face, it triggers the
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTapCommand(int, int, int, long)">
+{@code WatchFaceService.Engine.onTapCommand()}</a> method. Override this method in your
+implementation of
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.Engine.html">
+{@code WatchFaceService.Engine}</a>to initiate the action you wish to perform, such
+as showing a detailed step count or changing the theme of the watch face. The code snippet
+in <a href="#Handle">Handle Gestures</a> shows an example of such an
+implementation.</p>
+
+<h2 id="Handle">Handle Gestures</h2>
+
+<p> To provide a consistent user experience, the system
+reserves gestures such as drag and long-press for system UI elements.
+Therefore, the system does not send raw touch events to the watch face. Instead, the system forwards specific commands to the
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.Engine.html#onTapCommand(int, int, int, long)">
+onTapCommand()</a> method.
+
+<p>The system sends the first command,
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH">
+{@code TAP_TYPE_TOUCH}</a>, when the user initially touches the
+screen. This event lets you provide visual feedback to the user on touch.  Your app should not
+launch a UI when this event triggers. Launching a UI prevents drag events from opening the app
+launcher, settings shade, and notifications stream.</p>
+
+<p>Before sending the next command, the system judges whether the contact is a single tap, which is
+<a href="{@docRoot}design/wear/watchfaces.html#ag">the only gesture allowed</a>. If the user
+immediately lifts their finger, the system determines that a single tap took place, and forwards
+a
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP"</a>
+{@code TAP_TYPE_TAP}</a> event. If the user does not immediately lift their finger, the system
+forwards a
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL"</a>
+{@code TAP_TYPE_TOUCH_CANCEL}</a> event. Once the user has triggered a
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TOUCH_CANCEL"</a>
+{@code TAP_TYPE_TOUCH_CANCEL}</a> event, they cannot trigger a
+<a href="{@docRoot}reference/android/support/wearable/watchface/WatchFaceService.html#TAP_TYPE_TAP"</a>
+{@code TAP_TYPE_TAP}</a> event until they
+make a new contact with the screen.</p>
+
+<p>The following example shows you how to implement tap events on a watch face:</p>
+
+
+<pre>
+&#64;Override
+public void onTapCommand(
+       &#64;TapType int tapType, int x, int y, long eventTime) {
+    switch (tapType) {
+        case WatchFaceService.TAP_TYPE_TAP:
+            hideTapHighlight();
+            if (withinTapRegion(x, y)) {
+                // Implement the tap action
+                // (e.g. show detailed step count)
+                onWatchFaceTap();
+            }
+            break;
+
+        case WatchFaceService.TAP_TYPE_TOUCH:
+            if (withinTapRegion(x, y)) {
+                // Provide visual feedback of touch event
+                startTapHighlight(x, y, eventTime);
+            }
+            break;
+
+        case WatchFaceService.TAP_TYPE_TOUCH_CANCEL:
+            hideTapHighlight();
+            break;
+
+        default:
+            super.onTapCommand(tapType, x, y, eventTime);
+            break;
+    }
+}
+</pre>
+
+<p>In this example, the app determines what kind of event has taken place,
+and responds accordingly. If the event is initial contact by the user's finger,
+the app displays visual feedback. If the event is an immediate lifting
+of the finger after contact, it performs the action on which the
+user tapped. If the event is prolonged contact by the finger, the app
+does nothing.</p>
+
+
+
+
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index 0e9823d..91e704a 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -486,9 +486,9 @@
      */
     public enum Direction {
         /** clockwise */
-        CW  (1),    // must match enum in SkPath.h
+        CW  (0),    // must match enum in SkPath.h
         /** counter-clockwise */
-        CCW (2);    // must match enum in SkPath.h
+        CCW (1);    // must match enum in SkPath.h
 
         Direction(int ni) {
             nativeInt = ni;
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 32f6a89..464f3de 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -855,7 +855,8 @@
 
         // Position the shader to account for canvas translation.
         if (mMaskShader != null) {
-            mMaskMatrix.setTranslate(-x, -y);
+            final Rect bounds = getBounds();
+            mMaskMatrix.setTranslate(bounds.left - x, bounds.top - y);
             mMaskShader.setLocalMatrix(mMaskMatrix);
         }
 
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 751531e..20ecda2 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -52,14 +52,14 @@
 // If this is set to negative value, then all the edge will be tessellated.
 #define ALPHA_THRESHOLD (0.1f / 255.0f)
 
-#include <math.h>
-#include <utils/Log.h>
-
 #include "AmbientShadow.h"
+
 #include "ShadowTessellator.h"
 #include "Vertex.h"
 #include "VertexBuffer.h"
-#include "utils/MathUtils.h"
+
+#include <algorithm>
+#include <utils/Log.h>
 
 namespace android {
 namespace uirenderer {
@@ -78,7 +78,7 @@
 // The input z value will be converted to be non-negative inside.
 // The output must be ranged from 0 to 1.
 inline float getAlphaFromFactoredZ(float factoredZ) {
-    return 1.0 / (1 + MathUtils::max(factoredZ, 0.0f));
+    return 1.0 / (1 + std::max(factoredZ, 0.0f));
 }
 
 // The shader is using gaussian function e^-(1-x)*(1-x)*4, therefore, we transform
diff --git a/libs/hwui/Canvas.h b/libs/hwui/Canvas.h
index 3c77b3d..4bd4ac8 100644
--- a/libs/hwui/Canvas.h
+++ b/libs/hwui/Canvas.h
@@ -85,10 +85,6 @@
     virtual void getMatrix(SkMatrix* outMatrix) const = 0;
     virtual void setMatrix(const SkMatrix& matrix) = 0;
 
-    /// Like setMatrix(), but to be translated into local / view-relative coordinates
-    /// rather than executed in global / device coordinates at rendering time.
-    virtual void setLocalMatrix(const SkMatrix& matrix) = 0;
-
     virtual void concat(const SkMatrix& matrix) = 0;
     virtual void rotate(float degrees) = 0;
     virtual void scale(float sx, float sy) = 0;
diff --git a/libs/hwui/CanvasState.cpp b/libs/hwui/CanvasState.cpp
index e22b0d3..54fb5f2 100644
--- a/libs/hwui/CanvasState.cpp
+++ b/libs/hwui/CanvasState.cpp
@@ -138,7 +138,7 @@
 }
 
 void CanvasState::setMatrix(const Matrix4& matrix) {
-    mSnapshot->transform->load(matrix);
+    *(mSnapshot->transform) = matrix;
 }
 
 void CanvasState::concatMatrix(const SkMatrix& matrix) {
diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp
index 61c5883..bb149fe 100644
--- a/libs/hwui/DisplayListCanvas.cpp
+++ b/libs/hwui/DisplayListCanvas.cpp
@@ -168,11 +168,6 @@
     mState.setMatrix(matrix);
 }
 
-void DisplayListCanvas::setLocalMatrix(const SkMatrix& matrix) {
-    addStateOp(new (alloc()) SetLocalMatrixOp(matrix));
-    mState.setMatrix(matrix);
-}
-
 void DisplayListCanvas::concat(const SkMatrix& matrix) {
     addStateOp(new (alloc()) ConcatMatrixOp(matrix));
     mState.concatMatrix(matrix);
diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h
index 3b61904..f29e835 100644
--- a/libs/hwui/DisplayListCanvas.h
+++ b/libs/hwui/DisplayListCanvas.h
@@ -143,7 +143,6 @@
     // Matrix
     virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); }
     virtual void setMatrix(const SkMatrix& matrix) override;
-    virtual void setLocalMatrix(const SkMatrix& matrix) override;
 
     virtual void concat(const SkMatrix& matrix) override;
     virtual void rotate(float degrees) override;
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 8ff58d4..8bb892f 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -472,7 +472,9 @@
             : mMatrix(matrix) {}
 
     virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.setMatrix(mMatrix);
+        // Setting a matrix on a Canvas isn't equivalent to setting a total matrix on the scene.
+        // Set a canvas-relative matrix on the renderer instead.
+        renderer.setLocalMatrix(mMatrix);
     }
 
     virtual void output(int level, uint32_t logFlags) const override {
@@ -489,25 +491,6 @@
     const SkMatrix mMatrix;
 };
 
-class SetLocalMatrixOp : public StateOp {
-public:
-    SetLocalMatrixOp(const SkMatrix& matrix)
-            : mMatrix(matrix) {}
-
-    virtual void applyState(OpenGLRenderer& renderer, int saveCount) const override {
-        renderer.setLocalMatrix(mMatrix);
-    }
-
-    virtual void output(int level, uint32_t logFlags) const override {
-        OP_LOG("SetLocalMatrix " SK_MATRIX_STRING, SK_MATRIX_ARGS(&mMatrix));
-    }
-
-    virtual const char* name() override { return "SetLocalMatrix"; }
-
-private:
-    const SkMatrix mMatrix;
-};
-
 class ConcatMatrixOp : public StateOp {
 public:
     ConcatMatrixOp(const SkMatrix& matrix)
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 057c231..75c3ead 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -26,14 +26,12 @@
 #include "Rect.h"
 #include "renderstate/RenderState.h"
 #include "utils/Blur.h"
-#include "utils/MathUtils.h"
 #include "utils/Timing.h"
 
+#include <algorithm>
+#include <cutils/properties.h>
 #include <SkGlyph.h>
 #include <SkUtils.h>
-
-#include <cutils/properties.h>
-
 #include <utils/Log.h>
 
 #ifdef ANDROID_ENABLE_RENDERSCRIPT
@@ -118,10 +116,10 @@
 
     uint32_t maxTextureSize = (uint32_t) Caches::getInstance().maxTextureSize;
 
-    mSmallCacheWidth = MathUtils::min(mSmallCacheWidth, maxTextureSize);
-    mSmallCacheHeight = MathUtils::min(mSmallCacheHeight, maxTextureSize);
-    mLargeCacheWidth = MathUtils::min(mLargeCacheWidth, maxTextureSize);
-    mLargeCacheHeight = MathUtils::min(mLargeCacheHeight, maxTextureSize);
+    mSmallCacheWidth = std::min(mSmallCacheWidth, maxTextureSize);
+    mSmallCacheHeight = std::min(mSmallCacheHeight, maxTextureSize);
+    mLargeCacheWidth = std::min(mLargeCacheWidth, maxTextureSize);
+    mLargeCacheHeight = std::min(mLargeCacheHeight, maxTextureSize);
 
     if (sLogFontRendererCreate) {
         INIT_LOGD("  Text cache sizes, in pixels: %i x %i, %i x %i, %i x %i, %i x %i",
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 288fed3..c9e3880 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -467,8 +467,8 @@
         const int transformFlags) {
     TRIGGER_STAGE(kTransformStage);
 
-    mOutGlop->transform.ortho.load(ortho);
-    mOutGlop->transform.canvas.load(canvas);
+    mOutGlop->transform.ortho = ortho;
+    mOutGlop->transform.canvas = canvas;
     mOutGlop->transform.transformFlags = transformFlags;
 }
 
@@ -615,7 +615,7 @@
             shaderMatrix.loadInverse(mOutGlop->transform.canvas);
             shaderMatrix.multiply(mOutGlop->transform.modelView);
         } else {
-            shaderMatrix.load(mOutGlop->transform.modelView);
+            shaderMatrix = mOutGlop->transform.modelView;
         }
         SkiaShader::store(mCaches, *mShader, shaderMatrix,
                 &textureUnit, &mDescription, &(mOutGlop->fill.skiaShaderData));
diff --git a/libs/hwui/Interpolator.cpp b/libs/hwui/Interpolator.cpp
index e1b0fc3..cc47f00 100644
--- a/libs/hwui/Interpolator.cpp
+++ b/libs/hwui/Interpolator.cpp
@@ -16,11 +16,11 @@
 
 #include "Interpolator.h"
 
-#include <cmath>
-#include <cutils/log.h>
-
 #include "utils/MathUtils.h"
 
+#include <algorithm>
+#include <cutils/log.h>
+
 namespace android {
 namespace uirenderer {
 
@@ -106,7 +106,7 @@
     weight = modff(lutpos, &ipart);
 
     int i1 = (int) ipart;
-    int i2 = MathUtils::min(i1 + 1, (int) mSize - 1);
+    int i2 = std::min(i1 + 1, (int) mSize - 1);
 
     LOG_ALWAYS_FATAL_IF(i1 < 0 || i2 < 0, "negatives in interpolation!"
             " i1=%d, i2=%d, input=%f, lutpos=%f, size=%zu, values=%p, ipart=%f, weight=%f",
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 115e23c..73ebd1304 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -152,10 +152,6 @@
     mType = kTypeUnknown;
 }
 
-void Matrix4::load(const Matrix4& v) {
-    *this = v;
-}
-
 void Matrix4::load(const SkMatrix& v) {
     memset(data, 0, sizeof(data));
 
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index ed54a25..ed517ac 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -114,7 +114,6 @@
     void loadIdentity();
 
     void load(const float* v);
-    void load(const Matrix4& v);
     void load(const SkMatrix& v);
 
     void loadInverse(const Matrix4& v);
@@ -139,7 +138,7 @@
     void multiply(const Matrix4& v) {
         Matrix4 u;
         u.loadMultiply(*this, v);
-        load(u);
+        *this = u;
     }
 
     void multiply(float v);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 7a56d42..b35c017 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1141,7 +1141,7 @@
 
     // Transform and alpha always deferred, since they are used by state operations
     // (Note: saveLayer/restore use colorFilter and alpha, so we just save restore everything)
-    state.mMatrix.load(*currentMatrix);
+    state.mMatrix = *currentMatrix;
     state.mAlpha = currentSnapshot()->alpha;
 
     // always store/restore, since these are just pointers
@@ -1151,7 +1151,7 @@
 }
 
 void OpenGLRenderer::restoreDisplayState(const DeferredDisplayState& state, bool skipClipRestore) {
-    setMatrix(state.mMatrix);
+    setGlobalMatrix(state.mMatrix);
     writableSnapshot()->alpha = state.mAlpha;
     writableSnapshot()->roundRectClipState = state.mRoundRectClipState;
     writableSnapshot()->projectionPathMask = state.mProjectionPathMask;
@@ -2098,8 +2098,9 @@
     mState.skew(sx, sy);
 }
 
-void OpenGLRenderer::setMatrix(const Matrix4& matrix) {
-    mState.setMatrix(matrix);
+void OpenGLRenderer::setLocalMatrix(const Matrix4& matrix) {
+    mState.setMatrix(mBaseTransform);
+    mState.concatMatrix(matrix);
 }
 
 void OpenGLRenderer::setLocalMatrix(const SkMatrix& matrix) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 4f75482..77f6a1b 100755
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -35,6 +35,7 @@
 #include <SkBitmap.h>
 #include <SkCanvas.h>
 #include <SkColorFilter.h>
+#include <SkDrawLooper.h>
 #include <SkMatrix.h>
 #include <SkPaint.h>
 #include <SkRegion.h>
@@ -367,8 +368,10 @@
     void restore();
     void restoreToCount(int saveCount);
 
-    void getMatrix(SkMatrix* outMatrix) const { mState.getMatrix(outMatrix); }
-    void setMatrix(const SkMatrix& matrix) { mState.setMatrix(matrix); }
+    void setGlobalMatrix(const Matrix4& matrix) {
+        mState.setMatrix(matrix);
+    }
+    void setLocalMatrix(const Matrix4& matrix);
     void setLocalMatrix(const SkMatrix& matrix);
     void concatMatrix(const SkMatrix& matrix) { mState.concatMatrix(matrix); }
 
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 500f9e9..b471e78 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-#include <cmath>
-
-#include <utils/Log.h>
+#include "Patch.h"
 
 #include "Caches.h"
-#include "Patch.h"
 #include "Properties.h"
 #include "UvMapper.h"
 #include "utils/MathUtils.h"
 
+#include <algorithm>
+#include <utils/Log.h>
+
 namespace android {
 namespace uirenderer {
 
@@ -189,10 +189,10 @@
     const uint32_t oldQuadCount = quadCount;
     quadCount++;
 
-    x1 = MathUtils::max(x1, 0.0f);
-    x2 = MathUtils::max(x2, 0.0f);
-    y1 = MathUtils::max(y1, 0.0f);
-    y2 = MathUtils::max(y2, 0.0f);
+    x1 = std::max(x1, 0.0f);
+    x2 = std::max(x2, 0.0f);
+    y1 = std::max(y1, 0.0f);
+    y2 = std::max(y2, 0.0f);
 
     // Skip degenerate and transparent (empty) quads
     if ((mColors[oldQuadCount] == 0) || x1 >= x2 || y1 >= y2) {
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index 8fa187c..b57b8f0 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -32,6 +32,15 @@
 #define DEBUG_DUMP_BUFFER()
 #endif
 
+#include "PathTessellator.h"
+
+#include "Matrix.h"
+#include "Vector.h"
+#include "Vertex.h"
+#include "utils/MathUtils.h"
+
+#include <algorithm>
+
 #include <SkPath.h>
 #include <SkPaint.h>
 #include <SkPoint.h>
@@ -44,12 +53,6 @@
 #include <utils/Log.h>
 #include <utils/Trace.h>
 
-#include "PathTessellator.h"
-#include "Matrix.h"
-#include "Vector.h"
-#include "Vertex.h"
-#include "utils/MathUtils.h"
-
 namespace android {
 namespace uirenderer {
 
@@ -152,7 +155,7 @@
             // always use 2 points for hairline
             if (halfStrokeWidth == 0.0f) return 2;
 
-            float threshold = MathUtils::min(inverseScaleX, inverseScaleY) * ROUND_CAP_THRESH;
+            float threshold = std::min(inverseScaleX, inverseScaleY) * ROUND_CAP_THRESH;
             return MathUtils::divisionsNeededToApproximateArc(halfStrokeWidth, PI, threshold);
         }
         return 0;
diff --git a/libs/hwui/PathTessellator.h b/libs/hwui/PathTessellator.h
index b66e832..cddfb04 100644
--- a/libs/hwui/PathTessellator.h
+++ b/libs/hwui/PathTessellator.h
@@ -22,8 +22,12 @@
 #include "Vertex.h"
 #include "VertexBuffer.h"
 
+#include <algorithm>
 #include <vector>
 
+class SkPath;
+class SkPaint;
+
 namespace android {
 namespace uirenderer {
 
@@ -38,7 +42,7 @@
         : thresholdSquared(pixelThreshold * pixelThreshold)
         , sqrInvScaleX(invScaleX * invScaleX)
         , sqrInvScaleY(invScaleY * invScaleY)
-        , thresholdForConicQuads(pixelThreshold * MathUtils::min(invScaleX, invScaleY) / 2.0f) {
+        , thresholdForConicQuads(pixelThreshold * std::min(invScaleX, invScaleY) / 2.0f) {
     };
 
     const float thresholdSquared;
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 7f16deb..29cca36 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -38,7 +38,8 @@
 // Vertex shaders snippets
 ///////////////////////////////////////////////////////////////////////////////
 
-const char* gVS_Header_Attributes =
+const char* gVS_Header_Start =
+        "#version 100\n"
         "attribute vec4 position;\n";
 const char* gVS_Header_Attributes_TexCoords =
         "attribute vec2 texCoords;\n";
@@ -132,6 +133,8 @@
 // Fragment shaders snippets
 ///////////////////////////////////////////////////////////////////////////////
 
+const char* gFS_Header_Start =
+        "#version 100\n";
 const char* gFS_Header_Extension_FramebufferFetch =
         "#extension GL_NV_shader_framebuffer_fetch : enable\n\n";
 const char* gFS_Header_Extension_ExternalTexture =
@@ -457,7 +460,7 @@
 
 String8 ProgramCache::generateVertexShader(const ProgramDescription& description) {
     // Add attributes
-    String8 shader(gVS_Header_Attributes);
+    String8 shader(gVS_Header_Start);
     if (description.hasTexture || description.hasExternalTexture) {
         shader.append(gVS_Header_Attributes_TexCoords);
     }
@@ -543,7 +546,7 @@
 }
 
 String8 ProgramCache::generateFragmentShader(const ProgramDescription& description) {
-    String8 shader;
+    String8 shader(gFS_Header_Start);
 
     const bool blendFramebuffer = description.framebufferMode >= SkXfermode::kPlus_Mode;
     if (blendFramebuffer) {
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 48da3e8..73c0107 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -532,7 +532,7 @@
     if (properties().getProjectBackwards()) {
         // composited projectee, flag for out of order draw, save matrix, and store in proj surface
         opState->mSkipInOrderDraw = true;
-        opState->mTransformFromCompositingAncestor.load(localTransformFromProjectionSurface);
+        opState->mTransformFromCompositingAncestor = localTransformFromProjectionSurface;
         compositedChildrenOfProjectionSurface->push_back(opState);
     } else {
         // standard in order draw
@@ -719,7 +719,7 @@
     // Apply the base transform of the parent of the 3d children. This isolates
     // 3d children of the current chunk from transformations made in previous chunks.
     int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
-    renderer.setMatrix(initialTransform);
+    renderer.setGlobalMatrix(initialTransform);
 
     /**
      * Draw shadows and (potential) casters mostly in order, but allow the shadows of casters
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index c122d99..36633b5 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -74,7 +74,6 @@
 
     virtual void getMatrix(SkMatrix* outMatrix) const override;
     virtual void setMatrix(const SkMatrix& matrix) override;
-    virtual void setLocalMatrix(const SkMatrix& matrix) override { this->setMatrix(matrix); }
     virtual void concat(const SkMatrix& matrix) override;
     virtual void rotate(float degrees) override;
     virtual void scale(float sx, float sy) override;
@@ -702,7 +701,7 @@
     SkPaint paintCopy(paint);
     paintCopy.setTextAlign(SkPaint::kLeft_Align);
 
-    SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+    static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
     mCanvas->drawPosText(text, count << 1, reinterpret_cast<const SkPoint*>(positions), paintCopy);
 }
 
diff --git a/libs/hwui/SkiaCanvasProxy.cpp b/libs/hwui/SkiaCanvasProxy.cpp
index 5e6d774..c3f5eb2 100644
--- a/libs/hwui/SkiaCanvasProxy.cpp
+++ b/libs/hwui/SkiaCanvasProxy.cpp
@@ -45,7 +45,7 @@
     }
 
     // convert the SkPoints into floats
-    SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+    static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
     const size_t floatCount = count << 1;
     const float* floatArray = &pts[0].fX;
 
@@ -142,7 +142,7 @@
         const SkPaint* paint) {
     // TODO: if bitmap is a subset, do we need to add pixelRefOrigin to src?
     mCanvas->save(SkCanvas::kMatrixClip_SaveFlag);
-    mCanvas->setLocalMatrix(SkMatrix::I());
+    mCanvas->setMatrix(SkMatrix::I());
     mCanvas->drawBitmap(bitmap, left, top, paint);
     mCanvas->restore();
 }
@@ -154,7 +154,7 @@
         return;
     }
     // convert the SkPoints into floats
-    SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+    static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
     const int floatCount = vertexCount << 1;
     const float* vArray = &vertices[0].fX;
     const float* tArray = (texs) ? &texs[0].fX : NULL;
@@ -192,9 +192,7 @@
 }
 
 void SkiaCanvasProxy::didSetMatrix(const SkMatrix& matrix) {
-    // SkCanvas setMatrix() is relative to the Canvas origin, but OpenGLRenderer's
-    // setMatrix() is relative to device origin; call setLocalMatrix() instead.
-    mCanvas->setLocalMatrix(matrix);
+    mCanvas->setMatrix(matrix);
 }
 
 void SkiaCanvasProxy::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
@@ -286,7 +284,7 @@
         }
     }
 
-    SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+    static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
     mCanvas->drawText(glyphs.glyphIDs, &pointStorage[0].fX, glyphs.count, glyphs.paint,
                       x, y, bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
 }
@@ -322,7 +320,7 @@
     glyphs.paint.measureText(glyphs.glyphIDs, glyphs.count << 1, &bounds);
     bounds.offset(x, y);
 
-    SK_COMPILE_ASSERT(sizeof(SkPoint) == sizeof(float)*2, SkPoint_is_no_longer_2_floats);
+    static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
     mCanvas->drawText(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y,
                       bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
 }
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index fd077d9..ca19a42 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -58,7 +58,7 @@
         , mViewportData(s->mViewportData)
         , mRelativeLightCenter(s->mRelativeLightCenter) {
     if (saveFlags & SkCanvas::kMatrix_SaveFlag) {
-        mTransformRoot.load(*s->transform);
+        mTransformRoot = *s->transform;
         transform = &mTransformRoot;
     } else {
         transform = s->transform;
@@ -190,8 +190,7 @@
     state->highPriority = highPriority;
 
     // store the inverse drawing matrix
-    Matrix4 roundRectDrawingMatrix;
-    roundRectDrawingMatrix.load(getOrthoMatrix());
+    Matrix4 roundRectDrawingMatrix = getOrthoMatrix();
     roundRectDrawingMatrix.multiply(*transform);
     state->matrix.loadInverse(roundRectDrawingMatrix);
 
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index eaf0303..9b0a1aa 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -46,17 +46,18 @@
 #define TRANSFORMED_PENUMBRA_ALPHA 1.0f
 #define TRANSFORMED_UMBRA_ALPHA 0.0f
 
+#include "SpotShadow.h"
+
+#include "ShadowTessellator.h"
+#include "Vertex.h"
+#include "VertexBuffer.h"
+#include "utils/MathUtils.h"
+
 #include <algorithm>
 #include <math.h>
 #include <stdlib.h>
 #include <utils/Log.h>
 
-#include "ShadowTessellator.h"
-#include "SpotShadow.h"
-#include "Vertex.h"
-#include "VertexBuffer.h"
-#include "utils/MathUtils.h"
-
 // TODO: After we settle down the new algorithm, we can remove the old one and
 // its utility functions.
 // Right now, we still need to keep it for comparison purpose and future expansion.
@@ -543,7 +544,7 @@
         }
 
         float ratioVI = outlineData[i].radius / distOutline;
-        minRaitoVI = MathUtils::min(minRaitoVI, ratioVI);
+        minRaitoVI = std::min(minRaitoVI, ratioVI);
         if (ratioVI >= (1 - FAKE_UMBRA_SIZE_RATIO)) {
             ratioVI = (1 - FAKE_UMBRA_SIZE_RATIO);
         }
diff --git a/libs/hwui/VertexBuffer.h b/libs/hwui/VertexBuffer.h
index 9be4d84..c0373ac 100644
--- a/libs/hwui/VertexBuffer.h
+++ b/libs/hwui/VertexBuffer.h
@@ -17,7 +17,7 @@
 #ifndef ANDROID_HWUI_VERTEX_BUFFER_H
 #define ANDROID_HWUI_VERTEX_BUFFER_H
 
-#include "utils/MathUtils.h"
+#include <algorithm>
 
 namespace android {
 namespace uirenderer {
@@ -129,10 +129,10 @@
     unsigned int getSize() const { return mByteCount; }
     unsigned int getIndexCount() const { return mIndexCount; }
     void updateIndexCount(unsigned int newCount)  {
-        mIndexCount = MathUtils::min(newCount, mAllocatedIndexCount);
+        mIndexCount = std::min(newCount, mAllocatedIndexCount);
     }
     void updateVertexCount(unsigned int newCount)  {
-        mVertexCount = MathUtils::min(newCount, mAllocatedVertexCount);
+        mVertexCount = std::min(newCount, mAllocatedVertexCount);
     }
     MeshFeatureFlags getMeshFeatureFlags() const { return mMeshFeatureFlags; }
     void setMeshFeatureFlags(int flags) {
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index 1e39bfa..b5ed9e6 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -19,6 +19,8 @@
 #include "renderthread/EglManager.h"
 #include "utils/GLUtils.h"
 
+#include <algorithm>
+
 namespace android {
 namespace uirenderer {
 
@@ -320,7 +322,7 @@
         GLsizei elementsCount = mesh.elementCount;
         const GLbyte* vertexData = static_cast<const GLbyte*>(vertices.position);
         while (elementsCount > 0) {
-            GLsizei drawCount = MathUtils::min(elementsCount, (GLsizei) kMaxNumberOfQuads * 6);
+            GLsizei drawCount = std::min(elementsCount, (GLsizei) kMaxNumberOfQuads * 6);
 
             // rebind pointers without forcing, since initial bind handled above
             meshState().bindPositionVertexPointer(false, vertexData, vertices.stride);
diff --git a/libs/hwui/utils/MathUtils.h b/libs/hwui/utils/MathUtils.h
index 9c3787c..8d20f21 100644
--- a/libs/hwui/utils/MathUtils.h
+++ b/libs/hwui/utils/MathUtils.h
@@ -16,6 +16,7 @@
 #ifndef MATHUTILS_H
 #define MATHUTILS_H
 
+#include <algorithm>
 #include <math.h>
 
 namespace android {
@@ -82,18 +83,8 @@
     }
 
     template<typename T>
-    static inline T max(T a, T b) {
-        return a > b ? a : b;
-    }
-
-    template<typename T>
-    static inline T min(T a, T b) {
-        return a < b ? a : b;
-    }
-
-    template<typename T>
     static inline T clamp(T a, T minValue, T maxValue) {
-        return min(max(a, minValue), maxValue);
+        return std::min(std::max(a, minValue), maxValue);
     }
 
     inline static float lerp(float v1, float v2, float t) {
diff --git a/media/java/android/mtp/MtpObjectInfo.java b/media/java/android/mtp/MtpObjectInfo.java
index d2824b5..f79d52e 100644
--- a/media/java/android/mtp/MtpObjectInfo.java
+++ b/media/java/android/mtp/MtpObjectInfo.java
@@ -256,7 +256,7 @@
     /**
      * Builds a new object info instance.
      */
-    public class Builder {
+    public static class Builder {
         private MtpObjectInfo mObjectInfo;
 
         public Builder() {
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index ad804f3..9dd3861 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -430,12 +430,14 @@
 android_mtp_MtpDevice_send_object_info(JNIEnv *env, jobject thiz, jobject info)
 {
     MtpDevice* device = get_device_from_object(env, thiz);
-    if (!device)
+    if (!device) {
         return JNI_FALSE;
+    }
 
     // Updating existing objects is not supported.
-    if (env->GetIntField(info, field_objectInfo_handle) != -1)
+    if (env->GetIntField(info, field_objectInfo_handle) != -1) {
         return JNI_FALSE;
+    }
 
     MtpObjectInfo* object_info = new MtpObjectInfo(-1);
     object_info->mStorageID = env->GetIntField(info, field_objectInfo_storageId);
@@ -456,17 +458,21 @@
     object_info->mSequenceNumber = env->GetIntField(info, field_objectInfo_sequenceNumber);
 
     jstring name_jstring = (jstring) env->GetObjectField(info, field_objectInfo_name);
-    const char* name_string = env->GetStringUTFChars(name_jstring, NULL);
-    object_info->mName = strdup(name_string);
-    env->ReleaseStringUTFChars(name_jstring, name_string);
+    if (name_jstring != NULL) {
+        const char* name_string = env->GetStringUTFChars(name_jstring, NULL);
+        object_info->mName = strdup(name_string);
+        env->ReleaseStringUTFChars(name_jstring, name_string);
+    }
 
     object_info->mDateCreated = env->GetLongField(info, field_objectInfo_dateCreated) / 1000LL;
     object_info->mDateModified = env->GetLongField(info, field_objectInfo_dateModified) / 1000LL;
 
     jstring keywords_jstring = (jstring) env->GetObjectField(info, field_objectInfo_keywords);
-    const char* keywords_string = env->GetStringUTFChars(keywords_jstring, NULL);
-    object_info->mKeywords = strdup(keywords_string);
-    env->ReleaseStringUTFChars(keywords_jstring, keywords_string);
+    if (keywords_jstring != NULL) {
+        const char* keywords_string = env->GetStringUTFChars(keywords_jstring, NULL);
+        object_info->mKeywords = strdup(keywords_string);
+        env->ReleaseStringUTFChars(keywords_jstring, keywords_string);
+    }
 
     int object_handle = device->sendObjectInfo(object_info);
     if (object_handle == -1) {
diff --git a/packages/DocumentsUI/res/layout/item_doc_grid.xml b/packages/DocumentsUI/res/layout/item_doc_grid.xml
index 1001e10..71e618b 100644
--- a/packages/DocumentsUI/res/layout/item_doc_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_doc_grid.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.documentsui.GridItem xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="@dimen/grid_item_height"
     android:layout_margin="@dimen/grid_item_margin"
@@ -140,4 +140,4 @@
         android:contentDescription="@null"
         android:duplicateParentState="true" />
 
-</FrameLayout>
+</com.android.documentsui.GridItem>
diff --git a/packages/DocumentsUI/res/layout/item_loading_grid.xml b/packages/DocumentsUI/res/layout/item_loading_grid.xml
index 005a111..147dfd4 100644
--- a/packages/DocumentsUI/res/layout/item_loading_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_loading_grid.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.documentsui.GridItem xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="@dimen/grid_height"
     android:orientation="horizontal">
@@ -26,4 +26,4 @@
         android:indeterminate="true"
         style="?android:attr/progressBarStyle" />
 
-</FrameLayout>
+</com.android.documentsui.GridItem>
diff --git a/packages/DocumentsUI/res/layout/item_message_grid.xml b/packages/DocumentsUI/res/layout/item_message_grid.xml
index 385563d..45d61a5 100644
--- a/packages/DocumentsUI/res/layout/item_message_grid.xml
+++ b/packages/DocumentsUI/res/layout/item_message_grid.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.documentsui.GridItem xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="@dimen/grid_height"
     android:paddingStart="?android:attr/listPreferredItemPaddingStart"
@@ -48,4 +48,4 @@
 
     </LinearLayout>
 
-</FrameLayout>
+</com.android.documentsui.GridItem>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BandSelectMatrix.java b/packages/DocumentsUI/src/com/android/documentsui/BandSelectMatrix.java
new file mode 100644
index 0000000..f259059
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/BandSelectMatrix.java
@@ -0,0 +1,645 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.base.Preconditions;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.support.v7.widget.RecyclerView.LayoutManager;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import android.util.SparseBooleanArray;
+import android.view.View;
+
+/**
+ * Provides a band selection item model for views within a RecyclerView. This class queries the
+ * RecyclerView to determine where its items are placed; then, once band selection is underway, it
+ * alerts listeners of which items are covered by the selections.
+ */
+public final class BandSelectMatrix extends RecyclerView.OnScrollListener {
+
+    private final RecyclerViewHelper mHelper;
+    private final List<OnSelectionChangedListener> mOnSelectionChangedListeners = new ArrayList<>();
+
+    // Map from the x-value of the left side of an item to an ordered list of metadata of all items
+    // whose x-values are the same. The list is ordered by the y-values of the items in the column.
+    // For example, if the first column of the view starts at an x-value of 5, mColumns.get(5) would
+    // return a list of all items in that column, with the top-most item first in the list and the
+    // bottom-most item last in the list.
+    private final Map<Integer, List<ItemData>> mColumns = new HashMap<>();
+
+    // List of limits along the x-axis. For example, if the view has two columns, this list will
+    // have two elements, each of which lists the lower- and upper-limits of the x-values of the
+    // view items. This list is sorted from furthest left to furthest right.
+    private final List<Limits> mXLimitsList = new ArrayList<>();
+
+    // Like mXLimitsList, but for y-coordinates. Note that this list only contains items which have
+    // been in the viewport. Thus, limits which exist in an area of the view to which the view has
+    // not scrolled are not present in the list.
+    private final List<Limits> mYLimitsList = new ArrayList<>();
+
+    // The adapter positions which have been recorded so far.
+    private final SparseBooleanArray mRecordedPositions = new SparseBooleanArray();
+
+    // Array passed to registered OnSelectionChangedListeners. One array is created and reused
+    // throughout the lifetime of the object.
+    private final SparseBooleanArray mSelectionForListeners = new SparseBooleanArray();
+
+    // The current pointer (in absolute positioning from the top of the view).
+    private Point mPointer = null;
+
+    // The bounds of the band selection.
+    private RelativePoint mRelativeOrigin;
+    private RelativePoint mRelativePointer;
+
+    BandSelectMatrix(RecyclerViewHelper helper) {
+        mHelper = helper;
+        mHelper.addOnScrollListener(this);
+    }
+
+    BandSelectMatrix(RecyclerView rv) {
+        this(new RuntimeRecyclerViewHelper(rv));
+    }
+
+    /**
+     * Stops listening to the view's scrolls. Call this function before discarding a
+     * BandSelecMatrix object to prevent memory leaks.
+     */
+    void stopListening() {
+        mHelper.removeOnScrollListener(this);
+    }
+
+    /**
+     * Start a band select operation at the given point.
+     * @param relativeOrigin The origin of the band select operation, relative to the viewport.
+     *     For example, if the view is scrolled to the bottom, the top-left of the viewport would
+     *     have a relative origin of (0, 0), even though its absolute point has a higher y-value.
+     */
+    void startSelection(Point relativeOrigin) {
+        Point absoluteOrigin = mHelper.createAbsolutePoint(relativeOrigin);
+        mPointer = new Point(absoluteOrigin.x, absoluteOrigin.y);
+
+        processVisibleChildren();
+        mRelativeOrigin = new RelativePoint(absoluteOrigin);
+        mRelativePointer = new RelativePoint(mPointer);
+        computeCurrentSelection();
+        notifyListeners();
+    }
+
+    /**
+     * Resizes the selection by adjusting the pointer (i.e., the corner of the selection opposite
+     * the origin.
+     * @param relativePointer The pointer (opposite of the origin) of the band select operation,
+     *     relative to the viewport. For example, if the view is scrolled to the bottom, the
+     *     top-left of the viewport would have a relative origin of (0, 0), even though its absolute
+     *     point has a higher y-value.
+     */
+    void resizeSelection(Point relativePointer) {
+        mPointer = mHelper.createAbsolutePoint(relativePointer);
+        handlePointerMoved();
+    }
+
+    @Override
+    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+        if (mPointer == null) {
+            return;
+        }
+
+        mPointer.x += dx;
+        mPointer.y += dy;
+        processVisibleChildren();
+        handlePointerMoved();
+    }
+
+    /**
+     * Queries the view for all children and records their location metadata.
+     */
+    private void processVisibleChildren() {
+        for (int i = 0; i < mHelper.getVisibleChildCount(); i++) {
+            int adapterPosition = mHelper.getAdapterPositionAt(i);
+            if (!mRecordedPositions.get(adapterPosition)) {
+                mRecordedPositions.put(adapterPosition, true);
+                captureItemLayoutData(mHelper.getAbsoluteRectForChildViewAt(i), adapterPosition);
+            }
+        }
+    }
+
+    /**
+     * Updates the limits lists and column map with the given item metadata.
+     * @param absoluteChildRect The absolute rectangle for the child view being processed.
+     * @param adapterPosition The position of the child view being processed.
+     */
+    private void captureItemLayoutData(Rect absoluteChildRect, int adapterPosition) {
+        if (mXLimitsList.size() != mHelper.getNumColumns()) {
+            // If not all x-limits have been recorded, record this one.
+            recordLimits(
+                    mXLimitsList, new Limits(absoluteChildRect.left, absoluteChildRect.right));
+        }
+
+        if (mYLimitsList.size() != mHelper.getNumRows()) {
+            // If not all y-limits have been recorded, record this one.
+            recordLimits(
+                    mYLimitsList, new Limits(absoluteChildRect.top, absoluteChildRect.bottom));
+        }
+
+        List<ItemData> columnList = mColumns.get(absoluteChildRect.left);
+        if (columnList == null) {
+            columnList = new ArrayList<ItemData>();
+            mColumns.put(absoluteChildRect.left, columnList);
+        }
+        recordItemData(
+                columnList, new ItemData(adapterPosition, absoluteChildRect.top));
+    }
+
+    /**
+     * Ensures limits exists within the sorted list limitsList, and adds it to the list if it does
+     * not exist.
+     */
+    private static void recordLimits(List<Limits> limitsList, Limits limits) {
+        int index = Collections.binarySearch(limitsList, limits);
+        if (index < 0) {
+            limitsList.add(~index, limits);
+        }
+    }
+
+    /**
+     * Ensures itemData exists within the sorted list itemDataList, and adds it to the list if it
+     * does not exist.
+     */
+    private static void recordItemData(List<ItemData> itemDataList, ItemData itemData) {
+        int index = Collections.binarySearch(itemDataList, itemData);
+        if (index < 0) {
+            itemDataList.add(~index, itemData);
+        }
+    }
+
+    /**
+     * Handles a moved pointer; this function determines whether the pointer movement resulted in a
+     * selection change and, if it has, notifies listeners of this change.
+     */
+    private void handlePointerMoved() {
+        RelativePoint old = mRelativePointer;
+        mRelativePointer = new RelativePoint(mPointer);
+        if (old != null && mRelativePointer.equals(old)) {
+            return;
+        }
+
+        computeCurrentSelection();
+        notifyListeners();
+    }
+
+    /**
+     * Computes the currently-selected items.
+     */
+    private void computeCurrentSelection() {
+        Rect selectionRect = mRelativePointer.computeBounds(mRelativeOrigin);
+        computePositionsCoveredByRect(selectionRect);
+    }
+
+    /**
+     * Notifies all listeners of a selection change. Note that this function simply passes
+     * mSelectionForListeners, so computeCurrentSelection() should be called before this function.
+     */
+    private void notifyListeners() {
+        for (OnSelectionChangedListener listener : mOnSelectionChangedListeners) {
+            listener.onSelectionChanged(mSelectionForListeners);
+        }
+    }
+
+    /**
+     * @param rect Rectangle including all covered items.
+     */
+    private void computePositionsCoveredByRect(@Nullable Rect rect) {
+        mSelectionForListeners.clear();
+        if (rect == null) {
+            // If there is no bounding rectangle, there are no items selected, so just return early.
+            return;
+        }
+
+        int columnIndex = Collections.binarySearch(mXLimitsList, new Limits(rect.left, rect.left));
+        Preconditions.checkState(columnIndex >= 0);
+
+        for (; columnIndex < mXLimitsList.size() &&
+                mXLimitsList.get(columnIndex).lowerLimit <= rect.right; columnIndex++) {
+            List<ItemData> positions =
+                    mColumns.get(mXLimitsList.get(columnIndex).lowerLimit);
+            int rowIndex = Collections.binarySearch(positions, new ItemData(0, rect.top));
+            if (rowIndex < 0) {
+                // If band select occurs after the last item in a row with fewer items than columns,
+                // go to the next column. This situation occurs in the last row of the grid when the
+                // total number of items is not a multiple of the number of columns (e.g., when 10
+                // items exist in a grid with 4 columns).
+                continue;
+            }
+
+            for (; rowIndex < positions.size() &&
+                    positions.get(rowIndex).offset <= rect.bottom; rowIndex++) {
+                mSelectionForListeners.append(positions.get(rowIndex).position, true);
+            }
+        }
+    }
+
+    /**
+     * Provides functionality for interfacing with the view. In practice, RecyclerViewMatrixHelper
+     * should be used; this interface exists solely for the purpose of decoupling the view from
+     * this class so that the view can be mocked out for tests.
+     */
+    interface RecyclerViewHelper {
+        public void addOnScrollListener(RecyclerView.OnScrollListener listener);
+        public void removeOnScrollListener(RecyclerView.OnScrollListener listener);
+        public Point createAbsolutePoint(Point relativePoint);
+        public int getVisibleChildCount();
+        public int getTotalChildCount();
+        public int getNumColumns();
+        public int getNumRows();
+        public int getAdapterPositionAt(int index);
+        public Rect getAbsoluteRectForChildViewAt(int index);
+    }
+
+    /**
+     * Concrete MatrixHelper implementation for use within the Files app.
+     */
+    static class RuntimeRecyclerViewHelper implements RecyclerViewHelper {
+        private final RecyclerView mRecyclerView;
+
+        RuntimeRecyclerViewHelper(RecyclerView rv) {
+            mRecyclerView = rv;
+        }
+
+        @Override
+        public int getAdapterPositionAt(int index) {
+            View child = mRecyclerView.getChildAt(index);
+            return mRecyclerView.getChildViewHolder(child).getAdapterPosition();
+        }
+
+        @Override
+        public void addOnScrollListener(OnScrollListener listener) {
+            mRecyclerView.addOnScrollListener(listener);
+        }
+
+        @Override
+        public void removeOnScrollListener(OnScrollListener listener) {
+            mRecyclerView.removeOnScrollListener(listener);
+        }
+
+        @Override
+        public Point createAbsolutePoint(Point relativePoint) {
+            return new Point(relativePoint.x + mRecyclerView.computeHorizontalScrollOffset(),
+                    relativePoint.y + mRecyclerView.computeVerticalScrollOffset());
+        }
+
+        @Override
+        public Rect getAbsoluteRectForChildViewAt(int index) {
+            final View child = mRecyclerView.getChildAt(index);
+            final Rect childRect = new Rect();
+            child.getHitRect(childRect);
+            childRect.left += mRecyclerView.computeHorizontalScrollOffset();
+            childRect.right += mRecyclerView.computeHorizontalScrollOffset();
+            childRect.top += mRecyclerView.computeVerticalScrollOffset();
+            childRect.bottom += mRecyclerView.computeVerticalScrollOffset();
+            return childRect;
+        }
+
+        @Override
+        public int getVisibleChildCount() {
+            return mRecyclerView.getChildCount();
+        }
+
+        @Override
+        public int getTotalChildCount() {
+            return mRecyclerView.getAdapter().getItemCount();
+        }
+
+        @Override
+        public int getNumColumns() {
+            LayoutManager layoutManager = mRecyclerView.getLayoutManager();
+            if (layoutManager instanceof GridLayoutManager) {
+                return ((GridLayoutManager) layoutManager).getSpanCount();
+            }
+
+            // Otherwise, it is a list with 1 column.
+            return 1;
+        }
+
+        @Override
+        public int getNumRows() {
+            int numFullColumns = getTotalChildCount() / getNumColumns();
+            boolean hasPartiallyFullColumn = getTotalChildCount() % getNumColumns() != 0;
+            return numFullColumns + (hasPartiallyFullColumn ? 1 : 0);
+        }
+    }
+
+    /**
+     * Listener for changes in which items have been band selected.
+     */
+    interface OnSelectionChangedListener {
+        public void onSelectionChanged(SparseBooleanArray updatedSelection);
+    }
+
+    void addOnSelectionChangedListener(OnSelectionChangedListener listener) {
+        mOnSelectionChangedListeners.add(listener);
+    }
+
+    void removeOnSelectionChangedListener(OnSelectionChangedListener listener) {
+        mOnSelectionChangedListeners.remove(listener);
+    }
+
+    /**
+     * Metadata for an item in the view, consisting of the adapter position and the offset from the
+     * top of the view (in pixels). Stored in the mColumns map to model the item grid.
+     */
+    private static class ItemData implements Comparable<ItemData> {
+        int position;
+        int offset;
+
+        ItemData(int position, int offset) {
+            this.position = position;
+            this.offset = offset;
+        }
+
+        @Override
+        public int compareTo(ItemData other) {
+            // The list of columns is sorted via the offset from the top, so PositionMetadata
+            // objects with lower y-values are befor those with higher y-values.
+            return offset - other.offset;
+        }
+    }
+
+    /**
+     * Limits of a view item. For example, if an item's left side is at x-value 5 and its right side
+     * is at x-value 10, the limits would be from 5 to 10. Used to record the left- and right sides
+     * of item columns and the top- and bottom sides of item rows so that it can be determined
+     * whether the pointer is located within the bounds of an item.
+     */
+    private static class Limits implements Comparable<Limits> {
+        int lowerLimit;
+        int upperLimit;
+
+        Limits(int lowerLimit, int upperLimit) {
+            this.lowerLimit = lowerLimit;
+            this.upperLimit = upperLimit;
+        }
+
+        @Override
+        public int compareTo(Limits other) {
+            return lowerLimit - other.lowerLimit;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof Limits)) {
+                return false;
+            }
+
+            return ((Limits) other).lowerLimit == lowerLimit &&
+                    ((Limits) other).upperLimit == upperLimit;
+        }
+    }
+
+    /**
+     * The location of a coordinate relative to items. This class represents a general area of the
+     * view as it relates to band selection rather than an explicit point. For example, two
+     * different points within an item are considered to have the same "location" because band
+     * selection originating within the item would select the same items no matter which point
+     * was used. Same goes for points between items as well as those at the very beginning or end
+     * of the view.
+     *
+     * Tracking a coordinate (e.g., an x-value) as a CoordinateLocation instead of as an int has the
+     * advantage of tying the value to the Limits of items along that axis. This allows easy
+     * selection of items within those Limits as opposed to a search through every item to see if a
+     * given coordinate value falls within those Limits.
+     */
+    private static class RelativeCoordinate
+            implements Comparable<RelativeCoordinate> {
+        /**
+         * Location describing points after the last known item.
+         */
+        static final int AFTER_LAST_ITEM = 0;
+
+        /**
+         * Location describing points before the first known item.
+         */
+        static final int BEFORE_FIRST_ITEM = 1;
+
+        /**
+         * Location describing points between two items.
+         */
+        static final int BETWEEN_TWO_ITEMS = 2;
+
+        /**
+         * Location describing points within the limits of one item.
+         */
+        static final int WITHIN_LIMITS = 3;
+
+        /**
+         * The type of this coordinate, which is one of AFTER_LAST_ITEM, BEFORE_FIRST_ITEM,
+         * BETWEEN_TWO_ITEMS, or WITHIN_LIMITS.
+         */
+        final int type;
+
+        /**
+         * The limits before the coordinate; only populated when type == WITHIN_LIMITS or type ==
+         * BETWEEN_TWO_ITEMS.
+         */
+        Limits limitsBeforeCoordinate;
+
+        /**
+         * The limits after the coordinate; only populated when type == BETWEEN_TWO_ITEMS.
+         */
+        Limits limitsAfterCoordinate;
+
+        // Limits of the first known item; only populated when type == BEFORE_FIRST_ITEM.
+        Limits mFirstKnownItem;
+        // Limits of the last known item; only populated when type == AFTER_LAST_ITEM.
+        Limits mLastKnownItem;
+
+        /**
+         * @param limitsList The sorted limits list for the coordinate type. If this
+         *     CoordinateLocation is an x-value, mXLimitsList should be passed; otherwise,
+         *     mYLimitsList should be pased.
+         * @param value The coordinate value.
+         */
+        RelativeCoordinate(List<Limits> limitsList, int value) {
+            Limits dummyLimits = new Limits(value, value);
+            int index = Collections.binarySearch(limitsList, dummyLimits);
+
+            if (index >= 0) {
+                this.type = WITHIN_LIMITS;
+                this.limitsBeforeCoordinate = limitsList.get(index);
+            } else if (~index == 0) {
+                this.type = BEFORE_FIRST_ITEM;
+                this.mFirstKnownItem = limitsList.get(0);
+            } else if (~index == limitsList.size()) {
+                Limits lastLimits = limitsList.get(limitsList.size() - 1);
+                if (lastLimits.lowerLimit <= value && value <= lastLimits.upperLimit) {
+                    this.type = WITHIN_LIMITS;
+                    this.limitsBeforeCoordinate = lastLimits;
+                } else {
+                    this.type = AFTER_LAST_ITEM;
+                    this.mLastKnownItem = lastLimits;
+                }
+            } else {
+                Limits limitsBeforeIndex = limitsList.get(~index - 1);
+                if (limitsBeforeIndex.lowerLimit <= value && value <= limitsBeforeIndex.upperLimit) {
+                    this.type = WITHIN_LIMITS;
+                    this.limitsBeforeCoordinate = limitsList.get(~index - 1);
+                } else {
+                    this.type = BETWEEN_TWO_ITEMS;
+                    this.limitsBeforeCoordinate = limitsList.get(~index - 1);
+                    this.limitsAfterCoordinate = limitsList.get(~index);
+                }
+            }
+        }
+
+        int toComparisonValue() {
+            if (type == BEFORE_FIRST_ITEM) {
+                return mFirstKnownItem.lowerLimit - 1;
+            } else if (type == AFTER_LAST_ITEM) {
+                return mLastKnownItem.upperLimit + 1;
+            } else if (type == BETWEEN_TWO_ITEMS) {
+                return limitsBeforeCoordinate.upperLimit + 1;
+            } else {
+                return limitsBeforeCoordinate.lowerLimit;
+            }
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof RelativeCoordinate)) {
+                return false;
+            }
+
+            RelativeCoordinate otherCoordinate = (RelativeCoordinate) other;
+            return toComparisonValue() == otherCoordinate.toComparisonValue();
+        }
+
+        @Override
+        public int compareTo(RelativeCoordinate other) {
+            return toComparisonValue() - other.toComparisonValue();
+        }
+    }
+
+    /**
+     * The location of a point relative to the Limits of nearby items; consists of both an x- and
+     * y-RelativeCoordinateLocation.
+     */
+    private class RelativePoint {
+        final RelativeCoordinate xLocation;
+        final RelativeCoordinate yLocation;
+
+        RelativePoint(Point point) {
+            this.xLocation = new RelativeCoordinate(mXLimitsList, point.x);
+            this.yLocation = new RelativeCoordinate(mYLimitsList, point.y);
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (!(other instanceof RelativePoint)) {
+                return false;
+            }
+
+            RelativePoint otherPoint = (RelativePoint) other;
+            return xLocation.equals(otherPoint.xLocation) && yLocation.equals(otherPoint.yLocation);
+        }
+
+        /**
+         * Generates a rectangle which contains the items selected by the two points.
+         * @param other The other PointLocation. A rectangle will be formed between "this" and
+         *     "other".
+         * @return The rectangle, or null if no items were selected.
+         */
+        Rect computeBounds(RelativePoint other) {
+            if (!areItemsCoveredBySelection(mRelativePointer, mRelativeOrigin)) {
+                return null;
+            }
+
+            RelativeCoordinate minXLocation =
+                    xLocation.compareTo(other.xLocation) < 0 ? xLocation : other.xLocation;
+            RelativeCoordinate maxXLocation =
+                    minXLocation == xLocation ? other.xLocation : xLocation;
+            RelativeCoordinate minYLocation =
+                    yLocation.compareTo(other.yLocation) < 0 ? yLocation : other.yLocation;
+            RelativeCoordinate maxYLocation =
+                    minYLocation == yLocation ? other.yLocation : yLocation;
+
+            Rect rect = new Rect();
+            rect.left = getCoordinateValue(minXLocation, mXLimitsList, true);
+            rect.right = getCoordinateValue(maxXLocation, mXLimitsList, false);
+            rect.top = getCoordinateValue(minYLocation, mYLimitsList, true);
+            rect.bottom = getCoordinateValue(maxYLocation, mYLimitsList, false);
+            return rect;
+        }
+
+        int getCoordinateValue(RelativeCoordinate coordinate,
+                List<Limits> limitsList, boolean isStartOfRange) {
+            switch (coordinate.type) {
+                case RelativeCoordinate.BEFORE_FIRST_ITEM:
+                    return limitsList.get(0).lowerLimit;
+                case RelativeCoordinate.AFTER_LAST_ITEM:
+                    return limitsList.get(limitsList.size() - 1).upperLimit;
+                case RelativeCoordinate.BETWEEN_TWO_ITEMS:
+                    if (isStartOfRange) {
+                        return coordinate.limitsAfterCoordinate.lowerLimit;
+                    } else {
+                        return coordinate.limitsBeforeCoordinate.upperLimit;
+                    }
+                case RelativeCoordinate.WITHIN_LIMITS:
+                    return coordinate.limitsBeforeCoordinate.lowerLimit;
+            }
+
+            throw new RuntimeException("Invalid coordinate value.");
+        }
+    }
+
+    private static boolean areItemsCoveredBySelection(
+            RelativePoint first, RelativePoint second) {
+        return doesCoordinateLocationCoverItems(first.xLocation, second.xLocation) &&
+                doesCoordinateLocationCoverItems(first.yLocation, second.yLocation);
+    }
+
+    private static boolean doesCoordinateLocationCoverItems(
+            RelativeCoordinate pointerCoordinate,
+            RelativeCoordinate originCoordinate) {
+        if (pointerCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM &&
+                originCoordinate.type == RelativeCoordinate.BEFORE_FIRST_ITEM) {
+            return false;
+        }
+
+        if (pointerCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM &&
+                originCoordinate.type == RelativeCoordinate.AFTER_LAST_ITEM) {
+            return false;
+        }
+
+        if (pointerCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
+                originCoordinate.type == RelativeCoordinate.BETWEEN_TWO_ITEMS &&
+                pointerCoordinate.limitsBeforeCoordinate.equals(originCoordinate) &&
+                pointerCoordinate.limitsAfterCoordinate.equals(originCoordinate)) {
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 9b8d847..a804e9a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -22,7 +22,6 @@
 import static com.android.documentsui.DirectoryFragment.ANIM_UP;
 import static com.android.internal.util.Preconditions.checkArgument;
 
-import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.Fragment;
 import android.content.Intent;
@@ -38,6 +37,7 @@
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Root;
+import android.support.annotation.Nullable;
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
@@ -60,8 +60,6 @@
 import com.android.documentsui.model.DurableUtils;
 import com.android.documentsui.model.RootInfo;
 
-import com.google.common.collect.Maps;
-
 import libcore.io.IoUtils;
 
 import java.io.FileNotFoundException;
@@ -371,7 +369,7 @@
         public String currentSearch;
 
         /** Instance state for every shown directory */
-        public HashMap<String, SparseArray<Parcelable>> dirState = Maps.newHashMap();
+        public HashMap<String, SparseArray<Parcelable>> dirState = new HashMap<>();
 
         /** Currently copying file */
         public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<DocumentInfo>();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
index f927595..e408e6e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/CreateDirectoryFragment.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
 
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -36,7 +36,6 @@
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.inputmethod.EditorInfo;
 import android.widget.EditText;
 import android.widget.TextView;
 import android.widget.TextView.OnEditorActionListener;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
index 5223d76..704e607 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java
@@ -24,14 +24,13 @@
 import static com.android.documentsui.BaseActivity.State.MODE_LIST;
 import static com.android.documentsui.BaseActivity.State.MODE_UNKNOWN;
 import static com.android.documentsui.BaseActivity.State.SORT_ORDER_UNKNOWN;
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
 import static com.android.documentsui.model.DocumentInfo.getCursorInt;
 import static com.android.documentsui.model.DocumentInfo.getCursorLong;
 import static com.android.documentsui.model.DocumentInfo.getCursorString;
 import static com.android.internal.util.Preconditions.checkNotNull;
 import static com.android.internal.util.Preconditions.checkState;
 
-import android.annotation.NonNull;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.Fragment;
@@ -98,7 +97,7 @@
 import com.android.documentsui.model.RootInfo;
 import com.android.internal.util.Preconditions;
 
-import com.google.android.collect.Lists;
+import com.google.common.collect.Lists;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -235,8 +234,7 @@
                     public void onLayoutChange(
                             View v, int left, int top, int right, int bottom, int oldLeft,
                             int oldTop, int oldRight, int oldBottom) {
-                        int thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width);
-                        mColumnCount = pickColumnCount(thumbSize);
+                        mColumnCount = calculateColumnCount();
                         if (mGridLayout != null) {
                             mGridLayout.setSpanCount(mColumnCount);
                         }
@@ -535,8 +533,6 @@
 
         updateLayout(state.derivedMode);
 
-        final int thumbSize = getResources().getDimensionPixelSize(R.dimen.icon_size);
-        mThumbSize = new Point(thumbSize, thumbSize);
         mRecView.setAdapter(mAdapter);
     }
 
@@ -573,13 +569,15 @@
         mThumbSize = new Point(thumbSize, thumbSize);
     }
 
-    private int pickColumnCount(final int thumbSize) {
-        int itemPadding =
-                getResources().getDimensionPixelSize(R.dimen.grid_item_margin);
+    private int calculateColumnCount() {
+        int cellWidth = getResources().getDimensionPixelSize(R.dimen.grid_width);
+        int cellMargin = 2 * getResources().getDimensionPixelSize(R.dimen.grid_item_margin);
         int viewPadding = mRecView.getPaddingLeft() + mRecView.getPaddingRight();
+
         checkState(mRecView.getWidth() > 0);
         int columnCount = Math.max(1,
-                (mRecView.getWidth() - viewPadding) / (thumbSize + itemPadding));
+                (mRecView.getWidth() - viewPadding) / (cellWidth + cellMargin));
+
         return columnCount;
     }
 
@@ -753,7 +751,7 @@
                 Intent intent;
 
                 // Filter out directories - those can't be shared.
-                List<DocumentInfo> docsForSend = Lists.newArrayList();
+                List<DocumentInfo> docsForSend = new ArrayList<>();
                 for (DocumentInfo doc: docs) {
                     if (!Document.MIME_TYPE_DIR.equals(doc.mimeType)) {
                         docsForSend.add(doc);
@@ -774,8 +772,8 @@
                     intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                     intent.addCategory(Intent.CATEGORY_DEFAULT);
 
-                    final ArrayList<String> mimeTypes = Lists.newArrayList();
-                    final ArrayList<Uri> uris = Lists.newArrayList();
+                    final ArrayList<String> mimeTypes = new ArrayList<>();
+                    final ArrayList<Uri> uris = new ArrayList<>();
                     for (DocumentInfo doc : docsForSend) {
                         mimeTypes.add(doc.mimeType);
                         uris.add(doc.derivedUri);
@@ -956,7 +954,7 @@
         private final Context mContext;
         private final LayoutInflater mInflater;
         // TODO: Bring back support for footers.
-        private final List<Footer> mFooters = Lists.newArrayList();
+        private final List<Footer> mFooters = new ArrayList<>();
 
         private Cursor mCursor;
         private int mCursorCount;
@@ -1330,7 +1328,7 @@
         return MimePredicate.mimeMatches(state.acceptMimes, docMimeType);
     }
 
-    private @NonNull List<DocumentInfo> getSelectedDocuments() {
+    private List<DocumentInfo> getSelectedDocuments() {
         Selection sel = mSelectionManager.getSelection(new Selection());
         return getItemsAsDocuments(sel);
     }
@@ -1570,6 +1568,7 @@
         final Cursor cursor = mAdapter.getItem(position);
         checkNotNull(cursor, "Cursor cannot be null.");
         final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor);
+
         return Lists.newArrayList(doc);
     }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
index a8a61d2..0edb241 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java
@@ -16,12 +16,12 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.DocumentsActivity.TAG;
 import static com.android.documentsui.BaseActivity.State.MODE_UNKNOWN;
 import static com.android.documentsui.BaseActivity.State.SORT_ORDER_DISPLAY_NAME;
 import static com.android.documentsui.BaseActivity.State.SORT_ORDER_LAST_MODIFIED;
 import static com.android.documentsui.BaseActivity.State.SORT_ORDER_SIZE;
 import static com.android.documentsui.BaseActivity.State.SORT_ORDER_UNKNOWN;
+import static com.android.documentsui.Shared.TAG;
 import static com.android.documentsui.model.DocumentInfo.getCursorInt;
 
 import android.content.AsyncTaskLoader;
@@ -31,8 +31,6 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.CancellationSignal;
-import android.os.Handler;
-import android.os.Looper;
 import android.os.OperationCanceledException;
 import android.os.RemoteException;
 import android.provider.DocumentsContract;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java
index 2370575..6ba07fbb 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentClipper.java
@@ -16,8 +16,6 @@
 
 package com.android.documentsui;
 
-import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.content.ClipData;
 import android.content.ClipboardManager;
 import android.content.ContentProviderClient;
@@ -26,15 +24,15 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.provider.DocumentsContract;
+import android.support.annotation.Nullable;
 import android.util.Log;
 
 import com.android.documentsui.model.DocumentInfo;
 import com.android.internal.util.Preconditions;
 
-import com.google.android.collect.Lists;
-
 import libcore.io.IoUtils;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -78,7 +76,7 @@
      * Returns a list of Documents as decoded from Clipboard primary clipdata.
      * This should be run from inside an AsyncTask.
      */
-    public @NonNull List<DocumentInfo> getClippedDocuments() {
+    public List<DocumentInfo> getClippedDocuments() {
         return getDocumentsFromClipData(mClipboard.getPrimaryClip());
     }
 
@@ -86,9 +84,9 @@
      * Returns a list of Documents as decoded in clipData.
      * This should be run from inside an AsyncTask.
      */
-    public @NonNull List<DocumentInfo> getDocumentsFromClipData(ClipData clipData) {
+    public List<DocumentInfo> getDocumentsFromClipData(ClipData clipData) {
         Preconditions.checkNotNull(clipData);
-        final List<DocumentInfo> srcDocs = Lists.newArrayList();
+        final List<DocumentInfo> srcDocs = new ArrayList<>();
 
         int count = clipData.getItemCount();
         if (count == 0) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
index 2de7fc4..2c6bdb3 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java
@@ -26,7 +26,6 @@
 import static com.android.documentsui.DirectoryFragment.ANIM_DOWN;
 import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
 import static com.android.documentsui.DirectoryFragment.ANIM_UP;
-import static com.android.internal.util.Preconditions.checkArgument;
 
 import android.app.Activity;
 import android.app.Fragment;
@@ -48,9 +47,6 @@
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Root;
-import android.support.v4.app.ActionBarDrawerToggle;
-import android.support.v4.widget.DrawerLayout;
-import android.support.v4.widget.DrawerLayout.DrawerListener;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -81,9 +77,7 @@
 
     private Toolbar mRootsToolbar;
 
-    private DrawerLayout mDrawerLayout;
-    private ActionBarDrawerToggle mDrawerToggle;
-    private View mRootsDrawer;
+    private DrawerController mDrawer;
 
     private DirectoryContainerView mDirectoryContainer;
 
@@ -105,6 +99,7 @@
         final Resources res = getResources();
         mShowAsDialog = res.getBoolean(R.bool.show_as_dialog) && mState.action != ACTION_MANAGE &&
                 mState.action != ACTION_BROWSE;
+
         if (!mShowAsDialog) {
             setTheme(R.style.DocumentsNonDialogTheme);
         }
@@ -117,6 +112,8 @@
         final Context context = this;
 
         if (mShowAsDialog) {
+            mDrawer = DrawerController.createDummy();
+
             // Strongly define our horizontal dimension; we leave vertical as
             // WRAP_CONTENT so that system resizes us when IME is showing.
             final WindowManager.LayoutParams a = getWindow().getAttributes();
@@ -128,17 +125,7 @@
             getWindow().setAttributes(a);
 
         } else {
-            // Non-dialog means we have a drawer
-            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
-
-            if (mDrawerLayout != null) {
-                mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
-                        R.drawable.ic_hamburger, R.string.drawer_open, R.string.drawer_close);
-
-                mDrawerLayout.setDrawerListener(mDrawerListener);
-
-                mRootsDrawer = findViewById(R.id.drawer_roots);
-            }
+            mDrawer = DrawerController.create(this);
         }
 
         mDirectoryContainer = (DirectoryContainerView) findViewById(R.id.container_directory);
@@ -162,10 +149,9 @@
 
         // Hide roots when we're managing a specific root
         if (mState.action == ACTION_MANAGE || mState.action == ACTION_BROWSE) {
-            if (mShowAsDialog || mDrawerLayout == null) {
+            mDrawer.lockClosed();
+            if (mShowAsDialog) {
                 findViewById(R.id.container_roots).setVisibility(View.GONE);
-            } else {
-                mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
             }
         }
 
@@ -341,53 +327,15 @@
         }
     }
 
-    private DrawerListener mDrawerListener = new DrawerListener() {
-        @Override
-        public void onDrawerSlide(View drawerView, float slideOffset) {
-            mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
-        }
-
-        @Override
-        public void onDrawerOpened(View drawerView) {
-            mDrawerToggle.onDrawerOpened(drawerView);
-        }
-
-        @Override
-        public void onDrawerClosed(View drawerView) {
-            mDrawerToggle.onDrawerClosed(drawerView);
-        }
-
-        @Override
-        public void onDrawerStateChanged(int newState) {
-            mDrawerToggle.onDrawerStateChanged(newState);
-        }
-    };
-
     @Override
     protected void onPostCreate(Bundle savedInstanceState) {
         super.onPostCreate(savedInstanceState);
-        if (mDrawerToggle != null) {
-            mDrawerToggle.syncState();
-        }
+        mDrawer.syncState();
         updateActionBar();
     }
 
     public void setRootsDrawerOpen(boolean open) {
-        if (!mShowAsDialog && mDrawerLayout != null) {
-            if (open) {
-                mDrawerLayout.openDrawer(mRootsDrawer);
-            } else {
-                mDrawerLayout.closeDrawer(mRootsDrawer);
-            }
-        }
-    }
-
-    private boolean isRootsDrawerOpen() {
-        if (mShowAsDialog || mDrawerLayout == null) {
-            return false;
-        } else {
-            return mDrawerLayout.isDrawerOpen(mRootsDrawer);
-        }
+        mDrawer.setOpen(open);
     }
 
     @Override
@@ -408,8 +356,7 @@
             }
         }
 
-        if (!mShowAsDialog && mDrawerLayout != null &&
-                mDrawerLayout.getDrawerLockMode(mRootsDrawer) == DrawerLayout.LOCK_MODE_UNLOCKED) {
+        if (!mShowAsDialog && mDrawer.isUnlocked()) {
             mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
             mToolbar.setNavigationContentDescription(R.string.drawer_open);
             mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
@@ -504,10 +451,7 @@
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        if (mDrawerToggle != null && mDrawerToggle.onOptionsItemSelected(item)) {
-            return true;
-        }
-        return super.onOptionsItemSelected(item);
+        return mDrawer.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
     }
 
     @Override
@@ -526,7 +470,7 @@
         if (size > 1) {
             mState.stack.pop();
             onCurrentDirectoryChanged(ANIM_UP);
-        } else if (size == 1 && !isRootsDrawerOpen()) {
+        } else if (size == 1 && !mDrawer.isOpen()) {
             // TODO: open root drawer once we can capture back key
             super.onBackPressed();
         } else {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
new file mode 100644
index 0000000..cf16c3f
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import android.app.Activity;
+import android.support.v4.app.ActionBarDrawerToggle;
+import android.support.v4.widget.DrawerLayout;
+import android.support.v4.widget.DrawerLayout.DrawerListener;
+import android.view.MenuItem;
+import android.view.View;
+
+/**
+ * A facade over the various pieces comprising "roots fragment in a Drawer".
+ *
+ * @see DrawerController#create(DrawerLayout)
+ */
+abstract class DrawerController implements DrawerListener {
+
+    abstract void setOpen(boolean open);
+    abstract void lockOpen();
+    abstract void lockClosed();
+    abstract boolean isOpen();
+    abstract boolean isUnlocked();
+    abstract void syncState();
+    abstract boolean onOptionsItemSelected(MenuItem item);
+
+    /**
+     * Returns a controller suitable for {@code Layout}.
+     */
+    static DrawerController create(Activity activity) {
+
+        DrawerLayout layout = (DrawerLayout) activity.findViewById(R.id.drawer_layout);
+
+        if (layout == null) {
+            return new DummyDrawerController();
+        }
+
+        View drawer = activity.findViewById(R.id.drawer_roots);
+        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
+                activity,
+                layout,
+                R.drawable.ic_hamburger,
+                R.string.drawer_open,
+                R.string.drawer_close);
+
+        return new RuntimeDrawerController(layout, drawer, toggle);
+    }
+
+    /**
+     * Returns a controller suitable for {@code Layout}.
+     */
+    static DrawerController createDummy() {
+        return new DummyDrawerController();
+    }
+
+    /**
+     * Runtime controller that manages a real drawer.
+     */
+    private static final class RuntimeDrawerController extends DrawerController {
+
+        private final ActionBarDrawerToggle mToggle;
+        private DrawerLayout mLayout;
+        private View mDrawer;
+
+        public RuntimeDrawerController(
+                DrawerLayout layout, View drawer, ActionBarDrawerToggle toggle) {
+            checkArgument(layout != null);
+
+            mLayout = layout;
+            mDrawer = drawer;
+            mToggle = toggle;
+
+            mLayout.setDrawerListener(this);
+        }
+
+        @Override
+        void setOpen(boolean open) {
+            if (open) {
+                mLayout.openDrawer(mDrawer);
+            } else {
+                mLayout.closeDrawer(mDrawer);
+            }
+        }
+
+        @Override
+        boolean isOpen() {
+            return mLayout.isDrawerOpen(mDrawer);
+        }
+
+        @Override
+        void syncState() {
+            mToggle.syncState();
+        }
+
+        @Override
+        boolean isUnlocked() {
+            return mLayout.getDrawerLockMode(mDrawer) == DrawerLayout.LOCK_MODE_UNLOCKED;
+        }
+
+        @Override
+        void lockOpen() {
+            mLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
+        }
+
+        @Override
+        void lockClosed() {
+            mLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
+        }
+
+        @Override
+        boolean onOptionsItemSelected(MenuItem item) {
+            return false;
+        }
+
+        @Override
+        public void onDrawerSlide(View drawerView, float slideOffset) {
+            mToggle.onDrawerSlide(drawerView, slideOffset);
+        }
+
+        @Override
+        public void onDrawerOpened(View drawerView) {
+            mToggle.onDrawerOpened(drawerView);
+        }
+
+        @Override
+        public void onDrawerClosed(View drawerView) {
+            mToggle.onDrawerClosed(drawerView);
+        }
+
+        @Override
+        public void onDrawerStateChanged(int newState) {
+            mToggle.onDrawerStateChanged(newState);
+        }
+    }
+
+    /*
+     * Dummy controller useful with clients that don't host a real drawer.
+     */
+    private static final class DummyDrawerController extends DrawerController {
+
+        @Override
+        boolean isOpen() {
+            return false;
+        }
+
+        @Override
+        void syncState() {}
+
+        @Override
+        void lockOpen() {}
+
+        @Override
+        void lockClosed() {}
+
+        @Override
+        boolean isUnlocked() {
+            return true;
+        }
+
+        @Override
+        boolean onOptionsItemSelected(MenuItem item) {
+            return false;
+        }
+
+        @Override
+        public void onDrawerSlide(View drawerView, float slideOffset) {}
+
+        @Override
+        public void onDrawerOpened(View drawerView) {}
+
+        @Override
+        public void onDrawerClosed(View drawerView) {}
+
+        @Override
+        public void onDrawerStateChanged(int newState) {}
+
+        @Override
+        void setOpen(boolean open) {}
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java b/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java
index 1cbc221..17a1161 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilteringCursorWrapper.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
 import static com.android.documentsui.model.DocumentInfo.getCursorLong;
 import static com.android.documentsui.model.DocumentInfo.getCursorString;
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/GridItem.java b/packages/DocumentsUI/src/com/android/documentsui/GridItem.java
new file mode 100644
index 0000000..990dca7
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/GridItem.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+/**
+ * A FrameLayout subclass used by DirectoryFragment. Ensures that the resulting grid item is always
+ * square.
+ */
+public class GridItem extends FrameLayout {
+    public GridItem(Context context) {
+        super(context);
+    }
+
+    public GridItem(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public GridItem(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // Grid layout uses item width to figure out the number of columns, then dynamically fits
+        // rows into the view. The upshot of this is that changing the item width will mess up the
+        // grid layout - so to make the items square, throw out the height and use the width for
+        // both dimensions. The grid layout will correctly adjust the row height.
+        //
+        // Note that this code will need to be changed if the layout manager's orientation is
+        // changed from VERTICAL to HORIZONTAL.
+        super.onMeasure(widthMeasureSpec, widthMeasureSpec);
+    }
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
index b43fedf..9959265 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/IconUtils.java
@@ -23,13 +23,11 @@
 import android.provider.DocumentsContract.Document;
 import android.util.TypedValue;
 
-import com.google.android.collect.Maps;
-
 import java.util.HashMap;
 
 public class IconUtils {
 
-    private static HashMap<String, Integer> sMimeIcons = Maps.newHashMap();
+    private static HashMap<String, Integer> sMimeIcons = new HashMap<>();
 
     private static void add(String mimeType, int resId) {
         if (sMimeIcons.put(mimeType, resId) != null) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java b/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
index 02edd0c..f87fe4c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/MultiSelectManager.java
@@ -31,7 +31,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 
-import com.google.common.annotations.VisibleForTesting;
+import android.support.annotation.VisibleForTesting;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java b/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
index f94aebd..b0e332f 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/ProviderExecutor.java
@@ -20,8 +20,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Maps;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
@@ -32,7 +30,7 @@
 public class ProviderExecutor extends Thread implements Executor {
 
     @GuardedBy("sExecutors")
-    private static HashMap<String, ProviderExecutor> sExecutors = Maps.newHashMap();
+    private static HashMap<String, ProviderExecutor> sExecutors = new HashMap<>();
 
     public static ProviderExecutor forAuthority(String authority) {
         synchronized (sExecutors) {
@@ -53,7 +51,7 @@
 
     private final LinkedBlockingQueue<Runnable> mQueue = new LinkedBlockingQueue<Runnable>();
 
-    private final ArrayList<WeakReference<Preemptable>> mPreemptable = Lists.newArrayList();
+    private final ArrayList<WeakReference<Preemptable>> mPreemptable = new ArrayList<>();
 
     private void preempt() {
         synchronized (mPreemptable) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
index 878c4c2..4685c41 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java
@@ -18,7 +18,6 @@
 
 import static com.android.documentsui.model.DocumentInfo.getCursorString;
 
-import android.annotation.Nullable;
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.ComponentName;
@@ -28,6 +27,7 @@
 import android.net.Uri;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
+import android.support.annotation.Nullable;
 import android.util.Log;
 
 import com.android.documentsui.BaseActivity.DocumentContext;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
index f5908c5..1a7095a 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentLoader.java
@@ -16,8 +16,8 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.DocumentsActivity.TAG;
 import static com.android.documentsui.BaseActivity.State.SORT_ORDER_LAST_MODIFIED;
+import static com.android.documentsui.Shared.TAG;
 
 import android.app.ActivityManager;
 import android.content.AsyncTaskLoader;
@@ -36,14 +36,14 @@
 
 import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.model.RootInfo;
-import com.google.android.collect.Maps;
-import com.google.common.collect.Lists;
+
 import com.google.common.util.concurrent.AbstractFuture;
 
 import libcore.io.IoUtils;
 
 import java.io.Closeable;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
@@ -53,7 +53,7 @@
 import java.util.concurrent.TimeUnit;
 
 public class RecentLoader extends AsyncTaskLoader<DirectoryResult> {
-    private static final boolean LOGD = true;
+    private static final boolean DEBUG = false;
 
     // TODO: clean up cursor ownership so background thread doesn't traverse
     // previously returned cursors for filtering/sorting; this currently races
@@ -81,7 +81,7 @@
     private final RootsCache mRoots;
     private final State mState;
 
-    private final HashMap<RootInfo, RecentTask> mTasks = Maps.newHashMap();
+    private final HashMap<RootInfo, RecentTask> mTasks = new HashMap<>();
 
     private final int mSortOrder = State.SORT_ORDER_LAST_MODIFIED;
 
@@ -196,7 +196,7 @@
 
         // Collect all finished tasks
         boolean allDone = true;
-        List<Cursor> cursors = Lists.newArrayList();
+        List<Cursor> cursors = new ArrayList<>();
         for (RecentTask task : mTasks.values()) {
             if (task.isDone()) {
                 try {
@@ -221,7 +221,7 @@
             }
         }
 
-        if (LOGD) {
+        if (DEBUG) {
             Log.d(TAG, "Found " + cursors.size() + " of " + mTasks.size() + " recent queries done");
         }
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
index e11d7d9..662822e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RecentsCreateFragment.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
 
 import android.app.Fragment;
 import android.app.FragmentManager;
@@ -50,7 +50,6 @@
 import com.android.documentsui.model.DocumentStack;
 import com.android.documentsui.model.DurableUtils;
 import com.android.documentsui.model.RootInfo;
-import com.google.android.collect.Lists;
 
 import libcore.io.IoUtils;
 
@@ -157,7 +156,7 @@
         @Override
         public List<DocumentStack> loadInBackground(Uri uri, CancellationSignal signal) {
             final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState);
-            final ArrayList<DocumentStack> result = Lists.newArrayList();
+            final ArrayList<DocumentStack> result = new ArrayList<>();
 
             final ContentResolver resolver = getContext().getContentResolver();
             final Cursor cursor = resolver.query(
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
index fbcb938..05f7d8d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui;
 
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
 
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
@@ -39,14 +39,14 @@
 import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.model.RootInfo;
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
+import android.support.annotation.VisibleForTesting;
+
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
 
 import libcore.io.IoUtils;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
@@ -74,10 +74,10 @@
     @GuardedBy("mLock")
     private Multimap<String, RootInfo> mRoots = ArrayListMultimap.create();
     @GuardedBy("mLock")
-    private HashSet<String> mStoppedAuthorities = Sets.newHashSet();
+    private HashSet<String> mStoppedAuthorities = new HashSet<>();
 
     @GuardedBy("mObservedAuthorities")
-    private final HashSet<String> mObservedAuthorities = Sets.newHashSet();
+    private final HashSet<String> mObservedAuthorities = new HashSet<>();
 
     public RootsCache(Context context) {
         mContext = context;
@@ -159,7 +159,7 @@
         private final String mFilterPackage;
 
         private final Multimap<String, RootInfo> mTaskRoots = ArrayListMultimap.create();
-        private final HashSet<String> mTaskStoppedAuthorities = Sets.newHashSet();
+        private final HashSet<String> mTaskStoppedAuthorities = new HashSet<>();
 
         /**
          * Update all roots.
@@ -251,7 +251,7 @@
             }
         }
 
-        final List<RootInfo> roots = Lists.newArrayList();
+        final List<RootInfo> roots = new ArrayList<>();
         final Uri rootsUri = DocumentsContract.buildRootsUri(authority);
 
         ContentProviderClient client = null;
@@ -350,7 +350,7 @@
 
     @VisibleForTesting
     static List<RootInfo> getMatchingRoots(Collection<RootInfo> roots, State state) {
-        final List<RootInfo> matching = Lists.newArrayList();
+        final List<RootInfo> matching = new ArrayList<>();
         for (RootInfo root : roots) {
             final boolean supportsCreate = (root.flags & Root.FLAG_SUPPORTS_CREATE) != 0;
             final boolean supportsIsChild = (root.flags & Root.FLAG_SUPPORTS_IS_CHILD) != 0;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index fd67a77..c02184b 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -44,8 +44,8 @@
 import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.model.DocumentInfo;
 import com.android.documentsui.model.RootInfo;
-import com.google.common.collect.Lists;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -293,8 +293,8 @@
             RootItem audio = null;
             RootItem downloads = null;
 
-            final List<RootInfo> clouds = Lists.newArrayList();
-            final List<RootInfo> locals = Lists.newArrayList();
+            final List<RootInfo> clouds = new ArrayList<>();
+            final List<RootInfo> locals = new ArrayList<>();
 
             for (RootInfo root : roots) {
                 if (root.isRecents()) {
@@ -338,7 +338,7 @@
                 final List<ResolveInfo> infos = pm.queryIntentActivities(
                         includeApps, PackageManager.MATCH_DEFAULT_ONLY);
 
-                final List<AppItem> apps = Lists.newArrayList();
+                final List<AppItem> apps = new ArrayList<>();
 
                 // Omit ourselves from the list
                 for (ResolveInfo info : infos) {
diff --git a/packages/DocumentsUI/src/com/android/documentsui/SectionedListAdapter.java b/packages/DocumentsUI/src/com/android/documentsui/SectionedListAdapter.java
index 088e3fa..ae959f9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/SectionedListAdapter.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/SectionedListAdapter.java
@@ -22,8 +22,6 @@
 import android.widget.BaseAdapter;
 import android.widget.ListAdapter;
 
-import com.google.android.collect.Lists;
-
 import java.util.ArrayList;
 
 /**
@@ -31,7 +29,7 @@
  * provide a header, and correctly handling item types across child adapters.
  */
 public class SectionedListAdapter extends BaseAdapter {
-    private ArrayList<SectionAdapter> mSections = Lists.newArrayList();
+    private ArrayList<SectionAdapter> mSections = new ArrayList<>();
 
     public interface SectionAdapter extends ListAdapter {
         public View getHeaderView(View convertView, ViewGroup parent);
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
new file mode 100644
index 0000000..b414ee3
--- /dev/null
+++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+/**
+ * @hide
+ */
+public final class Shared {
+    public static final String TAG = "Documents";
+}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java b/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
index 1ca277d..7ca3954 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/StandaloneActivity.java
@@ -20,7 +20,6 @@
 import static com.android.documentsui.DirectoryFragment.ANIM_NONE;
 import static com.android.documentsui.DirectoryFragment.ANIM_UP;
 
-import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.FragmentManager;
 import android.content.ActivityNotFoundException;
@@ -33,6 +32,7 @@
 import android.os.Bundle;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Root;
+import android.support.annotation.Nullable;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.Menu;
@@ -70,6 +70,8 @@
     private ItemSelectedListener mStackListener;
     private BaseAdapter mStackAdapter;
     private DocumentClipper mClipper;
+    private DrawerController mDrawer;
+    private boolean mCompactMode;
 
     public StandaloneActivity() {
         super(TAG);
@@ -107,6 +109,18 @@
 
         setActionBar(mToolbar);
 
+
+        // "show as dialog" is true on BIG screens. But we *assume* a big screen
+        // and specialize for smaller screens by moving roots into an auto-hide drawer.
+        // This works in conjunction with the specialized layouts defined for sw720dp.
+        mCompactMode = !getResources().getBoolean(R.bool.show_as_dialog);
+
+        if (mCompactMode) {
+            setTheme(R.style.DocumentsNonDialogTheme);
+        }
+
+        mDrawer = DrawerController.create(this);
+
         mClipper = new DocumentClipper(this);
 
         RootsFragment.show(getFragmentManager(), null);
@@ -164,10 +178,23 @@
     @Override
     public void updateActionBar() {
         final RootInfo root = getCurrentRoot();
-        mToolbar.setNavigationIcon(
-                root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null);
-        mToolbar.setNavigationContentDescription(R.string.drawer_open);
-        mToolbar.setNavigationOnClickListener(null);
+
+        if (mCompactMode) {
+            mToolbar.setNavigationIcon(R.drawable.ic_hamburger);
+            mToolbar.setNavigationContentDescription(R.string.drawer_open);
+            mToolbar.setNavigationOnClickListener(
+                    new View.OnClickListener() {
+                        @Override
+                        public void onClick(View v) {
+                            mDrawer.setOpen(true);
+                        }
+                    });
+        } else {
+            mToolbar.setNavigationIcon(
+                    root != null ? root.loadToolbarIcon(mToolbar.getContext()) : null);
+            mToolbar.setNavigationContentDescription(R.string.drawer_open);
+            mToolbar.setNavigationOnClickListener(null);
+        }
 
         if (mSearchManager.isExpanded()) {
             mToolbar.setTitle(null);
@@ -284,6 +311,12 @@
     }
 
     @Override
+    void onRootPicked(RootInfo root) {
+        super.onRootPicked(root);
+        mDrawer.setOpen(false);
+    }
+
+    @Override
     public void onDocumentsPicked(List<DocumentInfo> docs) {
         throw new UnsupportedOperationException();
     }
diff --git a/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java b/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java
index 1a5bb0c..7bb662c 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/UriDerivativeLoader.java
@@ -27,16 +27,16 @@
  * changes while started, manages {@link CancellationSignal}, and caches
  * returned results.
  */
-public abstract class UriDerivativeLoader<P, R> extends AsyncTaskLoader<R> {
+public abstract class UriDerivativeLoader<Param, Res> extends AsyncTaskLoader<Res> {
     final ForceLoadContentObserver mObserver;
 
-    private final P mParam;
+    private final Param mParam;
 
-    private R mResult;
+    private Res mResult;
     private CancellationSignal mCancellationSignal;
 
     @Override
-    public final R loadInBackground() {
+    public final Res loadInBackground() {
         synchronized (this) {
             if (isLoadInBackgroundCanceled()) {
                 throw new OperationCanceledException();
@@ -52,7 +52,7 @@
         }
     }
 
-    public abstract R loadInBackground(P param, CancellationSignal signal);
+    public abstract Res loadInBackground(Param param, CancellationSignal signal);
 
     @Override
     public void cancelLoadInBackground() {
@@ -66,12 +66,12 @@
     }
 
     @Override
-    public void deliverResult(R result) {
+    public void deliverResult(Res result) {
         if (isReset()) {
             closeQuietly(result);
             return;
         }
-        R oldResult = mResult;
+        Res oldResult = mResult;
         mResult = result;
 
         if (isStarted()) {
@@ -83,7 +83,7 @@
         }
     }
 
-    public UriDerivativeLoader(Context context, P param) {
+    public UriDerivativeLoader(Context context, Param param) {
         super(context);
         mObserver = new ForceLoadContentObserver();
         mParam = param;
@@ -105,7 +105,7 @@
     }
 
     @Override
-    public void onCanceled(R result) {
+    public void onCanceled(Res result) {
         closeQuietly(result);
     }
 
@@ -122,7 +122,7 @@
         getContext().getContentResolver().unregisterContentObserver(mObserver);
     }
 
-    private void closeQuietly(R result) {
+    private void closeQuietly(Res result) {
         if (result instanceof AutoCloseable) {
             try {
                 ((AutoCloseable) result).close();
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
index 5d5f2eb..cc981e1e 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java
@@ -24,7 +24,6 @@
 import android.os.Parcelable;
 import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
-import android.provider.DocumentsContract.Root;
 import android.provider.DocumentsProvider;
 import android.text.TextUtils;
 
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DurableUtils.java b/packages/DocumentsUI/src/com/android/documentsui/model/DurableUtils.java
index 2a29cbc..e21dd49 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/DurableUtils.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/DurableUtils.java
@@ -16,7 +16,7 @@
 
 package com.android.documentsui.model;
 
-import static com.android.documentsui.DocumentsActivity.TAG;
+import static com.android.documentsui.Shared.TAG;
 
 import android.os.BadParcelableException;
 import android.os.Parcel;
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/BandSelectMatrixTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/BandSelectMatrixTest.java
new file mode 100644
index 0000000..f15a643
--- /dev/null
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/BandSelectMatrixTest.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.documentsui;
+
+import static org.junit.Assert.*;
+
+import com.android.documentsui.BandSelectMatrix;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import android.util.SparseBooleanArray;
+
+import org.junit.After;
+import org.junit.Test;
+
+public class BandSelectMatrixTest {
+
+    private static final int VIEW_PADDING_PX = 5;
+    private static final int CHILD_VIEW_EDGE_PX = 100;
+    private static final int VIEWPORT_HEIGHT = 500;
+
+    private static BandSelectMatrix matrix;
+    private static TestHelper helper;
+    private static SparseBooleanArray lastSelection;
+    private static int viewWidth;
+
+    private static void setUp(int numChildren, int numColumns) {
+        helper = new TestHelper(numChildren, numColumns);
+        viewWidth = VIEW_PADDING_PX + numColumns * (VIEW_PADDING_PX + CHILD_VIEW_EDGE_PX);
+        matrix = new BandSelectMatrix(helper);
+        matrix.addOnSelectionChangedListener(new BandSelectMatrix.OnSelectionChangedListener() {
+
+            @Override
+            public void onSelectionChanged(SparseBooleanArray updatedSelection) {
+                lastSelection = updatedSelection;
+            }
+        });
+    }
+
+    @After
+    public void tearDown() {
+        matrix = null;
+        helper = null;
+        lastSelection = null;
+    }
+
+    @Test
+    public void testSelectionLeftOfItems() {
+        setUp(20, 5);
+        matrix.startSelection(new Point(0, 10));
+        matrix.resizeSelection(new Point(1, 11));
+        assertSelected(new int[0]);
+    }
+
+    @Test
+    public void testSelectionRightOfItems() {
+        setUp(20, 4);
+        matrix.startSelection(new Point(viewWidth - 1, 10));
+        matrix.resizeSelection(new Point(viewWidth - 2, 11));
+        assertSelected(new int[0]);
+    }
+
+    @Test
+    public void testSelectionAboveItems() {
+        setUp(20, 4);
+        matrix.startSelection(new Point(10, 0));
+        matrix.resizeSelection(new Point(11, 1));
+        assertSelected(new int[0]);
+    }
+
+    @Test
+    public void testSelectionBelowItems() {
+        setUp(5, 4);
+        matrix.startSelection(new Point(10, VIEWPORT_HEIGHT - 1));
+        matrix.resizeSelection(new Point(11, VIEWPORT_HEIGHT - 2));
+        assertSelected(new int[0]);
+    }
+
+    @Test
+    public void testVerticalSelectionBetweenItems() {
+        setUp(20, 4);
+        matrix.startSelection(new Point(106, 0));
+        matrix.resizeSelection(new Point(107, 200));
+        assertSelected(new int[0]);
+    }
+
+    @Test
+    public void testHorizontalSelectionBetweenItems() {
+        setUp(20, 4);
+        matrix.startSelection(new Point(0, 105));
+        matrix.resizeSelection(new Point(200, 106));
+        assertSelected(new int[0]);
+    }
+
+    @Test
+    public void testGrowingAndShrinkingSelection() {
+        setUp(20, 4);
+        matrix.startSelection(new Point(0, 0));
+        matrix.resizeSelection(new Point(5, 5));
+        assertSelected(new int[] {0});
+        matrix.resizeSelection(new Point(109, 109));
+        assertSelected(new int[] {0});
+        matrix.resizeSelection(new Point(110, 109));
+        assertSelected(new int[] {0, 1});
+        matrix.resizeSelection(new Point(110, 110));
+        assertSelected(new int[] {0, 1, 4, 5});
+        matrix.resizeSelection(new Point(214, 214));
+        assertSelected(new int[] {0, 1, 4, 5});
+        matrix.resizeSelection(new Point(215, 214));
+        assertSelected(new int[] {0, 1, 2, 4, 5, 6});
+        matrix.resizeSelection(new Point(214, 214));
+        assertSelected(new int[] {0, 1, 4, 5});
+        matrix.resizeSelection(new Point(110, 110));
+        assertSelected(new int[] {0, 1, 4, 5});
+        matrix.resizeSelection(new Point(110, 109));
+        assertSelected(new int[] {0, 1});
+        matrix.resizeSelection(new Point(109, 109));
+        assertSelected(new int[] {0});
+        matrix.resizeSelection(new Point(5, 5));
+        assertSelected(new int[] {0});
+        matrix.resizeSelection(new Point(0, 0));
+        assertSelected(new int[0]);
+    }
+
+    @Test
+    public void testSelectionMovingAroundOrigin() {
+        setUp(16, 4);
+        matrix.startSelection(new Point(210, 210));
+        matrix.resizeSelection(new Point(viewWidth - 1, 0));
+        assertSelected(new int[] {2, 3, 6, 7});
+        matrix.resizeSelection(new Point(0, 0));
+        assertSelected(new int[] {0, 1, 4, 5});
+        matrix.resizeSelection(new Point(0, 420));
+        assertSelected(new int[] {8, 9, 12, 13});
+        matrix.resizeSelection(new Point(viewWidth - 1, 420));
+        assertSelected(new int[] {10, 11, 14, 15});
+    }
+
+    @Test
+    public void testScrollingBandSelect() {
+        setUp(40, 4);
+        matrix.startSelection(new Point(0, 0));
+        matrix.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
+        assertSelected(new int[] {0, 4, 8, 12, 16});
+        scroll(CHILD_VIEW_EDGE_PX);
+        assertSelected(new int[] {0, 4, 8, 12, 16, 20});
+        matrix.resizeSelection(new Point(200, VIEWPORT_HEIGHT - 1));
+        assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21});
+        scroll(CHILD_VIEW_EDGE_PX);
+        assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25});
+        scroll(-2 * CHILD_VIEW_EDGE_PX);
+        assertSelected(new int[] {0, 1, 4, 5, 8, 9, 12, 13, 16, 17});
+        matrix.resizeSelection(new Point(100, VIEWPORT_HEIGHT - 1));
+        assertSelected(new int[] {0, 4, 8, 12, 16});
+    }
+
+    private static void assertSelected(int[] selectedPositions) {
+        assertEquals(selectedPositions.length, lastSelection.size());
+        for (int position : selectedPositions) {
+            assertTrue(lastSelection.get(position));
+        }
+    }
+
+    private static void scroll(int dy) {
+        assertTrue(helper.verticalOffset + VIEWPORT_HEIGHT + dy <= helper.getTotalHeight());
+        helper.verticalOffset += dy;
+        matrix.onScrolled(null, 0, dy);
+    }
+
+    private static final class TestHelper implements BandSelectMatrix.RecyclerViewHelper {
+
+        public int horizontalOffset = 0;
+        public int verticalOffset = 0;
+        private final int mNumColumns;
+        private final int mNumRows;
+        private final int mNumChildren;
+
+        public TestHelper(int numChildren, int numColumns) {
+            mNumChildren = numChildren;
+            mNumColumns = numColumns;
+            mNumRows = (int) Math.ceil((double) numChildren / mNumColumns);
+        }
+
+        private int getTotalHeight() {
+            return CHILD_VIEW_EDGE_PX * mNumRows + VIEW_PADDING_PX * (mNumRows + 1);
+        }
+
+        private int getFirstVisibleRowIndex() {
+            return verticalOffset / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+        }
+
+        private int getLastVisibleRowIndex() {
+            int lastVisibleRowUncapped =
+                    (VIEWPORT_HEIGHT + verticalOffset - 1) / (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+            return Math.min(lastVisibleRowUncapped, mNumRows - 1);
+        }
+
+        private int getNumItemsInRow(int index) {
+            assertTrue(index >= 0 && index < mNumRows);
+            if (index == mNumRows - 1 && mNumChildren % mNumColumns != 0) {
+                return mNumChildren % mNumColumns;
+            }
+
+            return mNumColumns;
+        }
+
+        @Override
+        public void addOnScrollListener(OnScrollListener listener) {}
+
+        @Override
+        public void removeOnScrollListener(OnScrollListener listener) {}
+
+        @Override
+        public Point createAbsolutePoint(Point relativePoint) {
+            return new Point(
+                    relativePoint.x + horizontalOffset, relativePoint.y + verticalOffset);
+        }
+
+        @Override
+        public int getVisibleChildCount() {
+            int childCount = 0;
+            for (int i = getFirstVisibleRowIndex(); i <= getLastVisibleRowIndex(); i++) {
+                childCount += getNumItemsInRow(i);
+            }
+            return childCount;
+        }
+
+        @Override
+        public int getAdapterPositionAt(int index) {
+            return index + mNumColumns * (getFirstVisibleRowIndex());
+        }
+
+        @Override
+        public Rect getAbsoluteRectForChildViewAt(int index) {
+            int adapterPosition = getAdapterPositionAt(index);
+            int rowIndex = adapterPosition / mNumColumns;
+            int columnIndex = adapterPosition % mNumColumns;
+
+            Rect rect = new Rect();
+            rect.top = VIEW_PADDING_PX + rowIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+            rect.bottom = rect.top + CHILD_VIEW_EDGE_PX - 1;
+            rect.left = VIEW_PADDING_PX + columnIndex * (CHILD_VIEW_EDGE_PX + VIEW_PADDING_PX);
+            rect.right = rect.left + CHILD_VIEW_EDGE_PX - 1;
+            return rect;
+        }
+
+        @Override
+        public int getTotalChildCount() {
+            return mNumChildren;
+        }
+
+        @Override
+        public int getNumColumns() {
+            return mNumColumns;
+        }
+
+        @Override
+        public int getNumRows() {
+            return mNumRows;
+        }
+    }
+}
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java
index 8c5bac1..1325706 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/RootsCacheTest.java
@@ -21,7 +21,8 @@
 
 import com.android.documentsui.BaseActivity.State;
 import com.android.documentsui.model.RootInfo;
-import com.google.android.collect.Lists;
+
+import com.google.common.collect.Lists;
 
 import java.util.List;
 
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
index c2f1762..6a2e03a 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java
@@ -36,8 +36,6 @@
 import android.support.annotation.VisibleForTesting;
 import android.util.Log;
 
-import com.google.android.collect.Maps;
-
 import libcore.io.IoUtils;
 
 import java.io.File;
@@ -101,7 +99,7 @@
             });
         }
         // Create new roots.
-        mRoots = Maps.newHashMap();
+        mRoots = new HashMap<>();
         for (String rootId : rootIds) {
             final RootInfo rootInfo = new RootInfo(rootId, getSize(rootId));
             mRoots.put(rootId, rootInfo);
diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/UnitTests.java b/packages/DocumentsUI/tests/src/com/android/documentsui/UnitTests.java
index 4ffe799..0553270 100644
--- a/packages/DocumentsUI/tests/src/com/android/documentsui/UnitTests.java
+++ b/packages/DocumentsUI/tests/src/com/android/documentsui/UnitTests.java
@@ -22,6 +22,7 @@
 
 @RunWith(Suite.class)
 @SuiteClasses({
+        BandSelectMatrixTest.class,
         MultiSelectManager_SelectionTest.class,
         MultiSelectManagerTest.class
 })
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 4eb6f88..40dcd0d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -147,6 +147,12 @@
     private int mRingMode;
     private int mPhoneState;
     private boolean mKeyguardIsVisible;
+
+    /**
+     * If true, fingerprint was already authenticated and we don't need to start listening again
+     * until the Keyguard has been dismissed.
+     */
+    private boolean mFingerprintAlreadyAuthenticated;
     private boolean mBouncer;
     private boolean mBootCompleted;
     private boolean mUserHasAuthenticatedSinceBoot;
@@ -373,6 +379,11 @@
 
     private void onFingerprintAuthenticated(int userId) {
         mUserFingerprintAuthenticated.put(userId, true);
+
+        // If fingerprint unlocking is allowed, this event will lead to a Keyguard dismiss or to a
+        // wake-up (if Keyguard is not showing), so we don't need to listen until Keyguard is
+        // fully gone.
+        mFingerprintAlreadyAuthenticated = isUnlockingWithFingerprintAllowed();
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -818,6 +829,7 @@
                 cb.onFinishedGoingToSleep(arg1);
             }
         }
+        mFingerprintAlreadyAuthenticated = false;
         updateFingerprintListeningState();
     }
 
@@ -951,13 +963,14 @@
     }
 
     private boolean shouldListenForFingerprint() {
-        return (mKeyguardIsVisible || !mDeviceInteractive) && !mSwitchingUser;
+        return (mKeyguardIsVisible || !mDeviceInteractive) && !mSwitchingUser
+                && !mFingerprintAlreadyAuthenticated;
     }
 
     private void startListeningForFingerprint() {
         if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
         int userId = ActivityManager.getCurrentUser();
-        if (!mFingerprintDetectionRunning && isUnlockWithFingerprintPossible(userId)) {
+        if (isUnlockWithFingerprintPossible(userId)) {
             mUserHasAuthenticatedSinceBoot = mTrustManager.hasUserAuthenticatedSinceBoot(
                     ActivityManager.getCurrentUser());
             if (mFingerprintCancelSignal != null) {
@@ -1249,6 +1262,9 @@
                 cb.onKeyguardVisibilityChangedRaw(isShowing);
             }
         }
+        if (!isShowing) {
+            mFingerprintAlreadyAuthenticated = false;
+        }
         updateFingerprintListeningState();
     }
 
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
index 2353205..c430def 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/DocumentLoader.java
@@ -30,6 +30,11 @@
 import java.util.Date;
 import java.util.LinkedList;
 
+/**
+ * Loader for MTP document.
+ * At the first request, the loader returns only first NUM_INITIAL_ENTRIES. Then it launches
+ * background thread to load the rest documents and caches its result for next requests.
+ */
 class DocumentLoader {
     static final int NUM_INITIAL_ENTRIES = 10;
     static final int NUM_LOADING_ENTRIES = 20;
@@ -37,7 +42,7 @@
 
     private final MtpManager mMtpManager;
     private final ContentResolver mResolver;
-    private final LinkedList<LoaderTask> mTasks = new LinkedList<LoaderTask>();
+    private final TaskList mTaskList = new TaskList();
     private boolean mHasBackgroundThread = false;
 
     DocumentLoader(MtpManager mtpManager, ContentResolver resolver) {
@@ -56,7 +61,7 @@
 
     synchronized Cursor queryChildDocuments(String[] columnNames, Identifier parent)
             throws IOException {
-        LoaderTask task = findTask(parent);
+        LoaderTask task = mTaskList.findTask(parent);
         if (task == null) {
             int parentHandle = parent.mObjectHandle;
             // Need to pass the special value MtpManager.OBJECT_HANDLE_ROOT_CHILDREN to
@@ -70,11 +75,12 @@
                     mMtpManager,
                     parent.mDeviceId,
                     task.getUnloadedObjectHandles(NUM_INITIAL_ENTRIES)));
+        } else {
+            // Once remove the existing task in order to add it to the head of the list.
+            mTaskList.remove(task);
         }
 
-        // Move this task to the head of the list to prioritize it.
-        mTasks.remove(task);
-        mTasks.addFirst(task);
+        mTaskList.addFirst(task);
         if (!task.completed() && !mHasBackgroundThread) {
             mHasBackgroundThread = true;
             new BackgroundLoaderThread().start();
@@ -84,41 +90,11 @@
     }
 
     synchronized void clearCache(int deviceId) {
-        int i = 0;
-        while (i < mTasks.size()) {
-            if (mTasks.get(i).mIdentifier.mDeviceId == deviceId) {
-                mTasks.remove(i);
-            } else {
-                i++;
-            }
-        }
+        mTaskList.clearTaskForDevice(deviceId);
     }
 
     synchronized void clearCache() {
-        int i = 0;
-        while (i < mTasks.size()) {
-            if (mTasks.get(i).completed()) {
-                mTasks.remove(i);
-            } else {
-                i++;
-            }
-        }
-    }
-
-    private LoaderTask findTask(Identifier parent) {
-        for (int i = 0; i < mTasks.size(); i++) {
-            if (mTasks.get(i).mIdentifier.equals(parent))
-                return mTasks.get(i);
-        }
-        return null;
-    }
-
-    private LoaderTask findUncompletedTask() {
-        for (int i = 0; i < mTasks.size(); i++) {
-            if (!mTasks.get(i).completed())
-                return mTasks.get(i);
-        }
-        return null;
+        mTaskList.clearCompletedTask();
     }
 
     private class BackgroundLoaderThread extends Thread {
@@ -130,7 +106,7 @@
                 int deviceId;
                 int[] handles;
                 synchronized (DocumentLoader.this) {
-                    task = findUncompletedTask();
+                    task = mTaskList.findRunningTask();
                     if (task == null) {
                         mHasBackgroundThread = false;
                         return;
@@ -156,13 +132,53 @@
                             task.notify(mResolver);
                         }
                     } else {
-                        mTasks.remove(task);
+                        mTaskList.remove(task);
                     }
                 }
             }
         }
     }
 
+    private static class TaskList extends LinkedList<LoaderTask> {
+        LoaderTask findTask(Identifier parent) {
+            for (int i = 0; i < size(); i++) {
+                if (get(i).mIdentifier.equals(parent))
+                    return get(i);
+            }
+            return null;
+        }
+
+        LoaderTask findRunningTask() {
+            for (int i = 0; i < size(); i++) {
+                if (!get(i).completed())
+                    return get(i);
+            }
+            return null;
+        }
+
+        void clearTaskForDevice(int deviceId) {
+            int i = 0;
+            while (i < size()) {
+                if (get(i).mIdentifier.mDeviceId == deviceId) {
+                    remove(i);
+                } else {
+                    i++;
+                }
+            }
+        }
+
+        void clearCompletedTask() {
+            int i = 0;
+            while (i < size()) {
+                if (get(i).completed()) {
+                    remove(i);
+                } else {
+                    i++;
+                }
+            }
+        }
+    }
+
     private static class LoaderTask {
         final Identifier mIdentifier;
         final int[] mObjectHandles;
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java
index 98775b3..7126694 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocument.java
@@ -32,6 +32,7 @@
     private final Date mDateModified;
     private final int mSize;
     private final int mThumbSize;
+    private final boolean mReadOnly;
 
     /**
      * Constructor for root document.
@@ -40,9 +41,10 @@
         this(DUMMY_HANDLE_FOR_ROOT,
              0x3001,  // Directory.
              root.mDescription,
-             null,  // Unknown,
+             null,    // Unknown name.
              (int) Math.min(root.mMaxCapacity - root.mFreeSpace, Integer.MAX_VALUE),
-             0);
+             0,       // Total size.
+             true);   // Writable.
     }
 
     MtpDocument(MtpObjectInfo objectInfo) {
@@ -51,7 +53,8 @@
              objectInfo.getName(),
              objectInfo.getDateModified() != 0 ? new Date(objectInfo.getDateModified()) : null,
              objectInfo.getCompressedSize(),
-             objectInfo.getThumbCompressedSize());
+             objectInfo.getThumbCompressedSize(),
+             objectInfo.getProtectionStatus() != 0);
     }
 
     MtpDocument(int objectHandle,
@@ -59,13 +62,15 @@
                 String name,
                 Date dateModified,
                 int size,
-                int thumbSize) {
+                int thumbSize,
+                boolean readOnly) {
         this.mObjectHandle = objectHandle;
         this.mFormat = format;
         this.mName = name;
         this.mDateModified = dateModified;
         this.mSize = size;
         this.mThumbSize = thumbSize;
+        this.mReadOnly = readOnly;
     }
 
     void addToCursor(Identifier rootIdentifier, MatrixCursor.RowBuilder builder) {
@@ -82,7 +87,7 @@
 
         builder.add(Document.COLUMN_DOCUMENT_ID, identifier.toDocumentId());
         builder.add(Document.COLUMN_DISPLAY_NAME, mName);
-        builder.add(Document.COLUMN_MIME_TYPE, getMimeType());
+        builder.add(Document.COLUMN_MIME_TYPE, formatTypeToMimeType(mFormat));
         builder.add(
                 Document.COLUMN_LAST_MODIFIED,
                 mDateModified != null ? mDateModified.getTime() : null);
@@ -90,9 +95,9 @@
         builder.add(Document.COLUMN_SIZE, mSize);
     }
 
-    private String getMimeType() {
+    static String formatTypeToMimeType(int format) {
         // TODO: Add complete list of mime types.
-        switch (mFormat) {
+        switch (format) {
             case 0x3001:
                 return DocumentsContract.Document.MIME_TYPE_DIR;
             case 0x3009:
@@ -100,7 +105,21 @@
             case 0x3801:
                 return "image/jpeg";
             default:
-                return "";
+                return "application/octet-stream";
+        }
+    }
+
+    static int mimeTypeToFormatType(String mimeType) {
+        // TODO: Add complete list of mime types.
+        switch (mimeType.toLowerCase()) {
+            case Document.MIME_TYPE_DIR:
+                return 0x3001;
+            case "audio/mp3":
+                return 0x3009;
+            case "image/jpeg":
+                return 0x3801;
+            default:
+                return 0x3000;  // Undefined object.
         }
     }
 }
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
index 61b9fc5..031cc07 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java
@@ -96,7 +96,7 @@
             final Identifier rootIdentifier = new Identifier(root.mDeviceId, root.mStorageId);
             final MatrixCursor.RowBuilder builder = cursor.newRow();
             builder.add(Root.COLUMN_ROOT_ID, rootIdentifier.toRootId());
-            builder.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_IS_CHILD);
+            builder.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_IS_CHILD | Root.FLAG_SUPPORTS_CREATE);
             builder.add(Root.COLUMN_TITLE, root.mDescription);
             builder.add(
                     Root.COLUMN_DOCUMENT_ID,
@@ -214,6 +214,24 @@
         mDocumentLoader.clearCache();
     }
 
+    @Override
+    public String createDocument(String parentDocumentId, String mimeType, String displayName)
+            throws FileNotFoundException {
+        try {
+            final Identifier parentId = Identifier.createFromDocumentId(parentDocumentId);
+            final int objectHandle = mMtpManager.createDocument(
+                    parentId.mDeviceId, parentId.mStorageId, parentId.mObjectHandle, mimeType,
+                    displayName);
+            final String documentId =  new Identifier(parentId.mDeviceId, parentId.mStorageId,
+                   objectHandle).toDocumentId();
+            notifyChildDocumentsChange(parentDocumentId);
+            return documentId;
+        } catch (IOException error) {
+            Log.e(TAG, error.getMessage());
+            throw new FileNotFoundException(error.getMessage());
+        }
+    }
+
     void openDevice(int deviceId) throws IOException {
         mMtpManager.openDevice(deviceId);
         mRootScanner.scanNow();
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
index 3afc173..27ba794 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpManager.java
@@ -21,7 +21,10 @@
 import android.hardware.usb.UsbDeviceConnection;
 import android.hardware.usb.UsbManager;
 import android.mtp.MtpDevice;
+import android.mtp.MtpObjectInfo;
 import android.os.ParcelFileDescriptor;
+import android.provider.DocumentsContract.Document;
+import android.provider.DocumentsContract;
 import android.util.SparseArray;
 
 import java.io.FileNotFoundException;
@@ -134,6 +137,22 @@
         }
     }
 
+    synchronized int createDocument(int deviceId, int storageId, int parentObjectHandle,
+            String mimeType, String name) throws IOException {
+        final MtpDevice device = getDevice(deviceId);
+        final MtpObjectInfo objectInfo = new MtpObjectInfo.Builder()
+                .setName(name)
+                .setStorageId(storageId)
+                .setParent(parentObjectHandle)
+                .setFormat(MtpDocument.mimeTypeToFormatType(mimeType))
+                .build();
+        final MtpObjectInfo result = device.sendObjectInfo(objectInfo);
+        if (result == null) {
+            throw new IOException("Failed to create a document");
+        }
+        return result.getObjectHandle();
+    }
+
     synchronized int getParent(int deviceId, int objectHandle) throws IOException {
         final MtpDevice device = getDevice(deviceId);
         final int result = (int) device.getParent(objectHandle);
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
index 5504147..1e015bd 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/DocumentLoaderTest.java
@@ -91,7 +91,8 @@
                     "file" + objectHandle,
                     new Date(),
                     1024,
-                    0 /* thumbnail size */));
+                    0 /* thumbnail size */,
+                    false /* not read only */));
         }
         manager.setObjectHandles(0, 0, MtpManager.OBJECT_HANDLE_ROOT_CHILDREN, childDocuments);
     }
diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
index c1da59f..f06e2ff 100644
--- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
+++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDocumentsProviderTest.java
@@ -210,7 +210,8 @@
                 "image.jpg" /* display name */,
                 new Date(1422716400000L) /* modified date */,
                 1024 * 1024 * 5 /* file size */,
-                1024 * 50 /* thumbnail size */));
+                1024 * 50 /* thumbnail size */,
+                true /* read only */));
         final Cursor cursor = mProvider.queryDocument("0_1_2", null);
         assertEquals(1, cursor.getCount());
 
@@ -257,7 +258,8 @@
                 "image.jpg" /* display name */,
                 new Date(0) /* modified date */,
                 1024 * 1024 * 5 /* file size */,
-                1024 * 50 /* thumbnail size */));
+                1024 * 50 /* thumbnail size */,
+                true /* read only */));
 
         final Cursor cursor = mProvider.queryChildDocuments("0_0_0", null, null);
         assertEquals(1, cursor.getCount());
@@ -302,7 +304,8 @@
                 "image.jpg" /* display name */,
                 new Date(1422716400000L) /* modified date */,
                 1024 * 1024 * 5 /* file size */,
-                1024 * 50 /* thumbnail size */));
+                1024 * 50 /* thumbnail size */,
+                false /* not read only */));
         mMtpManager.setParent(0, 1, 2);
         mProvider.deleteDocument("0_0_1");
         assertEquals(1, mResolver.getChangeCount(
diff --git a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
index 096a5c4..f52d755 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TetherUtil.java
@@ -54,29 +54,7 @@
     public static boolean setWifiTethering(boolean enable, Context context) {
         final WifiManager wifiManager =
                 (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
-        final ContentResolver cr = context.getContentResolver();
-        /**
-         * Disable Wifi if enabling tethering
-         */
-        int wifiState = wifiManager.getWifiState();
-        if (enable && ((wifiState == WifiManager.WIFI_STATE_ENABLING) ||
-                    (wifiState == WifiManager.WIFI_STATE_ENABLED))) {
-            wifiManager.setWifiEnabled(false);
-            Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 1);
-        }
-
-        boolean success = wifiManager.setWifiApEnabled(null, enable);
-        /**
-         *  If needed, restore Wifi on tether disable
-         */
-        if (!enable) {
-            int wifiSavedState = Settings.Global.getInt(cr, Settings.Global.WIFI_SAVED_STATE, 0);
-            if (wifiSavedState == 1) {
-                wifiManager.setWifiEnabled(true);
-                Settings.Global.putInt(cr, Settings.Global.WIFI_SAVED_STATE, 0);
-            }
-        }
-        return success;
+        return wifiManager.setWifiApEnabled(null, enable);
     }
 
     public static boolean isWifiTetherEnabled(Context context) {
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 918d856..8b3f2d8 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1140,4 +1140,9 @@
     <!-- Displayed when user launches an app that was uninstalled  [CHAR LIMIT=NONE] -->
     <string name="activity_not_found">Application is not installed on your device</string>
 
+    <!-- Name of setting to show clock seconds [CHAR LIMIT=40] -->
+    <string name="clock_seconds">Show clock seconds</string>
+    <!-- Description of setting to show clock seconds [CHAR LIMIT=NONE] -->
+    <string name="clock_seconds_desc">Show clock seconds in the status bar. May impact battery life.</string>
+
 </resources>
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 3a41c3c..beb863c 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -72,10 +72,16 @@
         android:summary="@string/show_battery_percentage_summary"
         android:persistent="false" />
 
+    <com.android.systemui.tuner.TunerSwitch
+        android:key="clock_seconds"
+        android:title="@string/clock_seconds"
+        android:summary="@string/clock_seconds_desc" />
+
     <Preference
         android:key="demo_mode"
         android:title="@string/demo_mode" />
 
+    <!-- Warning, this goes last. -->
     <Preference
         android:summary="@string/tuner_persistent_warning"
         android:selectable="false" />
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
index 328ee35..36efead 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeService.java
@@ -256,6 +256,8 @@
 
     private void continuePulsing(int reason) {
         if (mHost.isPulsingBlocked()) {
+            mPulsing = false;
+            mWakeLock.release();
             return;
         }
         mHost.pulseWhileDozing(new DozeHost.PulseCallback() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 947c19c..00ac5f9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.recents.views;
 
+import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.TaskStackBuilder;
 import android.content.Context;
@@ -31,6 +32,8 @@
 import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.SparseArray;
+import android.view.AppTransitionAnimationSpec;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowInsets;
@@ -60,6 +63,8 @@
 
     private static final String TAG = "RecentsView";
 
+    private static final boolean ADD_HEADER_BITMAP = true;
+
     /** The RecentsView callbacks */
     public interface RecentsViewCallbacks {
         public void onTaskViewClicked();
@@ -443,62 +448,158 @@
         }
     }
 
-    private void postDrawHeaderThumbnailTransitionRunnable(final TaskView tv, final int offsetX,
-            final int offsetY, final TaskViewTransform transform,
+    private void postDrawHeaderThumbnailTransitionRunnable(final TaskStackView view,
+            final TaskView clickedView, final int offsetX, final int offsetY,
+            final float stackScroll,
             final ActivityOptions.OnAnimationStartedListener animStartedListener) {
         Runnable r = new Runnable() {
             @Override
             public void run() {
-                // Disable any focused state before we draw the header
-                if (tv.isFocusedTask()) {
-                    tv.unsetFocusedTask();
-                }
+                overrideDrawHeaderThumbnailTransition(view, clickedView, offsetX, offsetY,
+                        stackScroll, animStartedListener);
 
-                float scale = tv.getScaleX();
-                int fromHeaderWidth = (int) (tv.mHeaderView.getMeasuredWidth() * scale);
-                int fromHeaderHeight = (int) (tv.mHeaderView.getMeasuredHeight() * scale);
-
-                Bitmap b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
-                        Bitmap.Config.ARGB_8888);
-                if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) {
-                    b.eraseColor(0xFFff0000);
-                } else {
-                    Canvas c = new Canvas(b);
-                    c.scale(tv.getScaleX(), tv.getScaleY());
-                    tv.mHeaderView.draw(c);
-                    c.setBitmap(null);
-                }
-                b = b.createAshmemBitmap();
-                int[] pts = new int[2];
-                tv.getLocationOnScreen(pts);
-                try {
-                    WindowManagerGlobal.getWindowManagerService()
-                            .overridePendingAppTransitionAspectScaledThumb(b,
-                                    pts[0] + offsetX,
-                                    pts[1] + offsetY,
-                                    transform.rect.width(),
-                                    transform.rect.height(),
-                                    new IRemoteCallback.Stub() {
-                                        @Override
-                                        public void sendResult(Bundle data)
-                                                throws RemoteException {
-                                            post(new Runnable() {
-                                                @Override
-                                                public void run() {
-                                                    if (animStartedListener != null) {
-                                                        animStartedListener.onAnimationStarted();
-                                                    }
-                                                }
-                                            });
-                                        }
-                                    }, true);
-                } catch (RemoteException e) {
-                    Log.w(TAG, "Error overriding app transition", e);
-                }
             }
         };
+
         mCb.runAfterPause(r);
     }
+
+    private void overrideDrawHeaderThumbnailTransition(TaskStackView stackView,
+            TaskView clickedTask, int offsetX, int offsetY, float stackScroll,
+            final ActivityOptions.OnAnimationStartedListener animStartedListener) {
+        List<AppTransitionAnimationSpec> specs = getAppTransitionAnimationSpecs(stackView,
+                clickedTask, offsetX, offsetY, stackScroll);
+        if (specs == null) {
+            return;
+        }
+
+        IRemoteCallback.Stub callback = new IRemoteCallback.Stub() {
+            @Override
+            public void sendResult(Bundle data) throws RemoteException {
+                post(new Runnable() {
+                    @Override
+                    public void run() {
+                        if (animStartedListener != null) {
+                            animStartedListener.onAnimationStarted();
+                        }
+                    }
+                });
+            }
+        };
+
+        AppTransitionAnimationSpec[] specsArray =
+                new AppTransitionAnimationSpec[specs.size()];
+        try {
+            WindowManagerGlobal.getWindowManagerService().overridePendingAppTransitionMultiThumb(
+                    specs.toArray(specsArray), callback, true /* scaleUp */);
+
+        } catch (RemoteException e) {
+            Log.w(TAG, "Error overriding app transition", e);
+        }
+    }
+
+    private List<AppTransitionAnimationSpec> getAppTransitionAnimationSpecs(TaskStackView stackView,
+            TaskView clickedTask, int offsetX, int offsetY, float stackScroll) {
+        final int targetStackId = clickedTask.getTask().key.stackId;
+        if (targetStackId != ActivityManager.FREEFORM_WORKSPACE_STACK_ID
+                && targetStackId != ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID) {
+            return null;
+        }
+        // If this is a full screen stack, the transition will be towards the single, full screen
+        // task. We only need the transition spec for this task.
+        List<AppTransitionAnimationSpec> specs = new ArrayList<>();
+        if (targetStackId == ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID) {
+            specs.add(createThumbnailHeaderAnimationSpec(
+                    stackView, offsetX, offsetY, stackScroll, clickedTask,
+                    clickedTask.getTask().key.id, ADD_HEADER_BITMAP));
+            return specs;
+        }
+        // This is a free form stack or full screen stack, so there will be multiple windows
+        // animating from thumbnails. We need transition animation specs for all of them.
+
+        // We will use top and bottom task views as a base for tasks, that aren't visible on the
+        // screen. This is necessary for cascade recents list, where some of the tasks might be
+        // hidden.
+        List<TaskView> taskViews = stackView.getTaskViews();
+        int childCount = taskViews.size();
+        TaskView topChild = taskViews.get(0);
+        TaskView bottomChild = taskViews.get(childCount - 1);
+        SparseArray<TaskView> taskViewsByTaskId = new SparseArray<>();
+        for (int i = 0; i < childCount; i++) {
+            TaskView taskView = taskViews.get(i);
+            taskViewsByTaskId.put(taskView.getTask().key.id, taskView);
+        }
+
+        TaskStack stack = stackView.getStack();
+        // We go through all tasks now and for each generate transition animation spec. If there is
+        // a view associated with a task, we use that view as a base for the animation. If there
+        // isn't, we use bottom or top view, depending on which one would be closer to the task
+        // view if it existed.
+        ArrayList<Task> tasks = stack.getTasks();
+        boolean passedClickedTask = false;
+        for (int i = 0, n = tasks.size(); i < n; i++) {
+            Task task = tasks.get(i);
+            TaskView taskView = taskViewsByTaskId.get(task.key.id);
+            if (taskView != null) {
+                specs.add(createThumbnailHeaderAnimationSpec(stackView, offsetX, offsetY,
+                        stackScroll, taskView, taskView.getTask().key.id, ADD_HEADER_BITMAP));
+                if (taskView == clickedTask) {
+                    passedClickedTask = true;
+                }
+            } else {
+                taskView = passedClickedTask ? bottomChild : topChild;
+                specs.add(createThumbnailHeaderAnimationSpec(stackView, offsetX, offsetY,
+                        stackScroll, taskView, task.key.id, !ADD_HEADER_BITMAP));
+            }
+        }
+
+        return specs;
+    }
+
+    private AppTransitionAnimationSpec createThumbnailHeaderAnimationSpec(TaskStackView stackView,
+            int offsetX, int offsetY, float stackScroll, TaskView tv, int taskId,
+            boolean addHeaderBitmap) {
+        // Disable any focused state before we draw the header
+        // Upfront the processing of the thumbnail
+        if (tv.isFocusedTask()) {
+            tv.unsetFocusedTask();
+        }
+        TaskViewTransform transform = new TaskViewTransform();
+        transform = stackView.getStackAlgorithm().getStackTransform(tv.mTask, stackScroll,
+                transform, null);
+
+        float scale = tv.getScaleX();
+        int fromHeaderWidth = (int) (tv.mHeaderView.getMeasuredWidth() * scale);
+        int fromHeaderHeight = (int) (tv.mHeaderView.getMeasuredHeight() * scale);
+
+        Bitmap b = null;
+        if (addHeaderBitmap) {
+            b = Bitmap.createBitmap(fromHeaderWidth, fromHeaderHeight,
+                    Bitmap.Config.ARGB_8888);
+
+            if (Constants.DebugFlags.App.EnableTransitionThumbnailDebugMode) {
+                b.eraseColor(0xFFff0000);
+            } else {
+                Canvas c = new Canvas(b);
+                c.scale(tv.getScaleX(), tv.getScaleY());
+                tv.mHeaderView.draw(c);
+                c.setBitmap(null);
+
+            }
+            b = b.createAshmemBitmap();
+        }
+
+        int[] pts = new int[2];
+        tv.getLocationOnScreen(pts);
+
+        final int left = pts[0] + offsetX;
+        final int top = pts[1] + offsetY;
+        final Rect rect = new Rect(left, top, left + transform.rect.width(),
+                top + transform.rect.height());
+
+        return new AppTransitionAnimationSpec(taskId, b, rect);
+    }
+
     /**** TaskStackView.TaskStackCallbacks Implementation ****/
 
     @Override
@@ -521,12 +622,10 @@
             // and then offset to the expected transform rect, but bound this to just
             // outside the display rect (to ensure we don't animate from too far away)
             sourceView = stackView;
-            transform = stackView.getStackAlgorithm().getStackTransform(task, stackScroll, transform, null);
             offsetX = transform.rect.left;
             offsetY = mConfig.displayRect.height();
         } else {
             sourceView = tv.mThumbnailView;
-            transform = stackView.getStackAlgorithm().getStackTransform(task, stackScroll, transform, null);
         }
 
         // Compute the thumbnail to scale up from
@@ -553,10 +652,8 @@
                     }
                 };
             }
-            if (tv != null) {
-                postDrawHeaderThumbnailTransitionRunnable(tv, offsetX, offsetY, transform,
-                        animStartedListener);
-            }
+            postDrawHeaderThumbnailTransitionRunnable(stackView, tv, offsetX, offsetY, stackScroll,
+                    animStartedListener);
             if (mConfig.multiStackEnabled) {
                 opts = ActivityOptions.makeCustomAnimation(sourceView.getContext(),
                         R.anim.recents_from_unknown_enter,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index a55256d..3a96626 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -135,6 +135,7 @@
     protected static final int MSG_CANCEL_PRELOAD_RECENT_APPS = 1023;
     protected static final int MSG_SHOW_NEXT_AFFILIATED_TASK = 1024;
     protected static final int MSG_SHOW_PREV_AFFILIATED_TASK = 1025;
+    protected static final int MSG_SHOW_KEYBOARD_SHORTCUTS_MENU = 1026;
 
     protected static final boolean ENABLE_HEADS_UP = true;
     // scores above this threshold should be displayed in heads up mode.
@@ -1066,6 +1067,13 @@
         mHandler.sendEmptyMessage(msg);
     }
 
+    @Override
+    public void showKeyboardShortcutsMenu() {
+        int msg = MSG_SHOW_KEYBOARD_SHORTCUTS_MENU;
+        mHandler.removeMessages(msg);
+        mHandler.sendEmptyMessage(msg);
+    }
+
     /** Jumps to the next affiliated task in the group. */
     public void showNextAffiliatedTask() {
         int msg = MSG_SHOW_NEXT_AFFILIATED_TASK;
@@ -1143,6 +1151,10 @@
         }
     }
 
+    protected void showKeyboardShortcuts() {
+        Toast.makeText(mContext, "Show keyboard shortcuts screen", Toast.LENGTH_LONG).show();
+    }
+
     protected void cancelPreloadingRecents() {
         if (mRecents != null) {
             mRecents.cancelPreloadingRecents();
@@ -1253,6 +1265,9 @@
              case MSG_SHOW_PREV_AFFILIATED_TASK:
                   showRecentsPreviousAffiliatedTask();
                   break;
+             case MSG_SHOW_KEYBOARD_SHORTCUTS_MENU:
+                  showKeyboardShortcuts();
+                  break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index a1b07b5..d0cd6cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -64,6 +64,7 @@
     private static final int MSG_APP_TRANSITION_STARTING    = 21 << MSG_SHIFT;
     private static final int MSG_ASSIST_DISCLOSURE          = 22 << MSG_SHIFT;
     private static final int MSG_START_ASSIST               = 23 << MSG_SHIFT;
+    private static final int MSG_SHOW_KEYBOARD_SHORTCUTS    = 24 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -98,6 +99,7 @@
         public void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHomeKey);
         public void toggleRecentApps();
         public void preloadRecentApps();
+        public void showKeyboardShortcutsMenu();
         public void cancelPreloadRecentApps();
         public void setWindowState(int window, int state);
         public void buzzBeepBlinked();
@@ -224,6 +226,14 @@
         }
     }
 
+    @Override
+    public void showKeyboardShortcutsMenu() {
+        synchronized (mList) {
+            mHandler.removeMessages(MSG_SHOW_KEYBOARD_SHORTCUTS);
+            mHandler.obtainMessage(MSG_SHOW_KEYBOARD_SHORTCUTS).sendToTarget();
+        }
+    }
+
     public void setWindowState(int window, int state) {
         synchronized (mList) {
             // don't coalesce these
@@ -360,6 +370,9 @@
                 case MSG_CANCEL_PRELOAD_RECENT_APPS:
                     mCallbacks.cancelPreloadRecentApps();
                     break;
+                case MSG_SHOW_KEYBOARD_SHORTCUTS:
+                    mCallbacks.showKeyboardShortcutsMenu();
+                    break;
                 case MSG_SET_WINDOW_STATE:
                     mCallbacks.setWindowState(msg.arg1, msg.arg2);
                     break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index 4d3e57e..3ff69c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -104,13 +104,11 @@
      * Aborts pulsing immediately.
      */
     public void abortPulsing() {
-        mHandler.removeCallbacks(mPulseIn);
-        abortAnimations();
+        cancelPulsing();
         if (mDozing) {
             mScrimController.setDozeBehindAlpha(1f);
             mScrimController.setDozeInFrontAlpha(1f);
         }
-        mPulseCallback = null;
     }
 
     public void onScreenTurnedOn() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
index d74c5b0..cb5c125 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarApps.java
@@ -20,7 +20,6 @@
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
-import android.app.AppGlobals;
 import android.content.BroadcastReceiver;
 import android.content.ClipData;
 import android.content.ClipDescription;
@@ -29,13 +28,10 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.ActivityInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.graphics.Rect;
 import android.os.Bundle;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.AttributeSet;
@@ -49,6 +45,7 @@
 import android.widget.LinearLayout;
 import android.widget.Toast;
 
+import com.android.internal.content.PackageMonitor;
 import com.android.systemui.R;
 
 import java.util.List;
@@ -75,6 +72,8 @@
     private final PackageManager mPackageManager;
     private final UserManager mUserManager;
     private final LayoutInflater mLayoutInflater;
+    private final AppPackageMonitor mAppPackageMonitor;
+
 
     // This view has two roles:
     // 1) If the drag started outside the pinned apps list, it is a placeholder icon with a null
@@ -106,6 +105,7 @@
         mPackageManager = context.getPackageManager();
         mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
         mLayoutInflater = LayoutInflater.from(context);
+        mAppPackageMonitor = new AppPackageMonitor();
 
         // Dragging an icon removes and adds back the dragged icon. Use the layout transitions to
         // trigger animation. By default all transitions animate, so turn off the unneeded ones.
@@ -121,6 +121,76 @@
         setLayoutTransition(transition);
     }
 
+    // Monitor that catches events like "app uninstalled".
+    private class AppPackageMonitor extends PackageMonitor {
+        @Override
+        public void onPackageRemoved(String packageName, int uid) {
+            postRemoveIfUnlauncheable(packageName, new UserHandle(getChangingUserId()));
+            super.onPackageRemoved(packageName, uid);
+        }
+
+        @Override
+        public void onPackageModified(String packageName) {
+            postRemoveIfUnlauncheable(packageName, new UserHandle(getChangingUserId()));
+            super.onPackageModified(packageName);
+        }
+
+        @Override
+        public void onPackagesAvailable(String[] packages) {
+            if (isReplacing()) {
+                UserHandle user = new UserHandle(getChangingUserId());
+
+                for (String packageName : packages) {
+                    postRemoveIfUnlauncheable(packageName, user);
+                }
+            }
+            super.onPackagesAvailable(packages);
+        }
+
+        @Override
+        public void onPackagesUnavailable(String[] packages) {
+            if (!isReplacing()) {
+                UserHandle user = new UserHandle(getChangingUserId());
+
+                for (String packageName : packages) {
+                    postRemoveIfUnlauncheable(packageName, user);
+                }
+            }
+            super.onPackagesUnavailable(packages);
+        }
+    }
+
+    private void postRemoveIfUnlauncheable(final String packageName, final UserHandle user) {
+        // This method doesn't necessarily get called in the main thread. Redirect the call into
+        // the main thread.
+        post(new Runnable() {
+            @Override
+            public void run() {
+                if (!isAttachedToWindow()) return;
+                removeIfUnlauncheable(packageName, user);
+            }
+        });
+    }
+
+    private void removeIfUnlauncheable(String packageName, UserHandle user) {
+        long appUserSerialNumber = mUserManager.getSerialNumberForUser(user);
+
+        // Remove icons for all apps that match a package that perhaps became unlauncheable.
+        for(int i = sAppsModel.getAppCount() - 1; i >= 0; --i) {
+            AppInfo appInfo = sAppsModel.getApp(i);
+            if (appInfo.getUserSerialNumber() != appUserSerialNumber) continue;
+
+            ComponentName appComponentName = appInfo.getComponentName();
+            if (!appComponentName.getPackageName().equals(packageName)) continue;
+
+            if (sAppsModel.buildAppLaunchIntent(appComponentName, user) != null) continue;
+
+            removeViewAt(i);
+            sAppsModel.removeApp(i);
+            sAppsModel.savePrefs();
+        }
+    }
+
     @Override
     protected void onAttachedToWindow() {
       super.onAttachedToWindow();
@@ -145,12 +215,15 @@
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_SWITCHED);
         mContext.registerReceiver(mBroadcastReceiver, filter);
+
+        mAppPackageMonitor.register(mContext, null, UserHandle.ALL, true);
     }
 
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
         mContext.unregisterReceiver(mBroadcastReceiver);
+        mAppPackageMonitor.unregister();
     }
 
     /**
@@ -470,7 +543,6 @@
             ComponentName component = appInfo.getComponentName();
 
             long appUserSerialNumber = appInfo.getUserSerialNumber();
-
             UserHandle appUser = mUserManager.getUserForSerialNumber(appUserSerialNumber);
             if (appUser == null) {
                 Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
@@ -478,7 +550,12 @@
                         " because its user doesn't exist.");
                 return;
             }
-            int appUserId = appUser.getIdentifier();
+
+            Intent launchIntent = sAppsModel.buildAppLaunchIntent(component, appUser);
+            if (launchIntent == null) {
+                Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+                return;
+            }
 
             // Play a scale-up animation while launching the activity.
             // TODO: Consider playing a different animation, or no animation, if the activity is
@@ -489,54 +566,9 @@
             ActivityOptions opts =
                     ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getWidth(), v.getHeight());
             Bundle optsBundle = opts.toBundle();
-
-            // Launch the activity. This code is based on LauncherAppsService.startActivityAsUser code.
-            Intent launchIntent = new Intent(Intent.ACTION_MAIN);
-            launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
             launchIntent.setSourceBounds(sourceBounds);
-            launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            launchIntent.setPackage(component.getPackageName());
 
-            IPackageManager pm = AppGlobals.getPackageManager();
-            try {
-                ActivityInfo info = pm.getActivityInfo(component, 0, appUserId);
-                if (info == null) {
-                    Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
-                    Log.e(TAG, "Can't start activity " + component + " because it's not installed.");
-                    return;
-                }
-
-                if (!info.exported) {
-                    Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
-                    Log.e(TAG, "Can't start activity " + component + " because it doesn't have 'exported' attribute.");
-                    return;
-                }
-            } catch (RemoteException e) {
-                Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
-                Log.e(TAG, "Failed to get activity info for " + component, e);
-                return;
-            }
-
-            // Check that the component actually has Intent.CATEGORY_LAUCNCHER
-            // as calling startActivityAsUser ignores the category and just
-            // resolves based on the component if present.
-            List<ResolveInfo> apps = getContext().getPackageManager().queryIntentActivitiesAsUser(launchIntent,
-                    0 /* flags */, appUserId);
-            final int size = apps.size();
-            for (int i = 0; i < size; ++i) {
-                ActivityInfo activityInfo = apps.get(i).activityInfo;
-                if (activityInfo.packageName.equals(component.getPackageName()) &&
-                        activityInfo.name.equals(component.getClassName())) {
-                    // Found an activity with category launcher that matches
-                    // this component so ok to launch.
-                    launchIntent.setComponent(component);
-                    mContext.startActivityAsUser(launchIntent, optsBundle, appUser);
-                    return;
-                }
-            }
-
-            Toast.makeText(getContext(), R.string.activity_not_found, Toast.LENGTH_SHORT).show();
-            Log.e(TAG, "Attempt to launch activity without category Intent.CATEGORY_LAUNCHER " + component);
+            mContext.startActivityAsUser(launchIntent, optsBundle, appUser);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
index b8764cf..c4c31fd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarAppsModel.java
@@ -16,16 +16,23 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.app.AppGlobals;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.content.pm.ActivityInfo;
+import android.content.pm.IPackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.Log;
 import android.util.Slog;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -94,6 +101,58 @@
         }
     }
 
+    @VisibleForTesting
+    protected IPackageManager getPackageManager() {
+        return AppGlobals.getPackageManager();
+    }
+
+    // Returns a launch intent for a given component, or null if the component is unlauncheable.
+    public Intent buildAppLaunchIntent(ComponentName component, UserHandle appUser) {
+        int appUserId = appUser.getIdentifier();
+
+        // This code is based on LauncherAppsService.startActivityAsUser code.
+        Intent launchIntent = new Intent(Intent.ACTION_MAIN);
+        launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        launchIntent.setPackage(component.getPackageName());
+
+        try {
+            ActivityInfo info = getPackageManager().getActivityInfo(component, 0, appUserId);
+            if (info == null) {
+                Log.e(TAG, "Activity " + component + " is not installed.");
+                return null;
+            }
+
+            if (!info.exported) {
+                Log.e(TAG, "Activity " + component + " doesn't have 'exported' attribute.");
+                return null;
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to get activity info for " + component, e);
+            return null;
+        }
+
+        // Check that the component actually has Intent.CATEGORY_LAUNCHER
+        // as calling startActivityAsUser ignores the category and just
+        // resolves based on the component if present.
+        List<ResolveInfo> apps = mContext.getPackageManager().queryIntentActivitiesAsUser(launchIntent,
+                0 /* flags */, appUserId);
+        final int size = apps.size();
+        for (int i = 0; i < size; ++i) {
+            ActivityInfo activityInfo = apps.get(i).activityInfo;
+            if (activityInfo.packageName.equals(component.getPackageName()) &&
+                    activityInfo.name.equals(component.getClassName())) {
+                // Found an activity with category launcher that matches
+                // this component so ok to launch.
+                launchIntent.setComponent(component);
+                return launchIntent;
+            }
+        }
+
+        Log.e(TAG, "Activity doesn't have category Intent.CATEGORY_LAUNCHER " + component);
+        return null;
+    }
+
     /**
      * Reinitializes the model for a new user.
      */
@@ -199,6 +258,10 @@
 
     /** Loads the list of apps from SharedPreferences. */
     private void loadAppsFromPrefs() {
+        UserManager mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
+        boolean hadUnlauncheableApps = false;
+
         int appCount = mPrefs.getInt(userPrefixed(APP_COUNT_PREF), -1);
         for (int i = 0; i < appCount; i++) {
             String prefValue = mPrefs.getString(prefNameForApp(i), null);
@@ -214,8 +277,15 @@
                 // Couldn't find the saved state. Just skip this item.
                 continue;
             }
-            mApps.add(new AppInfo(componentName, userSerialNumber));
+            UserHandle appUser = mUserManager.getUserForSerialNumber(userSerialNumber);
+            if (appUser != null && buildAppLaunchIntent(componentName, appUser) != null) {
+                mApps.add(new AppInfo(componentName, userSerialNumber));
+            } else {
+                hadUnlauncheableApps = true;
+            }
         }
+
+        if (hadUnlauncheableApps) savePrefs();
     }
 
     /** Adds the first few apps from the owner profile. Used for demo purposes. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 1649acb..7de7a7b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -91,7 +91,8 @@
 
     private OnVerticalChangedListener mOnVerticalChangedListener;
     private boolean mIsLayoutRtl;
-    private boolean mLayoutTransitionsEnabled;
+    private boolean mLayoutTransitionsEnabled = true;
+    private boolean mWakeAndUnlocking;
 
     private class NavTransitionListener implements TransitionListener {
         private boolean mBackTransitioning;
@@ -371,13 +372,19 @@
         }
     }
 
-    public void setWakeAndUnlocking(boolean wakeAndUnlocking) {
-        setUseFadingAnimations(wakeAndUnlocking);
-        setLayoutTransitionsEnabled(!wakeAndUnlocking);
+    public void setLayoutTransitionsEnabled(boolean enabled) {
+        mLayoutTransitionsEnabled = enabled;
+        updateLayoutTransitionsEnabled();
     }
 
-    private void setLayoutTransitionsEnabled(boolean enabled) {
-        mLayoutTransitionsEnabled = enabled;
+    public void setWakeAndUnlocking(boolean wakeAndUnlocking) {
+        setUseFadingAnimations(wakeAndUnlocking);
+        mWakeAndUnlocking = wakeAndUnlocking;
+        updateLayoutTransitionsEnabled();
+    }
+
+    private void updateLayoutTransitionsEnabled() {
+        boolean enabled = !mWakeAndUnlocking && mLayoutTransitionsEnabled;
         ViewGroup navButtons = (ViewGroup) mCurrentView.findViewById(R.id.nav_buttons);
         LayoutTransition lt = navButtons.getLayoutTransition();
         if (lt != null) {
@@ -469,7 +476,7 @@
         }
         mCurrentView = mRotatedViews[rot];
         mCurrentView.setVisibility(View.VISIBLE);
-        setLayoutTransitionsEnabled(mLayoutTransitionsEnabled);
+        updateLayoutTransitionsEnabled();
 
         getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 710c335..3c3c325 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2388,4 +2388,9 @@
     protected boolean isPanelVisibleBecauseOfHeadsUp() {
         return mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway;
     }
+
+    @Override
+    public boolean hasOverlappingRendering() {
+        return !mDozing;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index b794353..d8f5ccf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -155,6 +155,7 @@
 import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
+import com.android.systemui.statusbar.stack.StackStateAnimator;
 import com.android.systemui.statusbar.stack.StackViewState;
 import com.android.systemui.volume.VolumeComponent;
 
@@ -232,7 +233,7 @@
 
     public static final int FADE_KEYGUARD_START_DELAY = 100;
     public static final int FADE_KEYGUARD_DURATION = 300;
-    public static final int FADE_KEYGUARD_DURATION_PULSING = 120;
+    public static final int FADE_KEYGUARD_DURATION_PULSING = 96;
 
     /** Allow some time inbetween the long press for back and recents. */
     private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
@@ -3477,16 +3478,7 @@
                 .alpha(0f)
                 .setStartDelay(0)
                 .setDuration(FADE_KEYGUARD_DURATION_PULSING)
-                .setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR)
-                .withLayer()
-                .withEndAction(new Runnable() {
-                    @Override
-                    public void run() {
-                        mNotificationPanel.setAlpha(1f);
-                        hideKeyguard();
-                    }
-                })
-                .start();
+                .setInterpolator(ScrimController.KEYGUARD_FADE_OUT_INTERPOLATOR);
     }
 
     /**
@@ -3523,11 +3515,24 @@
         setBarState(StatusBarState.SHADE);
         if (mLeaveOpenOnKeyguardHide) {
             mLeaveOpenOnKeyguardHide = false;
-            mNotificationPanel.animateToFullShade(calculateGoingToFullShadeDelay());
+            long delay = calculateGoingToFullShadeDelay();
+            mNotificationPanel.animateToFullShade(delay);
             if (mDraggedDownRow != null) {
                 mDraggedDownRow.setUserLocked(false);
                 mDraggedDownRow = null;
             }
+
+            // Disable layout transitions in navbar for this transition because the load is just
+            // too heavy for the CPU and GPU on any device.
+            if (mNavigationBarView != null) {
+                mNavigationBarView.setLayoutTransitionsEnabled(false);
+                mNavigationBarView.postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        mNavigationBarView.setLayoutTransitionsEnabled(true);
+                    }
+                }, delay + StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE);
+            }
         } else {
             instantCollapseNotificationPanel();
         }
@@ -3539,6 +3544,7 @@
             mQSPanel.refreshAllTiles();
         }
         mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
+        mNotificationPanel.setAlpha(1f);
         return staying;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 448f16d..7e83f26 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -279,10 +279,15 @@
             if (mFingerprintUnlockController.getMode()
                     == FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING) {
                 mFingerprintUnlockController.startKeyguardFadingAway();
-                mPhoneStatusBar.setKeyguardFadingAway(startTime, 0, 250);
+                mPhoneStatusBar.setKeyguardFadingAway(startTime, 0, 240);
                 mStatusBarWindowManager.setKeyguardFadingAway(true);
                 mPhoneStatusBar.fadeKeyguardWhilePulsing();
-                animateScrimControllerKeyguardFadingOut(0, 250);
+                animateScrimControllerKeyguardFadingOut(0, 240, new Runnable() {
+                    @Override
+                    public void run() {
+                        mPhoneStatusBar.hideKeyguard();
+                    }
+                });
             } else {
                 mFingerprintUnlockController.startKeyguardFadingAway();
                 mPhoneStatusBar.setKeyguardFadingAway(startTime, delay, fadeoutDuration);
@@ -316,10 +321,18 @@
     }
 
     private void animateScrimControllerKeyguardFadingOut(long delay, long duration) {
+        animateScrimControllerKeyguardFadingOut(delay, duration, null /* endRunnable */);
+    }
+
+    private void animateScrimControllerKeyguardFadingOut(long delay, long duration,
+            final Runnable endRunnable) {
         Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW, "Fading out", 0);
         mScrimController.animateKeyguardFadingOut(delay, duration, new Runnable() {
             @Override
             public void run() {
+                if (endRunnable != null) {
+                    endRunnable.run();
+                }
                 mStatusBarWindowManager.setKeyguardFadingAway(false);
                 mPhoneStatusBar.finishKeyguardFadingAway();
                 mFingerprintUnlockController.finishKeyguardFadingAway();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 61986ad..896bd62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -23,6 +23,8 @@
 import android.content.IntentFilter;
 import android.content.res.TypedArray;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
@@ -30,22 +32,28 @@
 import android.text.style.CharacterStyle;
 import android.text.style.RelativeSizeSpan;
 import android.util.AttributeSet;
+import android.view.Display;
 import android.widget.TextView;
 
 import com.android.systemui.DemoMode;
 import com.android.systemui.R;
+import com.android.systemui.tuner.TunerService;
+import com.android.systemui.tuner.TunerService.Tunable;
+
+import libcore.icu.LocaleData;
 
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Locale;
 import java.util.TimeZone;
 
-import libcore.icu.LocaleData;
-
 /**
  * Digital clock for the status bar.
  */
-public class Clock extends TextView implements DemoMode {
+public class Clock extends TextView implements DemoMode, Tunable {
+
+    public static final String CLOCK_SECONDS = "clock_seconds";
+
     private boolean mAttached;
     private Calendar mCalendar;
     private String mClockFormatString;
@@ -57,6 +65,8 @@
     private static final int AM_PM_STYLE_GONE    = 2;
 
     private final int mAmPmStyle;
+    private boolean mShowSeconds;
+    private Handler mSecondsHandler;
 
     public Clock(Context context) {
         this(context, null);
@@ -77,6 +87,7 @@
         } finally {
             a.recycle();
         }
+        TunerService.get(context).addTunable(this, CLOCK_SECONDS);
     }
 
     @Override
@@ -105,6 +116,7 @@
 
         // Make sure we update to the current time
         updateClock();
+        updateShowSeconds();
     }
 
     @Override
@@ -143,6 +155,35 @@
         setText(getSmallTime());
     }
 
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        mShowSeconds = newValue != null && Integer.parseInt(newValue) != 0;
+        updateShowSeconds();
+    }
+
+    private void updateShowSeconds() {
+        if (mShowSeconds) {
+            // Wait until we have a display to start trying to show seconds.
+            if (mSecondsHandler == null && getDisplay() != null) {
+                mSecondsHandler = new Handler();
+                if (getDisplay().getState() == Display.STATE_ON) {
+                    mSecondsHandler.postAtTime(mSecondTick,
+                            SystemClock.uptimeMillis() / 1000 * 1000 + 1000);
+                }
+                IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
+                filter.addAction(Intent.ACTION_SCREEN_ON);
+                mContext.registerReceiver(mScreenReceiver, filter);
+            }
+        } else {
+            if (mSecondsHandler != null) {
+                mContext.unregisterReceiver(mScreenReceiver);
+                mSecondsHandler.removeCallbacks(mSecondTick);
+                mSecondsHandler = null;
+                updateClock();
+            }
+        }
+    }
+
     private final CharSequence getSmallTime() {
         Context context = getContext();
         boolean is24 = DateFormat.is24HourFormat(context, ActivityManager.getCurrentUser());
@@ -152,7 +193,9 @@
         final char MAGIC2 = '\uEF01';
 
         SimpleDateFormat sdf;
-        String format = is24 ? d.timeFormat_Hm : d.timeFormat_hm;
+        String format = mShowSeconds
+                ? is24 ? d.timeFormat_Hms : d.timeFormat_hms
+                : is24 ? d.timeFormat_Hm : d.timeFormat_hm;
         if (!format.equals(mClockFormatString)) {
             /*
              * Search for an unquoted "a" in the format string, so we can
@@ -244,5 +287,32 @@
             setText(getSmallTime());
         }
     }
+
+    private final BroadcastReceiver mScreenReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+                if (mSecondsHandler != null) {
+                    mSecondsHandler.removeCallbacks(mSecondTick);
+                }
+            } else if (Intent.ACTION_SCREEN_ON.equals(action)) {
+                if (mSecondsHandler != null) {
+                    mSecondsHandler.postAtTime(mSecondTick,
+                            SystemClock.uptimeMillis() / 1000 * 1000 + 1000);
+                }
+            }
+        }
+    };
+
+    private final Runnable mSecondTick = new Runnable() {
+        @Override
+        public void run() {
+            if (mCalendar != null) {
+                updateClock();
+            }
+            mSecondsHandler.postAtTime(this, SystemClock.uptimeMillis() / 1000 * 1000 + 1000);
+        }
+    };
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
index e5b550e..dcb0d8d 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/StatusBarSwitch.java
@@ -38,6 +38,18 @@
     }
 
     @Override
+    protected void onAttachedToActivity() {
+        super.onAttachedToActivity();
+        TunerService.get(getContext()).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+    }
+
+    @Override
+    protected void onDetachedFromActivity() {
+        TunerService.get(getContext()).removeTunable(this);
+        super.onDetachedFromActivity();
+    }
+
+    @Override
     public void onTuningChanged(String key, String newValue) {
         if (!StatusBarIconController.ICON_BLACKLIST.equals(key)) {
             return;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 71b5de5..96ad756 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -15,8 +15,6 @@
  */
 package com.android.systemui.tuner;
 
-import static com.android.systemui.BatteryMeterView.SHOW_PERCENT_SETTING;
-
 import android.app.AlertDialog;
 import android.app.FragmentTransaction;
 import android.content.DialogInterface;
@@ -29,7 +27,6 @@
 import android.preference.Preference.OnPreferenceChangeListener;
 import android.preference.Preference.OnPreferenceClickListener;
 import android.preference.PreferenceFragment;
-import android.preference.PreferenceGroup;
 import android.preference.SwitchPreference;
 import android.provider.Settings;
 import android.provider.Settings.System;
@@ -39,8 +36,8 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.systemui.R;
-import com.android.systemui.statusbar.phone.StatusBarIconController;
-import com.android.systemui.tuner.TunerService.Tunable;
+
+import static com.android.systemui.BatteryMeterView.SHOW_PERCENT_SETTING;
 
 public class TunerFragment extends PreferenceFragment {
 
@@ -108,7 +105,6 @@
         getContext().getContentResolver().registerContentObserver(
                 System.getUriFor(SHOW_PERCENT_SETTING), false, mSettingObserver);
 
-        registerPrefs(getPreferenceScreen());
         MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, true);
     }
 
@@ -117,36 +113,9 @@
         super.onPause();
         getContext().getContentResolver().unregisterContentObserver(mSettingObserver);
 
-        unregisterPrefs(getPreferenceScreen());
         MetricsLogger.visibility(getContext(), MetricsLogger.TUNER, false);
     }
 
-    private void registerPrefs(PreferenceGroup group) {
-        TunerService tunerService = TunerService.get(getContext());
-        final int N = group.getPreferenceCount();
-        for (int i = 0; i < N; i++) {
-            Preference pref = group.getPreference(i);
-            if (pref instanceof StatusBarSwitch) {
-                tunerService.addTunable((Tunable) pref, StatusBarIconController.ICON_BLACKLIST);
-            } else if (pref instanceof PreferenceGroup) {
-                registerPrefs((PreferenceGroup) pref);
-            }
-        }
-    }
-
-    private void unregisterPrefs(PreferenceGroup group) {
-        TunerService tunerService = TunerService.get(getContext());
-        final int N = group.getPreferenceCount();
-        for (int i = 0; i < N; i++) {
-            Preference pref = group.getPreference(i);
-            if (pref instanceof Tunable) {
-                tunerService.removeTunable((Tunable) pref);
-            } else if (pref instanceof PreferenceGroup) {
-                registerPrefs((PreferenceGroup) pref);
-            }
-        }
-    }
-
     @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         menu.add(Menu.NONE, MENU_REMOVE, Menu.NONE, R.string.remove_from_settings);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
new file mode 100644
index 0000000..0740e08
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerSwitch.java
@@ -0,0 +1,39 @@
+package com.android.systemui.tuner;
+
+import android.content.Context;
+import android.preference.SwitchPreference;
+import android.provider.Settings;
+import android.util.AttributeSet;
+
+import com.android.systemui.tuner.TunerService.Tunable;
+
+public class TunerSwitch extends SwitchPreference implements Tunable {
+
+    public TunerSwitch(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onAttachedToActivity() {
+        super.onAttachedToActivity();
+        TunerService.get(getContext()).addTunable(this, getKey());
+    }
+
+    @Override
+    protected void onDetachedFromActivity() {
+        TunerService.get(getContext()).removeTunable(this);
+        super.onDetachedFromActivity();
+    }
+
+    @Override
+    public void onTuningChanged(String key, String newValue) {
+        setChecked(newValue != null && Integer.parseInt(newValue) != 0);
+    }
+
+    @Override
+    protected boolean persistBoolean(boolean value) {
+        Settings.Secure.putString(getContext().getContentResolver(), getKey(), value ? "1" : "0");
+        return true;
+    }
+
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java
index 62213ab..4d0e28b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarAppsModelTest.java
@@ -16,21 +16,26 @@
 
 package com.android.systemui.statusbar.phone;
 
+import org.mockito.InOrder;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
+import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.test.AndroidTestCase;
@@ -45,6 +50,7 @@
 /** Tests for the data model for the navigation bar app icons. */
 public class NavigationBarAppsModelTest extends AndroidTestCase {
     private PackageManager mMockPackageManager;
+    private IPackageManager mMockIPackageManager;
     private SharedPreferences mMockPrefs;
     private SharedPreferences.Editor mMockEdit;
     private UserManager mMockUserManager;
@@ -61,6 +67,7 @@
 
         final Context context = mock(Context.class);
         mMockPackageManager = mock(PackageManager.class);
+        mMockIPackageManager = mock(IPackageManager.class);
         mMockPrefs = mock(SharedPreferences.class);
         mMockEdit = mock(SharedPreferences.Editor.class);
         mMockUserManager = mock(UserManager.class);
@@ -78,8 +85,71 @@
         when(mMockPrefs.edit()).thenReturn(mMockEdit);
 
         when(mMockUserManager.getSerialNumberForUser(new UserHandle(2))).thenReturn(22L);
+        when(mMockUserManager.getUserForSerialNumber(45L)).thenReturn(new UserHandle(4));
+        when(mMockUserManager.getUserForSerialNumber(239L)).thenReturn(new UserHandle(5));
 
-        mModel = new NavigationBarAppsModel(context);
+        mModel = new NavigationBarAppsModel(context) {
+            @Override
+            protected IPackageManager getPackageManager() {
+                return mMockIPackageManager;
+            }
+        };
+    }
+
+    /** Tests buildAppLaunchIntent(). */
+    public void testBuildAppLaunchIntent() {
+        ActivityInfo mockNonExportedActivityInfo = new ActivityInfo();
+        mockNonExportedActivityInfo.exported = false;
+        ActivityInfo mockExportedActivityInfo = new ActivityInfo();
+        mockExportedActivityInfo.exported = true;
+        try {
+            when(mMockIPackageManager.getActivityInfo(
+                    new ComponentName("package1", "class1"), 0, 4)).
+                    thenReturn(mockNonExportedActivityInfo);
+            when(mMockIPackageManager.getActivityInfo(
+                    new ComponentName("package2", "class2"), 0, 5)).
+                    thenThrow(new RemoteException());
+            when(mMockIPackageManager.getActivityInfo(
+                    new ComponentName("package3", "class3"), 0, 6)).
+                    thenReturn(mockExportedActivityInfo);
+            when(mMockIPackageManager.getActivityInfo(
+                    new ComponentName("package4", "class4"), 0, 7)).
+                    thenReturn(mockExportedActivityInfo);
+        } catch (RemoteException e) {
+            fail("RemoteException can't happen in the test, but it happened.");
+        }
+
+        // Assume some installed activities.
+        ActivityInfo ai0 = new ActivityInfo();
+        ai0.packageName = "package0";
+        ai0.name = "class0";
+        ActivityInfo ai1 = new ActivityInfo();
+        ai1.packageName = "package4";
+        ai1.name = "class4";
+        ResolveInfo ri0 = new ResolveInfo();
+        ri0.activityInfo = ai0;
+        ResolveInfo ri1 = new ResolveInfo();
+        ri1.activityInfo = ai1;
+        when(mMockPackageManager
+                .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
+                .thenReturn(Arrays.asList(ri0, ri1));
+
+        // Unlauncheable (for various reasons) apps.
+        assertEquals(null, mModel.buildAppLaunchIntent(
+                new ComponentName("package0", "class0"), new UserHandle(3)));
+        assertEquals(null, mModel.buildAppLaunchIntent(
+                new ComponentName("package1", "class1"), new UserHandle(4)));
+        assertEquals(null, mModel.buildAppLaunchIntent(
+                new ComponentName("package2", "class2"), new UserHandle(5)));
+        assertEquals(null, mModel.buildAppLaunchIntent(
+                new ComponentName("package3", "class3"), new UserHandle(6)));
+
+        // A launcheable app.
+        Intent intent = mModel.buildAppLaunchIntent(
+                new ComponentName("package4", "class4"), new UserHandle(7));
+        assertNotNull(intent);
+        assertEquals(new ComponentName("package4", "class4"), intent.getComponent());
+        assertEquals("package4", intent.getPackage());
     }
 
     /** Initializes the model from SharedPreferences for a few app activites. */
@@ -93,6 +163,39 @@
         when(mMockPrefs.getString("22|app_2", null)).thenReturn("package2/class2");
         when(mMockPrefs.getLong("22|app_user_2", -1)).thenReturn(239L);
 
+        ActivityInfo mockActivityInfo = new ActivityInfo();
+        mockActivityInfo.exported = true;
+        try {
+            when(mMockIPackageManager.getActivityInfo(
+                    new ComponentName("package0", "class0"), 0, 5)).thenReturn(mockActivityInfo);
+            when(mMockIPackageManager.getActivityInfo(
+                    new ComponentName("package1", "class1"), 0, 4)).thenReturn(mockActivityInfo);
+            when(mMockIPackageManager.getActivityInfo(
+                    new ComponentName("package2", "class2"), 0, 5)).thenReturn(mockActivityInfo);
+        } catch (RemoteException e) {
+            fail("RemoteException can't happen in the test, but it happened.");
+        }
+
+        // Assume some installed activities.
+        ActivityInfo ai0 = new ActivityInfo();
+        ai0.packageName = "package0";
+        ai0.name = "class0";
+        ActivityInfo ai1 = new ActivityInfo();
+        ai1.packageName = "package1";
+        ai1.name = "class1";
+        ActivityInfo ai2 = new ActivityInfo();
+        ai2.packageName = "package2";
+        ai2.name = "class2";
+        ResolveInfo ri0 = new ResolveInfo();
+        ri0.activityInfo = ai0;
+        ResolveInfo ri1 = new ResolveInfo();
+        ri1.activityInfo = ai1;
+        ResolveInfo ri2 = new ResolveInfo();
+        ri2.activityInfo = ai2;
+        when(mMockPackageManager
+                .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
+                .thenReturn(Arrays.asList(ri0, ri1, ri2));
+
         mModel.setCurrentUser(2);
     }
 
@@ -133,6 +236,15 @@
         assertEquals(22L, mModel.getApp(0).getUserSerialNumber());
         assertEquals("package2/class2", mModel.getApp(1).getComponentName().flattenToString());
         assertEquals(22L, mModel.getApp(1).getUserSerialNumber());
+        InOrder order = inOrder(mMockEdit);
+        order.verify(mMockEdit).apply();
+        order.verify(mMockEdit).putInt("22|app_count", 2);
+        order.verify(mMockEdit).putString("22|app_0", "package1/class1");
+        order.verify(mMockEdit).putLong("22|app_user_0", 22L);
+        order.verify(mMockEdit).putString("22|app_1", "package2/class2");
+        order.verify(mMockEdit).putLong("22|app_user_1", 22L);
+        order.verify(mMockEdit).apply();
+        verifyNoMoreInteractions(mMockEdit);
     }
 
     /** Tests initializing the model if one of the prefs is missing. */
@@ -145,11 +257,72 @@
         // But assume one pref is missing.
         when(mMockPrefs.getString("22|app_1", null)).thenReturn(null);
 
+        ActivityInfo mockActivityInfo = new ActivityInfo();
+        mockActivityInfo.exported = true;
+        try {
+            when(mMockIPackageManager.getActivityInfo(
+                    new ComponentName("package0", "class0"), 0, 5)).thenReturn(mockActivityInfo);
+        } catch (RemoteException e) {
+            fail("RemoteException can't happen in the test, but it happened.");
+        }
+
+        ActivityInfo ai0 = new ActivityInfo();
+        ai0.packageName = "package0";
+        ai0.name = "class0";
+        ResolveInfo ri0 = new ResolveInfo();
+        ri0.activityInfo = ai0;
+        when(mMockPackageManager
+                .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
+                .thenReturn(Arrays.asList(ri0));
+
         // Initializing the model should load from prefs and skip the missing one.
         mModel.setCurrentUser(2);
         assertEquals(1, mModel.getAppCount());
         assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString());
         assertEquals(239L, mModel.getApp(0).getUserSerialNumber());
+        verifyNoMoreInteractions(mMockEdit);
+    }
+
+    /** Tests initializing the model if one of the apps is unlauncheable. */
+    public void testInitializeWithUnlauncheableApp() {
+        // Assume two apps are nominally stored.
+        when(mMockPrefs.getInt("22|app_count", -1)).thenReturn(2);
+        when(mMockPrefs.getString("22|app_0", null)).thenReturn("package0/class0");
+        when(mMockPrefs.getLong("22|app_user_0", -1)).thenReturn(239L);
+        when(mMockPrefs.getString("22|app_1", null)).thenReturn("package1/class1");
+        when(mMockPrefs.getLong("22|app_user_1", -1)).thenReturn(45L);
+
+        ActivityInfo mockActivityInfo = new ActivityInfo();
+        mockActivityInfo.exported = true;
+        try {
+            when(mMockIPackageManager.getActivityInfo(
+                    new ComponentName("package0", "class0"), 0, 5)).thenReturn(mockActivityInfo);
+        } catch (RemoteException e) {
+            fail("RemoteException can't happen in the test, but it happened.");
+        }
+
+        ActivityInfo ai0 = new ActivityInfo();
+        ai0.packageName = "package0";
+        ai0.name = "class0";
+        ResolveInfo ri0 = new ResolveInfo();
+        ri0.activityInfo = ai0;
+        when(mMockPackageManager
+                .queryIntentActivitiesAsUser(any(Intent.class), eq(0), any(int.class)))
+                .thenReturn(Arrays.asList(ri0));
+
+        // Initializing the model should load from prefs and skip the unlauncheable one.
+        mModel.setCurrentUser(2);
+        assertEquals(1, mModel.getAppCount());
+        assertEquals("package0/class0", mModel.getApp(0).getComponentName().flattenToString());
+        assertEquals(239L, mModel.getApp(0).getUserSerialNumber());
+
+        // Once an unlauncheable app is detected, the model should save all apps excluding the
+        // unlauncheable one.
+        verify(mMockEdit).putInt("22|app_count", 1);
+        verify(mMockEdit).putString("22|app_0", "package0/class0");
+        verify(mMockEdit).putLong("22|app_user_0", 239L);
+        verify(mMockEdit).apply();
+        verifyNoMoreInteractions(mMockEdit);
     }
 
     /** Tests saving the model to SharedPreferences. */
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 34aeb60..f724749 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -401,21 +401,40 @@
         public boolean isSystemRestore;
         public String[] filterSet;
 
-        // Restore a single package
+        /**
+         * Restore a single package; no kill after restore
+         */
         RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
-                long _token, PackageInfo _pkg, int _pmToken) {
+                long _token, PackageInfo _pkg) {
             transport = _transport;
             dirName = _dirName;
             observer = _obs;
             token = _token;
             pkgInfo = _pkg;
-            pmToken = _pmToken;
+            pmToken = 0;
             isSystemRestore = false;
             filterSet = null;
         }
 
-        // Restore everything possible.  This is the form that Setup Wizard or similar
-        // restore UXes use.
+        /**
+         * Restore at install: PM token needed, kill after restore
+         */
+        RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
+                long _token, String _pkgName, int _pmToken) {
+            transport = _transport;
+            dirName = _dirName;
+            observer = _obs;
+            token = _token;
+            pkgInfo = null;
+            pmToken = _pmToken;
+            isSystemRestore = false;
+            filterSet = new String[] { _pkgName };
+        }
+
+        /**
+         * Restore everything possible.  This is the form that Setup Wizard or similar
+         * restore UXes use.
+         */
         RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
                 long _token) {
             transport = _transport;
@@ -428,8 +447,10 @@
             filterSet = null;
         }
 
-        // Restore some set of packages.  Leave this one up to the caller to specify
-        // whether it's to be considered a system-level restore.
+        /**
+         * Restore some set of packages.  Leave this one up to the caller to specify
+         * whether it's to be considered a system-level restore.
+         */
         RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
                 long _token, String[] _filterSet, boolean _isSystemRestore) {
             transport = _transport;
@@ -9137,19 +9158,13 @@
                 // This can throw and so *must* happen before the wakelock is acquired
                 String dirName = transport.transportDirName();
 
-                // We can use a synthetic PackageInfo here because:
-                //   1. We know it's valid, since the Package Manager supplied the name
-                //   2. Only the packageName field will be used by the restore code
-                PackageInfo pkg = new PackageInfo();
-                pkg.packageName = packageName;
-
                 mWakelock.acquire();
                 if (MORE_DEBUG) {
                     Slog.d(TAG, "Restore at install of " + packageName);
                 }
                 Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
                 msg.obj = new RestoreParams(transport, dirName, null,
-                        restoreSet, pkg, token);
+                        restoreSet, packageName, token);
                 mBackupHandler.sendMessage(msg);
             } catch (RemoteException e) {
                 // Binding to the transport broke; back off and proceed with the installation.
@@ -9528,8 +9543,7 @@
                     Slog.d(TAG, "restorePackage() : " + packageName);
                 }
                 Message msg = mBackupHandler.obtainMessage(MSG_RUN_RESTORE);
-                msg.obj = new RestoreParams(mRestoreTransport, dirName,
-                        observer, token, app, 0);
+                msg.obj = new RestoreParams(mRestoreTransport, dirName, observer, token, app);
                 mBackupHandler.sendMessage(msg);
             } finally {
                 Binder.restoreCallingIdentity(oldId);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f3cf08f..c1b0753 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -10906,7 +10906,7 @@
         synchronized (this) {
             buildAssistBundleLocked(pae, pae.result);
             mPendingAssistExtras.remove(pae);
-            mHandler.removeCallbacks(pae);
+            mUiHandler.removeCallbacks(pae);
         }
         return pae.extras;
     }
@@ -10994,7 +10994,7 @@
                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
                         requestType);
                 mPendingAssistExtras.add(pae);
-                mHandler.postDelayed(pae, timeout);
+                mUiHandler.postDelayed(pae, timeout);
             } catch (RemoteException e) {
                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
                 return null;
@@ -11051,7 +11051,7 @@
         synchronized (this) {
             buildAssistBundleLocked(pae, extras);
             boolean exists = mPendingAssistExtras.remove(pae);
-            mHandler.removeCallbacks(pae);
+            mUiHandler.removeCallbacks(pae);
             if (!exists) {
                 // Timed out.
                 return;
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 356565f..fcd596f 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -248,6 +248,8 @@
     /** Run all ActivityStacks through this */
     final ActivityStackSupervisor mStackSupervisor;
 
+    private final LaunchingTaskPositioner mTaskPositioner;
+
     static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
     static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
     static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
@@ -363,6 +365,33 @@
         mStackId = activityContainer.mStackId;
         mCurrentUser = mService.mCurrentUserId;
         mRecentTasks = recentTasks;
+        mTaskPositioner = mStackId == FREEFORM_WORKSPACE_STACK_ID
+                ? new LaunchingTaskPositioner() : null;
+    }
+
+    void attachDisplay(ActivityStackSupervisor.ActivityDisplay activityDisplay, boolean onTop) {
+        mDisplayId = activityDisplay.mDisplayId;
+        mStacks = activityDisplay.mStacks;
+        mBounds = mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId, onTop);
+        mFullscreen = mBounds == null;
+        if (mTaskPositioner != null) {
+            mTaskPositioner.setDisplay(activityDisplay.mDisplay);
+            mTaskPositioner.configure(mBounds);
+        }
+    }
+
+    void detachDisplay() {
+        mDisplayId = Display.INVALID_DISPLAY;
+        mStacks = null;
+        if (mTaskPositioner != null) {
+            mTaskPositioner.reset();
+        }
+        mWindowManager.detachStack(mStackId);
+    }
+
+    void setBounds(Rect bounds) {
+        mBounds = mFullscreen ? null : new Rect(bounds);
+        mTaskPositioner.configure(bounds);
     }
 
     boolean okToShowLocked(ActivityRecord r) {
@@ -2223,7 +2252,7 @@
                                 + task, new RuntimeException("here").fillInStackTrace());
                         task.addActivityToTop(r);
                         r.putInHistory();
-                        addAppToken(r, task);
+                        addConfigOverride(r, task);
                         if (VALIDATE_TOKENS) {
                             validateAppTokensLocked();
                         }
@@ -2283,7 +2312,7 @@
                         : AppTransition.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
                 mNoAnimActivities.remove(r);
             }
-            addAppToken(r, task);
+            addConfigOverride(r, task);
             boolean doShow = true;
             if (newTask) {
                 // Even though this activity is starting fresh, we still need
@@ -2332,7 +2361,7 @@
         } else {
             // If this is the first activity, don't do any fancy animations,
             // because there is nothing for it to animate on top of.
-            addAppToken(r, task);
+            addConfigOverride(r, task);
             ActivityOptions.abort(options);
             options = null;
         }
@@ -4513,6 +4542,9 @@
             boolean toTop) {
         TaskRecord task = new TaskRecord(mService, taskId, info, intent, voiceSession,
                 voiceInteractor);
+        if (mTaskPositioner != null) {
+            mTaskPositioner.updateDefaultBounds(task, mTaskHistory);
+        }
         addTask(task, toTop, false);
         return task;
     }
@@ -4548,7 +4580,7 @@
         }
     }
 
-    void addAppToken(ActivityRecord r, TaskRecord task) {
+    void addConfigOverride(ActivityRecord r, TaskRecord task) {
         final Rect bounds = task.getLaunchBounds();
         final Configuration config =
                 mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 12b848b..0bdeed7 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2977,7 +2977,7 @@
 
             }
         }
-        stack.mBounds = stack.mFullscreen ? null : new Rect(bounds);
+        stack.setBounds(bounds);
 
         if (r != null) {
             final boolean updated = stack.ensureActivityConfigurationLocked(r, 0);
@@ -3112,7 +3112,7 @@
                 "Added restored task=" + task + " to stack=" + stack);
         final ArrayList<ActivityRecord> activities = task.mActivities;
         for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
-            stack.addAppToken(activities.get(activityNdx), task);
+            stack.addConfigOverride(activities.get(activityNdx), task);
         }
         return true;
     }
@@ -4387,13 +4387,8 @@
             if (DEBUG_STACK) Slog.d(TAG_STACK, "attachToDisplayLocked: " + this
                     + " to display=" + activityDisplay + " onTop=" + onTop);
             mActivityDisplay = activityDisplay;
-            mStack.mDisplayId = activityDisplay.mDisplayId;
-            mStack.mStacks = activityDisplay.mStacks;
-
+            mStack.attachDisplay(activityDisplay, onTop);
             activityDisplay.attachActivities(mStack, onTop);
-            mStack.mBounds =
-                    mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId, onTop);
-            mStack.mFullscreen = mStack.mBounds == null;
         }
 
         @Override
@@ -4465,9 +4460,7 @@
             if (mActivityDisplay != null) {
                 mActivityDisplay.detachActivitiesLocked(mStack);
                 mActivityDisplay = null;
-                mStack.mDisplayId = -1;
-                mStack.mStacks = null;
-                mWindowManager.detachStack(mStackId);
+                mStack.detachDisplay();
             }
         }
 
diff --git a/services/core/java/com/android/server/am/LaunchingTaskPositioner.java b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
new file mode 100644
index 0000000..3005c86
--- /dev/null
+++ b/services/core/java/com/android/server/am/LaunchingTaskPositioner.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.view.Display;
+
+import java.util.ArrayList;
+
+/**
+ * Determines where a launching task should be positioned and sized on the display.
+ */
+class LaunchingTaskPositioner {
+    // Determines how close window frames/corners have to be to call them colliding.
+    private static final int BOUNDS_CONFLICT_MIN_DISTANCE = 4;
+
+    // Task will receive dimensions based on available dimensions divided by this.
+    private static final int WINDOW_SIZE_DENOMINATOR = 2;
+
+    // Task will receive margins based on available dimensions divided by this.
+    private static final int MARGIN_SIZE_DENOMINATOR = 4;
+
+    // If task bounds collide with some other, we will step and try again until we find a good
+    // position. The step will be determined by using dimensions and dividing it by this.
+    private static final int STEP_DENOMINATOR = 16;
+
+    // We always want to step by at least this.
+    private static final int MINIMAL_STEP = 1;
+
+    private boolean mDefaultStartBoundsConfigurationSet = false;
+    private final Rect mAvailableRect = new Rect();
+    private int mDefaultFreeformStartX;
+    private int mDefaultFreeformStartY;
+    private int mDefaultFreeformWidth;
+    private int mDefaultFreeformHeight;
+    private int mDefaultFreeformStepHorizontal;
+    private int mDefaultFreeformStepVertical;
+    private int mDisplayWidth;
+    private int mDisplayHeight;
+
+    void setDisplay(Display display) {
+        Point size = new Point();
+        display.getSize(size);
+        mDisplayWidth = size.x;
+        mDisplayHeight = size.y;
+    }
+
+    void configure(Rect stackBounds) {
+        if (stackBounds == null) {
+            mAvailableRect.set(0, 0, mDisplayWidth, mDisplayHeight);
+        } else {
+            mAvailableRect.set(stackBounds);
+        }
+        int width = mAvailableRect.width();
+        int height = mAvailableRect.height();
+        mDefaultFreeformStartX = mAvailableRect.left + width / MARGIN_SIZE_DENOMINATOR;
+        mDefaultFreeformStartY = mAvailableRect.top + height / MARGIN_SIZE_DENOMINATOR;
+        mDefaultFreeformWidth = width / WINDOW_SIZE_DENOMINATOR;
+        mDefaultFreeformHeight = height / WINDOW_SIZE_DENOMINATOR;
+        mDefaultFreeformStepHorizontal = Math.max(width / STEP_DENOMINATOR, MINIMAL_STEP);
+        mDefaultFreeformStepVertical = Math.max(height / STEP_DENOMINATOR, MINIMAL_STEP);
+        mDefaultStartBoundsConfigurationSet = true;
+    }
+
+    /**
+     * Tries to set task's bound in a way that it won't collide with any other task. By colliding
+     * we mean that two tasks have left-top corner very close to each other, so one might get
+     * obfuscated by the other one.
+     *
+     * @param task Task for which we want to find bounds that won't collide with other.
+     * @param tasks Existing tasks with which we don't want to collide.
+     */
+    void updateDefaultBounds(TaskRecord task, ArrayList<TaskRecord> tasks) {
+        if (!mDefaultStartBoundsConfigurationSet) {
+            return;
+        }
+        int startX = mDefaultFreeformStartX;
+        int startY = mDefaultFreeformStartY;
+        final int right = mAvailableRect.right;
+        final int bottom = mAvailableRect.bottom;
+        boolean restarted = false;
+        while (boundsConflict(startX, startY, tasks)) {
+            // Unfortunately there is already a task at that spot, so we need to look for some
+            // other place.
+            startX += mDefaultFreeformStepHorizontal;
+            startY += mDefaultFreeformStepVertical;
+            if (startX + mDefaultFreeformWidth > right
+                    || startY + mDefaultFreeformHeight > bottom) {
+                // We don't want the task to go outside of the display, because it won't look
+                // nice. Let's restart from the top instead, because there should be some space
+                // there.
+                startX = mAvailableRect.left;
+                startY = mAvailableRect.top;
+                restarted = true;
+            }
+            if (restarted
+                    && (startX > mDefaultFreeformStartX || startY > mDefaultFreeformStartY)) {
+                // If we restarted and crossed the initial position, let's not struggle anymore.
+                // The user already must have ton of tasks visible, we can just smack the new
+                // one in the center.
+                startX = mDefaultFreeformStartX;
+                startY = mDefaultFreeformStartY;
+                break;
+            }
+        }
+        task.setInitialBounds(startX, startY, startX + mDefaultFreeformWidth,
+                startY + mDefaultFreeformHeight);
+    }
+
+    private boolean boundsConflict(int startX, int startY, ArrayList<TaskRecord> tasks) {
+        for (int i = tasks.size() - 1; i >= 0; i--) {
+            TaskRecord task = tasks.get(i);
+            if (!task.mActivities.isEmpty()) {
+                Rect bounds = task.mBounds;
+                if (bounds != null && (Math.abs(bounds.left - startX) < BOUNDS_CONFLICT_MIN_DISTANCE
+                        || Math.abs(bounds.top - startY) < BOUNDS_CONFLICT_MIN_DISTANCE)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    void reset() {
+        mDefaultStartBoundsConfigurationSet = false;
+    }
+}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index ed935a1..ff412d1 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1217,6 +1217,14 @@
         return mLastNonFullscreenBounds;
     }
 
+    void setInitialBounds(int left, int top, int right, int bottom) {
+        if (mBounds == null) {
+            mBounds = new Rect();
+        }
+        mBounds.set(left, top, right, bottom);
+        mLastNonFullscreenBounds = mBounds;
+    }
+
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("userId="); pw.print(userId);
                 pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index 40956c1..19d8538 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -67,7 +67,7 @@
     public void addSystemProvider(SystemConditionProviderService service) {
         mSystemConditionProviders.add(service);
         service.attachBase(mContext);
-        registerService(service.asInterface(), service.getComponent(), UserHandle.USER_OWNER);
+        registerService(service.asInterface(), service.getComponent(), UserHandle.USER_SYSTEM);
     }
 
     public Iterable<SystemConditionProviderService> getSystemProviders() {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 4351798..0c884f15 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -716,7 +716,7 @@
                             final IPackageManager pm = AppGlobals.getPackageManager();
                             final int enabled = pm.getApplicationEnabledSetting(pkgName,
                                     changeUserId != UserHandle.USER_ALL ? changeUserId :
-                                    UserHandle.USER_OWNER);
+                                    UserHandle.USER_SYSTEM);
                             if (enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED
                                     || enabled == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
                                 cancelNotifications = false;
@@ -1420,7 +1420,7 @@
                             if (!r.isSeen()) {
                                 if (DBG) Slog.d(TAG, "Marking notification as seen " + keys[i]);
                                 mAppUsageStats.reportEvent(r.sbn.getPackageName(),
-                                        userId == UserHandle.USER_ALL ? UserHandle.USER_OWNER
+                                        userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM
                                                 : userId,
                                         UsageEvents.Event.USER_INTERACTION);
                                 r.setSeen();
@@ -1701,7 +1701,8 @@
         @Override
         public byte[] getBackupPayload(int user) {
             if (DBG) Slog.d(TAG, "getBackupPayload u=" + user);
-            if (user != UserHandle.USER_OWNER) {
+            //TODO: http://b/22388012
+            if (user != UserHandle.USER_SYSTEM) {
                 Slog.w(TAG, "getBackupPayload: cannot backup policy for user " + user);
                 return null;
             }
@@ -1723,7 +1724,8 @@
                 Slog.w(TAG, "applyRestore: no payload to restore for user " + user);
                 return;
             }
-            if (user != UserHandle.USER_OWNER) {
+            //TODO: http://b/22388012
+            if (user != UserHandle.USER_SYSTEM) {
                 Slog.w(TAG, "applyRestore: cannot restore policy for user " + user);
                 return;
             }
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index a089518..66381f5 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -148,7 +148,8 @@
                     if (!TextUtils.isEmpty(name)) {
                         if (forRestore) {
                             try {
-                                uid = pm.getPackageUid(name, UserHandle.USER_OWNER);
+                                //TODO: http://b/22388012
+                                uid = pm.getPackageUid(name, UserHandle.USER_SYSTEM);
                             } catch (NameNotFoundException e) {
                                 // noop
                             }
@@ -213,7 +214,8 @@
         final int N = mRecords.size();
         for (int i = 0; i < N; i++) {
             final Record r = mRecords.valueAt(i);
-            if (forBackup && UserHandle.getUserId(r.uid) != UserHandle.USER_OWNER) {
+            //TODO: http://b/22388012
+            if (forBackup && UserHandle.getUserId(r.uid) != UserHandle.USER_SYSTEM) {
                 continue;
             }
             out.startTag(null, TAG_PACKAGE);
@@ -437,7 +439,8 @@
             final Record r = mRestoredWithoutUids.get(pkg);
             if (r != null) {
                 try {
-                    r.uid = pm.getPackageUid(r.pkg, UserHandle.USER_OWNER);
+                    //TODO: http://b/22388012
+                    r.uid = pm.getPackageUid(r.pkg, UserHandle.USER_SYSTEM);
                     mRestoredWithoutUids.remove(pkg);
                     mRecords.put(recordKey(r.pkg, r.uid), r);
                     updated = true;
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 57d7758..edd274b 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -85,7 +85,7 @@
     private final Metrics mMetrics = new Metrics();
 
     private int mZenMode;
-    private int mUser = UserHandle.USER_OWNER;
+    private int mUser = UserHandle.USER_SYSTEM;
     private ZenModeConfig mConfig;
     private AudioManagerInternal mAudioManager;
     private boolean mEffectsSuppressed;
@@ -99,7 +99,7 @@
         appendDefaultScheduleRules(mDefaultConfig);
         appendDefaultEventRules(mDefaultConfig);
         mConfig = mDefaultConfig;
-        mConfigs.put(UserHandle.USER_OWNER, mConfig);
+        mConfigs.put(UserHandle.USER_SYSTEM, mConfig);
         mSettingsObserver = new SettingsObserver(mHandler);
         mSettingsObserver.observe();
         mFiltering = new ZenModeFiltering(mContext);
@@ -152,7 +152,7 @@
     }
 
     public void onUserSwitched(int user) {
-        if (mUser == user || user < UserHandle.USER_OWNER) return;
+        if (mUser == user || user < UserHandle.USER_SYSTEM) return;
         mUser = user;
         if (DEBUG) Log.d(TAG, "onUserSwitched u=" + user);
         ZenModeConfig config = mConfigs.get(user);
@@ -165,7 +165,7 @@
     }
 
     public void onUserRemoved(int user) {
-        if (user < UserHandle.USER_OWNER) return;
+        if (user < UserHandle.USER_SYSTEM) return;
         if (DEBUG) Log.d(TAG, "onUserRemoved u=" + user);
         mConfigs.remove(user);
     }
@@ -265,7 +265,8 @@
         final ZenModeConfig config = ZenModeConfig.readXml(parser, mConfigMigration);
         if (config != null) {
             if (forRestore) {
-                if (config.user != UserHandle.USER_OWNER) {
+                //TODO: http://b/22388012
+                if (config.user != UserHandle.USER_SYSTEM) {
                     return;
                 }
                 config.manualRule = null;  // don't restore the manual rule
@@ -285,7 +286,8 @@
     public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
         final int N = mConfigs.size();
         for (int i = 0; i < N; i++) {
-            if (forBackup && mConfigs.keyAt(i) != UserHandle.USER_OWNER) {
+            //TODO: http://b/22388012
+            if (forBackup && mConfigs.keyAt(i) != UserHandle.USER_SYSTEM) {
                 continue;
             }
             mConfigs.valueAt(i).writeXml(out);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 153bd3b..a559116 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -71,7 +71,7 @@
 import static android.system.OsConstants.O_CREAT;
 import static android.system.OsConstants.O_RDWR;
 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
-import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_USER_OWNER;
+import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
 import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
 import static com.android.internal.util.ArrayUtils.appendInt;
@@ -4949,18 +4949,25 @@
     private ResolveInfo createForwardingResolveInfo(IntentFilter filter,
             int sourceUserId, int targetUserId) {
         ResolveInfo forwardingResolveInfo = new ResolveInfo();
+        long ident = Binder.clearCallingIdentity();
+        boolean targetIsProfile;
+        try {
+            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
         String className;
-        if (targetUserId == UserHandle.USER_OWNER) {
-            className = FORWARD_INTENT_TO_USER_OWNER;
-        } else {
+        if (targetIsProfile) {
             className = FORWARD_INTENT_TO_MANAGED_PROFILE;
+        } else {
+            className = FORWARD_INTENT_TO_PARENT;
         }
         ComponentName forwardingActivityComponentName = new ComponentName(
                 mAndroidApplication.packageName, className);
         ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
                 sourceUserId);
-        if (targetUserId == UserHandle.USER_OWNER) {
-            forwardingActivityInfo.showUserIcon = UserHandle.USER_OWNER;
+        if (!targetIsProfile) {
+            forwardingActivityInfo.showUserIcon = targetUserId;
             forwardingResolveInfo.noResourceId = true;
         }
         forwardingResolveInfo.activityInfo = forwardingActivityInfo;
@@ -6112,7 +6119,7 @@
             }
             // Give priority to system apps that listen for pre boot complete.
             Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
-            ArraySet<String> pkgNames = getPackageNamesForIntent(intent);
+            ArraySet<String> pkgNames = getPackageNamesForIntent(intent, UserHandle.USER_SYSTEM);
             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
                 PackageParser.Package pkg = it.next();
                 if (pkgNames.contains(pkg.packageName)) {
@@ -6147,7 +6154,7 @@
             }
             // Give priority to apps that listen for boot complete.
             intent = new Intent(Intent.ACTION_BOOT_COMPLETED);
-            pkgNames = getPackageNamesForIntent(intent);
+            pkgNames = getPackageNamesForIntent(intent, UserHandle.USER_SYSTEM);
             for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) {
                 PackageParser.Package pkg = it.next();
                 if (pkgNames.contains(pkg.packageName)) {
@@ -6218,11 +6225,11 @@
         }
     }
 
-    private ArraySet<String> getPackageNamesForIntent(Intent intent) {
+    private ArraySet<String> getPackageNamesForIntent(Intent intent, int userId) {
         List<ResolveInfo> ris = null;
         try {
             ris = AppGlobals.getPackageManager().queryIntentReceivers(
-                    intent, null, 0, UserHandle.USER_OWNER);
+                    intent, null, 0, userId);
         } catch (RemoteException e) {
         }
         ArraySet<String> pkgNames = new ArraySet<String>();
@@ -11845,8 +11852,9 @@
         String pkgName = pkg.packageName;
 
         if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
+        // TODO: b/23350563
         final boolean dataDirExists = Environment
-                .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_OWNER, pkgName).exists();
+                .getDataUserPackageDirectory(volumeUuid, UserHandle.USER_SYSTEM, pkgName).exists();
 
         synchronized(mPackages) {
             if (mSettings.mRenamedPackages.containsKey(pkgName)) {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index fe205e5..4bfcb90 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -133,7 +133,7 @@
 
     private static final long EPOCH_PLUS_30_YEARS = 30L * 365 * 24 * 60 * 60 * 1000L; // ms
 
-    // Maximum number of managed profiles permitted is 1. This cannot be increased
+    // Maximum number of managed profiles permitted per user is 1. This cannot be increased
     // without first making sure that the rest of the framework is prepared for it.
     private static final int MAX_MANAGED_PROFILES = 1;
 
@@ -627,7 +627,7 @@
     }
 
     @Override
-    public boolean canAddMoreManagedProfiles() {
+    public boolean canAddMoreManagedProfiles(int userId) {
         checkManageUsersPermission("check if more managed profiles can be added.");
         if (ActivityManager.isLowRamDeviceStatic()) {
             return false;
@@ -636,10 +636,14 @@
                 PackageManager.FEATURE_MANAGED_USERS)) {
             return false;
         }
+        // Limit number of managed profiles that can be created
+        int managedProfilesCount = getProfiles(userId, true).size() - 1;
+        if (managedProfilesCount >= MAX_MANAGED_PROFILES) {
+            return false;
+        }
         synchronized(mPackagesLock) {
-            // Limit number of managed profiles that can be created
-            if (numberOfUsersOfTypeLocked(UserInfo.FLAG_MANAGED_PROFILE, true)
-                    >= MAX_MANAGED_PROFILES) {
+            UserInfo userInfo = getUserInfoLocked(userId);
+            if (!userInfo.canHaveProfile()) {
                 return false;
             }
             int usersCount = getAliveUsersExcludingGuestsCountLocked();
@@ -1238,10 +1242,6 @@
     @Override
     public UserInfo createProfileForUser(String name, int flags, int userId) {
         checkManageUsersPermission("Only the system can create users");
-        if (userId != UserHandle.USER_OWNER) {
-            Slog.w(LOG_TAG, "Only user owner can have profiles");
-            return null;
-        }
         return createUserInternal(name, flags, userId);
     }
 
@@ -1273,7 +1273,8 @@
                         parent = getUserInfoLocked(parentId);
                         if (parent == null) return null;
                     }
-                    if (isManagedProfile && !canAddMoreManagedProfiles()) {
+                    if (isManagedProfile && !canAddMoreManagedProfiles(parentId)) {
+                        Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId);
                         return null;
                     }
                     if (!isGuest && !isManagedProfile && isUserLimitReachedLocked()) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 45bbf37..e0da33f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2835,6 +2835,12 @@
                     }
                 }
             }
+        } else if (keyCode == KeyEvent.KEYCODE_SLASH && event.isMetaPressed()) {
+            if (down) {
+                if (repeatCount == 0) {
+                    showKeyboardShortcutsMenu();
+                }
+            }
         } else if (keyCode == KeyEvent.KEYCODE_ASSIST) {
             if (down) {
                 if (repeatCount == 0) {
@@ -3255,6 +3261,17 @@
         }
     }
 
+    private void showKeyboardShortcutsMenu() {
+        try {
+            IStatusBarService statusbar = getStatusBarService();
+            if (statusbar != null) {
+                statusbar.showKeyboardShortcutsMenu();
+            }
+        } catch (RemoteException e) {
+            Slog.e(TAG, "RemoteException when showing keyboard shortcuts menu", e);
+        }
+    }
+
     private void hideRecentApps(boolean triggeredFromAltTab, boolean triggeredFromHome) {
         mPreloadedRecentApps = false; // preloading no longer needs to be canceled
         try {
@@ -6113,6 +6130,7 @@
         }
         startedWakingUp();
         screenTurningOn(null);
+        screenTurnedOn();
     }
 
     ProgressDialog mBootMsgDialog = null;
diff --git a/services/core/java/com/android/server/policy/StatusBarController.java b/services/core/java/com/android/server/policy/StatusBarController.java
index d1b50da..da23f45 100644
--- a/services/core/java/com/android/server/policy/StatusBarController.java
+++ b/services/core/java/com/android/server/policy/StatusBarController.java
@@ -122,7 +122,7 @@
      *
      * @return the desired start time of the status bar transition, in uptime millis
      */
-    private long calculateStatusBarTransitionStartTime(Animation openAnimation,
+    private static long calculateStatusBarTransitionStartTime(Animation openAnimation,
             Animation closeAnimation) {
         if (openAnimation != null && closeAnimation != null) {
             TranslateAnimation openTranslateAnimation = findTranslateAnimation(openAnimation);
@@ -151,7 +151,7 @@
      *
      * @return the found animation, {@code null} otherwise
      */
-    private TranslateAnimation findTranslateAnimation(Animation animation) {
+    private static TranslateAnimation findTranslateAnimation(Animation animation) {
         if (animation instanceof TranslateAnimation) {
             return (TranslateAnimation) animation;
         } else if (animation instanceof AnimationSet) {
@@ -170,7 +170,7 @@
      * Binary searches for a {@code t} such that there exists a {@code -0.01 < eps < 0.01} for which
      * {@code interpolator(t + eps) > 0.99}.
      */
-    private float findAlmostThereFraction(Interpolator interpolator) {
+    private static float findAlmostThereFraction(Interpolator interpolator) {
         float val = 0.5f;
         float adj = 0.25f;
         while (adj >= 0.01f) {
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 5d52307..6b45941 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -32,6 +32,14 @@
     private static final String TAG = "KeyguardServiceDelegate";
     private static final boolean DEBUG = true;
 
+    private static final int SCREEN_STATE_OFF = 0;
+    private static final int SCREEN_STATE_TURNING_ON = 1;
+    private static final int SCREEN_STATE_ON = 2;
+
+    private static final int INTERACTIVE_STATE_SLEEP = 0;
+    private static final int INTERACTIVE_STATE_AWAKE = 1;
+    private static final int INTERACTIVE_STATE_GOING_TO_SLEEP = 2;
+
     protected KeyguardServiceWrapper mKeyguardService;
     private final Context mContext;
     private final View mScrim; // shown if keyguard crashes
@@ -61,6 +69,8 @@
         public int offReason;
         public int currentUser;
         public boolean bootCompleted;
+        public int screenState;
+        public int interactiveState;
     };
 
     public interface DrawnListener {
@@ -144,10 +154,17 @@
                 // If the system is ready, it means keyguard crashed and restarted.
                 mKeyguardService.onSystemReady();
                 // This is used to hide the scrim once keyguard displays.
-                mKeyguardService.onStartedWakingUp();
-                mKeyguardService.onScreenTurningOn(
-                        new KeyguardShowDelegate(mDrawnListenerWhenConnect));
-                mKeyguardService.onScreenTurnedOn();
+                if (mKeyguardState.interactiveState == INTERACTIVE_STATE_AWAKE) {
+                    mKeyguardService.onStartedWakingUp();
+                }
+                if (mKeyguardState.screenState == SCREEN_STATE_ON
+                        || mKeyguardState.screenState == SCREEN_STATE_TURNING_ON) {
+                    mKeyguardService.onScreenTurningOn(
+                            new KeyguardShowDelegate(mDrawnListenerWhenConnect));
+                }
+                if (mKeyguardState.screenState == SCREEN_STATE_ON) {
+                    mKeyguardService.onScreenTurnedOn();
+                }
                 mDrawnListenerWhenConnect = null;
             }
             if (mKeyguardState.bootCompleted) {
@@ -231,6 +248,7 @@
             if (DEBUG) Log.v(TAG, "onStartedWakingUp()");
             mKeyguardService.onStartedWakingUp();
         }
+        mKeyguardState.interactiveState = INTERACTIVE_STATE_AWAKE;
     }
 
     public void onScreenTurnedOff() {
@@ -238,6 +256,7 @@
             if (DEBUG) Log.v(TAG, "onScreenTurnedOff()");
             mKeyguardService.onScreenTurnedOff();
         }
+        mKeyguardState.screenState = SCREEN_STATE_OFF;
     }
 
     public void onScreenTurningOn(final DrawnListener drawnListener) {
@@ -252,6 +271,7 @@
             mDrawnListenerWhenConnect = drawnListener;
             showScrim();
         }
+        mKeyguardState.screenState = SCREEN_STATE_TURNING_ON;
     }
 
     public void onScreenTurnedOn() {
@@ -259,6 +279,7 @@
             if (DEBUG) Log.v(TAG, "onScreenTurnedOn()");
             mKeyguardService.onScreenTurnedOn();
         }
+        mKeyguardState.screenState = SCREEN_STATE_ON;
     }
 
     public void onStartedGoingToSleep(int why) {
@@ -266,12 +287,14 @@
             mKeyguardService.onStartedGoingToSleep(why);
         }
         mKeyguardState.offReason = why;
+        mKeyguardState.interactiveState = INTERACTIVE_STATE_GOING_TO_SLEEP;
     }
 
     public void onFinishedGoingToSleep(int why) {
         if (mKeyguardService != null) {
             mKeyguardService.onFinishedGoingToSleep(why);
         }
+        mKeyguardState.interactiveState = INTERACTIVE_STATE_SLEEP;
     }
 
     public void setKeyguardEnabled(boolean enabled) {
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 2a817ea..8663254 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -494,6 +494,15 @@
     }
 
     @Override
+    public void showKeyboardShortcutsMenu() {
+        if (mBar != null) {
+            try {
+                mBar.showKeyboardShortcutsMenu();
+            } catch (RemoteException ex) {}
+        }
+    }
+
+    @Override
     public void setCurrentUser(int newUserId) {
         if (SPEW) Slog.d(TAG, "Setting current user to user " + newUserId);
         mCurrentUserId = newUserId;
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index dfdb29c..d1145d0 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -26,6 +26,8 @@
 import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.util.Slog;
+import android.util.SparseArray;
+import android.view.AppTransitionAnimationSpec;
 import android.view.WindowManager;
 import android.view.animation.AlphaAnimation;
 import android.view.animation.Animation;
@@ -153,22 +155,25 @@
     private static final int THUMBNAIL_TRANSITION_EXIT_SCALE_DOWN = 3;
 
     private String mNextAppTransitionPackage;
-    private Bitmap mNextAppTransitionThumbnail;
     // Used for thumbnail transitions. True if we're scaling up, false if scaling down
     private boolean mNextAppTransitionScaleUp;
     private IRemoteCallback mNextAppTransitionCallback;
     private int mNextAppTransitionEnter;
     private int mNextAppTransitionExit;
     private int mNextAppTransitionInPlace;
-    private int mNextAppTransitionStartX;
-    private int mNextAppTransitionStartY;
-    private int mNextAppTransitionStartWidth;
-    private int mNextAppTransitionStartHeight;
+
+    // Keyed by task id.
+    private final SparseArray<AppTransitionAnimationSpec> mNextAppTransitionAnimationsSpecs
+            = new SparseArray<>();
+    private AppTransitionAnimationSpec mDefaultNextAppTransitionAnimationSpec;
+
     private Rect mNextAppTransitionInsets = new Rect();
 
     private Rect mTmpFromClipRect = new Rect();
     private Rect mTmpToClipRect = new Rect();
 
+    private final Rect mTmpStartRect = new Rect();
+
     private final static int APP_STATE_IDLE = 0;
     private final static int APP_STATE_READY = 1;
     private final static int APP_STATE_RUNNING = 2;
@@ -276,8 +281,9 @@
         mAppTransitionState = APP_STATE_TIMEOUT;
     }
 
-    Bitmap getNextAppTransitionThumbnail() {
-        return mNextAppTransitionThumbnail;
+    Bitmap getAppTransitionThumbnailHeader(int taskId) {
+        AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
+        return spec != null ? spec.bitmap : null;
     }
 
     /** Returns whether the next thumbnail transition is aspect scaled up. */
@@ -291,14 +297,6 @@
         return mNextAppTransitionScaleUp;
     }
 
-    int getStartingX() {
-        return mNextAppTransitionStartX;
-    }
-
-    int getStartingY() {
-        return mNextAppTransitionStartY;
-    }
-
     boolean prepare() {
         if (!isRunning()) {
             mAppTransitionState = APP_STATE_IDLE;
@@ -321,7 +319,7 @@
     void clear() {
         mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
         mNextAppTransitionPackage = null;
-        mNextAppTransitionThumbnail = null;
+        mNextAppTransitionAnimationsSpecs.clear();
     }
 
     void freeze() {
@@ -459,16 +457,17 @@
         return -startPos / denom;
     }
 
-    private Animation createScaleUpAnimationLocked(int transit, boolean enter,
-                                                   int appWidth, int appHeight) {
+    private Animation createScaleUpAnimationLocked(
+            int transit, boolean enter, int appWidth, int appHeight) {
         Animation a = null;
+        getDefaultNextAppTransitionStartRect(mTmpStartRect);
         if (enter) {
             // Entering app zooms out from the center of the initial rect.
-            float scaleW = mNextAppTransitionStartWidth / (float) appWidth;
-            float scaleH = mNextAppTransitionStartHeight / (float) appHeight;
+            float scaleW = mTmpStartRect.width() / (float) appWidth;
+            float scaleH = mTmpStartRect.height() / (float) appHeight;
             Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
-                    computePivot(mNextAppTransitionStartX, scaleW),
-                    computePivot(mNextAppTransitionStartY, scaleH));
+                    computePivot(mTmpStartRect.left, scaleW),
+                    computePivot(mTmpStartRect.right, scaleH));
             scale.setInterpolator(mDecelerateInterpolator);
 
             Animation alpha = new AlphaAnimation(0, 1);
@@ -512,6 +511,32 @@
         return a;
     }
 
+    private void getDefaultNextAppTransitionStartRect(Rect rect) {
+        if (mDefaultNextAppTransitionAnimationSpec == null ||
+                mDefaultNextAppTransitionAnimationSpec.rect == null) {
+            Slog.wtf(TAG, "Starting rect for app requested, but none available", new Throwable());
+            rect.setEmpty();
+        } else {
+            rect.set(mDefaultNextAppTransitionAnimationSpec.rect);
+        }
+    }
+
+    void getNextAppTransitionStartRect(int taskId, Rect rect) {
+        AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
+        if (spec == null || spec.rect == null) {
+            Slog.wtf(TAG, "Starting rect for task: " + taskId + " requested, but not available",
+                    new Throwable());
+            rect.setEmpty();
+        } else {
+            rect.set(spec.rect);
+        }
+    }
+
+    private void putDefaultNextAppTransitionCoordinates(int left, int top, int width, int height) {
+        mDefaultNextAppTransitionAnimationSpec = new AppTransitionAnimationSpec(-1 /* taskId */,
+                null /* bitmap */, new Rect(left, top, left + width, top + height));
+    }
+
     private Animation createClipRevealAnimationLocked(int transit, boolean enter, Rect appFrame) {
         final Animation anim;
         if (enter) {
@@ -519,28 +544,27 @@
 
             final int appWidth = appFrame.width();
             final int appHeight = appFrame.height();
+            getDefaultNextAppTransitionStartRect(mTmpStartRect);
 
             float t = 0f;
             if (appHeight > 0) {
-                t = (float) mNextAppTransitionStartY / appHeight;
+                t = (float) mTmpStartRect.left / appHeight;
             }
             int translationY = mClipRevealTranslationY
                     + (int)(appHeight / 7f * t);
 
-            int centerX = mNextAppTransitionStartX + mNextAppTransitionStartWidth / 2;
-            int centerY = mNextAppTransitionStartY + mNextAppTransitionStartHeight / 2;
+            int centerX = mTmpStartRect.centerX();
+            int centerY = mTmpStartRect.centerY();
+            int halfWidth = mTmpStartRect.width() / 2;
+            int halfHeight = mTmpStartRect.height() / 2;
 
             // Clip third of the from size of launch icon, expand to full width/height
             Animation clipAnimLR = new ClipRectLRAnimation(
-                    centerX - mNextAppTransitionStartWidth / 2,
-                    centerX + mNextAppTransitionStartWidth / 2,
-                    0, appWidth);
+                    centerX - halfWidth, centerX + halfWidth, 0, appWidth);
             clipAnimLR.setInterpolator(mClipHorizontalInterpolator);
             clipAnimLR.setDuration((long) (DEFAULT_APP_TRANSITION_DURATION / 2.5f));
-            Animation clipAnimTB = new ClipRectTBAnimation(
-                    centerY - mNextAppTransitionStartHeight / 2 - translationY,
-                    centerY + mNextAppTransitionStartHeight / 2 - translationY,
-                    0, appHeight);
+            Animation clipAnimTB = new ClipRectTBAnimation(centerY - halfHeight - translationY,
+                    centerY + halfHeight/ 2 - translationY, 0, appHeight);
             clipAnimTB.setInterpolator(mTouchResponseInterpolator);
             clipAnimTB.setDuration(DEFAULT_APP_TRANSITION_DURATION);
 
@@ -649,31 +673,32 @@
 
     /**
      * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
-     * when a thumbnail is specified with the activity options.
+     * when a thumbnail is specified with the pending animation override.
      */
-    Animation createThumbnailAspectScaleAnimationLocked(Rect appRect) {
+    Animation createThumbnailAspectScaleAnimationLocked(Rect appRect, Bitmap thumbnailHeader,
+            final int taskId) {
         Animation a;
-        final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
+        final int thumbWidthI = thumbnailHeader.getWidth();
         final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
-        final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
+        final int thumbHeightI = thumbnailHeader.getHeight();
         final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
         final int appWidth = appRect.width();
 
         float scaleW = appWidth / thumbWidth;
         float unscaledHeight = thumbHeight * scaleW;
-        float unscaledStartY = mNextAppTransitionStartY - (unscaledHeight - thumbHeight) / 2f;
+        getNextAppTransitionStartRect(taskId, mTmpStartRect);
+        float unscaledStartY = mTmpStartRect.top - (unscaledHeight - thumbHeight) / 2f;
         if (mNextAppTransitionScaleUp) {
             // Animation up from the thumbnail to the full screen
             Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW,
-                    mNextAppTransitionStartX + (thumbWidth / 2f),
-                    mNextAppTransitionStartY + (thumbHeight / 2f));
+                    mTmpStartRect.left + (thumbWidth / 2f), mTmpStartRect.top + (thumbHeight / 2f));
             scale.setInterpolator(mTouchResponseInterpolator);
             scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
             Animation alpha = new AlphaAnimation(1, 0);
             alpha.setInterpolator(mThumbnailFadeOutInterpolator);
             alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
             final float toX = appRect.left + appRect.width() / 2 -
-                    (mNextAppTransitionStartX + thumbWidth / 2);
+                    (mTmpStartRect.left + thumbWidth / 2);
             final float toY = appRect.top + mNextAppTransitionInsets.top + -unscaledStartY;
             Animation translate = new TranslateAnimation(0, toX, 0, toY);
             translate.setInterpolator(mTouchResponseInterpolator);
@@ -688,8 +713,7 @@
         } else {
             // Animation down from the full screen to the thumbnail
             Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f,
-                    mNextAppTransitionStartX + (thumbWidth / 2f),
-                    mNextAppTransitionStartY + (thumbHeight / 2f));
+                    mTmpStartRect.left + (thumbWidth / 2f), mTmpStartRect.top + (thumbHeight / 2f));
             scale.setInterpolator(mTouchResponseInterpolator);
             scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
             Animation alpha = new AlphaAnimation(0f, 1f);
@@ -718,11 +742,13 @@
      */
     Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState,
             int appWidth, int appHeight, int orientation, int transit, Rect containingFrame,
-            Rect contentInsets, @Nullable Rect surfaceInsets, boolean resizedWindow) {
+            Rect contentInsets, @Nullable Rect surfaceInsets, boolean resizedWindow,
+            int taskId) {
         Animation a;
-        final int thumbWidthI = mNextAppTransitionStartWidth;
+        getDefaultNextAppTransitionStartRect(mTmpStartRect);
+        final int thumbWidthI = mTmpStartRect.width();
         final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
-        final int thumbHeightI = mNextAppTransitionStartHeight;
+        final int thumbHeightI = mTmpStartRect.height();
         final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
 
         // Used for the ENTER_SCALE_UP and EXIT_SCALE_DOWN transitions
@@ -733,7 +759,7 @@
             case THUMBNAIL_TRANSITION_ENTER_SCALE_UP: {
                 if (resizedWindow) {
                     a = createAspectScaledThumbnailEnterNonFullscreenAnimationLocked(
-                            containingFrame, surfaceInsets);
+                            containingFrame, surfaceInsets, taskId);
                 } else {
                     // App window scaling up to become full screen
                     if (orientation == Configuration.ORIENTATION_PORTRAIT) {
@@ -759,8 +785,8 @@
                     mNextAppTransitionInsets.set(contentInsets);
 
                     Animation scaleAnim = new ScaleAnimation(scale, 1, scale, 1,
-                            computePivot(mNextAppTransitionStartX, scale),
-                            computePivot(mNextAppTransitionStartY, scale));
+                            computePivot(mTmpStartRect.left, scale),
+                            computePivot(mTmpStartRect.top, scale));
                     Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
                     Animation translateAnim = new TranslateAnimation(0, 0, -scaledTopDecor, 0);
 
@@ -819,8 +845,8 @@
                 mNextAppTransitionInsets.set(contentInsets);
 
                 Animation scaleAnim = new ScaleAnimation(1, scale, 1, scale,
-                        computePivot(mNextAppTransitionStartX, scale),
-                        computePivot(mNextAppTransitionStartY, scale));
+                        computePivot(mTmpStartRect.left, scale),
+                        computePivot(mTmpStartRect.top, scale));
                 Animation clipAnim = new ClipRectAnimation(mTmpFromClipRect, mTmpToClipRect);
                 Animation translateAnim = new TranslateAnimation(0, 0, 0, -scaledTopDecor);
 
@@ -844,11 +870,12 @@
     }
 
     private Animation createAspectScaledThumbnailEnterNonFullscreenAnimationLocked(
-            Rect containingFrame, @Nullable Rect surfaceInsets) {
+            Rect containingFrame, @Nullable Rect surfaceInsets, int taskId) {
+        getNextAppTransitionStartRect(taskId, mTmpStartRect);
         float width = containingFrame.width();
         float height = containingFrame.height();
-        float scaleWidth = mNextAppTransitionStartWidth / width;
-        float scaleHeight = mNextAppTransitionStartHeight / height;
+        float scaleWidth = mTmpStartRect.width() / width;
+        float scaleHeight = mTmpStartRect.height() / height;
         AnimationSet set = new AnimationSet(true);
         int surfaceInsetsHorizontal = surfaceInsets == null
                 ? 0 : surfaceInsets.left + surfaceInsets.right;
@@ -858,9 +885,9 @@
         // we need to account for surface insets that will be used to enlarge the surface.
         ScaleAnimation scale = new ScaleAnimation(scaleWidth, 1, scaleHeight, 1,
                 (width + surfaceInsetsHorizontal) / 2, (height + surfaceInsetsVertical) / 2);
-        int fromX = mNextAppTransitionStartX + mNextAppTransitionStartWidth / 2
+        int fromX = mTmpStartRect.left + mTmpStartRect.width() / 2
                 - (containingFrame.left + containingFrame.width() / 2);
-        int fromY = mNextAppTransitionStartY + mNextAppTransitionStartHeight / 2
+        int fromY = mTmpStartRect.top + mTmpStartRect.height() / 2
                 - (containingFrame.top + containingFrame.height() / 2);
         TranslateAnimation translation = new TranslateAnimation(fromX, 0, fromY, 0);
         set.addAnimation(scale);
@@ -870,13 +897,15 @@
 
     /**
      * This animation runs for the thumbnail that gets cross faded with the enter/exit activity
-     * when a thumbnail is specified with the activity options.
+     * when a thumbnail is specified with the pending animation override.
      */
-    Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit) {
+    Animation createThumbnailScaleAnimationLocked(int appWidth, int appHeight, int transit,
+            Bitmap thumbnailHeader) {
         Animation a;
-        final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
+        getDefaultNextAppTransitionStartRect(mTmpStartRect);
+        final int thumbWidthI = thumbnailHeader.getWidth();
         final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
-        final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
+        final int thumbHeightI = thumbnailHeader.getHeight();
         final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
 
         if (mNextAppTransitionScaleUp) {
@@ -884,8 +913,8 @@
             float scaleW = appWidth / thumbWidth;
             float scaleH = appHeight / thumbHeight;
             Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
-                    computePivot(mNextAppTransitionStartX, 1 / scaleW),
-                    computePivot(mNextAppTransitionStartY, 1 / scaleH));
+                    computePivot(mTmpStartRect.left, 1 / scaleW),
+                    computePivot(mTmpStartRect.top, 1 / scaleH));
             scale.setInterpolator(mDecelerateInterpolator);
 
             Animation alpha = new AlphaAnimation(1, 0);
@@ -901,8 +930,8 @@
             float scaleW = appWidth / thumbWidth;
             float scaleH = appHeight / thumbHeight;
             a = new ScaleAnimation(scaleW, 1, scaleH, 1,
-                    computePivot(mNextAppTransitionStartX, 1 / scaleW),
-                    computePivot(mNextAppTransitionStartY, 1 / scaleH));
+                    computePivot(mTmpStartRect.left, 1 / scaleW),
+                    computePivot(mTmpStartRect.top, 1 / scaleH));
         }
 
         return prepareThumbnailAnimation(a, appWidth, appHeight, transit);
@@ -913,11 +942,13 @@
      * leaving, and the activity that is entering.
      */
     Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, int appWidth,
-            int appHeight, int transit) {
+            int appHeight, int transit, int taskId) {
+        Bitmap thumbnailHeader = getAppTransitionThumbnailHeader(taskId);
         Animation a;
-        final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
+        getDefaultNextAppTransitionStartRect(mTmpStartRect);
+        final int thumbWidthI = thumbnailHeader != null ? thumbnailHeader.getWidth() : appWidth;
         final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
-        final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
+        final int thumbHeightI = thumbnailHeader != null ? thumbnailHeader.getHeight() : appHeight;
         final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
 
         switch (thumbTransitState) {
@@ -926,8 +957,8 @@
                 float scaleW = thumbWidth / appWidth;
                 float scaleH = thumbHeight / appHeight;
                 a = new ScaleAnimation(scaleW, 1, scaleH, 1,
-                        computePivot(mNextAppTransitionStartX, scaleW),
-                        computePivot(mNextAppTransitionStartY, scaleH));
+                        computePivot(mTmpStartRect.left, scaleW),
+                        computePivot(mTmpStartRect.top, scaleH));
                 break;
             }
             case THUMBNAIL_TRANSITION_EXIT_SCALE_UP: {
@@ -954,8 +985,8 @@
                 float scaleW = thumbWidth / appWidth;
                 float scaleH = thumbHeight / appHeight;
                 Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
-                        computePivot(mNextAppTransitionStartX, scaleW),
-                        computePivot(mNextAppTransitionStartY, scaleH));
+                        computePivot(mTmpStartRect.left, scaleW),
+                        computePivot(mTmpStartRect.top, scaleH));
 
                 Animation alpha = new AlphaAnimation(1, 0);
 
@@ -987,7 +1018,7 @@
     Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
             int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets,
             @Nullable Rect surfaceInsets, Rect appFrame, boolean isVoiceInteraction,
-            boolean resizedWindow) {
+            boolean resizedWindow, int taskId) {
         Animation a;
         if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN
                 || transit == TRANSIT_TASK_OPEN
@@ -1042,7 +1073,7 @@
             mNextAppTransitionScaleUp =
                     (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
             a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
-                    appWidth, appHeight, transit);
+                    appWidth, appHeight, transit, taskId);
             if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
                 String animName = mNextAppTransitionScaleUp ?
                         "ANIM_THUMBNAIL_SCALE_UP" : "ANIM_THUMBNAIL_SCALE_DOWN";
@@ -1057,7 +1088,7 @@
                     (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP);
             a = createAspectScaledThumbnailEnterExitAnimationLocked(
                     getThumbnailTransitionState(enter), appWidth, appHeight, orientation, transit,
-                    containingFrame, contentInsets, surfaceInsets, resizedWindow);
+                    containingFrame, contentInsets, surfaceInsets, resizedWindow, taskId);
             if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) {
                 String animName = mNextAppTransitionScaleUp ?
                         "ANIM_THUMBNAIL_ASPECT_SCALE_UP" : "ANIM_THUMBNAIL_ASPECT_SCALE_DOWN";
@@ -1147,7 +1178,7 @@
         if (isTransitionSet()) {
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM;
             mNextAppTransitionPackage = packageName;
-            mNextAppTransitionThumbnail = null;
+            mNextAppTransitionAnimationsSpecs.clear();
             mNextAppTransitionEnter = enterAnim;
             mNextAppTransitionExit = exitAnim;
             postAnimationCallback();
@@ -1158,15 +1189,13 @@
     }
 
     void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
-                                                    int startHeight) {
+            int startHeight) {
         if (isTransitionSet()) {
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_SCALE_UP;
             mNextAppTransitionPackage = null;
-            mNextAppTransitionThumbnail = null;
-            mNextAppTransitionStartX = startX;
-            mNextAppTransitionStartY = startY;
-            mNextAppTransitionStartWidth = startWidth;
-            mNextAppTransitionStartHeight = startHeight;
+            mNextAppTransitionAnimationsSpecs.clear();
+            putDefaultNextAppTransitionCoordinates(startX, startY, startX + startWidth,
+                    startY + startHeight);
             postAnimationCallback();
             mNextAppTransitionCallback = null;
         }
@@ -1176,10 +1205,7 @@
                                                 int startWidth, int startHeight) {
         if (isTransitionSet()) {
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_CLIP_REVEAL;
-            mNextAppTransitionStartX = startX;
-            mNextAppTransitionStartY = startY;
-            mNextAppTransitionStartWidth = startWidth;
-            mNextAppTransitionStartHeight = startHeight;
+            putDefaultNextAppTransitionCoordinates(startX, startY, startWidth, startHeight);
             postAnimationCallback();
             mNextAppTransitionCallback = null;
         }
@@ -1191,10 +1217,9 @@
             mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP
                     : NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN;
             mNextAppTransitionPackage = null;
-            mNextAppTransitionThumbnail = srcThumb;
+            mNextAppTransitionAnimationsSpecs.clear();
             mNextAppTransitionScaleUp = scaleUp;
-            mNextAppTransitionStartX = startX;
-            mNextAppTransitionStartY = startY;
+            putDefaultNextAppTransitionCoordinates(startX, startY, 0 ,0);
             postAnimationCallback();
             mNextAppTransitionCallback = startedCallback;
         } else {
@@ -1208,12 +1233,9 @@
             mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
                     : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
             mNextAppTransitionPackage = null;
-            mNextAppTransitionThumbnail = srcThumb;
+            mNextAppTransitionAnimationsSpecs.clear();
             mNextAppTransitionScaleUp = scaleUp;
-            mNextAppTransitionStartX = startX;
-            mNextAppTransitionStartY = startY;
-            mNextAppTransitionStartWidth = targetWidth;
-            mNextAppTransitionStartHeight = targetHeight;
+            putDefaultNextAppTransitionCoordinates(startX, startY, targetWidth, targetHeight);
             postAnimationCallback();
             mNextAppTransitionCallback = startedCallback;
         } else {
@@ -1221,6 +1243,27 @@
         }
     }
 
+    public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
+            IRemoteCallback callback, boolean scaleUp) {
+        if (isTransitionSet()) {
+            mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
+                    : NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
+            mNextAppTransitionPackage = null;
+            mNextAppTransitionAnimationsSpecs.clear();
+            mNextAppTransitionScaleUp = scaleUp;
+            for (int i = 0; i < specs.length; i++) {
+                AppTransitionAnimationSpec spec = specs[i];
+                if (spec != null) {
+                    mNextAppTransitionAnimationsSpecs.put(spec.taskId, spec);
+                }
+            }
+            postAnimationCallback();
+            mNextAppTransitionCallback = callback;
+        } else {
+            postAnimationCallback();
+        }
+    }
+
     void overrideInPlaceAppTransition(String packageName, int anim) {
         if (isTransitionSet()) {
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE;
@@ -1350,33 +1393,30 @@
                 pw.print(prefix); pw.print("mNextAppTransitionInPlace=0x");
                         pw.print(Integer.toHexString(mNextAppTransitionInPlace));
                 break;
-            case NEXT_TRANSIT_TYPE_SCALE_UP:
+            case NEXT_TRANSIT_TYPE_SCALE_UP: {
+                getDefaultNextAppTransitionStartRect(mTmpStartRect);
                 pw.print(prefix); pw.print("mNextAppTransitionStartX=");
-                        pw.print(mNextAppTransitionStartX);
+                        pw.print(mTmpStartRect.left);
                         pw.print(" mNextAppTransitionStartY=");
-                        pw.println(mNextAppTransitionStartY);
+                        pw.println(mTmpStartRect.top);
                 pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
-                        pw.print(mNextAppTransitionStartWidth);
+                        pw.print(mTmpStartRect.width());
                         pw.print(" mNextAppTransitionStartHeight=");
-                        pw.println(mNextAppTransitionStartHeight);
+                        pw.println(mTmpStartRect.height());
                 break;
+            }
             case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP:
             case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
             case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
-            case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
-                pw.print(prefix); pw.print("mNextAppTransitionThumbnail=");
-                        pw.print(mNextAppTransitionThumbnail);
-                        pw.print(" mNextAppTransitionStartX=");
-                        pw.print(mNextAppTransitionStartX);
-                        pw.print(" mNextAppTransitionStartY=");
-                        pw.println(mNextAppTransitionStartY);
-                pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
-                        pw.print(mNextAppTransitionStartWidth);
-                        pw.print(" mNextAppTransitionStartHeight=");
-                        pw.println(mNextAppTransitionStartHeight);
+            case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN: {
+                pw.print(prefix); pw.print("mDefaultNextAppTransitionAnimationSpec=");
+                        pw.println(mDefaultNextAppTransitionAnimationSpec);
+                pw.print(prefix); pw.print("mNextAppTransitionAnimationsSpecs=");
+                        pw.println(mNextAppTransitionAnimationsSpecs);
                 pw.print(prefix); pw.print("mNextAppTransitionScaleUp=");
                         pw.println(mNextAppTransitionScaleUp);
                 break;
+            }
         }
         if (mNextAppTransitionCallback != null) {
             pw.print(prefix); pw.print("mNextAppTransitionCallback=");
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index df7b23d..2828cd0 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -193,6 +193,7 @@
         final int windowCount = mAppToken.allAppWindows.size();
         final int adj = animLayerAdjustment;
         thumbnailLayer = -1;
+        final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
         for (int i = 0; i < windowCount; i++) {
             final WindowState w = mAppToken.allAppWindows.get(i);
             final WindowStateAnimator winAnimator = w.mWinAnimator;
@@ -204,9 +205,7 @@
             if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
                 mService.setInputMethodAnimLayerAdjustment(adj);
             }
-            if (w == mService.mWallpaperTarget && mService.mLowerWallpaperTarget == null) {
-                mService.setWallpaperAnimLayerAdjustmentLocked(adj);
-            }
+            wallpaperController.setAnimLayerAdjustment(w, adj);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 222945c..e87dcde 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
 import com.android.server.input.InputApplicationHandle;
 import com.android.server.input.InputWindowHandle;
 import com.android.server.wm.WindowManagerService.DragInputEventReceiver;
@@ -413,7 +414,7 @@
                 continue;
             }
 
-            child.getTaskBounds(mTmpRect);
+            child.getTaskBounds(mTmpRect, !BOUNDS_FOR_TOUCH);
             if (!mTmpRect.contains(x, y)) {
                 // outside of this window's activity stack == don't tell about drags
                 continue;
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 21e92c9..b3244ff 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
 import android.app.ActivityManagerNative;
 import android.graphics.Rect;
 import android.os.RemoteException;
@@ -177,7 +178,7 @@
         if (modal && child.mAppToken != null) {
             // Limit the outer touch to the activity stack region.
             flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
-            child.getTaskBounds(mTmpRect);
+            child.getTaskBounds(mTmpRect, BOUNDS_FOR_TOUCH);
             inputWindowHandle.touchableRegion.set(mTmpRect);
         } else {
             // Not modal or full screen modal
@@ -260,6 +261,7 @@
 
         // Add all windows on the default display.
         final int numDisplays = mService.mDisplayContents.size();
+        final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
         for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
             WindowList windows = mService.mDisplayContents.valueAt(displayNdx).getWindowList();
             for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
@@ -287,7 +289,7 @@
                             != 0) {
                     disableWallpaperTouchEvents = true;
                 }
-                final boolean hasWallpaper = (child == mService.mWallpaperTarget)
+                final boolean hasWallpaper = wallpaperController.isWallpaperTarget(child)
                         && (privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD) == 0
                         && !disableWallpaperTouchEvents;
                 final boolean onDefaultDisplay = (child.getDisplayId() == Display.DEFAULT_DISPLAY);
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 75bb10a..12f61f9 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -403,7 +403,7 @@
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
             try {
-                mService.setWindowWallpaperPositionLocked(
+                mService.mWallpaperControllerLocked.setWindowWallpaperPosition(
                         mService.windowForClientLocked(this, window, true),
                         x, y, xStep, yStep);
             } finally {
@@ -413,14 +413,16 @@
     }
 
     public void wallpaperOffsetsComplete(IBinder window) {
-        mService.wallpaperOffsetsComplete(window);
+        synchronized (mService.mWindowMap) {
+            mService.mWallpaperControllerLocked.wallpaperOffsetsComplete(window);
+        }
     }
 
     public void setWallpaperDisplayOffset(IBinder window, int x, int y) {
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
             try {
-                mService.setWindowWallpaperDisplayOffsetLocked(
+                mService.mWallpaperControllerLocked.setWindowWallpaperDisplayOffset(
                         mService.windowForClientLocked(this, window, true), x, y);
             } finally {
                 Binder.restoreCallingIdentity(ident);
@@ -433,7 +435,7 @@
         synchronized(mService.mWindowMap) {
             long ident = Binder.clearCallingIdentity();
             try {
-                return mService.sendWindowWallpaperCommandLocked(
+                return mService.mWallpaperControllerLocked.sendWindowWallpaperCommand(
                         mService.windowForClientLocked(this, window, true),
                         action, x, y, z, extras, sync);
             } finally {
@@ -443,7 +445,9 @@
     }
 
     public void wallpaperCommandComplete(IBinder window, Bundle result) {
-        mService.wallpaperCommandComplete(window, result);
+        synchronized (mService.mWindowMap) {
+            mService.mWallpaperControllerLocked.wallpaperCommandComplete(window);
+        }
     }
 
     public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
new file mode 100644
index 0000000..d0962f4
--- /dev/null
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -0,0 +1,916 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static com.android.server.wm.WindowManagerService.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerService.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
+import static com.android.server.wm.WindowManagerService.DEBUG_WINDOW_MOVEMENT;
+import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER;
+import static com.android.server.wm.WindowManagerService.DEBUG_WALLPAPER_LIGHT;
+import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT;
+import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
+import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
+
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.util.Slog;
+import android.view.DisplayInfo;
+import android.view.WindowManager;
+import android.view.WindowManagerPolicy;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Controls wallpaper windows visibility, ordering, and so on.
+ * NOTE: All methods in this class must be called with the window manager service lock held.
+ */
+class WallpaperController {
+    private static final String TAG = com.android.server.wm.WindowManagerService.TAG;
+    final private WindowManagerService mService;
+
+    private final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<>();
+
+    // If non-null, this is the currently visible window that is associated
+    // with the wallpaper.
+    private WindowState mWallpaperTarget = null;
+    // If non-null, we are in the middle of animating from one wallpaper target
+    // to another, and this is the lower one in Z-order.
+    private WindowState mLowerWallpaperTarget = null;
+    // If non-null, we are in the middle of animating from one wallpaper target
+    // to another, and this is the higher one in Z-order.
+    private WindowState mUpperWallpaperTarget = null;
+
+    private int mWallpaperAnimLayerAdjustment;
+
+    private float mLastWallpaperX = -1;
+    private float mLastWallpaperY = -1;
+    private float mLastWallpaperXStep = -1;
+    private float mLastWallpaperYStep = -1;
+    private int mLastWallpaperDisplayOffsetX = Integer.MIN_VALUE;
+    private int mLastWallpaperDisplayOffsetY = Integer.MIN_VALUE;
+
+    // This is set when we are waiting for a wallpaper to tell us it is done
+    // changing its scroll position.
+    WindowState mWaitingOnWallpaper;
+
+    // The last time we had a timeout when waiting for a wallpaper.
+    private long mLastWallpaperTimeoutTime;
+    // We give a wallpaper up to 150ms to finish scrolling.
+    private static final long WALLPAPER_TIMEOUT = 150;
+    // Time we wait after a timeout before trying to wait again.
+    private static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
+
+    // Set to the wallpaper window we would like to hide once the transition animations are done.
+    // This is useful in cases where we don't want the wallpaper to be hidden when the close app
+    // is a wallpaper target and is done animating out, but the opening app isn't a wallpaper
+    // target and isn't done animating in.
+    private WindowState mDeferredHideWallpaper = null;
+
+    // We give a wallpaper up to 500ms to finish drawing before playing app transitions.
+    private static final long WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION = 500;
+    private static final int WALLPAPER_DRAW_NORMAL = 0;
+    private static final int WALLPAPER_DRAW_PENDING = 1;
+    private static final int WALLPAPER_DRAW_TIMEOUT = 2;
+    private int mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
+
+    private final FindWallpaperTargetResult mFindResults = new FindWallpaperTargetResult();
+
+    public WallpaperController(WindowManagerService service) {
+        mService = service;
+    }
+
+    WindowState getWallpaperTarget() {
+        return mWallpaperTarget;
+    }
+
+    WindowState getLowerWallpaperTarget() {
+        return mLowerWallpaperTarget;
+    }
+
+    WindowState getUpperWallpaperTarget() {
+        return mUpperWallpaperTarget;
+    }
+
+    boolean isWallpaperTarget(WindowState win) {
+        return win == mWallpaperTarget;
+    }
+
+    boolean isBelowWallpaperTarget(WindowState win) {
+        return mWallpaperTarget != null && mWallpaperTarget.mLayer >= win.mBaseLayer;
+    }
+
+    boolean isWallpaperVisible() {
+        return isWallpaperVisible(mWallpaperTarget);
+    }
+
+    private boolean isWallpaperVisible(WindowState wallpaperTarget) {
+        if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
+                + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
+                + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
+                ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
+                + " upper=" + mUpperWallpaperTarget
+                + " lower=" + mLowerWallpaperTarget);
+        return (wallpaperTarget != null
+                && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
+                && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
+                || mUpperWallpaperTarget != null
+                || mLowerWallpaperTarget != null;
+    }
+
+    boolean isWallpaperTargetAnimating() {
+        return mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
+                && !mWallpaperTarget.mWinAnimator.isDummyAnimation();
+    }
+
+    void updateWallpaperVisibility() {
+        final boolean visible = isWallpaperVisible(mWallpaperTarget);
+        final DisplayContent displayContent = mWallpaperTarget.getDisplayContent();
+        if (displayContent == null) {
+            return;
+        }
+        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+        final int dw = displayInfo.logicalWidth;
+        final int dh = displayInfo.logicalHeight;
+
+        for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+            WindowToken token = mWallpaperTokens.get(curTokenNdx);
+            if (token.hidden == visible) {
+                token.hidden = !visible;
+                // Need to do a layout to ensure the wallpaper now has the
+                // correct size.
+                displayContent.layoutNeeded = true;
+            }
+
+            final WindowList windows = token.windows;
+            for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+                WindowState wallpaper = windows.get(wallpaperNdx);
+                if (visible) {
+                    updateWallpaperOffset(wallpaper, dw, dh, false);
+                }
+
+                dispatchWallpaperVisibility(wallpaper, visible);
+            }
+        }
+    }
+
+    void hideDeferredWallpapersIfNeeded() {
+        if (mDeferredHideWallpaper != null) {
+            hideWallpapers(mDeferredHideWallpaper);
+            mDeferredHideWallpaper = null;
+        }
+    }
+
+    void hideWallpapers(final WindowState winGoingAway) {
+        if (mWallpaperTarget != null
+                && (mWallpaperTarget != winGoingAway || mLowerWallpaperTarget != null)) {
+            return;
+        }
+        if (mService.mAppTransition.isRunning()) {
+            // Defer hiding the wallpaper when app transition is running until the animations
+            // are done.
+            mDeferredHideWallpaper = winGoingAway;
+            return;
+        }
+
+        final boolean wasDeferred = (mDeferredHideWallpaper == winGoingAway);
+        for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
+            final WindowToken token = mWallpaperTokens.get(i);
+            for (int j = token.windows.size() - 1; j >= 0; j--) {
+                final WindowState wallpaper = token.windows.get(j);
+                final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
+                if (!winAnimator.mLastHidden || wasDeferred) {
+                    winAnimator.hide();
+                    dispatchWallpaperVisibility(wallpaper, false);
+                    final DisplayContent displayContent = wallpaper.getDisplayContent();
+                    if (displayContent != null) {
+                        displayContent.pendingLayoutChanges |=
+                                WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+                    }
+                }
+            }
+            if (DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG, "Hiding wallpaper " + token
+                    + " from " + winGoingAway + " target=" + mWallpaperTarget + " lower="
+                    + mLowerWallpaperTarget + "\n" + Debug.getCallers(5, "  "));
+            token.hidden = true;
+        }
+    }
+
+    /**
+     * Check wallpaper for visibility change and notify window if so.
+     * @param wallpaper The wallpaper to test and notify.
+     * @param visible Current visibility.
+     */
+    void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
+        // Only send notification if the visibility actually changed and we are not trying to hide
+        // the wallpaper when we are deferring hiding of the wallpaper.
+        if (wallpaper.mWallpaperVisible != visible
+                && (mDeferredHideWallpaper == null || visible)) {
+            wallpaper.mWallpaperVisible = visible;
+            try {
+                if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                        "Updating vis of wallpaper " + wallpaper
+                                + ": " + visible + " from:\n" + Debug.getCallers(4, "  "));
+                wallpaper.mClient.dispatchAppVisibility(visible);
+            } catch (RemoteException e) {
+            }
+        }
+    }
+
+    boolean updateWallpaperOffset(WindowState wallpaperWin, int dw, int dh, boolean sync) {
+        boolean rawChanged = false;
+        float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
+        float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
+        int availw = wallpaperWin.mFrame.right - wallpaperWin.mFrame.left - dw;
+        int offset = availw > 0 ? -(int)(availw * wpx + .5f) : 0;
+        if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+            offset += mLastWallpaperDisplayOffsetX;
+        }
+        boolean changed = wallpaperWin.mXOffset != offset;
+        if (changed) {
+            if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " + wallpaperWin + " x: " + offset);
+            wallpaperWin.mXOffset = offset;
+        }
+        if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
+            wallpaperWin.mWallpaperX = wpx;
+            wallpaperWin.mWallpaperXStep = wpxs;
+            rawChanged = true;
+        }
+
+        float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
+        float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
+        int availh = wallpaperWin.mFrame.bottom - wallpaperWin.mFrame.top - dh;
+        offset = availh > 0 ? -(int)(availh * wpy + .5f) : 0;
+        if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+            offset += mLastWallpaperDisplayOffsetY;
+        }
+        if (wallpaperWin.mYOffset != offset) {
+            if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " + wallpaperWin + " y: " + offset);
+            changed = true;
+            wallpaperWin.mYOffset = offset;
+        }
+        if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
+            wallpaperWin.mWallpaperY = wpy;
+            wallpaperWin.mWallpaperYStep = wpys;
+            rawChanged = true;
+        }
+
+        if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
+                WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
+            try {
+                if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
+                        + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
+                        + " y=" + wallpaperWin.mWallpaperY);
+                if (sync) {
+                    mWaitingOnWallpaper = wallpaperWin;
+                }
+                wallpaperWin.mClient.dispatchWallpaperOffsets(
+                        wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
+                        wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
+                if (sync) {
+                    if (mWaitingOnWallpaper != null) {
+                        long start = SystemClock.uptimeMillis();
+                        if ((mLastWallpaperTimeoutTime + WALLPAPER_TIMEOUT_RECOVERY)
+                                < start) {
+                            try {
+                                if (DEBUG_WALLPAPER) Slog.v(TAG,
+                                        "Waiting for offset complete...");
+                                mService.mWindowMap.wait(WALLPAPER_TIMEOUT);
+                            } catch (InterruptedException e) {
+                            }
+                            if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
+                            if ((start + WALLPAPER_TIMEOUT) < SystemClock.uptimeMillis()) {
+                                Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
+                                        + wallpaperWin);
+                                mLastWallpaperTimeoutTime = start;
+                            }
+                        }
+                        mWaitingOnWallpaper = null;
+                    }
+                }
+            } catch (RemoteException e) {
+            }
+        }
+
+        return changed;
+    }
+
+    void setWindowWallpaperPosition(
+            WindowState window, float x, float y, float xStep, float yStep) {
+        if (window.mWallpaperX != x || window.mWallpaperY != y)  {
+            window.mWallpaperX = x;
+            window.mWallpaperY = y;
+            window.mWallpaperXStep = xStep;
+            window.mWallpaperYStep = yStep;
+            updateWallpaperOffsetLocked(window, true);
+        }
+    }
+
+    void setWindowWallpaperDisplayOffset(WindowState window, int x, int y) {
+        if (window.mWallpaperDisplayOffsetX != x || window.mWallpaperDisplayOffsetY != y)  {
+            window.mWallpaperDisplayOffsetX = x;
+            window.mWallpaperDisplayOffsetY = y;
+            updateWallpaperOffsetLocked(window, true);
+        }
+    }
+
+    Bundle sendWindowWallpaperCommand(
+            WindowState window, String action, int x, int y, int z, Bundle extras, boolean sync) {
+        if (window == mWallpaperTarget
+                || window == mLowerWallpaperTarget
+                || window == mUpperWallpaperTarget) {
+            boolean doWait = sync;
+            for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+                final WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
+                for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+                    WindowState wallpaper = windows.get(wallpaperNdx);
+                    try {
+                        wallpaper.mClient.dispatchWallpaperCommand(action,
+                                x, y, z, extras, sync);
+                        // We only want to be synchronous with one wallpaper.
+                        sync = false;
+                    } catch (RemoteException e) {
+                    }
+                }
+            }
+
+            if (doWait) {
+                // TODO: Need to wait for result.
+            }
+        }
+
+        return null;
+    }
+
+    void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
+        final DisplayContent displayContent = changingTarget.getDisplayContent();
+        if (displayContent == null) {
+            return;
+        }
+        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+        final int dw = displayInfo.logicalWidth;
+        final int dh = displayInfo.logicalHeight;
+
+        WindowState target = mWallpaperTarget;
+        if (target != null) {
+            if (target.mWallpaperX >= 0) {
+                mLastWallpaperX = target.mWallpaperX;
+            } else if (changingTarget.mWallpaperX >= 0) {
+                mLastWallpaperX = changingTarget.mWallpaperX;
+            }
+            if (target.mWallpaperY >= 0) {
+                mLastWallpaperY = target.mWallpaperY;
+            } else if (changingTarget.mWallpaperY >= 0) {
+                mLastWallpaperY = changingTarget.mWallpaperY;
+            }
+            if (target.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetX = target.mWallpaperDisplayOffsetX;
+            } else if (changingTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetX = changingTarget.mWallpaperDisplayOffsetX;
+            }
+            if (target.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetY = target.mWallpaperDisplayOffsetY;
+            } else if (changingTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetY = changingTarget.mWallpaperDisplayOffsetY;
+            }
+            if (target.mWallpaperXStep >= 0) {
+                mLastWallpaperXStep = target.mWallpaperXStep;
+            } else if (changingTarget.mWallpaperXStep >= 0) {
+                mLastWallpaperXStep = changingTarget.mWallpaperXStep;
+            }
+            if (target.mWallpaperYStep >= 0) {
+                mLastWallpaperYStep = target.mWallpaperYStep;
+            } else if (changingTarget.mWallpaperYStep >= 0) {
+                mLastWallpaperYStep = changingTarget.mWallpaperYStep;
+            }
+        }
+
+        for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+            WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
+            for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+                WindowState wallpaper = windows.get(wallpaperNdx);
+                if (updateWallpaperOffset(wallpaper, dw, dh, sync)) {
+                    WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
+                    winAnimator.computeShownFrameLocked();
+                    // No need to lay out the windows - we can just set the wallpaper position
+                    // directly.
+                    winAnimator.setWallpaperOffset(wallpaper.mShownFrame);
+                    // We only want to be synchronous with one wallpaper.
+                    sync = false;
+                }
+            }
+        }
+    }
+
+    void clearLastWallpaperTimeoutTime() {
+        mLastWallpaperTimeoutTime = 0;
+    }
+
+    void wallpaperCommandComplete(IBinder window) {
+        if (mWaitingOnWallpaper != null &&
+                mWaitingOnWallpaper.mClient.asBinder() == window) {
+            mWaitingOnWallpaper = null;
+            mService.mWindowMap.notifyAll();
+        }
+    }
+
+    void wallpaperOffsetsComplete(IBinder window) {
+        if (mWaitingOnWallpaper != null &&
+                mWaitingOnWallpaper.mClient.asBinder() == window) {
+            mWaitingOnWallpaper = null;
+            mService.mWindowMap.notifyAll();
+        }
+    }
+
+    int getAnimLayerAdjustment() {
+        return mWallpaperAnimLayerAdjustment;
+    }
+
+    void setAnimLayerAdjustment(WindowState win, int adj) {
+        if (win != mWallpaperTarget || mLowerWallpaperTarget != null) {
+            return;
+        }
+
+        if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Setting wallpaper layer adj to " + adj);
+        mWallpaperAnimLayerAdjustment = adj;
+        for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
+            WindowList windows = mWallpaperTokens.get(i).windows;
+            for (int j = windows.size() - 1; j >= 0; j--) {
+                WindowState wallpaper = windows.get(j);
+                wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
+                if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
+                        + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
+            }
+        }
+    }
+
+    private void findWallpaperTarget(WindowList windows, FindWallpaperTargetResult result) {
+
+        final WindowAnimator winAnimator = mService.mAnimator;
+        result.reset();
+        WindowState w = null;
+        int windowDetachedI = -1;
+        boolean resetTopWallpaper = false;
+        boolean inFreeformSpace = false;
+        for (int i = windows.size() - 1; i >= 0; i--) {
+            w = windows.get(i);
+            if ((w.mAttrs.type == TYPE_WALLPAPER)) {
+                if (result.topWallpaper == null || resetTopWallpaper) {
+                    result.setTopWallpaper(w, i);
+                    resetTopWallpaper = false;
+                }
+                continue;
+            }
+            resetTopWallpaper = true;
+            if (w != winAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
+                // If this window's app token is hidden and not animating,
+                // it is of no interest to us.
+                if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
+                    if (DEBUG_WALLPAPER) Slog.v(TAG,
+                            "Skipping hidden and not animating token: " + w);
+                    continue;
+                }
+            }
+            if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
+                    + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
+
+            if (!inFreeformSpace) {
+                TaskStack stack = w.getStack();
+                inFreeformSpace = stack != null && stack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
+            }
+
+            // If the app is executing an animation because the keyguard is going away,
+            // keep the wallpaper during the animation so it doesn't flicker out.
+            final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
+                    || (w.mAppToken != null && w.mWinAnimator.mKeyguardGoingAwayAnimation);
+            if (hasWallpaper && w.isOnScreen()
+                    && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
+                if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: #" + i + "=" + w);
+                result.setWallpaperTarget(w, i);
+                if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
+                    // The current wallpaper target is animating, so we'll look behind it for
+                    // another possible target and figure out what is going on later.
+                    if (DEBUG_WALLPAPER) Slog.v(TAG,
+                            "Win " + w + ": token animating, looking behind.");
+                    continue;
+                }
+                break;
+            } else if (w == winAnimator.mWindowDetachedWallpaper) {
+                windowDetachedI = i;
+            }
+        }
+
+        if (result.wallpaperTarget == null && windowDetachedI >= 0) {
+            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                    "Found animating detached wallpaper activity: #" + windowDetachedI + "=" + w);
+            result.setWallpaperTarget(w, windowDetachedI);
+        }
+        if (result.wallpaperTarget == null && inFreeformSpace) {
+            // In freeform mode we set the wallpaper as its own target, so we don't need an
+            // additional window to make it visible.
+            result.setWallpaperTarget(result.topWallpaper, result.topWallpaperIndex);
+        }
+    }
+
+    private boolean updateWallpaperWindowsTarget(
+            WindowList windows, FindWallpaperTargetResult result) {
+
+        boolean targetChanged = false;
+        WindowState wallpaperTarget = result.wallpaperTarget;
+        int wallpaperTargetIndex = result.wallpaperTargetIndex;
+
+        if (mWallpaperTarget != wallpaperTarget
+                && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != wallpaperTarget)) {
+            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                    "New wallpaper target: " + wallpaperTarget + " oldTarget: " + mWallpaperTarget);
+
+            mLowerWallpaperTarget = null;
+            mUpperWallpaperTarget = null;
+
+            WindowState oldW = mWallpaperTarget;
+            mWallpaperTarget = wallpaperTarget;
+            targetChanged = true;
+
+            // Now what is happening...  if the current and new targets are animating,
+            // then we are in our super special mode!
+            if (wallpaperTarget != null && oldW != null) {
+                boolean oldAnim = oldW.isAnimatingLw();
+                boolean foundAnim = wallpaperTarget.isAnimatingLw();
+                if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                        "New animation: " + foundAnim + " old animation: " + oldAnim);
+                if (foundAnim && oldAnim) {
+                    int oldI = windows.indexOf(oldW);
+                    if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                            "New i: " + wallpaperTargetIndex + " old i: " + oldI);
+                    if (oldI >= 0) {
+                        if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                                "Animating wallpapers: old#" + oldI + "=" + oldW + "; new#"
+                                + wallpaperTargetIndex + "=" + wallpaperTarget);
+
+                        // Set the new target correctly.
+                        if (wallpaperTarget.mAppToken != null
+                                && wallpaperTarget.mAppToken.hiddenRequested) {
+                            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                                    "Old wallpaper still the target.");
+                            mWallpaperTarget = oldW;
+                            wallpaperTarget = oldW;
+                            wallpaperTargetIndex = oldI;
+                        }
+                        // Now set the upper and lower wallpaper targets correctly,
+                        // and make sure that we are positioning the wallpaper below the lower.
+                        else if (wallpaperTargetIndex > oldI) {
+                            // The new target is on top of the old one.
+                            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                                    "Found target above old target.");
+                            mUpperWallpaperTarget = wallpaperTarget;
+                            mLowerWallpaperTarget = oldW;
+                            wallpaperTarget = oldW;
+                            wallpaperTargetIndex = oldI;
+                        } else {
+                            // The new target is below the old one.
+                            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
+                                    "Found target below old target.");
+                            mUpperWallpaperTarget = oldW;
+                            mLowerWallpaperTarget = wallpaperTarget;
+                        }
+                    }
+                }
+            }
+
+        } else if (mLowerWallpaperTarget != null) {
+            // Is it time to stop animating?
+            if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
+                if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "No longer animating wallpaper targets!");
+                mLowerWallpaperTarget = null;
+                mUpperWallpaperTarget = null;
+                mWallpaperTarget = wallpaperTarget;
+                targetChanged = true;
+            }
+        }
+
+        result.setWallpaperTarget(wallpaperTarget, wallpaperTargetIndex);
+        return targetChanged;
+    }
+
+    boolean updateWallpaperWindowsTargetByLayer(
+            WindowList windows, FindWallpaperTargetResult result) {
+
+        WindowState wallpaperTarget = result.wallpaperTarget;
+        int wallpaperTargetIndex = result.wallpaperTargetIndex;
+        boolean visible = wallpaperTarget != null;
+
+        if (visible) {
+            // The window is visible to the compositor...but is it visible to the user?
+            // That is what the wallpaper cares about.
+            visible = isWallpaperVisible(wallpaperTarget);
+            if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
+
+            // If the wallpaper target is animating, we may need to copy its layer adjustment.
+            // Only do this if we are not transferring between two wallpaper targets.
+            mWallpaperAnimLayerAdjustment =
+                    (mLowerWallpaperTarget == null && wallpaperTarget.mAppToken != null)
+                            ? wallpaperTarget.mAppToken.mAppAnimator.animLayerAdjustment : 0;
+
+            final int maxLayer = (mService.mPolicy.getMaxWallpaperLayer() * TYPE_LAYER_MULTIPLIER)
+                    + TYPE_LAYER_OFFSET;
+
+            // Now w is the window we are supposed to be behind...  but we
+            // need to be sure to also be behind any of its attached windows,
+            // AND any starting window associated with it, AND below the
+            // maximum layer the policy allows for wallpapers.
+            while (wallpaperTargetIndex > 0) {
+                WindowState wb = windows.get(wallpaperTargetIndex - 1);
+                if (wb.mBaseLayer < maxLayer &&
+                        wb.mAttachedWindow != wallpaperTarget &&
+                        (wallpaperTarget.mAttachedWindow == null ||
+                                wb.mAttachedWindow != wallpaperTarget.mAttachedWindow) &&
+                        (wb.mAttrs.type != TYPE_APPLICATION_STARTING
+                                || wallpaperTarget.mToken == null
+                                || wb.mToken != wallpaperTarget.mToken)) {
+                    // This window is not related to the previous one in any
+                    // interesting way, so stop here.
+                    break;
+                }
+                wallpaperTarget = wb;
+                wallpaperTargetIndex--;
+            }
+        } else {
+            if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
+        }
+
+        result.setWallpaperTarget(wallpaperTarget, wallpaperTargetIndex);
+        return visible;
+    }
+
+    boolean updateWallpaperWindowsPlacement(WindowList windows,
+            WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible) {
+
+        // TODO(multidisplay): Wallpapers on main screen only.
+        final DisplayInfo displayInfo = mService.getDefaultDisplayContentLocked().getDisplayInfo();
+        final int dw = displayInfo.logicalWidth;
+        final int dh = displayInfo.logicalHeight;
+
+        // Start stepping backwards from here, ensuring that our wallpaper windows
+        // are correctly placed.
+        boolean changed = false;
+        for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
+            WindowToken token = mWallpaperTokens.get(curTokenNdx);
+            if (token.hidden == visible) {
+                if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
+                        "Wallpaper token " + token + " hidden=" + !visible);
+                token.hidden = !visible;
+                // Need to do a layout to ensure the wallpaper now has the correct size.
+                mService.getDefaultDisplayContentLocked().layoutNeeded = true;
+            }
+
+            final WindowList tokenWindows = token.windows;
+            for (int wallpaperNdx = tokenWindows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
+                WindowState wallpaper = tokenWindows.get(wallpaperNdx);
+
+                if (visible) {
+                    updateWallpaperOffset(wallpaper, dw, dh, false);
+                }
+
+                // First, make sure the client has the current visibility state.
+                dispatchWallpaperVisibility(wallpaper, visible);
+
+                wallpaper.mWinAnimator.mAnimLayer =
+                        wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
+                if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
+                        + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
+
+                // First, if this window is at the current index, then all is well.
+                if (wallpaper == wallpaperTarget) {
+                    wallpaperTargetIndex--;
+                    wallpaperTarget = wallpaperTargetIndex > 0
+                            ? windows.get(wallpaperTargetIndex - 1) : null;
+                    continue;
+                }
+
+                // The window didn't match...  the current wallpaper window,
+                // wherever it is, is in the wrong place, so make sure it is not in the list.
+                int oldIndex = windows.indexOf(wallpaper);
+                if (oldIndex >= 0) {
+                    if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG,
+                            "Wallpaper removing at " + oldIndex + ": " + wallpaper);
+                    windows.remove(oldIndex);
+                    mService.mWindowsChanged = true;
+                    if (oldIndex < wallpaperTargetIndex) {
+                        wallpaperTargetIndex--;
+                    }
+                }
+
+                // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
+                // layer. For keyguard over wallpaper put the wallpaper under the keyguard.
+                int insertionIndex = 0;
+                if (visible && wallpaperTarget != null) {
+                    final int type = wallpaperTarget.mAttrs.type;
+                    final int privateFlags = wallpaperTarget.mAttrs.privateFlags;
+                    if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0
+                            || type == TYPE_KEYGUARD_SCRIM) {
+                        insertionIndex = windows.indexOf(wallpaperTarget);
+                    }
+                }
+                if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) Slog.v(TAG,
+                        "Moving wallpaper " + wallpaper
+                        + " from " + oldIndex + " to " + insertionIndex);
+
+                windows.add(insertionIndex, wallpaper);
+                mService.mWindowsChanged = true;
+                changed = true;
+            }
+        }
+
+        return changed;
+    }
+
+    boolean adjustWallpaperWindows() {
+        mService.mInnerFields.mWallpaperMayChange = false;
+
+        final WindowList windows = mService.getDefaultWindowListLocked();
+        // First find top-most window that has asked to be on top of the wallpaper;
+        // all wallpapers go behind it.
+        findWallpaperTarget(windows, mFindResults);
+        final boolean targetChanged = updateWallpaperWindowsTarget(windows, mFindResults);
+        final boolean visible = updateWallpaperWindowsTargetByLayer(windows, mFindResults);
+        WindowState wallpaperTarget = mFindResults.wallpaperTarget;
+        int wallpaperTargetIndex = mFindResults.wallpaperTargetIndex;
+
+        if (wallpaperTarget == null && mFindResults.topWallpaper != null) {
+            // There is no wallpaper target, so it goes at the bottom.
+            // We will assume it is the same place as last time, if known.
+            wallpaperTarget = mFindResults.topWallpaper;
+            wallpaperTargetIndex = mFindResults.topWallpaperIndex + 1;
+        } else {
+            // Okay i is the position immediately above the wallpaper.
+            // Look at what is below it for later.
+            wallpaperTarget = wallpaperTargetIndex > 0
+                    ? windows.get(wallpaperTargetIndex - 1) : null;
+        }
+
+        if (visible) {
+            if (mWallpaperTarget.mWallpaperX >= 0) {
+                mLastWallpaperX = mWallpaperTarget.mWallpaperX;
+                mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
+            }
+            if (mWallpaperTarget.mWallpaperY >= 0) {
+                mLastWallpaperY = mWallpaperTarget.mWallpaperY;
+                mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
+            }
+            if (mWallpaperTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetX = mWallpaperTarget.mWallpaperDisplayOffsetX;
+            }
+            if (mWallpaperTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+                mLastWallpaperDisplayOffsetY = mWallpaperTarget.mWallpaperDisplayOffsetY;
+            }
+        }
+
+        final boolean changed = updateWallpaperWindowsPlacement(
+                windows, wallpaperTarget, wallpaperTargetIndex, visible);
+
+        if (targetChanged && DEBUG_WALLPAPER_LIGHT)  Slog.d(TAG, "New wallpaper: target="
+                + mWallpaperTarget + " lower=" + mLowerWallpaperTarget + " upper="
+                + mUpperWallpaperTarget);
+
+        return changed;
+    }
+
+    boolean processWallpaperDrawPendingTimeout() {
+        if (mWallpaperDrawState == WALLPAPER_DRAW_PENDING) {
+            mWallpaperDrawState = WALLPAPER_DRAW_TIMEOUT;
+            if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
+                    "*** WALLPAPER DRAW TIMEOUT");
+            return true;
+        }
+        return false;
+    }
+
+    boolean wallpaperTransitionReady() {
+        boolean transitionReady = true;
+        boolean wallpaperReady = true;
+        for (int curTokenIndex = mWallpaperTokens.size() - 1;
+                curTokenIndex >= 0 && wallpaperReady; curTokenIndex--) {
+            WindowToken token = mWallpaperTokens.get(curTokenIndex);
+            for (int curWallpaperIndex = token.windows.size() - 1; curWallpaperIndex >= 0;
+                    curWallpaperIndex--) {
+                WindowState wallpaper = token.windows.get(curWallpaperIndex);
+                if (wallpaper.mWallpaperVisible && !wallpaper.isDrawnLw()) {
+                    // We've told this wallpaper to be visible, but it is not drawn yet
+                    wallpaperReady = false;
+                    if (mWallpaperDrawState != WALLPAPER_DRAW_TIMEOUT) {
+                        // wait for this wallpaper until it is drawn or timeout
+                        transitionReady = false;
+                    }
+                    if (mWallpaperDrawState == WALLPAPER_DRAW_NORMAL) {
+                        mWallpaperDrawState = WALLPAPER_DRAW_PENDING;
+                        mService.mH.removeMessages(WALLPAPER_DRAW_PENDING_TIMEOUT);
+                        mService.mH.sendEmptyMessageDelayed(WALLPAPER_DRAW_PENDING_TIMEOUT,
+                                WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION);
+                    }
+                    if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
+                            "Wallpaper should be visible but has not been drawn yet. " +
+                                    "mWallpaperDrawState=" + mWallpaperDrawState);
+                    break;
+                }
+            }
+        }
+        if (wallpaperReady) {
+            mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
+            mService.mH.removeMessages(WALLPAPER_DRAW_PENDING_TIMEOUT);
+        }
+
+        return transitionReady;
+    }
+
+    void addWallpaperToken(WindowToken token) {
+        mWallpaperTokens.add(token);
+    }
+
+    void removeWallpaperToken(WindowToken token) {
+        mWallpaperTokens.remove(token);
+    }
+
+    void dump(PrintWriter pw, String prefix) {
+        pw.print(prefix); pw.print("mWallpaperTarget="); pw.println(mWallpaperTarget);
+        if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
+            pw.print(prefix); pw.print("mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
+            pw.print(prefix); pw.print("mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
+        }
+        pw.print(prefix); pw.print("mLastWallpaperX="); pw.print(mLastWallpaperX);
+        pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
+        if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE
+                || mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
+            pw.print(prefix);
+            pw.print("mLastWallpaperDisplayOffsetX="); pw.print(mLastWallpaperDisplayOffsetX);
+            pw.print(" mLastWallpaperDisplayOffsetY="); pw.println(mLastWallpaperDisplayOffsetY);
+        }
+    }
+
+    void dumpTokens(PrintWriter pw, String prefix, boolean dumpAll) {
+        if (!mWallpaperTokens.isEmpty()) {
+            pw.println();
+            pw.print(prefix); pw.println("Wallpaper tokens:");
+            for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
+                WindowToken token = mWallpaperTokens.get(i);
+                pw.print(prefix); pw.print("Wallpaper #"); pw.print(i);
+                pw.print(' '); pw.print(token);
+                if (dumpAll) {
+                    pw.println(':');
+                    token.dump(pw, "    ");
+                } else {
+                    pw.println();
+                }
+            }
+        }
+    }
+
+    /** Helper class for storing the results of a wallpaper target find operation. */
+    final private static class FindWallpaperTargetResult {
+        int topWallpaperIndex = 0;
+        WindowState topWallpaper = null;
+        int wallpaperTargetIndex = 0;
+        WindowState wallpaperTarget = null;
+
+        void setTopWallpaper(WindowState win, int index) {
+            topWallpaper = win;
+            topWallpaperIndex = index;
+        }
+
+        void setWallpaperTarget(WindowState win, int index) {
+            wallpaperTarget = win;
+            wallpaperTargetIndex = index;
+        }
+
+        void reset() {
+            topWallpaperIndex = 0;
+            topWallpaper = null;
+            wallpaperTargetIndex = 0;
+            wallpaperTarget = null;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 7578256..e6a1be1 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -258,6 +258,7 @@
         boolean startingInUnForceHiding = false;
         ArrayList<WindowStateAnimator> unForceHiding = null;
         WindowState wallpaper = null;
+        final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
         for (int i = windows.size() - 1; i >= 0; i--) {
             WindowState win = windows.get(i);
             WindowStateAnimator winAnimator = win.mWinAnimator;
@@ -294,7 +295,8 @@
                             ", nowAnimating=" + nowAnimating);
                 }
 
-                if (wasAnimating && !winAnimator.mAnimating && mService.mWallpaperTarget == win) {
+                if (wasAnimating && !winAnimator.mAnimating
+                        && wallpaperController.isWallpaperTarget(win)) {
                     mBulkUpdateParams |= SET_WALLPAPER_MAY_CHANGE;
                     setPendingLayoutChanges(Display.DEFAULT_DISPLAY,
                             WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 355b09b..69daa3c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -78,6 +78,7 @@
 import android.util.SparseIntArray;
 import android.util.TimeUtils;
 import android.util.TypedValue;
+import android.view.AppTransitionAnimationSpec;
 import android.view.Choreographer;
 import android.view.Display;
 import android.view.DisplayInfo;
@@ -113,6 +114,7 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 
+import static com.android.server.wm.WindowState.BOUNDS_FOR_TOUCH;
 import com.android.internal.app.IAssistScreenshotReceiver;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.util.FastPrintWriter;
@@ -176,7 +178,6 @@
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM;
 import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG;
@@ -443,6 +444,7 @@
 
     final float[] mTmpFloats = new float[9];
     final Rect mTmpContentRect = new Rect();
+    private final Rect mTmpStartRect = new Rect();
 
     boolean mDisplayReady;
     boolean mSafeMode;
@@ -579,48 +581,10 @@
         }
     }
 
-    private final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<WindowToken>();
+    WallpaperController mWallpaperControllerLocked;
 
-    // If non-null, this is the currently visible window that is associated
-    // with the wallpaper.
-    WindowState mWallpaperTarget = null;
-    // If non-null, we are in the middle of animating from one wallpaper target
-    // to another, and this is the lower one in Z-order.
-    WindowState mLowerWallpaperTarget = null;
-    // If non-null, we are in the middle of animating from one wallpaper target
-    // to another, and this is the higher one in Z-order.
-    WindowState mUpperWallpaperTarget = null;
-    int mWallpaperAnimLayerAdjustment;
-    float mLastWallpaperX = -1;
-    float mLastWallpaperY = -1;
-    float mLastWallpaperXStep = -1;
-    float mLastWallpaperYStep = -1;
-    int mLastWallpaperDisplayOffsetX = Integer.MIN_VALUE;
-    int mLastWallpaperDisplayOffsetY = Integer.MIN_VALUE;
-    // This is set when we are waiting for a wallpaper to tell us it is done
-    // changing its scroll position.
-    WindowState mWaitingOnWallpaper;
-    // The last time we had a timeout when waiting for a wallpaper.
-    long mLastWallpaperTimeoutTime;
-    // We give a wallpaper up to 150ms to finish scrolling.
-    static final long WALLPAPER_TIMEOUT = 150;
-    // Time we wait after a timeout before trying to wait again.
-    static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
     boolean mAnimateWallpaperWithTarget;
 
-    // We give a wallpaper up to 500ms to finish drawing before playing app transitions.
-    static final long WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION = 500;
-    static final int WALLPAPER_DRAW_NORMAL = 0;
-    static final int WALLPAPER_DRAW_PENDING = 1;
-    static final int WALLPAPER_DRAW_TIMEOUT = 2;
-    int mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
-
-    // Set to the wallpaper window we would like to hide once the transition animations are done.
-    // This is useful in cases where we don't want the wallpaper to be hidden when the close app
-    // is a wallpaper target and is done animating out, but the opening app isn't a wallpaper
-    // target and isn't done animating in.
-    WindowState mDeferredHideWallpaper = null;
-
     AppWindowToken mFocusedApp = null;
 
     PowerManager mPowerManager;
@@ -634,6 +598,7 @@
     final InputManagerService mInputManager;
     final DisplayManagerInternal mDisplayManagerInternal;
     final DisplayManager mDisplayManager;
+    final Display[] mDisplays;
 
     // Who is holding the screen on.
     Session mHoldingScreenOn;
@@ -804,7 +769,7 @@
 
     private ViewServer mViewServer;
     private final ArrayList<WindowChangeListener> mWindowChangeListeners = new ArrayList<>();
-    private boolean mWindowsChanged = false;
+    boolean mWindowsChanged = false;
 
     public interface WindowChangeListener {
         public void windowsChanged();
@@ -907,8 +872,8 @@
 
         mFxSession = new SurfaceSession();
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
-        Display[] displays = mDisplayManager.getDisplays();
-        for (Display display : displays) {
+        mDisplays = mDisplayManager.getDisplays();
+        for (Display display : mDisplays) {
             createDisplayContentLocked(display);
         }
 
@@ -988,6 +953,8 @@
 
         updateCircularDisplayMaskIfNeeded();
         showEmulatorDisplayOverlayIfNeeded();
+
+        mWallpaperControllerLocked = new WallpaperController(this);
     }
 
     public InputMonitor getInputMonitor() {
@@ -1767,578 +1734,6 @@
         return true;
     }
 
-    private boolean isWallpaperVisible(WindowState wallpaperTarget) {
-        if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
-                + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
-                + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
-                        ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
-                + " upper=" + mUpperWallpaperTarget
-                + " lower=" + mLowerWallpaperTarget);
-        return (wallpaperTarget != null
-                        && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
-                                && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
-                || mUpperWallpaperTarget != null
-                || mLowerWallpaperTarget != null;
-    }
-
-    void hideWallpapersLocked(final WindowState winGoingAway) {
-        if (mWallpaperTarget != null
-                && (mWallpaperTarget != winGoingAway || mLowerWallpaperTarget != null)) {
-            return;
-        }
-        if (mAppTransition.isRunning()) {
-            // Defer hiding the wallpaper when app transition is running until the animations
-            // are done.
-            mDeferredHideWallpaper = winGoingAway;
-            return;
-        }
-
-        final boolean wasDeferred = (mDeferredHideWallpaper == winGoingAway);
-        for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
-            final WindowToken token = mWallpaperTokens.get(i);
-            for (int j = token.windows.size() - 1; j >= 0; j--) {
-                final WindowState wallpaper = token.windows.get(j);
-                final WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
-                if (!winAnimator.mLastHidden || wasDeferred) {
-                    winAnimator.hide();
-                    dispatchWallpaperVisibility(wallpaper, false);
-                    final DisplayContent displayContent = wallpaper.getDisplayContent();
-                    if (displayContent != null) {
-                        displayContent.pendingLayoutChanges |=
-                                WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-                    }
-                }
-            }
-            if (DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG, "Hiding wallpaper " + token
-                    + " from " + winGoingAway + " target=" + mWallpaperTarget + " lower="
-                    + mLowerWallpaperTarget + "\n" + Debug.getCallers(5, "  "));
-            token.hidden = true;
-        }
-    }
-
-    boolean adjustWallpaperWindowsLocked() {
-        mInnerFields.mWallpaperMayChange = false;
-        boolean targetChanged = false;
-
-        // TODO(multidisplay): Wallpapers on main screen only.
-        final DisplayInfo displayInfo = getDefaultDisplayContentLocked().getDisplayInfo();
-        final int dw = displayInfo.logicalWidth;
-        final int dh = displayInfo.logicalHeight;
-
-        // First find top-most window that has asked to be on top of the
-        // wallpaper; all wallpapers go behind it.
-        final WindowList windows = getDefaultWindowListLocked();
-        int N = windows.size();
-        WindowState w = null;
-        WindowState foundW = null;
-        int foundI = 0;
-        WindowState topCurW = null;
-        int topCurI = 0;
-        int windowDetachedI = -1;
-        int i = N;
-        while (i > 0) {
-            i--;
-            w = windows.get(i);
-            if ((w.mAttrs.type == TYPE_WALLPAPER)) {
-                if (topCurW == null) {
-                    topCurW = w;
-                    topCurI = i;
-                }
-                continue;
-            }
-            topCurW = null;
-            if (w != mAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
-                // If this window's app token is hidden and not animating,
-                // it is of no interest to us.
-                if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
-                    if (DEBUG_WALLPAPER) Slog.v(TAG,
-                            "Skipping hidden and not animating token: " + w);
-                    continue;
-                }
-            }
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
-                    + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
-
-            // If the app is executing an animation because the keyguard is going away, keep the
-            // wallpaper during the animation so it doesn't flicker out.
-            final boolean hasWallpaper = (w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
-                    || (w.mAppToken != null
-                            && w.mWinAnimator.mKeyguardGoingAwayAnimation);
-            if (hasWallpaper && w.isOnScreen()
-                    && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
-                if (DEBUG_WALLPAPER) Slog.v(TAG,
-                        "Found wallpaper target: #" + i + "=" + w);
-                foundW = w;
-                foundI = i;
-                if (w == mWallpaperTarget && w.mWinAnimator.isAnimating()) {
-                    // The current wallpaper target is animating, so we'll
-                    // look behind it for another possible target and figure
-                    // out what is going on below.
-                    if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w
-                            + ": token animating, looking behind.");
-                    continue;
-                }
-                break;
-            } else if (w == mAnimator.mWindowDetachedWallpaper) {
-                windowDetachedI = i;
-            }
-        }
-
-        if (foundW == null && windowDetachedI >= 0) {
-            if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                    "Found animating detached wallpaper activity: #" + i + "=" + w);
-            foundW = w;
-            foundI = windowDetachedI;
-        }
-
-        if (mWallpaperTarget != foundW
-                && (mLowerWallpaperTarget == null || mLowerWallpaperTarget != foundW)) {
-            if (DEBUG_WALLPAPER_LIGHT) {
-                Slog.v(TAG, "New wallpaper target: " + foundW
-                        + " oldTarget: " + mWallpaperTarget);
-            }
-
-            mLowerWallpaperTarget = null;
-            mUpperWallpaperTarget = null;
-
-            WindowState oldW = mWallpaperTarget;
-            mWallpaperTarget = foundW;
-            targetChanged = true;
-
-            // Now what is happening...  if the current and new targets are
-            // animating, then we are in our super special mode!
-            if (foundW != null && oldW != null) {
-                boolean oldAnim = oldW.isAnimatingLw();
-                boolean foundAnim = foundW.isAnimatingLw();
-                if (DEBUG_WALLPAPER_LIGHT) {
-                    Slog.v(TAG, "New animation: " + foundAnim
-                            + " old animation: " + oldAnim);
-                }
-                if (foundAnim && oldAnim) {
-                    int oldI = windows.indexOf(oldW);
-                    if (DEBUG_WALLPAPER_LIGHT) {
-                        Slog.v(TAG, "New i: " + foundI + " old i: " + oldI);
-                    }
-                    if (oldI >= 0) {
-                        if (DEBUG_WALLPAPER_LIGHT) {
-                            Slog.v(TAG, "Animating wallpapers: old#" + oldI
-                                    + "=" + oldW + "; new#" + foundI
-                                    + "=" + foundW);
-                        }
-
-                        // Set the new target correctly.
-                        if (foundW.mAppToken != null && foundW.mAppToken.hiddenRequested) {
-                            if (DEBUG_WALLPAPER_LIGHT) {
-                                Slog.v(TAG, "Old wallpaper still the target.");
-                            }
-                            mWallpaperTarget = oldW;
-                            foundW = oldW;
-                            foundI = oldI;
-                        }
-                        // Now set the upper and lower wallpaper targets
-                        // correctly, and make sure that we are positioning
-                        // the wallpaper below the lower.
-                        else if (foundI > oldI) {
-                            // The new target is on top of the old one.
-                            if (DEBUG_WALLPAPER_LIGHT) {
-                                Slog.v(TAG, "Found target above old target.");
-                            }
-                            mUpperWallpaperTarget = foundW;
-                            mLowerWallpaperTarget = oldW;
-                            foundW = oldW;
-                            foundI = oldI;
-                        } else {
-                            // The new target is below the old one.
-                            if (DEBUG_WALLPAPER_LIGHT) {
-                                Slog.v(TAG, "Found target below old target.");
-                            }
-                            mUpperWallpaperTarget = oldW;
-                            mLowerWallpaperTarget = foundW;
-                        }
-                    }
-                }
-            }
-
-        } else if (mLowerWallpaperTarget != null) {
-            // Is it time to stop animating?
-            if (!mLowerWallpaperTarget.isAnimatingLw() || !mUpperWallpaperTarget.isAnimatingLw()) {
-                if (DEBUG_WALLPAPER_LIGHT) {
-                    Slog.v(TAG, "No longer animating wallpaper targets!");
-                }
-                mLowerWallpaperTarget = null;
-                mUpperWallpaperTarget = null;
-                mWallpaperTarget = foundW;
-                targetChanged = true;
-            }
-        }
-
-        boolean visible = foundW != null;
-        if (visible) {
-            // The window is visible to the compositor...  but is it visible
-            // to the user?  That is what the wallpaper cares about.
-            visible = isWallpaperVisible(foundW);
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
-
-            // If the wallpaper target is animating, we may need to copy
-            // its layer adjustment.  Only do this if we are not transfering
-            // between two wallpaper targets.
-            mWallpaperAnimLayerAdjustment =
-                    (mLowerWallpaperTarget == null && foundW.mAppToken != null)
-                    ? foundW.mAppToken.mAppAnimator.animLayerAdjustment : 0;
-
-            final int maxLayer = mPolicy.getMaxWallpaperLayer()
-                    * TYPE_LAYER_MULTIPLIER
-                    + TYPE_LAYER_OFFSET;
-
-            // Now w is the window we are supposed to be behind...  but we
-            // need to be sure to also be behind any of its attached windows,
-            // AND any starting window associated with it, AND below the
-            // maximum layer the policy allows for wallpapers.
-            while (foundI > 0) {
-                WindowState wb = windows.get(foundI - 1);
-                if (wb.mBaseLayer < maxLayer &&
-                        wb.mAttachedWindow != foundW &&
-                        (foundW.mAttachedWindow == null ||
-                                wb.mAttachedWindow != foundW.mAttachedWindow) &&
-                        (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
-                                foundW.mToken == null || wb.mToken != foundW.mToken)) {
-                    // This window is not related to the previous one in any
-                    // interesting way, so stop here.
-                    break;
-                }
-                foundW = wb;
-                foundI--;
-            }
-        } else {
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
-        }
-
-        if (foundW == null && topCurW != null) {
-            // There is no wallpaper target, so it goes at the bottom.
-            // We will assume it is the same place as last time, if known.
-            foundW = topCurW;
-            foundI = topCurI+1;
-        } else {
-            // Okay i is the position immediately above the wallpaper.  Look at
-            // what is below it for later.
-            foundW = foundI > 0 ? windows.get(foundI - 1) : null;
-        }
-
-        if (visible) {
-            if (mWallpaperTarget.mWallpaperX >= 0) {
-                mLastWallpaperX = mWallpaperTarget.mWallpaperX;
-                mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
-            }
-            if (mWallpaperTarget.mWallpaperY >= 0) {
-                mLastWallpaperY = mWallpaperTarget.mWallpaperY;
-                mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
-            }
-            if (mWallpaperTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
-                mLastWallpaperDisplayOffsetX = mWallpaperTarget.mWallpaperDisplayOffsetX;
-            }
-            if (mWallpaperTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
-                mLastWallpaperDisplayOffsetY = mWallpaperTarget.mWallpaperDisplayOffsetY;
-            }
-        }
-
-        // Start stepping backwards from here, ensuring that our wallpaper windows
-        // are correctly placed.
-        boolean changed = false;
-        for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
-            WindowToken token = mWallpaperTokens.get(curTokenNdx);
-            if (token.hidden == visible) {
-                if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG,
-                        "Wallpaper token " + token + " hidden=" + !visible);
-                token.hidden = !visible;
-                // Need to do a layout to ensure the wallpaper now has the correct size.
-                getDefaultDisplayContentLocked().layoutNeeded = true;
-            }
-
-            final WindowList tokenWindows = token.windows;
-            for (int wallpaperNdx = tokenWindows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
-                WindowState wallpaper = tokenWindows.get(wallpaperNdx);
-
-                if (visible) {
-                    updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
-                }
-
-                // First, make sure the client has the current visibility state.
-                dispatchWallpaperVisibility(wallpaper, visible);
-
-                wallpaper.mWinAnimator.mAnimLayer =
-                        wallpaper.mLayer + mWallpaperAnimLayerAdjustment;
-                if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
-                        + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
-
-                // First, if this window is at the current index, then all is well.
-                if (wallpaper == foundW) {
-                    foundI--;
-                    foundW = foundI > 0 ? windows.get(foundI - 1) : null;
-                    continue;
-                }
-
-                // The window didn't match...  the current wallpaper window,
-                // wherever it is, is in the wrong place, so make sure it is
-                // not in the list.
-                int oldIndex = windows.indexOf(wallpaper);
-                if (oldIndex >= 0) {
-                    if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Wallpaper removing at "
-                            + oldIndex + ": " + wallpaper);
-                    windows.remove(oldIndex);
-                    mWindowsChanged = true;
-                    if (oldIndex < foundI) {
-                        foundI--;
-                    }
-                }
-
-                // Now stick it in. For apps over wallpaper keep the wallpaper at the bottommost
-                // layer. For keyguard over wallpaper put the wallpaper under the keyguard.
-                int insertionIndex = 0;
-                if (visible && foundW != null) {
-                    final int type = foundW.mAttrs.type;
-                    final int privateFlags = foundW.mAttrs.privateFlags;
-                    if ((privateFlags & PRIVATE_FLAG_KEYGUARD) != 0
-                            || type == TYPE_KEYGUARD_SCRIM) {
-                        insertionIndex = windows.indexOf(foundW);
-                    }
-                }
-                if (DEBUG_WALLPAPER_LIGHT || DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE) {
-                    Slog.v(TAG, "Moving wallpaper " + wallpaper
-                            + " from " + oldIndex + " to " + insertionIndex);
-                }
-
-                windows.add(insertionIndex, wallpaper);
-                mWindowsChanged = true;
-                changed = true;
-            }
-        }
-
-        if (targetChanged && DEBUG_WALLPAPER_LIGHT)  Slog.d(TAG, "New wallpaper: target="
-                + mWallpaperTarget + " lower=" + mLowerWallpaperTarget + " upper="
-                + mUpperWallpaperTarget);
-
-        return changed;
-    }
-
-    void setWallpaperAnimLayerAdjustmentLocked(int adj) {
-        if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "Setting wallpaper layer adj to " + adj);
-        mWallpaperAnimLayerAdjustment = adj;
-        for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
-            WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
-            for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
-                WindowState wallpaper = windows.get(wallpaperNdx);
-                wallpaper.mWinAnimator.mAnimLayer = wallpaper.mLayer + adj;
-                if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "setWallpaper win "
-                        + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
-            }
-        }
-    }
-
-    boolean updateWallpaperOffsetLocked(WindowState wallpaperWin, int dw, int dh,
-            boolean sync) {
-        boolean changed = false;
-        boolean rawChanged = false;
-        float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : 0.5f;
-        float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
-        int availw = wallpaperWin.mFrame.right-wallpaperWin.mFrame.left-dw;
-        int offset = availw > 0 ? -(int)(availw*wpx+.5f) : 0;
-        if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
-            offset += mLastWallpaperDisplayOffsetX;
-        }
-        changed = wallpaperWin.mXOffset != offset;
-        if (changed) {
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
-                    + wallpaperWin + " x: " + offset);
-            wallpaperWin.mXOffset = offset;
-        }
-        if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
-            wallpaperWin.mWallpaperX = wpx;
-            wallpaperWin.mWallpaperXStep = wpxs;
-            rawChanged = true;
-        }
-
-        float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
-        float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
-        int availh = wallpaperWin.mFrame.bottom-wallpaperWin.mFrame.top-dh;
-        offset = availh > 0 ? -(int)(availh*wpy+.5f) : 0;
-        if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
-            offset += mLastWallpaperDisplayOffsetY;
-        }
-        if (wallpaperWin.mYOffset != offset) {
-            if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper "
-                    + wallpaperWin + " y: " + offset);
-            changed = true;
-            wallpaperWin.mYOffset = offset;
-        }
-        if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
-            wallpaperWin.mWallpaperY = wpy;
-            wallpaperWin.mWallpaperYStep = wpys;
-            rawChanged = true;
-        }
-
-        if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
-                    WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
-            try {
-                if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
-                        + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
-                        + " y=" + wallpaperWin.mWallpaperY);
-                if (sync) {
-                    mWaitingOnWallpaper = wallpaperWin;
-                }
-                wallpaperWin.mClient.dispatchWallpaperOffsets(
-                        wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
-                        wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
-                if (sync) {
-                    if (mWaitingOnWallpaper != null) {
-                        long start = SystemClock.uptimeMillis();
-                        if ((mLastWallpaperTimeoutTime+WALLPAPER_TIMEOUT_RECOVERY)
-                                < start) {
-                            try {
-                                if (DEBUG_WALLPAPER) Slog.v(TAG,
-                                        "Waiting for offset complete...");
-                                mWindowMap.wait(WALLPAPER_TIMEOUT);
-                            } catch (InterruptedException e) {
-                            }
-                            if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
-                            if ((start+WALLPAPER_TIMEOUT)
-                                    < SystemClock.uptimeMillis()) {
-                                Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
-                                        + wallpaperWin);
-                                mLastWallpaperTimeoutTime = start;
-                            }
-                        }
-                        mWaitingOnWallpaper = null;
-                    }
-                }
-            } catch (RemoteException e) {
-            }
-        }
-
-        return changed;
-    }
-
-    void wallpaperOffsetsComplete(IBinder window) {
-        synchronized (mWindowMap) {
-            if (mWaitingOnWallpaper != null &&
-                    mWaitingOnWallpaper.mClient.asBinder() == window) {
-                mWaitingOnWallpaper = null;
-                mWindowMap.notifyAll();
-            }
-        }
-    }
-
-    void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
-        final DisplayContent displayContent = changingTarget.getDisplayContent();
-        if (displayContent == null) {
-            return;
-        }
-        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final int dw = displayInfo.logicalWidth;
-        final int dh = displayInfo.logicalHeight;
-
-        WindowState target = mWallpaperTarget;
-        if (target != null) {
-            if (target.mWallpaperX >= 0) {
-                mLastWallpaperX = target.mWallpaperX;
-            } else if (changingTarget.mWallpaperX >= 0) {
-                mLastWallpaperX = changingTarget.mWallpaperX;
-            }
-            if (target.mWallpaperY >= 0) {
-                mLastWallpaperY = target.mWallpaperY;
-            } else if (changingTarget.mWallpaperY >= 0) {
-                mLastWallpaperY = changingTarget.mWallpaperY;
-            }
-            if (target.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
-                mLastWallpaperDisplayOffsetX = target.mWallpaperDisplayOffsetX;
-            } else if (changingTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
-                mLastWallpaperDisplayOffsetX = changingTarget.mWallpaperDisplayOffsetX;
-            }
-            if (target.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
-                mLastWallpaperDisplayOffsetY = target.mWallpaperDisplayOffsetY;
-            } else if (changingTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
-                mLastWallpaperDisplayOffsetY = changingTarget.mWallpaperDisplayOffsetY;
-            }
-            if (target.mWallpaperXStep >= 0) {
-                mLastWallpaperXStep = target.mWallpaperXStep;
-            } else if (changingTarget.mWallpaperXStep >= 0) {
-                mLastWallpaperXStep = changingTarget.mWallpaperXStep;
-            }
-            if (target.mWallpaperYStep >= 0) {
-                mLastWallpaperYStep = target.mWallpaperYStep;
-            } else if (changingTarget.mWallpaperYStep >= 0) {
-                mLastWallpaperYStep = changingTarget.mWallpaperYStep;
-            }
-        }
-
-        for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
-            WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
-            for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
-                WindowState wallpaper = windows.get(wallpaperNdx);
-                if (updateWallpaperOffsetLocked(wallpaper, dw, dh, sync)) {
-                    WindowStateAnimator winAnimator = wallpaper.mWinAnimator;
-                    winAnimator.computeShownFrameLocked();
-                    // No need to lay out the windows - we can just set the wallpaper position
-                    // directly.
-                    winAnimator.setWallpaperOffset(wallpaper.mShownFrame);
-                    // We only want to be synchronous with one wallpaper.
-                    sync = false;
-                }
-            }
-        }
-    }
-
-    /**
-     * Check wallpaper for visibility change and notify window if so.
-     * @param wallpaper The wallpaper to test and notify.
-     * @param visible Current visibility.
-     */
-    void dispatchWallpaperVisibility(final WindowState wallpaper, final boolean visible) {
-        // Only send notification if the visibility actually changed and we are not trying to hide
-        // the wallpaper when we are deferring hiding of the wallpaper.
-        if (wallpaper.mWallpaperVisible != visible
-                && (mDeferredHideWallpaper == null || visible)) {
-            wallpaper.mWallpaperVisible = visible;
-            try {
-                if (DEBUG_VISIBILITY || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
-                        "Updating vis of wallpaper " + wallpaper
-                        + ": " + visible + " from:\n" + Debug.getCallers(4, "  "));
-                wallpaper.mClient.dispatchAppVisibility(visible);
-            } catch (RemoteException e) {
-            }
-        }
-    }
-
-    private void updateWallpaperVisibilityLocked() {
-        final boolean visible = isWallpaperVisible(mWallpaperTarget);
-        final DisplayContent displayContent = mWallpaperTarget.getDisplayContent();
-        if (displayContent == null) {
-            return;
-        }
-        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        final int dw = displayInfo.logicalWidth;
-        final int dh = displayInfo.logicalHeight;
-
-        for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
-            WindowToken token = mWallpaperTokens.get(curTokenNdx);
-            if (token.hidden == visible) {
-                token.hidden = !visible;
-                // Need to do a layout to ensure the wallpaper now has the
-                // correct size.
-                displayContent.layoutNeeded = true;
-            }
-
-            final WindowList windows = token.windows;
-            for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
-                WindowState wallpaper = windows.get(wallpaperNdx);
-                if (visible) {
-                    updateWallpaperOffsetLocked(wallpaper, dw, dh, false);
-                }
-
-                dispatchWallpaperVisibility(wallpaper, visible);
-            }
-        }
-    }
-
     public int addWindow(Session session, IWindow client, int seq,
             WindowManager.LayoutParams attrs, int viewVisibility, int displayId,
             Rect outContentInsets, Rect outStableInsets, Rect outOutsets,
@@ -2561,12 +1956,11 @@
             } else {
                 addWindowToListInOrderLocked(win, true);
                 if (type == TYPE_WALLPAPER) {
-                    mLastWallpaperTimeoutTime = 0;
+                    mWallpaperControllerLocked.clearLastWallpaperTimeoutTime();
                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
                 } else if ((attrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
                     displayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
-                } else if (mWallpaperTarget != null
-                        && mWallpaperTarget.mLayer >= win.mBaseLayer) {
+                } else if (mWallpaperControllerLocked.isBelowWallpaperTarget(win)) {
                     // If there is currently a wallpaper being shown, and
                     // the base layer of the new window is below the current
                     // layer of the target window, then adjust the wallpaper.
@@ -2863,7 +2257,7 @@
         }
 
         if (win.mAttrs.type == TYPE_WALLPAPER) {
-            mLastWallpaperTimeoutTime = 0;
+            mWallpaperControllerLocked.clearLastWallpaperTimeoutTime();
             getDefaultDisplayContentLocked().pendingLayoutChanges |=
                     WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
         } else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
@@ -2983,62 +2377,6 @@
         }
     }
 
-    public void setWindowWallpaperPositionLocked(WindowState window, float x, float y,
-            float xStep, float yStep) {
-        if (window.mWallpaperX != x || window.mWallpaperY != y)  {
-            window.mWallpaperX = x;
-            window.mWallpaperY = y;
-            window.mWallpaperXStep = xStep;
-            window.mWallpaperYStep = yStep;
-            updateWallpaperOffsetLocked(window, true);
-        }
-    }
-
-    void wallpaperCommandComplete(IBinder window, Bundle result) {
-        synchronized (mWindowMap) {
-            if (mWaitingOnWallpaper != null &&
-                    mWaitingOnWallpaper.mClient.asBinder() == window) {
-                mWaitingOnWallpaper = null;
-                mWindowMap.notifyAll();
-            }
-        }
-    }
-
-    public void setWindowWallpaperDisplayOffsetLocked(WindowState window, int x, int y) {
-        if (window.mWallpaperDisplayOffsetX != x || window.mWallpaperDisplayOffsetY != y)  {
-            window.mWallpaperDisplayOffsetX = x;
-            window.mWallpaperDisplayOffsetY = y;
-            updateWallpaperOffsetLocked(window, true);
-        }
-    }
-
-    public Bundle sendWindowWallpaperCommandLocked(WindowState window,
-            String action, int x, int y, int z, Bundle extras, boolean sync) {
-        if (window == mWallpaperTarget || window == mLowerWallpaperTarget
-                || window == mUpperWallpaperTarget) {
-            boolean doWait = sync;
-            for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
-                final WindowList windows = mWallpaperTokens.get(curTokenNdx).windows;
-                for (int wallpaperNdx = windows.size() - 1; wallpaperNdx >= 0; wallpaperNdx--) {
-                    WindowState wallpaper = windows.get(wallpaperNdx);
-                    try {
-                        wallpaper.mClient.dispatchWallpaperCommand(action,
-                                x, y, z, extras, sync);
-                        // We only want to be synchronous with one wallpaper.
-                        sync = false;
-                    } catch (RemoteException e) {
-                    }
-                }
-            }
-
-            if (doWait) {
-                // XXX Need to wait for result.
-            }
-        }
-
-        return null;
-    }
-
     public void onRectangleOnScreenRequested(IBinder token, Rect rectangle) {
         synchronized (mWindowMap) {
             if (mAccessibilityController != null) {
@@ -3293,7 +2631,7 @@
                             // Currently in a hide animation... turn this into
                             // an exit.
                             win.mExiting = true;
-                        } else if (win == mWallpaperTarget) {
+                        } else if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
                             // If the wallpaper is currently behind this
                             // window, we need to change both of them inside
                             // of a transaction to avoid artifacts.
@@ -3351,8 +2689,8 @@
             performLayoutAndPlaceSurfacesLocked();
             if (toBeDisplayed && win.mIsWallpaper) {
                 DisplayInfo displayInfo = getDefaultDisplayInfoLocked();
-                updateWallpaperOffsetLocked(win,
-                        displayInfo.logicalWidth, displayInfo.logicalHeight, false);
+                mWallpaperControllerLocked.updateWallpaperOffset(
+                        win, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
             }
             if (win.mAppToken != null) {
                 win.mAppToken.updateReportedVisibilityLocked();
@@ -3495,7 +2833,8 @@
             final boolean resizedWindow = !fullscreen && !dialogWindow;
             Animation a = mAppTransition.loadAnimation(lp, transit, enter, containingWidth,
                     containingHeight, mCurConfiguration.orientation, containingFrame, contentInsets,
-                    surfaceInsets, appFrame, isVoiceInteraction, resizedWindow);
+                    surfaceInsets, appFrame, isVoiceInteraction, resizedWindow,
+                    atoken.mTask.mTaskId);
             if (a != null) {
                 if (DEBUG_ANIM) {
                     RuntimeException e = null;
@@ -3629,7 +2968,7 @@
             wtoken = new WindowToken(this, token, type, true);
             mTokenMap.put(token, wtoken);
             if (type == TYPE_WALLPAPER) {
-                mWallpaperTokens.add(wtoken);
+                mWallpaperControllerLocked.addWallpaperToken(wtoken);
             }
         }
     }
@@ -3685,10 +3024,10 @@
                     if (delayed && displayContent != null) {
                         displayContent.mExitingTokens.add(wtoken);
                     } else if (wtoken.windowType == TYPE_WALLPAPER) {
-                        mWallpaperTokens.remove(wtoken);
+                        mWallpaperControllerLocked.removeWallpaperToken(wtoken);
                     }
                 } else if (wtoken.windowType == TYPE_WALLPAPER) {
-                    mWallpaperTokens.remove(wtoken);
+                    mWallpaperControllerLocked.removeWallpaperToken(wtoken);
                 }
 
                 mInputMonitor.updateInputWindowsLw(true /*force*/);
@@ -4219,6 +3558,14 @@
     }
 
     @Override
+    public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
+            IRemoteCallback callback, boolean scaleUp) {
+        synchronized (mWindowMap) {
+            mAppTransition.overridePendingAppTransitionMultiThumb(specs, callback, scaleUp);
+        }
+    }
+
+    @Override
     public void overridePendingAppTransitionInPlace(String packageName, int anim) {
         synchronized(mWindowMap) {
             mAppTransition.overrideInPlaceAppTransition(packageName, anim);
@@ -4427,7 +3774,7 @@
                 }
                 if (ent.array.getBoolean(
                         com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
-                    if (mWallpaperTarget == null) {
+                    if (mWallpaperControllerLocked.getWallpaperTarget() == null) {
                         // If this theme is requesting a wallpaper, and the wallpaper
                         // is not curently visible, then this effectively serves as
                         // an opaque window and our starting window transition animation
@@ -5853,6 +5200,7 @@
 
             if (!mBootAnimationStopped) {
                 // Do this one time.
+                Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
                 try {
                     IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
                     if (surfaceFlinger != null) {
@@ -5875,6 +5223,7 @@
             }
 
             EventLog.writeEvent(EventLogTags.WM_BOOT_ANIMATION_DONE, SystemClock.uptimeMillis());
+            Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
             mDisplayEnabled = true;
             if (DEBUG_SCREEN_ON || DEBUG_BOOT) Slog.i(TAG, "******************** ENABLING SCREEN!");
 
@@ -6286,7 +5635,7 @@
                         int right = wf.right - cr.right;
                         int bottom = wf.bottom - cr.bottom;
                         frame.union(left, top, right, bottom);
-                        ws.getTaskBounds(stackBounds);
+                        ws.getTaskBounds(stackBounds, !BOUNDS_FOR_TOUCH);
                         if (!frame.intersect(stackBounds)) {
                             // Set frame empty if there's no intersection.
                             frame.setEmpty();
@@ -7656,7 +7005,9 @@
     }
 
     public void displayReady() {
-        displayReady(Display.DEFAULT_DISPLAY);
+        for (Display display : mDisplays) {
+            displayReady(display.getDisplayId());
+        }
 
         synchronized(mWindowMap) {
             final DisplayContent displayContent = getDefaultDisplayContentLocked();
@@ -8282,10 +7633,7 @@
                 break;
                 case WALLPAPER_DRAW_PENDING_TIMEOUT: {
                     synchronized (mWindowMap) {
-                        if (mWallpaperDrawState == WALLPAPER_DRAW_PENDING) {
-                            mWallpaperDrawState = WALLPAPER_DRAW_TIMEOUT;
-                            if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
-                                    "*** WALLPAPER DRAW TIMEOUT");
+                        if (mWallpaperControllerLocked.processWallpaperDrawPendingTimeout()) {
                             performLayoutAndPlaceSurfacesLocked();
                         }
                     }
@@ -8908,7 +8256,7 @@
             if (w.mIsImWindow) {
                 winAnimator.mAnimLayer += mInputMethodAnimLayerAdjustment;
             } else if (w.mIsWallpaper) {
-                winAnimator.mAnimLayer += mWallpaperAnimLayerAdjustment;
+                winAnimator.mAnimLayer += mWallpaperControllerLocked.getAnimLayerAdjustment();
             }
             if (winAnimator.mAnimLayer != oldLayer) {
                 layerChanged = true;
@@ -9231,38 +8579,8 @@
                 }
             }
 
-            if (goodToGo && isWallpaperVisible(mWallpaperTarget)) {
-                boolean wallpaperGoodToGo = true;
-                for (int curTokenIndex = mWallpaperTokens.size() - 1;
-                        curTokenIndex >= 0 && wallpaperGoodToGo; curTokenIndex--) {
-                    WindowToken token = mWallpaperTokens.get(curTokenIndex);
-                    for (int curWallpaperIndex = token.windows.size() - 1; curWallpaperIndex >= 0;
-                            curWallpaperIndex--) {
-                        WindowState wallpaper = token.windows.get(curWallpaperIndex);
-                        if (wallpaper.mWallpaperVisible && !wallpaper.isDrawnLw()) {
-                            // We've told this wallpaper to be visible, but it is not drawn yet
-                            wallpaperGoodToGo = false;
-                            if (mWallpaperDrawState != WALLPAPER_DRAW_TIMEOUT) {
-                                // wait for this wallpaper until it is drawn or timeout
-                                goodToGo = false;
-                            }
-                            if (mWallpaperDrawState == WALLPAPER_DRAW_NORMAL) {
-                                mWallpaperDrawState = WALLPAPER_DRAW_PENDING;
-                                mH.removeMessages(H.WALLPAPER_DRAW_PENDING_TIMEOUT);
-                                mH.sendEmptyMessageDelayed(H.WALLPAPER_DRAW_PENDING_TIMEOUT,
-                                        WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION);
-                            }
-                            if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
-                                    "Wallpaper should be visible but has not been drawn yet. " +
-                                    "mWallpaperDrawState=" + mWallpaperDrawState);
-                            break;
-                        }
-                    }
-                }
-                if (wallpaperGoodToGo) {
-                    mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
-                    mH.removeMessages(H.WALLPAPER_DRAW_PENDING_TIMEOUT);
-                }
+            if (goodToGo && mWallpaperControllerLocked.isWallpaperVisible()) {
+                goodToGo &= mWallpaperControllerLocked.wallpaperTransitionReady();
             }
         }
         if (goodToGo) {
@@ -9279,10 +8597,9 @@
             rebuildAppWindowListLocked();
 
             // if wallpaper is animating in or out set oldWallpaper to null else to wallpaper
-            WindowState oldWallpaper =
-                    mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimating()
-                        && !mWallpaperTarget.mWinAnimator.isDummyAnimation()
-                    ? null : mWallpaperTarget;
+            final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
+            final WindowState oldWallpaper = mWallpaperControllerLocked.isWallpaperTargetAnimating()
+                    ? null : wallpaperTarget;
 
             mInnerFields.mWallpaperMayChange = false;
 
@@ -9293,21 +8610,26 @@
             boolean fullscreenAnim = false;
             boolean voiceInteraction = false;
 
+            final WindowState lowerWallpaperTarget =
+                    mWallpaperControllerLocked.getLowerWallpaperTarget();
+            final WindowState upperWallpaperTarget =
+                    mWallpaperControllerLocked.getUpperWallpaperTarget();
+
             if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
-                    "New wallpaper target=" + mWallpaperTarget
+                    "New wallpaper target=" + wallpaperTarget
                     + ", oldWallpaper=" + oldWallpaper
-                    + ", lower target=" + mLowerWallpaperTarget
-                    + ", upper target=" + mUpperWallpaperTarget);
+                    + ", lower target=" + lowerWallpaperTarget
+                    + ", upper target=" + upperWallpaperTarget);
 
             boolean openingAppHasWallpaper = false;
             boolean closingAppHasWallpaper = false;
             final AppWindowToken lowerWallpaperAppToken;
             final AppWindowToken upperWallpaperAppToken;
-            if (mLowerWallpaperTarget == null) {
+            if (lowerWallpaperTarget == null) {
                 lowerWallpaperAppToken = upperWallpaperAppToken = null;
             } else {
-                lowerWallpaperAppToken = mLowerWallpaperTarget.mAppToken;
-                upperWallpaperAppToken = mUpperWallpaperTarget.mAppToken;
+                lowerWallpaperAppToken = lowerWallpaperTarget.mAppToken;
+                upperWallpaperAppToken = upperWallpaperTarget.mAppToken;
             }
 
             // Do a first pass through the tokens for two
@@ -9381,7 +8703,7 @@
                 if (DEBUG_APP_TRANSITIONS) Slog.v(TAG,
                         "New transit away from wallpaper: "
                         + AppTransition.appTransitionToString(transit));
-            } else if (mWallpaperTarget != null && mWallpaperTarget.isVisibleLw()) {
+            } else if (wallpaperTarget != null && wallpaperTarget.isVisibleLw()) {
                 // We are transitioning from an activity without
                 // a wallpaper to now showing the wallpaper
                 transit = AppTransition.TRANSIT_WALLPAPER_OPEN;
@@ -9402,11 +8724,6 @@
                 animLp = null;
             }
 
-            AppWindowToken topOpeningApp = null;
-            AppWindowToken topClosingApp = null;
-            int topOpeningLayer = 0;
-            int topClosingLayer = 0;
-
             // Process all applications animating in place
             if (transit == AppTransition.TRANSIT_TASK_IN_PLACE) {
                 // Find the focused window
@@ -9431,49 +8748,8 @@
                 }
             }
 
-            appsCount = mOpeningApps.size();
-            for (i = 0; i < appsCount; i++) {
-                AppWindowToken wtoken = mOpeningApps.valueAt(i);
-                final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
-                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
-
-                if (!appAnimator.usingTransferredAnimation) {
-                    appAnimator.clearThumbnail();
-                    appAnimator.animation = null;
-                }
-                wtoken.inPendingTransaction = false;
-                if (!setTokenVisibilityLocked(
-                        wtoken, animLp, true, transit, false, voiceInteraction)){
-                    // This token isn't going to be animating. Add it to the list of tokens to
-                    // be notified of app transition complete since the notification will not be
-                    // sent be the app window animator.
-                    mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
-                }
-                wtoken.updateReportedVisibilityLocked();
-                wtoken.waitingToShow = false;
-
-                appAnimator.mAllAppWinAnimators.clear();
-                final int windowsCount = wtoken.allAppWindows.size();
-                for (int j = 0; j < windowsCount; j++) {
-                    appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
-                }
-                mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
-                mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
-
-                if (animLp != null) {
-                    int layer = -1;
-                    for (int j = 0; j < wtoken.windows.size(); j++) {
-                        WindowState win = wtoken.windows.get(j);
-                        if (win.mWinAnimator.mAnimLayer > layer) {
-                            layer = win.mWinAnimator.mAnimLayer;
-                        }
-                    }
-                    if (topOpeningApp == null || layer > topOpeningLayer) {
-                        topOpeningApp = wtoken;
-                        topOpeningLayer = layer;
-                    }
-                }
-            }
+            AppWindowToken topClosingApp = null;
+            int topClosingLayer = 0;
             appsCount = mClosingApps.size();
             for (i = 0; i < appsCount; i++) {
                 AppWindowToken wtoken = mClosingApps.valueAt(i);
@@ -9511,77 +8787,57 @@
                 }
             }
 
-            AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ? null :
+            AppWindowToken topOpeningApp = null;
+            appsCount = mOpeningApps.size();
+            for (i = 0; i < appsCount; i++) {
+                AppWindowToken wtoken = mOpeningApps.valueAt(i);
+                final AppWindowAnimator appAnimator = wtoken.mAppAnimator;
+                if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now opening app" + wtoken);
+
+                if (!appAnimator.usingTransferredAnimation) {
+                    appAnimator.clearThumbnail();
+                    appAnimator.animation = null;
+                }
+                wtoken.inPendingTransaction = false;
+                if (!setTokenVisibilityLocked(
+                        wtoken, animLp, true, transit, false, voiceInteraction)){
+                    // This token isn't going to be animating. Add it to the list of tokens to
+                    // be notified of app transition complete since the notification will not be
+                    // sent be the app window animator.
+                    mNoAnimationNotifyOnTransitionFinished.add(wtoken.token);
+                }
+                wtoken.updateReportedVisibilityLocked();
+                wtoken.waitingToShow = false;
+
+                appAnimator.mAllAppWinAnimators.clear();
+                final int windowsCount = wtoken.allAppWindows.size();
+                for (int j = 0; j < windowsCount; j++) {
+                    appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
+                }
+                mAnimator.mAnimating |= appAnimator.showAllWindowsLocked();
+                mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
+
+                int topOpeningLayer = 0;
+                if (animLp != null) {
+                    int layer = -1;
+                    for (int j = 0; j < wtoken.windows.size(); j++) {
+                        WindowState win = wtoken.windows.get(j);
+                        if (win.mWinAnimator.mAnimLayer > layer) {
+                            layer = win.mWinAnimator.mAnimLayer;
+                        }
+                    }
+                    if (topOpeningApp == null || layer > topOpeningLayer) {
+                        topOpeningApp = wtoken;
+                        topOpeningLayer = layer;
+                    }
+                }
+                createThumbnailAppAnimator(transit, wtoken, topOpeningLayer, topClosingLayer);
+            }
+
+            AppWindowAnimator openingAppAnimator = (topOpeningApp == null) ?  null :
                     topOpeningApp.mAppAnimator;
             AppWindowAnimator closingAppAnimator = (topClosingApp == null) ? null :
                     topClosingApp.mAppAnimator;
-            Bitmap nextAppTransitionThumbnail = mAppTransition.getNextAppTransitionThumbnail();
-            if (nextAppTransitionThumbnail != null
-                    && openingAppAnimator != null && openingAppAnimator.animation != null &&
-                    nextAppTransitionThumbnail.getConfig() != Config.ALPHA_8) {
-                // This thumbnail animation is very special, we need to have
-                // an extra surface with the thumbnail included with the animation.
-                Rect dirty = new Rect(0, 0, nextAppTransitionThumbnail.getWidth(),
-                        nextAppTransitionThumbnail.getHeight());
-                try {
-                    // TODO(multi-display): support other displays
-                    final DisplayContent displayContent = getDefaultDisplayContentLocked();
-                    final Display display = displayContent.getDisplay();
-                    final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-
-                    // Create a new surface for the thumbnail
-                    SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
-                            "thumbnail anim", dirty.width(), dirty.height(),
-                            PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
-                    surfaceControl.setLayerStack(display.getLayerStack());
-                    if (SHOW_TRANSACTIONS) {
-                        Slog.i(TAG, "  THUMBNAIL " + surfaceControl + ": CREATE");
-                    }
-
-                    // Draw the thumbnail onto the surface
-                    Surface drawSurface = new Surface();
-                    drawSurface.copyFrom(surfaceControl);
-                    Canvas c = drawSurface.lockCanvas(dirty);
-                    c.drawBitmap(nextAppTransitionThumbnail, 0, 0, null);
-                    drawSurface.unlockCanvasAndPost(c);
-                    drawSurface.release();
-
-                    // Get the thumbnail animation
-                    Animation anim;
-                    if (mAppTransition.isNextThumbnailTransitionAspectScaled()) {
-                        // If this is a multi-window scenario, we use the windows frame as
-                        // destination of the thumbnail header animation. If this is a full screen
-                        // window scenario, we use the whole display as the target.
-                        WindowState win = topOpeningApp.findMainWindow();
-                        Rect appRect = win != null ? win.getContentFrameLw() :
-                                new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
-                        // For the new aspect-scaled transition, we want it to always show
-                        // above the animating opening/closing window, and we want to
-                        // synchronize its thumbnail surface with the surface for the
-                        // open/close animation (only on the way down)
-                        anim = mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect);
-                        openingAppAnimator.thumbnailForceAboveLayer = Math.max(topOpeningLayer,
-                                topClosingLayer);
-                        openingAppAnimator.deferThumbnailDestruction =
-                                !mAppTransition.isNextThumbnailTransitionScaleUp();
-                    } else {
-                        anim = mAppTransition.createThumbnailScaleAnimationLocked(
-                                displayInfo.appWidth, displayInfo.appHeight, transit);
-                    }
-                    anim.restrictDuration(MAX_ANIMATION_DURATION);
-                    anim.scaleCurrentDuration(getTransitionAnimationScaleLocked());
-
-                    openingAppAnimator.thumbnail = surfaceControl;
-                    openingAppAnimator.thumbnailLayer = topOpeningLayer;
-                    openingAppAnimator.thumbnailAnimation = anim;
-                    openingAppAnimator.thumbnailX = mAppTransition.getStartingX();
-                    openingAppAnimator.thumbnailY = mAppTransition.getStartingY();
-                } catch (OutOfResourcesException e) {
-                    Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width()
-                            + " h=" + dirty.height(), e);
-                    openingAppAnimator.clearThumbnail();
-                }
-            }
 
             mAppTransition.goodToGo(openingAppAnimator, closingAppAnimator);
             mAppTransition.postAnimationCallback();
@@ -9609,6 +8865,83 @@
         return changes;
     }
 
+    private void createThumbnailAppAnimator(int transit, AppWindowToken appToken,
+            int openingLayer, int closingLayer) {
+        AppWindowAnimator openingAppAnimator = (appToken == null) ? null : appToken.mAppAnimator;
+        if (openingAppAnimator == null || openingAppAnimator.animation == null) {
+            return;
+        }
+        final int taskId = appToken.mTask.mTaskId;
+        Bitmap thumbnailHeader = mAppTransition.getAppTransitionThumbnailHeader(taskId);
+        if (thumbnailHeader == null || thumbnailHeader.getConfig() == Config.ALPHA_8) {
+            return;
+        }
+        // This thumbnail animation is very special, we need to have
+        // an extra surface with the thumbnail included with the animation.
+        Rect dirty = new Rect(0, 0, thumbnailHeader.getWidth(), thumbnailHeader.getHeight());
+        try {
+            // TODO(multi-display): support other displays
+            final DisplayContent displayContent = getDefaultDisplayContentLocked();
+            final Display display = displayContent.getDisplay();
+            final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+
+            // Create a new surface for the thumbnail
+            SurfaceControl surfaceControl = new SurfaceControl(mFxSession,
+                    "thumbnail anim", dirty.width(), dirty.height(),
+                    PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN);
+            surfaceControl.setLayerStack(display.getLayerStack());
+            if (SHOW_TRANSACTIONS) {
+                Slog.i(TAG, "  THUMBNAIL " + surfaceControl + ": CREATE");
+            }
+
+            // Draw the thumbnail onto the surface
+            Surface drawSurface = new Surface();
+            drawSurface.copyFrom(surfaceControl);
+            Canvas c = drawSurface.lockCanvas(dirty);
+            c.drawBitmap(thumbnailHeader, 0, 0, null);
+            drawSurface.unlockCanvasAndPost(c);
+            drawSurface.release();
+
+            // Get the thumbnail animation
+            Animation anim;
+            if (mAppTransition.isNextThumbnailTransitionAspectScaled()) {
+                // If this is a multi-window scenario, we use the windows frame as
+                // destination of the thumbnail header animation. If this is a full screen
+                // window scenario, we use the whole display as the target.
+                WindowState win = appToken.findMainWindow();
+                Rect appRect = win != null ? win.getContentFrameLw() :
+                        new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight);
+                // For the new aspect-scaled transition, we want it to always show
+                // above the animating opening/closing window, and we want to
+                // synchronize its thumbnail surface with the surface for the
+                // open/close animation (only on the way down)
+                anim = mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect,
+                        thumbnailHeader, taskId);
+                Log.d(TAG, "assigning thumbnail force above layer: " + openingLayer + " " +
+                        closingLayer);
+                openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer);
+                openingAppAnimator.deferThumbnailDestruction =
+                        !mAppTransition.isNextThumbnailTransitionScaleUp();
+            } else {
+                anim = mAppTransition.createThumbnailScaleAnimationLocked(
+                        displayInfo.appWidth, displayInfo.appHeight, transit, thumbnailHeader);
+            }
+            anim.restrictDuration(MAX_ANIMATION_DURATION);
+            anim.scaleCurrentDuration(getTransitionAnimationScaleLocked());
+
+            openingAppAnimator.thumbnail = surfaceControl;
+            openingAppAnimator.thumbnailLayer = openingLayer;
+            openingAppAnimator.thumbnailAnimation = anim;
+            mAppTransition.getNextAppTransitionStartRect(taskId, mTmpStartRect);
+            openingAppAnimator.thumbnailX = mTmpStartRect.left;
+            openingAppAnimator.thumbnailY = mTmpStartRect.top;
+        } catch (OutOfResourcesException e) {
+            Slog.e(TAG, "Can't allocate thumbnail/Canvas surface w=" + dirty.width()
+                    + " h=" + dirty.height(), e);
+            openingAppAnimator.clearThumbnail();
+        }
+    }
+
     /**
      * Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
      * @return bitmap indicating if another pass through layout must be made.
@@ -9624,10 +8957,7 @@
         }
         mNoAnimationNotifyOnTransitionFinished.clear();
 
-        if (mDeferredHideWallpaper != null) {
-            hideWallpapersLocked(mDeferredHideWallpaper);
-            mDeferredHideWallpaper = null;
-        }
+        mWallpaperControllerLocked.hideDeferredWallpapersIfNeeded();
 
         // Restore window app tokens to the ActivityManager views
         ArrayList<TaskStack> stacks = getDefaultDisplayContentLocked().getStacks();
@@ -9948,7 +9278,7 @@
 
                     if ((displayContent.pendingLayoutChanges &
                             WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0 &&
-                            adjustWallpaperWindowsLocked()) {
+                            mWallpaperControllerLocked.adjustWallpaperWindows()) {
                         assignLayersLocked(windows);
                         displayContent.layoutNeeded = true;
                     }
@@ -10020,12 +9350,12 @@
                         handleFlagDimBehind(w);
                     }
 
-                    if (isDefaultDisplay && obscuredChanged && (mWallpaperTarget == w)
-                            && w.isVisibleLw()) {
+                    if (isDefaultDisplay && obscuredChanged
+                            && mWallpaperControllerLocked.isWallpaperTarget(w) && w.isVisibleLw()) {
                         // This is the wallpaper target and its obscured state
                         // changed... make sure the current wallaper's visibility
                         // has been updated accordingly.
-                        updateWallpaperVisibilityLocked();
+                        mWallpaperControllerLocked.updateWallpaperVisibility();
                     }
 
                     final WindowStateAnimator winAnimator = w.mWinAnimator;
@@ -10274,7 +9604,7 @@
                 if (mInputMethodWindow == win) {
                     mInputMethodWindow = null;
                 }
-                if (win == mWallpaperTarget) {
+                if (mWallpaperControllerLocked.isWallpaperTarget(win)) {
                     wallpaperDestroyed = true;
                 }
                 win.mWinAnimator.destroySurfaceLocked();
@@ -10291,7 +9621,7 @@
                 if (!token.hasVisible) {
                     exitingTokens.remove(i);
                     if (token.windowType == TYPE_WALLPAPER) {
-                        mWallpaperTokens.remove(token);
+                        mWallpaperControllerLocked.removeWallpaperToken(token);
                     }
                 }
             }
@@ -11198,21 +10528,7 @@
                 }
             }
         }
-        if (!mWallpaperTokens.isEmpty()) {
-            pw.println();
-            pw.println("  Wallpaper tokens:");
-            for (int i=mWallpaperTokens.size()-1; i>=0; i--) {
-                WindowToken token = mWallpaperTokens.get(i);
-                pw.print("  Wallpaper #"); pw.print(i);
-                        pw.print(' '); pw.print(token);
-                if (dumpAll) {
-                    pw.println(':');
-                    token.dump(pw, "    ");
-                } else {
-                    pw.println();
-                }
-            }
-        }
+        mWallpaperControllerLocked.dumpTokens(pw, "  ", dumpAll);
         if (!mFinishedStarting.isEmpty()) {
             pw.println();
             pw.println("  Finishing start of application tokens:");
@@ -11412,25 +10728,13 @@
             if (mInputMethodWindow != null) {
                 pw.print("  mInputMethodWindow="); pw.println(mInputMethodWindow);
             }
-            pw.print("  mWallpaperTarget="); pw.println(mWallpaperTarget);
-            if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
-                pw.print("  mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
-                pw.print("  mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
-            }
-            pw.print("  mLastWallpaperX="); pw.print(mLastWallpaperX);
-                    pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
-            if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE
-                    || mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
-                pw.print("  mLastWallpaperDisplayOffsetX="); pw.print(mLastWallpaperDisplayOffsetX);
-                        pw.print(" mLastWallpaperDisplayOffsetY=");
-                        pw.println(mLastWallpaperDisplayOffsetY);
-            }
+            mWallpaperControllerLocked.dump(pw, "  ");
             if (mInputMethodAnimLayerAdjustment != 0 ||
-                    mWallpaperAnimLayerAdjustment != 0) {
+                    mWallpaperControllerLocked.getAnimLayerAdjustment() != 0) {
                 pw.print("  mInputMethodAnimLayerAdjustment=");
                         pw.print(mInputMethodAnimLayerAdjustment);
                         pw.print("  mWallpaperAnimLayerAdjustment=");
-                        pw.println(mWallpaperAnimLayerAdjustment);
+                        pw.println(mWallpaperControllerLocked.getAnimLayerAdjustment());
             }
             pw.print("  mSystemBooted="); pw.print(mSystemBooted);
                     pw.print(" mDisplayEnabled="); pw.println(mDisplayEnabled);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 4061149..092a6d1 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
@@ -33,11 +34,11 @@
 import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
 
 import android.app.AppOpsManager;
-import android.os.Debug;
 import android.os.PowerManager;
 import android.os.RemoteCallbackList;
 import android.os.SystemClock;
 import android.os.WorkSource;
+import android.util.DisplayMetrics;
 import android.util.TimeUtils;
 import android.view.Display;
 import android.view.IWindowFocusObserver;
@@ -78,6 +79,16 @@
 final class WindowState implements WindowManagerPolicy.WindowState {
     static final String TAG = "WindowState";
 
+    // The minimal size of a window within the usable area of the freeform stack.
+    private static final int MINIMUM_VISIBLE_WIDTH_IN_DP = 48;
+    private static final int MINIMUM_VISIBLE_HEIGHT_IN_DP = 32;
+
+    // The thickness of a window resize handle outside the window bounds on the free form workspace
+    // to capture touch events in that area.
+    private static final int RESIZE_HANDLE_WIDTH_IN_DP = 10;
+
+    static final boolean BOUNDS_FOR_TOUCH = true;
+
     final WindowManagerService mService;
     final WindowManagerPolicy mPolicy;
     final Context mContext;
@@ -537,6 +548,7 @@
 
         final Task task = mAppToken != null ? getTask() : null;
         final boolean nonFullscreenTask = task != null && !task.isFullscreen();
+        final boolean freeformWorkspace = inFreeformWorkspace();
         if (nonFullscreenTask) {
             task.getBounds(mContainingFrame);
             final WindowState imeWin = mService.mInputMethodWindow;
@@ -545,10 +557,20 @@
                 // IME is up and obscuring this window. Adjust the window position so it is visible.
                 mContainingFrame.top -= mContainingFrame.bottom - cf.bottom;
             }
-            // Make sure the containing frame is within the content frame so we don't layout
-            // resized window under screen decorations.
-            if (!mContainingFrame.intersect(cf)) {
-                mContainingFrame.set(cf);
+
+            if (freeformWorkspace) {
+                // In free form mode we have only to set the rectangle if it wasn't set already. No
+                // need to intersect it with the (visible) "content frame" since it is allowed to
+                // be outside the visible desktop.
+                if (mContainingFrame.isEmpty()) {
+                    mContainingFrame.set(cf);
+                }
+            } else {
+                // Make sure the containing frame is within the content frame so we don't layout
+                // resized window under screen decorations.
+                if (!mContainingFrame.intersect(cf)) {
+                    mContainingFrame.set(cf);
+                }
             }
             mDisplayFrame.set(mContainingFrame);
         } else {
@@ -652,20 +674,38 @@
 
         // Make sure the content and visible frames are inside of the
         // final window frame.
-        mContentFrame.set(Math.max(mContentFrame.left, mFrame.left),
-                Math.max(mContentFrame.top, mFrame.top),
-                Math.min(mContentFrame.right, mFrame.right),
-                Math.min(mContentFrame.bottom, mFrame.bottom));
+        if (freeformWorkspace && !mFrame.isEmpty()) {
+            // Keep the frame out of the blocked system area, limit it in size to the content area
+            // and make sure that there is always a minimum visible so that the user can drag it
+            // into a usable area..
+            final int height = Math.min(mFrame.height(), mContentFrame.height());
+            final int width = Math.min(mContentFrame.width(), mFrame.width());
+            final int minVisibleHeight = calculatePixelFromDp(MINIMUM_VISIBLE_HEIGHT_IN_DP);
+            final int minVisibleWidth = calculatePixelFromDp(MINIMUM_VISIBLE_WIDTH_IN_DP);
+            final int top = Math.max(mContentFrame.top,
+                    Math.min(mFrame.top, mContentFrame.bottom - minVisibleHeight));
+            final int left = Math.max(mContentFrame.left + minVisibleWidth - width,
+                    Math.min(mFrame.left, mContentFrame.right - minVisibleWidth));
+            mFrame.set(left, top, left + width, top + height);
+            mContentFrame.set(mFrame);
+            mVisibleFrame.set(mContentFrame);
+            mStableFrame.set(mContentFrame);
+        } else {
+            mContentFrame.set(Math.max(mContentFrame.left, mFrame.left),
+                    Math.max(mContentFrame.top, mFrame.top),
+                    Math.min(mContentFrame.right, mFrame.right),
+                    Math.min(mContentFrame.bottom, mFrame.bottom));
 
-        mVisibleFrame.set(Math.max(mVisibleFrame.left, mFrame.left),
-                Math.max(mVisibleFrame.top, mFrame.top),
-                Math.min(mVisibleFrame.right, mFrame.right),
-                Math.min(mVisibleFrame.bottom, mFrame.bottom));
+            mVisibleFrame.set(Math.max(mVisibleFrame.left, mFrame.left),
+                    Math.max(mVisibleFrame.top, mFrame.top),
+                    Math.min(mVisibleFrame.right, mFrame.right),
+                    Math.min(mVisibleFrame.bottom, mFrame.bottom));
 
-        mStableFrame.set(Math.max(mStableFrame.left, mFrame.left),
-                Math.max(mStableFrame.top, mFrame.top),
-                Math.min(mStableFrame.right, mFrame.right),
-                Math.min(mStableFrame.bottom, mFrame.bottom));
+            mStableFrame.set(Math.max(mStableFrame.left, mFrame.left),
+                    Math.max(mStableFrame.top, mFrame.top),
+                    Math.min(mStableFrame.right, mFrame.right),
+                    Math.min(mStableFrame.bottom, mFrame.bottom));
+        }
 
         mOverscanInsets.set(Math.max(mOverscanFrame.left - mFrame.left, 0),
                 Math.max(mOverscanFrame.top - mFrame.top, 0),
@@ -707,8 +747,8 @@
             final DisplayContent displayContent = getDisplayContent();
             if (displayContent != null) {
                 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-                mService.updateWallpaperOffsetLocked(this,
-                        displayInfo.logicalWidth, displayInfo.logicalHeight, false);
+                mService.mWallpaperControllerLocked.updateWallpaperOffset(
+                        this, displayInfo.logicalWidth, displayInfo.logicalHeight, false);
             }
         }
 
@@ -875,10 +915,22 @@
         return mDisplayContent.getHomeStack();
     }
 
-    void getTaskBounds(Rect bounds) {
+    /**
+     * Retrieves the bounds for a task.
+     * @param bounds The rect which gets the bounds.
+     * @param forTouch Pass in BOUNDS_FOR_TOUCH to get touch related bounds, otherwise visible
+     *        bounds will be returned.
+     */
+    void getTaskBounds(Rect bounds, boolean forTouch) {
         final Task task = getTask();
         if (task != null) {
             task.getBounds(bounds);
+            if (forTouch == BOUNDS_FOR_TOUCH) {
+                if (inFreeformWorkspace()) {
+                    final int delta = calculatePixelFromDp(RESIZE_HANDLE_WIDTH_IN_DP);
+                    bounds.inset(-delta, -delta);
+                }
+            }
             return;
         }
         bounds.set(mFrame);
@@ -1577,6 +1629,19 @@
         }
     }
 
+    private boolean inFreeformWorkspace() {
+        final Task task = getTask();
+        return task != null && task.mStack != null &&
+                task.mStack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
+    }
+
+    private int calculatePixelFromDp(int dp) {
+        final Configuration serviceConfig = mService.mCurConfiguration;
+        // TODO(multidisplay): Update Dp to that of display stack is on.
+        final float density = serviceConfig.densityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
+        return (int)(dp * density);
+    }
+
     void dump(PrintWriter pw, String prefix, boolean dumpAll) {
         final TaskStack stack = getStack();
         pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId());
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 28491e4..7aa48ab 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -47,7 +47,6 @@
 import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
-import android.view.View;
 import android.view.WindowManager;
 import android.view.WindowManagerPolicy;
 import android.view.WindowManager.LayoutParams;
@@ -77,6 +76,7 @@
     final WindowManagerPolicy mPolicy;
     final Context mContext;
     final boolean mIsWallpaper;
+    final WallpaperController mWallpaperControllerLocked;
 
     // Currently running animation.
     boolean mAnimating;
@@ -209,6 +209,7 @@
         mSession = win.mSession;
         mAttrType = win.mAttrs.type;
         mIsWallpaper = win.mIsWallpaper;
+        mWallpaperControllerLocked = mService.mWallpaperControllerLocked;
     }
 
     public void setAnimation(Animation anim, long startTime) {
@@ -375,7 +376,7 @@
         if (mWin.mIsImWindow) {
             mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
         } else if (mIsWallpaper) {
-            mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
+            mAnimLayer += mWallpaperControllerLocked.getAnimLayerAdjustment();
         }
         if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
                 + " anim layer: " + mAnimLayer);
@@ -484,7 +485,7 @@
             mService.mPendingRemove.add(mWin);
             mWin.mRemoveOnExit = false;
         }
-        mService.hideWallpapersLocked(mWin);
+        mWallpaperControllerLocked.hideWallpapers(mWin);
     }
 
     void hide() {
@@ -986,7 +987,7 @@
                     }
                     mSurfaceControl.destroy();
                 }
-                mService.hideWallpapersLocked(mWin);
+                mWallpaperControllerLocked.hideWallpapers(mWin);
             } catch (RuntimeException e) {
                 Slog.w(TAG, "Exception thrown when destroying Window " + this
                     + " surface " + mSurfaceControl + " session " + mSession
@@ -1012,7 +1013,7 @@
                     WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
                 }
                 mPendingDestroySurface.destroy();
-                mService.hideWallpapersLocked(mWin);
+                mWallpaperControllerLocked.hideWallpapers(mWin);
             }
         } catch (RuntimeException e) {
             Slog.w(TAG, "Exception thrown when destroying Window "
@@ -1033,7 +1034,7 @@
 
         // Wallpapers are animated based on the "real" window they
         // are currently targeting.
-        final WindowState wallpaperTarget = mService.mWallpaperTarget;
+        final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
         if (mIsWallpaper && wallpaperTarget != null && mService.mAnimateWallpaperWithTarget) {
             final WindowStateAnimator wallpaperAnimator = wallpaperTarget.mWinAnimator;
             if (wallpaperAnimator.mHasLocalTransformation &&
@@ -1467,7 +1468,7 @@
             hide();
         } else if (w.mAttachedHidden || !w.isOnScreen()) {
             hide();
-            mService.hideWallpapersLocked(w);
+            mWallpaperControllerLocked.hideWallpapers(w);
 
             // If we are waiting for this window to handle an
             // orientation change, well, it is hidden, so
@@ -1522,7 +1523,7 @@
                         if (showSurfaceRobustlyLocked()) {
                             mLastHidden = false;
                             if (mIsWallpaper) {
-                                mService.dispatchWallpaperVisibility(w, true);
+                                mWallpaperControllerLocked.dispatchWallpaperVisibility(w, true);
                             }
                             // This draw means the difference between unique content and mirroring.
                             // Run another pass through performLayout to set mHasContent in the
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index cd2885b..471994a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4523,12 +4523,12 @@
             long id = Binder.clearCallingIdentity();
             try {
                 mUserManager.setUserEnabled(userId);
+                UserInfo parent = mUserManager.getProfileParent(userId);
                 Intent intent = new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED);
                 intent.putExtra(Intent.EXTRA_USER, new UserHandle(userHandle));
                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
                         Intent.FLAG_RECEIVER_FOREGROUND);
-                // TODO This should send to parent of profile (which is always owner at the moment).
-                mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
+                mContext.sendBroadcastAsUser(intent, new UserHandle(parent.id));
             } finally {
                 restoreCallingIdentity(id);
             }
@@ -4963,13 +4963,19 @@
             IPackageManager pm = AppGlobals.getPackageManager();
             long id = Binder.clearCallingIdentity();
             try {
+                UserInfo parent = mUserManager.getProfileParent(callingUserId);
+                if (parent == null) {
+                    Slog.e(LOG_TAG, "Cannot call addCrossProfileIntentFilter if there is no "
+                            + "parent");
+                    return;
+                }
                 if ((flags & DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED) != 0) {
                     pm.addCrossProfileIntentFilter(filter, who.getPackageName(), callingUserId,
-                            UserHandle.USER_OWNER, 0);
+                            parent.id, 0);
                 }
                 if ((flags & DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT) != 0) {
                     pm.addCrossProfileIntentFilter(filter, who.getPackageName(),
-                            UserHandle.USER_OWNER, callingUserId, 0);
+                            parent.id, callingUserId, 0);
                 }
             } catch (RemoteException re) {
                 // Shouldn't happen
@@ -4988,12 +4994,18 @@
             IPackageManager pm = AppGlobals.getPackageManager();
             long id = Binder.clearCallingIdentity();
             try {
-                // Removing those that go from the managed profile to the primary user.
+                UserInfo parent = mUserManager.getProfileParent(callingUserId);
+                if (parent == null) {
+                    Slog.e(LOG_TAG, "Cannot call clearCrossProfileIntentFilter if there is no "
+                            + "parent");
+                    return;
+                }
+                // Removing those that go from the managed profile to the parent.
                 pm.clearCrossProfileIntentFilters(callingUserId, who.getPackageName());
-                // And those that go from the primary user to the managed profile.
+                // And those that go from the parent to the managed profile.
                 // If we want to support multiple managed profiles, we will have to only remove
                 // those that have callingUserId as their target.
-                pm.clearCrossProfileIntentFilters(UserHandle.USER_OWNER, who.getPackageName());
+                pm.clearCrossProfileIntentFilters(parent.id, who.getPackageName());
             } catch (RemoteException re) {
                 // Shouldn't happen
             } finally {
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index 33979b1..3ad26d3 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -13,6 +13,7 @@
     services.net \
     easymocklib \
     guava \
+    android-support-test \
     mockito-target
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 919293a..386a9cb 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -69,7 +69,7 @@
     </application>
 
     <instrumentation
-    	android:name="android.test.InstrumentationTestRunner"
+    	android:name="android.support.test.runner.AndroidJUnitRunner"
     	android:targetPackage="com.android.frameworks.servicestests"
     	android:label="Frameworks Services Tests" />
 </manifest>
diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index 696f106..b4c76b7 100644
--- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -943,8 +943,7 @@
         if (capability == NET_CAPABILITY_CBS || capability == NET_CAPABILITY_DUN ||
                 capability == NET_CAPABILITY_EIMS || capability == NET_CAPABILITY_FOTA ||
                 capability == NET_CAPABILITY_IA || capability == NET_CAPABILITY_IMS ||
-                capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP ||
-                capability == NET_CAPABILITY_TRUSTED || capability == NET_CAPABILITY_NOT_VPN) {
+                capability == NET_CAPABILITY_RCS || capability == NET_CAPABILITY_XCAP) {
             assertFalse(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
         } else {
             assertTrue(nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED));
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index d91fa90..2d31a78 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -512,8 +512,8 @@
                         Objects.equals(mGatewayInfo, d.mGatewayInfo) &&
                         Objects.equals(mVideoState, d.mVideoState) &&
                         Objects.equals(mStatusHints, d.mStatusHints) &&
-                        Objects.equals(mExtras, d.mExtras) &&
-                        Objects.equals(mIntentExtras, d.mIntentExtras);
+                        areBundlesEqual(mExtras, d.mExtras) &&
+                        areBundlesEqual(mIntentExtras, d.mIntentExtras);
             }
             return false;
         }
@@ -1253,4 +1253,32 @@
             });
         }
     }
+
+    /**
+     * Determines if two bundles are equal.
+     *
+     * @param bundle The original bundle.
+     * @param newBundle The bundle to compare with.
+     * @retrun {@code true} if the bundles are equal, {@code false} otherwise.
+     */
+    private static boolean areBundlesEqual(Bundle bundle, Bundle newBundle) {
+        if (bundle == null || newBundle == null) {
+            return bundle == newBundle;
+        }
+
+        if (bundle.size() != newBundle.size()) {
+            return false;
+        }
+
+        for(String key : bundle.keySet()) {
+            if (key != null) {
+                final Object value = bundle.get(key);
+                final Object newValue = newBundle.get(key);
+                if (!Objects.equals(value, newValue)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
 }
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 263c5e9..31f1d7f 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -358,6 +358,13 @@
     public static final String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
 
     /**
+     * Determines whether conference calls are supported by a carrier.  When {@code true},
+     * conference calling is supported, {@code false otherwise}.
+     * @hide
+     */
+    public static final String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
+
+    /**
      * If this is true, the SIM card (through Customer Service Profile EF file) will be able to
      * prevent manual operator selection. If false, this SIM setting will be ignored and manual
      * operator selection will always be available. See CPHS4_2.WW6, CPHS B.4.7.1 for more
@@ -457,6 +464,7 @@
         sDefaults.putBoolean(KEY_FORCE_HOME_NETWORK_BOOL, false);
         sDefaults.putInt(KEY_IMS_DTMF_TONE_DELAY_INT, 0);
         sDefaults.putInt(KEY_CDMA_DTMF_TONE_DELAY_INT, 100);
+        sDefaults.putBoolean(KEY_SUPPORT_CONFERENCE_CALL_BOOL, true);
 
         // MMS defaults
         sDefaults.putBoolean(KEY_MMS_ALIAS_ENABLED_BOOL, false);
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 62859ec..a8fd91c 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -30,6 +30,7 @@
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
 import android.util.DisplayMetrics;
+import android.view.AppTransitionAnimationSpec;
 
 import java.lang.Override;
 
@@ -241,6 +242,12 @@
     }
 
     @Override
+    public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
+            IRemoteCallback callback, boolean scaleUp) {
+        // TODO Auto-generated method stub
+    }
+
+    @Override
     public void pauseKeyDispatching(IBinder arg0) throws RemoteException {
         // TODO Auto-generated method stub