DO NOT MERGE Cherry-pick: Api updates for wearable extensions to notifications

Change-Id: I40012fd0458ec103eabf75ed4c91f636e02f4c8f
diff --git a/api/current.txt b/api/current.txt
index a829bdf..1aa4d2a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4538,13 +4538,22 @@
     ctor public Notification.Action.Builder(android.app.Notification.Action);
     method public android.app.Notification.Action.Builder addExtras(android.os.Bundle);
     method public android.app.Notification.Action.Builder addRemoteInput(android.app.RemoteInput);
-    method public android.app.Notification.Action.Builder apply(android.app.Notification.Action.Builder.Extender);
     method public android.app.Notification.Action build();
+    method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Extender);
     method public android.os.Bundle getExtras();
   }
 
-  public static abstract interface Notification.Action.Builder.Extender {
-    method public abstract android.app.Notification.Action.Builder applyTo(android.app.Notification.Action.Builder);
+  public static abstract interface Notification.Action.Extender {
+    method public abstract android.app.Notification.Action.Builder extend(android.app.Notification.Action.Builder);
+  }
+
+  public static final class Notification.Action.WearableExtender implements android.app.Notification.Action.Extender {
+    ctor public Notification.Action.WearableExtender();
+    ctor public Notification.Action.WearableExtender(android.app.Notification.Action);
+    method public android.app.Notification.Action.WearableExtender clone();
+    method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Builder);
+    method public boolean isAvailableOffline();
+    method public android.app.Notification.Action.WearableExtender setAvailableOffline(boolean);
   }
 
   public static class Notification.BigPictureStyle extends android.app.Notification.Style {
@@ -4572,6 +4581,7 @@
     method public android.app.Notification.Builder addPerson(java.lang.String);
     method public android.app.Notification.Builder apply(android.app.Notification.Builder.Extender);
     method public android.app.Notification build();
+    method public android.app.Notification.Builder extend(android.app.Notification.Extender);
     method public android.os.Bundle getExtras();
     method public deprecated android.app.Notification getNotification();
     method public android.app.Notification.Builder setAutoCancel(boolean);
@@ -4613,8 +4623,8 @@
     method public android.app.Notification.Builder setWhen(long);
   }
 
-  public static abstract interface Notification.Builder.Extender {
-    method public abstract android.app.Notification.Builder applyTo(android.app.Notification.Builder);
+  public static abstract interface Notification.Extender {
+    method public abstract android.app.Notification.Builder extend(android.app.Notification.Builder);
   }
 
   public static class Notification.InboxStyle extends android.app.Notification.Style {
@@ -4644,6 +4654,51 @@
     field protected android.app.Notification.Builder mBuilder;
   }
 
+  public static final class Notification.WearableExtender implements android.app.Notification.Extender {
+    ctor public Notification.WearableExtender();
+    ctor public Notification.WearableExtender(android.app.Notification);
+    method public android.app.Notification.WearableExtender addAction(android.app.Notification.Action);
+    method public android.app.Notification.WearableExtender addActions(java.util.List<android.app.Notification.Action>);
+    method public android.app.Notification.WearableExtender addPage(android.app.Notification);
+    method public android.app.Notification.WearableExtender addPages(java.util.List<android.app.Notification>);
+    method public android.app.Notification.WearableExtender clearActions();
+    method public android.app.Notification.WearableExtender clearPages();
+    method public android.app.Notification.WearableExtender clone();
+    method public android.app.Notification.Builder extend(android.app.Notification.Builder);
+    method public java.util.List<android.app.Notification.Action> getActions();
+    method public android.graphics.Bitmap getBackground();
+    method public int getContentAction();
+    method public int getContentIcon();
+    method public int getContentIconGravity();
+    method public boolean getContentIntentAvailableOffline();
+    method public int getCustomContentHeight();
+    method public int getCustomSizePreset();
+    method public android.app.PendingIntent getDisplayIntent();
+    method public int getGravity();
+    method public boolean getHintHideIcon();
+    method public boolean getHintShowBackgroundOnly();
+    method public java.util.List<android.app.Notification> getPages();
+    method public boolean getStartScrollBottom();
+    method public android.app.Notification.WearableExtender setBackground(android.graphics.Bitmap);
+    method public android.app.Notification.WearableExtender setContentAction(int);
+    method public android.app.Notification.WearableExtender setContentIcon(int);
+    method public android.app.Notification.WearableExtender setContentIconGravity(int);
+    method public android.app.Notification.WearableExtender setContentIntentAvailableOffline(boolean);
+    method public android.app.Notification.WearableExtender setCustomContentHeight(int);
+    method public android.app.Notification.WearableExtender setCustomSizePreset(int);
+    method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
+    method public android.app.Notification.WearableExtender setGravity(int);
+    method public android.app.Notification.WearableExtender setHintHideIcon(boolean);
+    method public android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean);
+    method public android.app.Notification.WearableExtender setStartScrollBottom(boolean);
+    field public static final int SIZE_DEFAULT = 0; // 0x0
+    field public static final int SIZE_LARGE = 4; // 0x4
+    field public static final int SIZE_MEDIUM = 3; // 0x3
+    field public static final int SIZE_SMALL = 2; // 0x2
+    field public static final int SIZE_XSMALL = 1; // 0x1
+    field public static final int UNSET_ACTION_INDEX = -1; // 0xffffffff
+  }
+
   public class NotificationManager {
     method public void cancel(int);
     method public void cancel(java.lang.String, int);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index dfd927f..6e23b11 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -35,6 +35,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.TypedValue;
+import android.view.Gravity;
 import android.view.View;
 import android.widget.ProgressBar;
 import android.widget.RemoteViews;
@@ -46,7 +47,9 @@
 import java.lang.annotation.RetentionPolicy;
 import java.text.NumberFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.List;
 
 /**
  * A class that represents how a persistent notification is to be presented to
@@ -767,7 +770,7 @@
      */
     public static class Action implements Parcelable {
         private final Bundle mExtras;
-        private RemoteInput[] mRemoteInputs;
+        private final RemoteInput[] mRemoteInputs;
 
         /**
          * Small icon representing the action.
@@ -910,25 +913,12 @@
              * Apply an extender to this action builder. Extenders may be used to add
              * metadata or change options on this builder.
              */
-            public Builder apply(Extender extender) {
-                extender.applyTo(this);
+            public Builder extend(Extender extender) {
+                extender.extend(this);
                 return this;
             }
 
             /**
-             * Extender interface for use with {@link #apply}. Extenders may be used to add
-             * metadata or change options on this builder.
-             */
-            public interface Extender {
-                /**
-                 * Apply this extender to a notification action builder.
-                 * @param builder the builder to be modified.
-                 * @return the build object for chaining.
-                 */
-                public Builder applyTo(Builder builder);
-            }
-
-            /**
              * Combine all of the options that have been set and return a new {@link Action}
              * object.
              * @return the built action
@@ -975,6 +965,121 @@
                 return new Action[size];
             }
         };
+
+        /**
+         * Extender interface for use with {@link Builder#extend}. Extenders may be used to add
+         * metadata or change options on an action builder.
+         */
+        public interface Extender {
+            /**
+             * Apply this extender to a notification action builder.
+             * @param builder the builder to be modified.
+             * @return the build object for chaining.
+             */
+            public Builder extend(Builder builder);
+        }
+
+        /**
+         * Wearable extender for notification actions. To add extensions to an action,
+         * create a new {@link android.app.Notification.Action.WearableExtender} object using
+         * the {@code WearableExtender()} constructor and apply it to a
+         * {@link android.app.Notification.Action.Builder} using
+         * {@link android.app.Notification.Action.Builder#extend}.
+         *
+         * <pre class="prettyprint">
+         * Notification.Action action = new Notification.Action.Builder(
+         *         R.drawable.archive_all, "Archive all", actionIntent)
+         *         .apply(new Notification.Action.WearableExtender()
+         *                 .setAvailableOffline(false))
+         *         .build();
+         * </pre>
+         */
+        public static final class WearableExtender implements Extender {
+            /** Notification action extra which contains wearable extensions */
+            private static final String EXTRA_WEARABLE_EXTENSIONS = "android.wearable.EXTENSIONS";
+
+            private static final String KEY_FLAGS = "flags";
+
+            // Flags bitwise-ored to mFlags
+            private static final int FLAG_AVAILABLE_OFFLINE = 0x1;
+
+            // Default value for flags integer
+            private static final int DEFAULT_FLAGS = FLAG_AVAILABLE_OFFLINE;
+
+            private int mFlags = DEFAULT_FLAGS;
+
+            /**
+             * Create a {@link android.app.Notification.Action.WearableExtender} with default
+             * options.
+             */
+            public WearableExtender() {
+            }
+
+            /**
+             * Create a {@link android.app.Notification.Action.WearableExtender} by reading
+             * wearable options present in an existing notification action.
+             * @param action the notification action to inspect.
+             */
+            public WearableExtender(Action action) {
+                Bundle wearableBundle = action.getExtras().getBundle(EXTRA_WEARABLE_EXTENSIONS);
+                if (wearableBundle != null) {
+                    mFlags = wearableBundle.getInt(KEY_FLAGS, DEFAULT_FLAGS);
+                }
+            }
+
+            /**
+             * Apply wearable extensions to a notification action that is being built. This is
+             * typically called by the {@link android.app.Notification.Action.Builder#extend}
+             * method of {@link android.app.Notification.Action.Builder}.
+             */
+            @Override
+            public Action.Builder extend(Action.Builder builder) {
+                Bundle wearableBundle = new Bundle();
+
+                if (mFlags != DEFAULT_FLAGS) {
+                    wearableBundle.putInt(KEY_FLAGS, mFlags);
+                }
+
+                builder.getExtras().putBundle(EXTRA_WEARABLE_EXTENSIONS, wearableBundle);
+                return builder;
+            }
+
+            @Override
+            public WearableExtender clone() {
+                WearableExtender that = new WearableExtender();
+                that.mFlags = this.mFlags;
+                return that;
+            }
+
+            /**
+             * Set whether this action is available when the wearable device is not connected to
+             * a companion device. The user can still trigger this action when the wearable device is
+             * offline, but a visual hint will indicate that the action may not be available.
+             * Defaults to true.
+             */
+            public WearableExtender setAvailableOffline(boolean availableOffline) {
+                setFlag(FLAG_AVAILABLE_OFFLINE, availableOffline);
+                return this;
+            }
+
+            /**
+             * Get whether this action is available when the wearable device is not connected to
+             * a companion device. The user can still trigger this action when the wearable device is
+             * offline, but a visual hint will indicate that the action may not be available.
+             * Defaults to true.
+             */
+            public boolean isAvailableOffline() {
+                return (mFlags & FLAG_AVAILABLE_OFFLINE) != 0;
+            }
+
+            private void setFlag(int mask, boolean value) {
+                if (value) {
+                    mFlags |= mask;
+                } else {
+                    mFlags &= ~mask;
+                }
+            }
+        }
     }
 
     /**
@@ -2169,24 +2274,11 @@
          * Apply an extender to this notification builder. Extenders may be used to add
          * metadata or change options on this builder.
          */
-        public Builder apply(Extender extender) {
-            extender.applyTo(this);
+        public Builder extend(Extender extender) {
+            extender.extend(this);
             return this;
         }
 
-        /**
-         * Extender interface for use with {@link #apply}. Extenders may be used to add
-         * metadata or change options on this builder.
-         */
-        public interface Extender {
-            /**
-             * Apply this extender to a notification builder.
-             * @param builder the builder to be modified.
-             * @return the build object for chaining.
-             */
-            public Builder applyTo(Builder builder);
-        }
-
         private void setFlag(int mask, boolean value) {
             if (value) {
                 mFlags |= mask;
@@ -3163,4 +3255,634 @@
             return big;
         }
     }
+
+    /**
+     * Extender interface for use with {@link Builder#extend}. Extenders may be used to add
+     * metadata or change options on a notification builder.
+     */
+    public interface Extender {
+        /**
+         * Apply this extender to a notification builder.
+         * @param builder the builder to be modified.
+         * @return the build object for chaining.
+         */
+        public Builder extend(Builder builder);
+    }
+
+    /**
+     * Helper class to add wearable extensions to notifications.
+     * <p class="note"> See
+     * <a href="{@docRoot}wear/notifications/creating.html">Creating Notifications
+     * for Android Wear</a> for more information on how to use this class.
+     * <p>
+     * To create a notification with wearable extensions:
+     * <ol>
+     *   <li>Create a {@link android.app.Notification.Builder}, setting any desired
+     *   properties.
+     *   <li>Create a {@link android.app.Notification.WearableExtender}.
+     *   <li>Set wearable-specific properties using the
+     *   {@code add} and {@code set} methods of {@link android.app.Notification.WearableExtender}.
+     *   <li>Call {@link android.app.Notification.Builder#extend} to apply the extensions to a
+     *   notification.
+     *   <li>Post the notification to the notification system with the
+     *   {@code NotificationManager.notify(...)} methods.
+     * </ol>
+     *
+     * <pre class="prettyprint">
+     * Notification notif = new Notification.Builder(mContext)
+     *         .setContentTitle(&quot;New mail from &quot; + sender.toString())
+     *         .setContentText(subject)
+     *         .setSmallIcon(R.drawable.new_mail)
+     *         .extend(new Notification.WearableExtender()
+     *                 .setContentIcon(R.drawable.new_mail))
+     *         .build();
+     * NotificationManager notificationManger =
+     *         (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+     * notificationManger.notify(0, notif);</pre>
+     *
+     * <p>Wearable extensions can be accessed on an existing notification by using the
+     * {@code WearableExtender(Notification)} constructor,
+     * and then using the {@code get} methods to access values.
+     *
+     * <pre class="prettyprint">
+     * Notification.WearableExtender wearableExtender = new Notification.WearableExtender(
+     *         notification);
+     * List&lt;Notification&gt; pages = wearableExtender.getPages();
+     * </pre>
+     */
+    public static final class WearableExtender implements Extender {
+        /**
+         * Sentinel value for an action index that is unset.
+         */
+        public static final int UNSET_ACTION_INDEX = -1;
+
+        /**
+         * Size value for use with {@link #setCustomSizePreset} to show this notification with
+         * default sizing.
+         * <p>For custom display notifications created using {@link #setDisplayIntent},
+         * the default is {@link #SIZE_LARGE}. All other notifications size automatically based
+         * on their content.
+         */
+        public static final int SIZE_DEFAULT = 0;
+
+        /**
+         * Size value for use with {@link #setCustomSizePreset} to show this notification
+         * with an extra small size.
+         * <p>This value is only applicable for custom display notifications created using
+         * {@link #setDisplayIntent}.
+         */
+        public static final int SIZE_XSMALL = 1;
+
+        /**
+         * Size value for use with {@link #setCustomSizePreset} to show this notification
+         * with a small size.
+         * <p>This value is only applicable for custom display notifications created using
+         * {@link #setDisplayIntent}.
+         */
+        public static final int SIZE_SMALL = 2;
+
+        /**
+         * Size value for use with {@link #setCustomSizePreset} to show this notification
+         * with a medium size.
+         * <p>This value is only applicable for custom display notifications created using
+         * {@link #setDisplayIntent}.
+         */
+        public static final int SIZE_MEDIUM = 3;
+
+        /**
+         * Size value for use with {@link #setCustomSizePreset} to show this notification
+         * with a large size.
+         * <p>This value is only applicable for custom display notifications created using
+         * {@link #setDisplayIntent}.
+         */
+        public static final int SIZE_LARGE = 4;
+
+        /** Notification extra which contains wearable extensions */
+        private static final String EXTRA_WEARABLE_EXTENSIONS = "android.wearable.EXTENSIONS";
+
+        // Keys within EXTRA_WEARABLE_OPTIONS for wearable options.
+        private static final String KEY_ACTIONS = "actions";
+        private static final String KEY_FLAGS = "flags";
+        private static final String KEY_DISPLAY_INTENT = "displayIntent";
+        private static final String KEY_PAGES = "pages";
+        private static final String KEY_BACKGROUND = "background";
+        private static final String KEY_CONTENT_ICON = "contentIcon";
+        private static final String KEY_CONTENT_ICON_GRAVITY = "contentIconGravity";
+        private static final String KEY_CONTENT_ACTION_INDEX = "contentActionIndex";
+        private static final String KEY_CUSTOM_SIZE_PRESET = "customSizePreset";
+        private static final String KEY_CUSTOM_CONTENT_HEIGHT = "customContentHeight";
+        private static final String KEY_GRAVITY = "gravity";
+
+        // Flags bitwise-ored to mFlags
+        private static final int FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE = 0x1;
+        private static final int FLAG_HINT_HIDE_ICON = 1 << 1;
+        private static final int FLAG_HINT_SHOW_BACKGROUND_ONLY = 1 << 2;
+        private static final int FLAG_START_SCROLL_BOTTOM = 1 << 3;
+
+        // Default value for flags integer
+        private static final int DEFAULT_FLAGS = FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE;
+
+        private static final int DEFAULT_CONTENT_ICON_GRAVITY = Gravity.END;
+        private static final int DEFAULT_GRAVITY = Gravity.BOTTOM;
+
+        private ArrayList<Action> mActions = new ArrayList<Action>();
+        private int mFlags = DEFAULT_FLAGS;
+        private PendingIntent mDisplayIntent;
+        private ArrayList<Notification> mPages = new ArrayList<Notification>();
+        private Bitmap mBackground;
+        private int mContentIcon;
+        private int mContentIconGravity = DEFAULT_CONTENT_ICON_GRAVITY;
+        private int mContentActionIndex = UNSET_ACTION_INDEX;
+        private int mCustomSizePreset = SIZE_DEFAULT;
+        private int mCustomContentHeight;
+        private int mGravity = DEFAULT_GRAVITY;
+
+        /**
+         * Create a {@link android.app.Notification.WearableExtender} with default
+         * options.
+         */
+        public WearableExtender() {
+        }
+
+        public WearableExtender(Notification notif) {
+            Bundle wearableBundle = notif.extras.getBundle(EXTRA_WEARABLE_EXTENSIONS);
+            if (wearableBundle != null) {
+                List<Action> actions = wearableBundle.getParcelableArrayList(KEY_ACTIONS);
+                if (actions != null) {
+                    mActions.addAll(actions);
+                }
+
+                mFlags = wearableBundle.getInt(KEY_FLAGS, DEFAULT_FLAGS);
+                mDisplayIntent = wearableBundle.getParcelable(KEY_DISPLAY_INTENT);
+
+                Notification[] pages = getNotificationArrayFromBundle(
+                        wearableBundle, KEY_PAGES);
+                if (pages != null) {
+                    Collections.addAll(mPages, pages);
+                }
+
+                mBackground = wearableBundle.getParcelable(KEY_BACKGROUND);
+                mContentIcon = wearableBundle.getInt(KEY_CONTENT_ICON);
+                mContentIconGravity = wearableBundle.getInt(KEY_CONTENT_ICON_GRAVITY,
+                        DEFAULT_CONTENT_ICON_GRAVITY);
+                mContentActionIndex = wearableBundle.getInt(KEY_CONTENT_ACTION_INDEX,
+                        UNSET_ACTION_INDEX);
+                mCustomSizePreset = wearableBundle.getInt(KEY_CUSTOM_SIZE_PRESET,
+                        SIZE_DEFAULT);
+                mCustomContentHeight = wearableBundle.getInt(KEY_CUSTOM_CONTENT_HEIGHT);
+                mGravity = wearableBundle.getInt(KEY_GRAVITY, DEFAULT_GRAVITY);
+            }
+        }
+
+        /**
+         * Apply wearable extensions to a notification that is being built. This is typically
+         * called by the {@link android.app.Notification.Builder#extend} method of
+         * {@link android.app.Notification.Builder}.
+         */
+        @Override
+        public Notification.Builder extend(Notification.Builder builder) {
+            Bundle wearableBundle = new Bundle();
+
+            if (!mActions.isEmpty()) {
+                wearableBundle.putParcelableArrayList(KEY_ACTIONS, mActions);
+            }
+            if (mFlags != DEFAULT_FLAGS) {
+                wearableBundle.putInt(KEY_FLAGS, mFlags);
+            }
+            if (mDisplayIntent != null) {
+                wearableBundle.putParcelable(KEY_DISPLAY_INTENT, mDisplayIntent);
+            }
+            if (!mPages.isEmpty()) {
+                wearableBundle.putParcelableArray(KEY_PAGES, mPages.toArray(
+                        new Notification[mPages.size()]));
+            }
+            if (mBackground != null) {
+                wearableBundle.putParcelable(KEY_BACKGROUND, mBackground);
+            }
+            if (mContentIcon != 0) {
+                wearableBundle.putInt(KEY_CONTENT_ICON, mContentIcon);
+            }
+            if (mContentIconGravity != DEFAULT_CONTENT_ICON_GRAVITY) {
+                wearableBundle.putInt(KEY_CONTENT_ICON_GRAVITY, mContentIconGravity);
+            }
+            if (mContentActionIndex != UNSET_ACTION_INDEX) {
+                wearableBundle.putInt(KEY_CONTENT_ACTION_INDEX,
+                        mContentActionIndex);
+            }
+            if (mCustomSizePreset != SIZE_DEFAULT) {
+                wearableBundle.putInt(KEY_CUSTOM_SIZE_PRESET, mCustomSizePreset);
+            }
+            if (mCustomContentHeight != 0) {
+                wearableBundle.putInt(KEY_CUSTOM_CONTENT_HEIGHT, mCustomContentHeight);
+            }
+            if (mGravity != DEFAULT_GRAVITY) {
+                wearableBundle.putInt(KEY_GRAVITY, mGravity);
+            }
+
+            builder.getExtras().putBundle(EXTRA_WEARABLE_EXTENSIONS, wearableBundle);
+            return builder;
+        }
+
+        @Override
+        public WearableExtender clone() {
+            WearableExtender that = new WearableExtender();
+            that.mActions = new ArrayList<Action>(this.mActions);
+            that.mFlags = this.mFlags;
+            that.mDisplayIntent = this.mDisplayIntent;
+            that.mPages = new ArrayList<Notification>(this.mPages);
+            that.mBackground = this.mBackground;
+            that.mContentIcon = this.mContentIcon;
+            that.mContentIconGravity = this.mContentIconGravity;
+            that.mContentActionIndex = this.mContentActionIndex;
+            that.mCustomSizePreset = this.mCustomSizePreset;
+            that.mCustomContentHeight = this.mCustomContentHeight;
+            that.mGravity = this.mGravity;
+            return that;
+        }
+
+        /**
+         * Add a wearable action to this notification.
+         *
+         * <p>When wearable actions are added using this method, the set of actions that
+         * show on a wearable device splits from devices that only show actions added
+         * using {@link android.app.Notification.Builder#addAction}. This allows for customization
+         * of which actions display on different devices.
+         *
+         * @param action the action to add to this notification
+         * @return this object for method chaining
+         * @see android.app.Notification.Action
+         */
+        public WearableExtender addAction(Action action) {
+            mActions.add(action);
+            return this;
+        }
+
+        /**
+         * Adds wearable actions to this notification.
+         *
+         * <p>When wearable actions are added using this method, the set of actions that
+         * show on a wearable device splits from devices that only show actions added
+         * using {@link android.app.Notification.Builder#addAction}. This allows for customization
+         * of which actions display on different devices.
+         *
+         * @param actions the actions to add to this notification
+         * @return this object for method chaining
+         * @see android.app.Notification.Action
+         */
+        public WearableExtender addActions(List<Action> actions) {
+            mActions.addAll(actions);
+            return this;
+        }
+
+        /**
+         * Clear all wearable actions present on this builder.
+         * @return this object for method chaining.
+         * @see #addAction
+         */
+        public WearableExtender clearActions() {
+            mActions.clear();
+            return this;
+        }
+
+        /**
+         * Get the wearable actions present on this notification.
+         */
+        public List<Action> getActions() {
+            return mActions;
+        }
+
+        /**
+         * Set an intent to launch inside of an activity view when displaying
+         * this notification. This {@link PendingIntent} should be for an activity.
+         *
+         * @param intent the {@link PendingIntent} for an activity
+         * @return this object for method chaining
+         * @see android.app.Notification.WearableExtender#getDisplayIntent
+         */
+        public WearableExtender setDisplayIntent(PendingIntent intent) {
+            mDisplayIntent = intent;
+            return this;
+        }
+
+        /**
+         * Get the intent to launch inside of an activity view when displaying this
+         * notification. This {@code PendingIntent} should be for an activity.
+         */
+        public PendingIntent getDisplayIntent() {
+            return mDisplayIntent;
+        }
+
+        /**
+         * Add an additional page of content to display with this notification. The current
+         * notification forms the first page, and pages added using this function form
+         * subsequent pages. This field can be used to separate a notification into multiple
+         * sections.
+         *
+         * @param page the notification to add as another page
+         * @return this object for method chaining
+         * @see android.app.Notification.WearableExtender#getPages
+         */
+        public WearableExtender addPage(Notification page) {
+            mPages.add(page);
+            return this;
+        }
+
+        /**
+         * Add additional pages of content to display with this notification. The current
+         * notification forms the first page, and pages added using this function form
+         * subsequent pages. This field can be used to separate a notification into multiple
+         * sections.
+         *
+         * @param pages a list of notifications
+         * @return this object for method chaining
+         * @see android.app.Notification.WearableExtender#getPages
+         */
+        public WearableExtender addPages(List<Notification> pages) {
+            mPages.addAll(pages);
+            return this;
+        }
+
+        /**
+         * Clear all additional pages present on this builder.
+         * @return this object for method chaining.
+         * @see #addPage
+         */
+        public WearableExtender clearPages() {
+            mPages.clear();
+            return this;
+        }
+
+        /**
+         * Get the array of additional pages of content for displaying this notification. The
+         * current notification forms the first page, and elements within this array form
+         * subsequent pages. This field can be used to separate a notification into multiple
+         * sections.
+         * @return the pages for this notification
+         */
+        public List<Notification> getPages() {
+            return mPages;
+        }
+
+        /**
+         * Set a background image to be displayed behind the notification content.
+         * Contrary to the {@link android.app.Notification.BigPictureStyle}, this background
+         * will work with any notification style.
+         *
+         * @param background the background bitmap
+         * @return this object for method chaining
+         * @see android.app.Notification.WearableExtender#getBackground
+         */
+        public WearableExtender setBackground(Bitmap background) {
+            mBackground = background;
+            return this;
+        }
+
+        /**
+         * Get a background image to be displayed behind the notification content.
+         * Contrary to the {@link android.app.Notification.BigPictureStyle}, this background
+         * will work with any notification style.
+         *
+         * @return the background image
+         * @see android.app.Notification.WearableExtender#setBackground
+         */
+        public Bitmap getBackground() {
+            return mBackground;
+        }
+
+        /**
+         * Set an icon that goes with the content of this notification.
+         */
+        public WearableExtender setContentIcon(int icon) {
+            mContentIcon = icon;
+            return this;
+        }
+
+        /**
+         * Get an icon that goes with the content of this notification.
+         */
+        public int getContentIcon() {
+            return mContentIcon;
+        }
+
+        /**
+         * Set the gravity that the content icon should have within the notification display.
+         * Supported values include {@link android.view.Gravity#START} and
+         * {@link android.view.Gravity#END}. The default value is {@link android.view.Gravity#END}.
+         * @see #setContentIcon
+         */
+        public WearableExtender setContentIconGravity(int contentIconGravity) {
+            mContentIconGravity = contentIconGravity;
+            return this;
+        }
+
+        /**
+         * Get the gravity that the content icon should have within the notification display.
+         * Supported values include {@link android.view.Gravity#START} and
+         * {@link android.view.Gravity#END}. The default value is {@link android.view.Gravity#END}.
+         * @see #getContentIcon
+         */
+        public int getContentIconGravity() {
+            return mContentIconGravity;
+        }
+
+        /**
+         * Set an action from this notification's actions to be clickable with the content of
+         * this notification page. This action will no longer display separately from the
+         * notification content. This action's icon will display with optional subtext provided
+         * by the action's title.
+         * @param actionIndex The index of the action to hoist on the current notification page.
+         *                    If wearable actions are present, this index will apply to that list,
+         *                    otherwise it will apply to the main notification's actions list.
+         */
+        public WearableExtender setContentAction(int actionIndex) {
+            mContentActionIndex = actionIndex;
+            return this;
+        }
+
+        /**
+         * Get the action index of an action from this notification to show as clickable with
+         * the content of this notification page. When the user clicks this notification page,
+         * this action will trigger. This action will no longer display separately from the
+         * notification content. The action's icon will display with optional subtext provided
+         * by the action's title.
+         *
+         * <p>If wearable specific actions are present, this index will apply to that list,
+         * otherwise it will apply to the main notification's actions list.
+         */
+        public int getContentAction() {
+            return mContentActionIndex;
+        }
+
+        /**
+         * Set the gravity that this notification should have within the available viewport space.
+         * Supported values include {@link android.view.Gravity#TOP},
+         * {@link android.view.Gravity#CENTER_VERTICAL} and {@link android.view.Gravity#BOTTOM}.
+         * The default value is {@link android.view.Gravity#BOTTOM}.
+         */
+        public WearableExtender setGravity(int gravity) {
+            mGravity = gravity;
+            return this;
+        }
+
+        /**
+         * Get the gravity that this notification should have within the available viewport space.
+         * Supported values include {@link android.view.Gravity#TOP},
+         * {@link android.view.Gravity#CENTER_VERTICAL} and {@link android.view.Gravity#BOTTOM}.
+         * The default value is {@link android.view.Gravity#BOTTOM}.
+         */
+        public int getGravity() {
+            return mGravity;
+        }
+
+        /**
+         * Set the custom size preset for the display of this notification out of the available
+         * presets found in {@link android.app.Notification.WearableExtender}, e.g.
+         * {@link #SIZE_LARGE}.
+         * <p>Some custom size presets are only applicable for custom display notifications created
+         * using {@link android.app.Notification.WearableExtender#setDisplayIntent}. Check the
+         * documentation for the preset in question. See also
+         * {@link #setCustomContentHeight} and {@link #getCustomSizePreset}.
+         */
+        public WearableExtender setCustomSizePreset(int sizePreset) {
+            mCustomSizePreset = sizePreset;
+            return this;
+        }
+
+        /**
+         * Get the custom size preset for the display of this notification out of the available
+         * presets found in {@link android.app.Notification.WearableExtender}, e.g.
+         * {@link #SIZE_LARGE}.
+         * <p>Some custom size presets are only applicable for custom display notifications created
+         * using {@link #setDisplayIntent}. Check the documentation for the preset in question.
+         * See also {@link #setCustomContentHeight} and {@link #setCustomSizePreset}.
+         */
+        public int getCustomSizePreset() {
+            return mCustomSizePreset;
+        }
+
+        /**
+         * Set the custom height in pixels for the display of this notification's content.
+         * <p>This option is only available for custom display notifications created
+         * using {@link android.app.Notification.WearableExtender#setDisplayIntent}. See also
+         * {@link android.app.Notification.WearableExtender#setCustomSizePreset} and
+         * {@link #getCustomContentHeight}.
+         */
+        public WearableExtender setCustomContentHeight(int height) {
+            mCustomContentHeight = height;
+            return this;
+        }
+
+        /**
+         * Get the custom height in pixels for the display of this notification's content.
+         * <p>This option is only available for custom display notifications created
+         * using {@link #setDisplayIntent}. See also {@link #setCustomSizePreset} and
+         * {@link #setCustomContentHeight}.
+         */
+        public int getCustomContentHeight() {
+            return mCustomContentHeight;
+        }
+
+        /**
+         * Set whether the scrolling position for the contents of this notification should start
+         * at the bottom of the contents instead of the top when the contents are too long to
+         * display within the screen.  Default is false (start scroll at the top).
+         */
+        public WearableExtender setStartScrollBottom(boolean startScrollBottom) {
+            setFlag(FLAG_START_SCROLL_BOTTOM, startScrollBottom);
+            return this;
+        }
+
+        /**
+         * Get whether the scrolling position for the contents of this notification should start
+         * at the bottom of the contents instead of the top when the contents are too long to
+         * display within the screen. Default is false (start scroll at the top).
+         */
+        public boolean getStartScrollBottom() {
+            return (mFlags & FLAG_START_SCROLL_BOTTOM) != 0;
+        }
+
+        /**
+         * Set whether the content intent is available when the wearable device is not connected
+         * to a companion device.  The user can still trigger this intent when the wearable device
+         * is offline, but a visual hint will indicate that the content intent may not be available.
+         * Defaults to true.
+         */
+        public WearableExtender setContentIntentAvailableOffline(
+                boolean contentIntentAvailableOffline) {
+            setFlag(FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE, contentIntentAvailableOffline);
+            return this;
+        }
+
+        /**
+         * Get whether the content intent is available when the wearable device is not connected
+         * to a companion device.  The user can still trigger this intent when the wearable device
+         * is offline, but a visual hint will indicate that the content intent may not be available.
+         * Defaults to true.
+         */
+        public boolean getContentIntentAvailableOffline() {
+            return (mFlags & FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE) != 0;
+        }
+
+        /**
+         * Set a hint that this notification's icon should not be displayed.
+         * @param hintHideIcon {@code true} to hide the icon, {@code false} otherwise.
+         * @return this object for method chaining
+         */
+        public WearableExtender setHintHideIcon(boolean hintHideIcon) {
+            setFlag(FLAG_HINT_HIDE_ICON, hintHideIcon);
+            return this;
+        }
+
+        /**
+         * Get a hint that this notification's icon should not be displayed.
+         * @return {@code true} if this icon should not be displayed, false otherwise.
+         * The default value is {@code false} if this was never set.
+         */
+        public boolean getHintHideIcon() {
+            return (mFlags & FLAG_HINT_HIDE_ICON) != 0;
+        }
+
+        /**
+         * Set a visual hint that only the background image of this notification should be
+         * displayed, and other semantic content should be hidden. This hint is only applicable
+         * to sub-pages added using {@link #addPage}.
+         */
+        public WearableExtender setHintShowBackgroundOnly(boolean hintShowBackgroundOnly) {
+            setFlag(FLAG_HINT_SHOW_BACKGROUND_ONLY, hintShowBackgroundOnly);
+            return this;
+        }
+
+        /**
+         * Get a visual hint that only the background image of this notification should be
+         * displayed, and other semantic content should be hidden. This hint is only applicable
+         * to sub-pages added using {@link android.app.Notification.WearableExtender#addPage}.
+         */
+        public boolean getHintShowBackgroundOnly() {
+            return (mFlags & FLAG_HINT_SHOW_BACKGROUND_ONLY) != 0;
+        }
+
+        private void setFlag(int mask, boolean value) {
+            if (value) {
+                mFlags |= mask;
+            } else {
+                mFlags &= ~mask;
+            }
+        }
+    }
+
+    /**
+     * Get an array of Notification objects from a parcelable array bundle field.
+     * Update the bundle to have a typed array so fetches in the future don't need
+     * to do an array copy.
+     */
+    private static Notification[] getNotificationArrayFromBundle(Bundle bundle, String key) {
+        Parcelable[] array = bundle.getParcelableArray(key);
+        if (array instanceof Notification[] || array == null) {
+            return (Notification[]) array;
+        }
+        Notification[] typedArray = Arrays.copyOf(array, array.length,
+                Notification[].class);
+        bundle.putParcelableArray(key, typedArray);
+        return typedArray;
+    }
 }
diff --git a/core/java/android/app/RemoteInput.java b/core/java/android/app/RemoteInput.java
index 9cfc541..11420c5 100644
--- a/core/java/android/app/RemoteInput.java
+++ b/core/java/android/app/RemoteInput.java
@@ -64,18 +64,24 @@
     /** Extra added to a clip data intent object to hold the results bundle. */
     public static final String EXTRA_RESULTS_DATA = "android.remoteinput.resultsData";
 
+    // Flags bitwise-ored to mFlags
+    private static final int FLAG_ALLOW_FREE_FORM_INPUT = 0x1;
+
+    // Default value for flags integer
+    private static final int DEFAULT_FLAGS = FLAG_ALLOW_FREE_FORM_INPUT;
+
     private final String mResultKey;
     private final CharSequence mLabel;
     private final CharSequence[] mChoices;
-    private final boolean mAllowFreeFormInput;
+    private final int mFlags;
     private final Bundle mExtras;
 
     private RemoteInput(String resultKey, CharSequence label, CharSequence[] choices,
-            boolean allowFreeFormInput, Bundle extras) {
+            int flags, Bundle extras) {
         this.mResultKey = resultKey;
         this.mLabel = label;
         this.mChoices = choices;
-        this.mAllowFreeFormInput = allowFreeFormInput;
+        this.mFlags = flags;
         this.mExtras = extras;
     }
 
@@ -108,7 +114,7 @@
      * if you set this to false and {@link #getChoices} returns {@code null} or empty.
      */
     public boolean getAllowFreeFormInput() {
-        return mAllowFreeFormInput;
+        return (mFlags & FLAG_ALLOW_FREE_FORM_INPUT) != 0;
     }
 
     /**
@@ -125,7 +131,7 @@
         private final String mResultKey;
         private CharSequence mLabel;
         private CharSequence[] mChoices;
-        private boolean mAllowFreeFormInput = true;
+        private int mFlags = DEFAULT_FLAGS;
         private Bundle mExtras = new Bundle();
 
         /**
@@ -178,7 +184,7 @@
          * @return this object for method chaining
          */
         public Builder setAllowFreeFormInput(boolean allowFreeFormInput) {
-            mAllowFreeFormInput = allowFreeFormInput;
+            setFlag(mFlags, allowFreeFormInput);
             return this;
         }
 
@@ -205,12 +211,20 @@
             return mExtras;
         }
 
+        private void setFlag(int mask, boolean value) {
+            if (value) {
+                mFlags |= mask;
+            } else {
+                mFlags &= ~mask;
+            }
+        }
+
         /**
          * Combine all of the options that have been set and return a new {@link RemoteInput}
          * object.
          */
         public RemoteInput build() {
-            return new RemoteInput(mResultKey, mLabel, mChoices, mAllowFreeFormInput, mExtras);
+            return new RemoteInput(mResultKey, mLabel, mChoices, mFlags, mExtras);
         }
     }
 
@@ -218,7 +232,7 @@
         mResultKey = in.readString();
         mLabel = in.readCharSequence();
         mChoices = in.readCharSequenceArray();
-        mAllowFreeFormInput = in.readInt() != 0;
+        mFlags = in.readInt();
         mExtras = in.readBundle();
     }
 
@@ -279,7 +293,7 @@
         out.writeString(mResultKey);
         out.writeCharSequence(mLabel);
         out.writeCharSequenceArray(mChoices);
-        out.writeInt(mAllowFreeFormInput ? 1 : 0);
+        out.writeInt(mFlags);
         out.writeBundle(mExtras);
     }
 
diff --git a/core/java/android/app/wearable/WearableActionExtensions.java b/core/java/android/app/wearable/WearableActionExtensions.java
deleted file mode 100644
index c296ef2..0000000
--- a/core/java/android/app/wearable/WearableActionExtensions.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2014 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.app.wearable;
-
-import android.app.Notification;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Wearable extensions to notification actions. To add extensions to an action,
- * create a new {@link WearableActionExtensions} object using
- * {@link WearableActionExtensions.Builder} and apply it to a
- * {@link android.app.Notification.Action.Builder}.
- *
- * <pre class="prettyprint">
- * Notification.Action action = new Notification.Action.Builder(
- *         R.drawable.archive_all, "Archive all", actionIntent)
- *         .apply(new WearableActionExtensions.Builder()
- *                 .setAvailableOffline(false)
- *                 .build())
- *         .build();
- * </pre>
- */
-public final class WearableActionExtensions implements Notification.Action.Builder.Extender,
-        Parcelable {
-    /** Notification action extra which contains wearable extensions */
-    private static final String EXTRA_WEARABLE_EXTENSIONS = "android.wearable.EXTENSIONS";
-
-    // Flags bitwise-ored to mFlags
-    private static final int FLAG_AVAILABLE_OFFLINE = 1 << 0;
-
-    // Default value for flags integer
-    private static final int DEFAULT_FLAGS = FLAG_AVAILABLE_OFFLINE;
-
-    private final int mFlags;
-
-    private WearableActionExtensions(int flags) {
-        mFlags = flags;
-    }
-
-    private WearableActionExtensions(Parcel in) {
-        mFlags = in.readInt();
-    }
-
-    /**
-     * Create a {@link WearableActionExtensions} by reading wearable extensions present on an
-     * existing notification action.
-     * @param action the notification action to inspect.
-     * @return a new {@link WearableActionExtensions} object.
-     */
-    public static WearableActionExtensions from(Notification.Action action) {
-        WearableActionExtensions extensions = action.getExtras().getParcelable(
-                EXTRA_WEARABLE_EXTENSIONS);
-        if (extensions != null) {
-            return extensions;
-        } else {
-            // Return a WearableActionExtensions with default values.
-            return new Builder().build();
-        }
-    }
-
-    /**
-     * Get whether this action is available when the wearable device is not connected to
-     * a companion device. The user can still trigger this action when the wearable device is
-     * offline, but a visual hint will indicate that the action may not be available.
-     * Defaults to true.
-     */
-    public boolean isAvailableOffline() {
-        return (mFlags & FLAG_AVAILABLE_OFFLINE) != 0;
-    }
-
-    @Override
-    public Notification.Action.Builder applyTo(Notification.Action.Builder builder) {
-        builder.getExtras().putParcelable(EXTRA_WEARABLE_EXTENSIONS, this);
-        return builder;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(mFlags);
-    }
-
-    /**
-     * Builder for {@link WearableActionExtensions} objects, which adds wearable extensions to
-     * notification actions. To extend an action, create an instance of this class, call the set
-     * methods present, call {@link #build}, and finally apply the options to a
-     * {@link Notification.Action.Builder} using its
-     * {@link android.app.Notification.Action.Builder#apply} method.
-     */
-    public static final class Builder {
-        private int mFlags = DEFAULT_FLAGS;
-
-        /**
-         * Construct a builder to be used for adding wearable extensions to notification actions.
-         *
-         * <pre class="prettyprint">
-         * Notification.Action action = new Notification.Action.Builder(
-         *         R.drawable.archive_all, "Archive all", actionIntent)
-         *         .apply(new WearableActionExtensions.Builder()
-         *                 .setAvailableOffline(false)
-         *                 .build())
-         *         .build();</pre>
-         */
-        public Builder() {
-        }
-
-        /**
-         * Create a {@link Builder} by reading wearable extensions present on an
-         * existing {@code WearableActionExtensions} object.
-         * @param other the existing extensions to inspect.
-         */
-        public Builder(WearableActionExtensions other) {
-            mFlags = other.mFlags;
-        }
-
-        /**
-         * Set whether this action is available when the wearable device is not connected to
-         * a companion device. The user can still trigger this action when the wearable device is
-         * offline, but a visual hint will indicate that the action may not be available.
-         * Defaults to true.
-         */
-        public Builder setAvailableOffline(boolean availableOffline) {
-            setFlag(FLAG_AVAILABLE_OFFLINE, availableOffline);
-            return this;
-        }
-
-        /**
-         * Build a new {@link WearableActionExtensions} object with the extensions
-         * currently present on this builder.
-         * @return the extensions object.
-         */
-        public WearableActionExtensions build() {
-            return new WearableActionExtensions(mFlags);
-        }
-
-        private void setFlag(int mask, boolean value) {
-            if (value) {
-                mFlags |= mask;
-            } else {
-                mFlags &= ~mask;
-            }
-        }
-    }
-
-    public static final Creator<WearableActionExtensions> CREATOR =
-            new Creator<WearableActionExtensions>() {
-        @Override
-        public WearableActionExtensions createFromParcel(Parcel in) {
-            return new WearableActionExtensions(in);
-        }
-
-        @Override
-        public WearableActionExtensions[] newArray(int size) {
-            return new WearableActionExtensions[size];
-        }
-    };
-}
diff --git a/core/java/android/app/wearable/WearableNotificationExtensions.java b/core/java/android/app/wearable/WearableNotificationExtensions.java
deleted file mode 100644
index d433613..0000000
--- a/core/java/android/app/wearable/WearableNotificationExtensions.java
+++ /dev/null
@@ -1,702 +0,0 @@
-/*
- * Copyright (C) 2014 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.app.wearable;
-
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.graphics.Bitmap;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.view.Gravity;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Helper class that contains wearable extensions for notifications.
- * <p class="note"> See
- * <a href="{@docRoot}wear/notifications/creating.html">Creating Notifications
- * for Android Wear</a> for more information on how to use this class.
- * <p>
- * To create a notification with wearable extensions:
- * <ol>
- *   <li>Create a {@link Notification.Builder}, setting any desired
- *   properties.
- *   <li>Create a {@link WearableNotificationExtensions.Builder}.
- *   <li>Set wearable-specific properties using the
- *   {@code add} and {@code set} methods of {@link WearableNotificationExtensions.Builder}.
- *   <li>Call {@link WearableNotificationExtensions.Builder#build} to build the extensions
- *   object.
- *   <li>Call {@link Notification.Builder#apply} to apply the extensions to a notification.
- *   <li>Post the notification to the notification system with the
- *   {@code NotificationManager.notify(...)} methods.
- * </ol>
- *
- * <pre class="prettyprint">
- * Notification notif = new Notification.Builder(mContext)
- *         .setContentTitle(&quot;New mail from &quot; + sender.toString())
- *         .setContentText(subject)
- *         .setSmallIcon(R.drawable.new_mail)
- *         .apply(new new WearableNotificationExtensions.Builder()
- *                 .setContentIcon(R.drawable.new_mail)
- *                 .build())
- *         .build();
- * NotificationManager notificationManger =
- *         (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- * notificationManger.notify(0, notif);</pre>
- *
- * <p>Wearable extensions can be accessed on an existing notification by using the
- * {@link WearableNotificationExtensions#from} function.
- *
- * <pre class="prettyprint">
- * WearableNotificationExtensions wearableExtensions = WearableNotificationExtensions.from(
- *         notification);
- * Notification[] pages = wearableExtensions.getPages();
- * </pre>
- */
-public final class WearableNotificationExtensions implements Notification.Builder.Extender,
-        Parcelable {
-    /**
-     * Sentinel value for an action index that is unset.
-     */
-    public static final int UNSET_ACTION_INDEX = -1;
-
-    /**
-     * Size value for use with {@link Builder#setCustomSizePreset} to show this notification with
-     * default sizing.
-     * <p>For custom display notifications created using {@link Builder#setDisplayIntent},
-     * the default is {@link #SIZE_LARGE}. All other notifications size automatically based
-     * on their content.
-     */
-    public static final int SIZE_DEFAULT = 0;
-
-    /**
-     * Size value for use with {@link Builder#setCustomSizePreset} to show this notification
-     * with an extra small size.
-     * <p>This value is only applicable for custom display notifications created using
-     * {@link Builder#setDisplayIntent}.
-     */
-    public static final int SIZE_XSMALL = 1;
-
-    /**
-     * Size value for use with {@link Builder#setCustomSizePreset} to show this notification
-     * with a small size.
-     * <p>This value is only applicable for custom display notifications created using
-     * {@link Builder#setDisplayIntent}.
-     */
-    public static final int SIZE_SMALL = 2;
-
-    /**
-     * Size value for use with {@link Builder#setCustomSizePreset} to show this notification
-     * with a medium size.
-     * <p>This value is only applicable for custom display notifications created using
-     * {@link Builder#setDisplayIntent}.
-     */
-    public static final int SIZE_MEDIUM = 3;
-
-    /**
-     * Size value for use with {@link Builder#setCustomSizePreset} to show this notification
-     * with a large size.
-     * <p>This value is only applicable for custom display notifications created using
-     * {@link Builder#setDisplayIntent}.
-     */
-    public static final int SIZE_LARGE = 4;
-
-    /** Notification extra which contains wearable extensions */
-    static final String EXTRA_WEARABLE_EXTENSIONS = "android.wearable.EXTENSIONS";
-
-    // Flags bitwise-ored to mFlags
-    static final int FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE = 1 << 0;
-    static final int FLAG_HINT_HIDE_ICON = 1 << 1;
-    static final int FLAG_HINT_SHOW_BACKGROUND_ONLY = 1 << 2;
-    static final int FLAG_START_SCROLL_BOTTOM = 1 << 3;
-
-    // Default value for flags integer
-    static final int DEFAULT_FLAGS = FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE;
-
-    private final Notification.Action[] mActions;
-    private final int mFlags;
-    private final PendingIntent mDisplayIntent;
-    private final Notification[] mPages;
-    private final Bitmap mBackground;
-    private final int mContentIcon;
-    private final int mContentIconGravity;
-    private final int mContentActionIndex;
-    private final int mCustomSizePreset;
-    private final int mCustomContentHeight;
-    private final int mGravity;
-
-    private WearableNotificationExtensions(Notification.Action[] actions, int flags,
-            PendingIntent displayIntent, Notification[] pages, Bitmap background,
-            int contentIcon, int contentIconGravity, int contentActionIndex,
-            int customSizePreset, int customContentHeight, int gravity) {
-        mActions = actions;
-        mFlags = flags;
-        mDisplayIntent = displayIntent;
-        mPages = pages;
-        mBackground = background;
-        mContentIcon = contentIcon;
-        mContentIconGravity = contentIconGravity;
-        mContentActionIndex = contentActionIndex;
-        mCustomSizePreset = customSizePreset;
-        mCustomContentHeight = customContentHeight;
-        mGravity = gravity;
-    }
-
-    private WearableNotificationExtensions(Parcel in) {
-        mActions = in.createTypedArray(Notification.Action.CREATOR);
-        mFlags = in.readInt();
-        mDisplayIntent = in.readParcelable(PendingIntent.class.getClassLoader());
-        mPages = in.createTypedArray(Notification.CREATOR);
-        mBackground = in.readParcelable(Bitmap.class.getClassLoader());
-        mContentIcon = in.readInt();
-        mContentIconGravity = in.readInt();
-        mContentActionIndex = in.readInt();
-        mCustomSizePreset = in.readInt();
-        mCustomContentHeight = in.readInt();
-        mGravity = in.readInt();
-    }
-
-    /**
-     * Create a {@link WearableNotificationExtensions} by reading wearable extensions present on an
-     * existing notification.
-     * @param notif the notification to inspect.
-     * @return a new {@link WearableNotificationExtensions} object.
-     */
-    public static WearableNotificationExtensions from(Notification notif) {
-        WearableNotificationExtensions extensions = notif.extras.getParcelable(
-                EXTRA_WEARABLE_EXTENSIONS);
-        if (extensions != null) {
-            return extensions;
-        } else {
-            // Return a WearableNotificationExtensions with default values.
-            return new Builder().build();
-        }
-    }
-
-    /**
-     * Apply wearable extensions to a notification that is being built. This is typically
-     * called by {@link Notification.Builder#apply} method of {@link Notification.Builder}.
-     */
-    @Override
-    public Notification.Builder applyTo(Notification.Builder builder) {
-        builder.getExtras().putParcelable(EXTRA_WEARABLE_EXTENSIONS, this);
-        return builder;
-    }
-
-    /**
-     * Get the number of wearable actions present on this notification.
-     *
-     * @return the number of wearable actions for this notification
-     */
-    public int getActionCount() {
-        return mActions.length;
-    }
-
-    /**
-     * Get a {@link Notification.Action} for the wearable action at {@code actionIndex}.
-     * @param actionIndex the index of the desired wearable action
-     */
-    public Notification.Action getAction(int actionIndex) {
-        return mActions[actionIndex];
-    }
-
-    /**
-     * Get the wearable actions present on this notification.
-     */
-    public Notification.Action[] getActions() {
-        return mActions;
-    }
-
-    /**
-     * Get the intent to launch inside of an activity view when displaying this
-     * notification. This {@code PendingIntent} should be for an activity.
-     */
-    public PendingIntent getDisplayIntent() {
-        return mDisplayIntent;
-    }
-
-    /**
-     * Get the array of additional pages of content for displaying this notification. The
-     * current notification forms the first page, and elements within this array form
-     * subsequent pages. This field can be used to separate a notification into multiple
-     * sections.
-     * @return the pages for this notification
-     */
-    public Notification[] getPages() {
-        return mPages;
-    }
-
-    /**
-     * Get a background image to be displayed behind the notification content.
-     * Contrary to the {@link Notification.BigPictureStyle}, this background
-     * will work with any notification style.
-     *
-     * @return the background image
-     * @see Builder#setBackground
-     */
-    public Bitmap getBackground() {
-        return mBackground;
-    }
-
-    /**
-     * Get an icon that goes with the content of this notification.
-     */
-    public int getContentIcon() {
-        return mContentIcon;
-    }
-
-    /**
-     * Get the gravity that the content icon should have within the notification display.
-     * Supported values include {@link Gravity#START} and {@link Gravity#END}. The default
-     * value is {@link android.view.Gravity#END}.
-     * @see #getContentIcon
-     */
-    public int getContentIconGravity() {
-        return mContentIconGravity;
-    }
-
-    /**
-     * Get the action index of an action from this notification to show as clickable with
-     * the content of this notification page. When the user clicks this notification page,
-     * this action will trigger. This action will no longer display separately from the
-     * notification content. The action's icon will display with optional subtext provided
-     * by the action's title.
-     *
-     * <p>If wearable specific actions are present, this index will apply to that list,
-     * otherwise it will apply to the main notification's actions list.
-     */
-    public int getContentAction() {
-        return mContentActionIndex;
-    }
-
-    /**
-     * Get the gravity that this notification should have within the available viewport space.
-     * Supported values include {@link Gravity#TOP}, {@link Gravity#CENTER_VERTICAL} and
-     * {@link android.view.Gravity#BOTTOM}. The default value is
-     * {@link android.view.Gravity#BOTTOM}.
-     */
-    public int getGravity() {
-        return mGravity;
-    }
-
-    /**
-     * Get the custom size preset for the display of this notification out of the available
-     * presets found in {@link WearableNotificationExtensions}, e.g. {@link #SIZE_LARGE}.
-     * <p>Some custom size presets are only applicable for custom display notifications created
-     * using {@link Builder#setDisplayIntent}. Check the documentation for the preset in question.
-     * See also {@link Builder#setCustomContentHeight} and {@link Builder#setCustomSizePreset}.
-     */
-    public int getCustomSizePreset() {
-        return mCustomSizePreset;
-    }
-
-    /**
-     * Get the custom height in pixels for the display of this notification's content.
-     * <p>This option is only available for custom display notifications created
-     * using {@link Builder#setDisplayIntent}. See also {@link Builder#setCustomSizePreset} and
-     * {@link Builder#setCustomContentHeight}.
-     */
-    public int getCustomContentHeight() {
-        return mCustomContentHeight;
-    }
-
-    /**
-     * Get whether the scrolling position for the contents of this notification should start
-     * at the bottom of the contents instead of the top when the contents are too long to
-     * display within the screen. Default is false (start scroll at the top).
-     */
-    public boolean getStartScrollBottom() {
-        return (mFlags & FLAG_START_SCROLL_BOTTOM) != 0;
-    }
-
-    /**
-     * Get whether the content intent is available when the wearable device is not connected
-     * to a companion device.  The user can still trigger this intent when the wearable device is
-     * offline, but a visual hint will indicate that the content intent may not be available.
-     * Defaults to true.
-     */
-    public boolean getContentIntentAvailableOffline() {
-        return (mFlags & FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE) != 0;
-    }
-
-    /**
-     * Get a hint that this notification's icon should not be displayed.
-     * @return {@code true} if this icon should not be displayed, false otherwise.
-     * The default value is {@code false} if this was never set.
-     */
-    public boolean getHintHideIcon() {
-        return (mFlags & FLAG_HINT_HIDE_ICON) != 0;
-    }
-
-    /**
-     * Get a visual hint that only the background image of this notification should be
-     * displayed, and other semantic content should be hidden. This hint is only applicable
-     * to sub-pages added using {@link Builder#addPage}.
-     */
-    public boolean getHintShowBackgroundOnly() {
-        return (mFlags & FLAG_HINT_SHOW_BACKGROUND_ONLY) != 0;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeTypedArray(mActions, flags);
-        out.writeInt(mFlags);
-        out.writeParcelable(mDisplayIntent, flags);
-        out.writeTypedArray(mPages, flags);
-        out.writeParcelable(mBackground, flags);
-        out.writeInt(mContentIcon);
-        out.writeInt(mContentIconGravity);
-        out.writeInt(mContentActionIndex);
-        out.writeInt(mCustomSizePreset);
-        out.writeInt(mCustomContentHeight);
-        out.writeInt(mGravity);
-    }
-
-    /**
-     * Builder to apply wearable notification extensions to a {@link Notification.Builder}
-     * object.
-     *
-     * <p>You can chain the "set" methods for this builder in any order,
-     * but you must call the {@link #build} method and then the {@link Notification.Builder#apply}
-     * method to apply your extensions to a notification.
-     *
-     * <pre class="prettyprint">
-     * Notification notif = new Notification.Builder(mContext)
-     *         .setContentTitle(&quot;New mail from &quot; + sender.toString())
-     *         .setContentText(subject)
-     *         .setSmallIcon(R.drawable.new_mail);
-     *         .apply(new WearableNotificationExtensions.Builder()
-     *                 .setContentIcon(R.drawable.new_mail)
-     *                 .build())
-     *         .build();
-     * NotificationManager notificationManger =
-     *         (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-     * notificationManager.notify(0, notif);</pre>
-     */
-    public static final class Builder {
-        private final List<Notification.Action> mActions =
-                new ArrayList<Notification.Action>();
-        private int mFlags = DEFAULT_FLAGS;
-        private PendingIntent mDisplayIntent;
-        private final List<Notification> mPages = new ArrayList<Notification>();
-        private Bitmap mBackground;
-        private int mContentIcon;
-        private int mContentIconGravity = Gravity.END;
-        private int mContentActionIndex = UNSET_ACTION_INDEX;
-        private int mCustomContentHeight;
-        private int mCustomSizePreset = SIZE_DEFAULT;
-        private int mGravity = Gravity.BOTTOM;
-
-        /**
-         * Construct a builder to be used for adding wearable extensions to notifications.
-         *
-         * <pre class="prettyprint">
-         * Notification notif = new Notification.Builder(mContext)
-         *         .setContentTitle(&quot;New mail from &quot; + sender.toString())
-         *         .setContentText(subject)
-         *         .setSmallIcon(R.drawable.new_mail);
-         *         .apply(new WearableNotificationExtensions.Builder()
-         *                 .setContentIcon(R.drawable.new_mail)
-         *                 .build())
-         *         .build();
-         * NotificationManager notificationManger =
-         *         (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-         * notificationManager.notify(0, notif);</pre>
-         */
-        public Builder() {
-        }
-
-        /**
-         * Create a {@link Builder} by reading wearable extensions present on an
-         * existing {@code WearableNotificationExtensions} object.
-         * @param other the existing extensions to inspect.
-         */
-        public Builder(WearableNotificationExtensions other) {
-            Collections.addAll(mActions, other.mActions);
-            mFlags = other.mFlags;
-            mDisplayIntent = other.mDisplayIntent;
-            Collections.addAll(mPages, other.mPages);
-            mBackground = other.mBackground;
-            mContentIcon = other.mContentIcon;
-            mContentIconGravity = other.mContentIconGravity;
-            mContentActionIndex = other.mContentActionIndex;
-            mCustomContentHeight = other.mCustomContentHeight;
-            mCustomSizePreset = other.mCustomSizePreset;
-            mGravity = other.mGravity;
-        }
-
-        /**
-         * Add a wearable action to this notification.
-         *
-         * <p>When wearable actions are added using this method, the set of actions that
-         * show on a wearable device splits from devices that only show actions added
-         * using {@link android.app.Notification.Builder#addAction}. This allows for customization
-         * of which actions display on different devices.
-         *
-         * @param action the action to add to this notification
-         * @return this object for method chaining
-         * @see Notification.Action
-         */
-        public Builder addAction(Notification.Action action) {
-            mActions.add(action);
-            return this;
-        }
-
-        /**
-         * Adds wearable actions to this notification.
-         *
-         * <p>When wearable actions are added using this method, the set of actions that
-         * show on a wearable device splits from devices that only show actions added
-         * using {@link android.app.Notification.Builder#addAction}. This allows for customization
-         * of which actions display on different devices.
-         *
-         * @param actions the actions to add to this notification
-         * @return this object for method chaining
-         * @see Notification.Action
-         */
-        public Builder addActions(List<Notification.Action> actions) {
-            mActions.addAll(actions);
-            return this;
-        }
-
-        /**
-         * Clear all wearable actions present on this builder.
-         * @return this object for method chaining.
-         * @see #addAction
-         */
-        public Builder clearActions() {
-            mActions.clear();
-            return this;
-        }
-
-        /**
-         * Set an intent to launch inside of an activity view when displaying
-         * this notification. This {@link android.app.PendingIntent} should be for an activity.
-         *
-         * @param intent the {@link android.app.PendingIntent} for an activity
-         * @return this object for method chaining
-         * @see WearableNotificationExtensions#getDisplayIntent
-         */
-        public Builder setDisplayIntent(PendingIntent intent) {
-            mDisplayIntent = intent;
-            return this;
-        }
-
-        /**
-         * Add an additional page of content to display with this notification. The current
-         * notification forms the first page, and pages added using this function form
-         * subsequent pages. This field can be used to separate a notification into multiple
-         * sections.
-         *
-         * @param page the notification to add as another page
-         * @return this object for method chaining
-         * @see WearableNotificationExtensions#getPages
-         */
-        public Builder addPage(Notification page) {
-            mPages.add(page);
-            return this;
-        }
-
-        /**
-         * Add additional pages of content to display with this notification. The current
-         * notification forms the first page, and pages added using this function form
-         * subsequent pages. This field can be used to separate a notification into multiple
-         * sections.
-         *
-         * @param pages a list of notifications
-         * @return this object for method chaining
-         * @see WearableNotificationExtensions#getPages
-         */
-        public Builder addPages(List<Notification> pages) {
-            mPages.addAll(pages);
-            return this;
-        }
-
-        /**
-         * Clear all additional pages present on this builder.
-         * @return this object for method chaining.
-         * @see #addPage
-         */
-        public Builder clearPages() {
-            mPages.clear();
-            return this;
-        }
-
-        /**
-         * Set a background image to be displayed behind the notification content.
-         * Contrary to the {@link Notification.BigPictureStyle}, this background
-         * will work with any notification style.
-         *
-         * @param background the background bitmap
-         * @return this object for method chaining
-         * @see WearableNotificationExtensions#getBackground
-         */
-        public Builder setBackground(Bitmap background) {
-            mBackground = background;
-            return this;
-        }
-
-        /**
-         * Set an icon that goes with the content of this notification.
-         */
-        public Builder setContentIcon(int icon) {
-            mContentIcon = icon;
-            return this;
-        }
-
-        /**
-         * Set the gravity that the content icon should have within the notification display.
-         * Supported values include {@link Gravity#START} and {@link Gravity#END}. The default
-         * value is {@link android.view.Gravity#END}.
-         * @see #setContentIcon
-         */
-        public Builder setContentIconGravity(int contentIconGravity) {
-            mContentIconGravity = contentIconGravity;
-            return this;
-        }
-
-        /**
-         * Set an action from this notification's actions to be clickable with the content of
-         * this notification page. This action will no longer display separately from the
-         * notification content. This action's icon will display with optional subtext provided
-         * by the action's title.
-         * @param actionIndex The index of the action to hoist on the current notification page.
-         *                    If wearable actions are present, this index will apply to that list,
-         *                    otherwise it will apply to the main notification's actions list.
-         */
-        public Builder setContentAction(int actionIndex) {
-            mContentActionIndex = actionIndex;
-            return this;
-        }
-
-        /**
-         * Set the gravity that this notification should have within the available viewport space.
-         * Supported values include {@link Gravity#TOP}, {@link Gravity#CENTER_VERTICAL} and
-         * {@link Gravity#BOTTOM}. The default value is {@link Gravity#BOTTOM}.
-         */
-        public Builder setGravity(int gravity) {
-            mGravity = gravity;
-            return this;
-        }
-
-        /**
-         * Set the custom size preset for the display of this notification out of the available
-         * presets found in {@link WearableNotificationExtensions}, e.g. {@link #SIZE_LARGE}.
-         * <p>Some custom size presets are only applicable for custom display notifications created
-         * using {@link Builder#setDisplayIntent}. Check the documentation for the preset in
-         * question. See also {@link Builder#setCustomContentHeight} and
-         * {@link #getCustomSizePreset}.
-         */
-        public Builder setCustomSizePreset(int sizePreset) {
-            mCustomSizePreset = sizePreset;
-            return this;
-        }
-
-        /**
-         * Set the custom height in pixels for the display of this notification's content.
-         * <p>This option is only available for custom display notifications created
-         * using {@link Builder#setDisplayIntent}. See also {@link Builder#setCustomSizePreset} and
-         * {@link #getCustomContentHeight}.
-         */
-        public Builder setCustomContentHeight(int height) {
-            mCustomContentHeight = height;
-            return this;
-        }
-
-        /**
-         * Set whether the scrolling position for the contents of this notification should start
-         * at the bottom of the contents instead of the top when the contents are too long to
-         * display within the screen.  Default is false (start scroll at the top).
-         */
-        public Builder setStartScrollBottom(boolean startScrollBottom) {
-            setFlag(FLAG_START_SCROLL_BOTTOM, startScrollBottom);
-            return this;
-        }
-
-        /**
-         * Set whether the content intent is available when the wearable device is not connected
-         * to a companion device.  The user can still trigger this intent when the wearable device
-         * is offline, but a visual hint will indicate that the content intent may not be available.
-         * Defaults to true.
-         */
-        public Builder setContentIntentAvailableOffline(boolean contentIntentAvailableOffline) {
-            setFlag(FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE, contentIntentAvailableOffline);
-            return this;
-        }
-
-        /**
-         * Set a hint that this notification's icon should not be displayed.
-         * @param hintHideIcon {@code true} to hide the icon, {@code false} otherwise.
-         * @return this object for method chaining
-         */
-        public Builder setHintHideIcon(boolean hintHideIcon) {
-            setFlag(FLAG_HINT_HIDE_ICON, hintHideIcon);
-            return this;
-        }
-
-        /**
-         * Set a visual hint that only the background image of this notification should be
-         * displayed, and other semantic content should be hidden. This hint is only applicable
-         * to sub-pages added using {@link #addPage}.
-         */
-        public Builder setHintShowBackgroundOnly(boolean hintShowBackgroundOnly) {
-            setFlag(FLAG_HINT_SHOW_BACKGROUND_ONLY, hintShowBackgroundOnly);
-            return this;
-        }
-
-        /**
-         * Build a new {@link WearableNotificationExtensions} object with the extensions
-         * currently present on this builder.
-         * @return the extensions object.
-         */
-        public WearableNotificationExtensions build() {
-            return new WearableNotificationExtensions(
-                    mActions.toArray(new Notification.Action[mActions.size()]), mFlags,
-                    mDisplayIntent, mPages.toArray(new Notification[mPages.size()]),
-                    mBackground, mContentIcon, mContentIconGravity, mContentActionIndex,
-                    mCustomSizePreset, mCustomContentHeight, mGravity);
-        }
-
-        private void setFlag(int mask, boolean value) {
-            if (value) {
-                mFlags |= mask;
-            } else {
-                mFlags &= ~mask;
-            }
-        }
-    }
-
-    public static final Creator<WearableNotificationExtensions> CREATOR =
-            new Creator<WearableNotificationExtensions>() {
-        @Override
-        public WearableNotificationExtensions createFromParcel(Parcel in) {
-            return new WearableNotificationExtensions(in);
-        }
-
-        @Override
-        public WearableNotificationExtensions[] newArray(int size) {
-            return new WearableNotificationExtensions[size];
-        }
-    };
-}