Merge "Remove deprecated BufferQueue constructor"
diff --git a/Android.mk b/Android.mk
index 5c48dfe..a691987 100644
--- a/Android.mk
+++ b/Android.mk
@@ -616,6 +616,7 @@
 		$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
 		-stubs $(TARGET_OUT_COMMON_INTERMEDIATES)/JAVA_LIBRARIES/android_stubs_current_intermediates/src \
 		-api $(INTERNAL_PLATFORM_API_FILE) \
+		-removedApi $(INTERNAL_PLATFORM_REMOVED_API_FILE) \
 		-nodocs
 
 LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk
diff --git a/api/current.txt b/api/current.txt
index 9df5c9e..5ebe2eb 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -314,6 +314,7 @@
     field public static final int backgroundSplit = 16843659; // 0x101038b
     field public static final int backgroundStacked = 16843658; // 0x101038a
     field public static final int backupAgent = 16843391; // 0x101027f
+    field public static final int banner = 16843762; // 0x10103f2
     field public static final int baseline = 16843548; // 0x101031c
     field public static final int baselineAlignBottom = 16843042; // 0x1010122
     field public static final int baselineAligned = 16843046; // 0x1010126
@@ -345,7 +346,6 @@
     field public static final int canRetrieveWindowContent = 16843653; // 0x1010385
     field public static final int candidatesTextStyleSpans = 16843312; // 0x1010230
     field public static final deprecated int capitalize = 16843113; // 0x1010169
-    field public static final int castsShadow = 16843774; // 0x10103fe
     field public static final int category = 16843752; // 0x10103e8
     field public static final int centerBright = 16842956; // 0x10100cc
     field public static final int centerColor = 16843275; // 0x101020b
@@ -399,10 +399,10 @@
     field public static final int content = 16843355; // 0x101025b
     field public static final int contentAuthority = 16843408; // 0x1010290
     field public static final int contentDescription = 16843379; // 0x1010273
-    field public static final int controlX1 = 16843768; // 0x10103f8
-    field public static final int controlX2 = 16843770; // 0x10103fa
-    field public static final int controlY1 = 16843769; // 0x10103f9
-    field public static final int controlY2 = 16843771; // 0x10103fb
+    field public static final int controlX1 = 16843769; // 0x10103f9
+    field public static final int controlX2 = 16843771; // 0x10103fb
+    field public static final int controlY1 = 16843770; // 0x10103fa
+    field public static final int controlY2 = 16843772; // 0x10103fc
     field public static final int cropToPadding = 16843043; // 0x1010123
     field public static final int cursorVisible = 16843090; // 0x1010152
     field public static final int customNavigationLayout = 16843474; // 0x10102d2
@@ -505,7 +505,7 @@
     field public static final int fastScrollOverlayPosition = 16843578; // 0x101033a
     field public static final int fastScrollPreviewBackgroundLeft = 16843575; // 0x1010337
     field public static final int fastScrollPreviewBackgroundRight = 16843576; // 0x1010338
-    field public static final int fastScrollStyle = 16843763; // 0x10103f3
+    field public static final int fastScrollStyle = 16843764; // 0x10103f4
     field public static final int fastScrollTextColor = 16843609; // 0x1010359
     field public static final int fastScrollThumbDrawable = 16843574; // 0x1010336
     field public static final int fastScrollTrackDrawable = 16843577; // 0x1010339
@@ -531,7 +531,7 @@
     field public static final int format12Hour = 16843722; // 0x10103ca
     field public static final int format24Hour = 16843723; // 0x10103cb
     field public static final int fragment = 16843491; // 0x10102e3
-    field public static final int fragmentBreadCrumbsStyle = 16843762; // 0x10103f2
+    field public static final int fragmentBreadCrumbsStyle = 16843763; // 0x10103f3
     field public static final int fragmentCloseEnterAnimation = 16843495; // 0x10102e7
     field public static final int fragmentCloseExitAnimation = 16843496; // 0x10102e8
     field public static final int fragmentFadeEnterAnimation = 16843497; // 0x10102e9
@@ -960,7 +960,7 @@
     field public static final int shadowRadius = 16843108; // 0x1010164
     field public static final int shape = 16843162; // 0x101019a
     field public static final int shareInterpolator = 16843195; // 0x10101bb
-    field public static final int sharedElementName = 16843772; // 0x10103fc
+    field public static final int sharedElementName = 16843773; // 0x10103fd
     field public static final int sharedUserId = 16842763; // 0x101000b
     field public static final int sharedUserLabel = 16843361; // 0x1010261
     field public static final int shouldDisableView = 16843246; // 0x10101ee
@@ -1137,7 +1137,7 @@
     field public static final int tileMode = 16843265; // 0x1010201
     field public static final int timeZone = 16843724; // 0x10103cc
     field public static final int tint = 16843041; // 0x1010121
-    field public static final int tintMode = 16843767; // 0x10103f7
+    field public static final int tintMode = 16843768; // 0x10103f8
     field public static final int title = 16843233; // 0x10101e1
     field public static final int titleCondensed = 16843234; // 0x10101e2
     field public static final int titleTextStyle = 16843512; // 0x10102f8
@@ -1159,11 +1159,11 @@
     field public static final int transformPivotX = 16843552; // 0x1010320
     field public static final int transformPivotY = 16843553; // 0x1010321
     field public static final int transition = 16843743; // 0x10103df
-    field public static final int transitionGroup = 16843773; // 0x10103fd
+    field public static final int transitionGroup = 16843774; // 0x10103fe
     field public static final int transitionOrdering = 16843744; // 0x10103e0
     field public static final int translationX = 16843554; // 0x1010322
     field public static final int translationY = 16843555; // 0x1010323
-    field public static final int translationZ = 16843766; // 0x10103f6
+    field public static final int translationZ = 16843767; // 0x10103f7
     field public static final int type = 16843169; // 0x10101a1
     field public static final int typeface = 16842902; // 0x1010096
     field public static final int uiOptions = 16843672; // 0x1010398
@@ -1220,8 +1220,8 @@
     field public static final int windowBackground = 16842836; // 0x1010054
     field public static final int windowCloseOnTouchOutside = 16843611; // 0x101035b
     field public static final int windowContentOverlay = 16842841; // 0x1010059
-    field public static final int windowContentTransitionManager = 16843765; // 0x10103f5
-    field public static final int windowContentTransitions = 16843764; // 0x10103f4
+    field public static final int windowContentTransitionManager = 16843766; // 0x10103f6
+    field public static final int windowContentTransitions = 16843765; // 0x10103f5
     field public static final int windowDisablePreview = 16843298; // 0x1010222
     field public static final int windowEnableSplitTouch = 16843543; // 0x1010317
     field public static final int windowEnterAnimation = 16842932; // 0x10100b4
@@ -4796,7 +4796,7 @@
     method public int setStorageEncryption(android.content.ComponentName, boolean);
     method public void wipeData(int);
     field public static final java.lang.String ACTION_ADD_DEVICE_ADMIN = "android.app.action.ADD_DEVICE_ADMIN";
-    field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.managedprovisioning.ACTION_PROVISION_MANAGED_PROFILE";
+    field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.ACTION_PROVISION_MANAGED_PROFILE";
     field public static final java.lang.String ACTION_SET_NEW_PASSWORD = "android.app.action.SET_NEW_PASSWORD";
     field public static final java.lang.String ACTION_START_ENCRYPTION = "android.app.action.START_ENCRYPTION";
     field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2
@@ -6848,6 +6848,7 @@
     field public static final int FLAG_ACTIVITY_FORWARD_RESULT = 33554432; // 0x2000000
     field public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 1048576; // 0x100000
     field public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 134217728; // 0x8000000
+    field public static final int FLAG_ACTIVITY_NEW_DOCUMENT = 268959744; // 0x10080000
     field public static final int FLAG_ACTIVITY_NEW_TASK = 268435456; // 0x10000000
     field public static final int FLAG_ACTIVITY_NO_ANIMATION = 65536; // 0x10000
     field public static final int FLAG_ACTIVITY_NO_HISTORY = 1073741824; // 0x40000000
@@ -7417,6 +7418,7 @@
     ctor public ComponentInfo();
     ctor public ComponentInfo(android.content.pm.ComponentInfo);
     ctor protected ComponentInfo(android.os.Parcel);
+    method public final int getBannerResource();
     method public final int getIconResource();
     method public final int getLogoResource();
     method public boolean isEnabled();
@@ -7520,11 +7522,13 @@
     ctor protected PackageItemInfo(android.os.Parcel);
     method protected void dumpBack(android.util.Printer, java.lang.String);
     method protected void dumpFront(android.util.Printer, java.lang.String);
+    method public android.graphics.drawable.Drawable loadBanner(android.content.pm.PackageManager);
     method public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager);
     method public java.lang.CharSequence loadLabel(android.content.pm.PackageManager);
     method public android.graphics.drawable.Drawable loadLogo(android.content.pm.PackageManager);
     method public android.content.res.XmlResourceParser loadXmlMetaData(android.content.pm.PackageManager, java.lang.String);
     method public void writeToParcel(android.os.Parcel, int);
+    field public int banner;
     field public int icon;
     field public int labelRes;
     field public int logo;
@@ -7552,12 +7556,16 @@
     method public abstract void clearPackagePreferredActivities(java.lang.String);
     method public abstract java.lang.String[] currentToCanonicalPackageNames(java.lang.String[]);
     method public abstract void extendVerificationTimeout(int, int, long);
+    method public abstract android.graphics.drawable.Drawable getActivityBanner(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public abstract android.graphics.drawable.Drawable getActivityBanner(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract android.graphics.drawable.Drawable getActivityLogo(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract java.util.List<android.content.pm.PermissionGroupInfo> getAllPermissionGroups(int);
+    method public abstract android.graphics.drawable.Drawable getApplicationBanner(android.content.pm.ApplicationInfo);
+    method public abstract android.graphics.drawable.Drawable getApplicationBanner(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
     method public abstract int getApplicationEnabledSetting(java.lang.String);
     method public abstract android.graphics.drawable.Drawable getApplicationIcon(android.content.pm.ApplicationInfo);
     method public abstract android.graphics.drawable.Drawable getApplicationIcon(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -7637,6 +7645,7 @@
     field public static final java.lang.String FEATURE_FAKETOUCH_MULTITOUCH_JAZZHAND = "android.hardware.faketouch.multitouch.jazzhand";
     field public static final java.lang.String FEATURE_HOME_SCREEN = "android.software.home_screen";
     field public static final java.lang.String FEATURE_INPUT_METHODS = "android.software.input_methods";
+    field public static final java.lang.String FEATURE_LEANBACK = "android.software.leanback";
     field public static final java.lang.String FEATURE_LIVE_WALLPAPER = "android.software.live_wallpaper";
     field public static final java.lang.String FEATURE_LOCATION = "android.hardware.location";
     field public static final java.lang.String FEATURE_LOCATION_GPS = "android.hardware.location.gps";
@@ -7660,7 +7669,7 @@
     field public static final java.lang.String FEATURE_TELEPHONY = "android.hardware.telephony";
     field public static final java.lang.String FEATURE_TELEPHONY_CDMA = "android.hardware.telephony.cdma";
     field public static final java.lang.String FEATURE_TELEPHONY_GSM = "android.hardware.telephony.gsm";
-    field public static final java.lang.String FEATURE_TELEVISION = "android.hardware.type.television";
+    field public static final deprecated java.lang.String FEATURE_TELEVISION = "android.hardware.type.television";
     field public static final java.lang.String FEATURE_TOUCHSCREEN = "android.hardware.touchscreen";
     field public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH = "android.hardware.touchscreen.multitouch";
     field public static final java.lang.String FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT = "android.hardware.touchscreen.multitouch.distinct";
@@ -11286,6 +11295,7 @@
     field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_AWB_AVAILABLE_MODES;
     field public static final android.hardware.camera2.CameraMetadata.Key CONTROL_MAX_REGIONS;
     field public static final android.hardware.camera2.CameraMetadata.Key FLASH_INFO_AVAILABLE;
+    field public static final android.hardware.camera2.CameraMetadata.Key HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES;
     field public static final android.hardware.camera2.CameraMetadata.Key INFO_SUPPORTED_HARDWARE_LEVEL;
     field public static final android.hardware.camera2.CameraMetadata.Key JPEG_AVAILABLE_THUMBNAIL_SIZES;
     field public static final android.hardware.camera2.CameraMetadata.Key LENS_FACING;
@@ -11326,6 +11336,7 @@
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_ORIENTATION;
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_PROFILE_HUE_SAT_MAP_DIMENSIONS;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_INFO_MAX_FACE_COUNT;
     field public static final android.hardware.camera2.CameraMetadata.Key SYNC_MAX_LATENCY;
     field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_MAX_CURVE_POINTS;
@@ -11620,6 +11631,7 @@
     field public static final android.hardware.camera2.CameraMetadata.Key SENSOR_TEST_PATTERN_MODE;
     field public static final android.hardware.camera2.CameraMetadata.Key SHADING_MODE;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP_MODE;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP_MODE;
     field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_BLUE;
     field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_GREEN;
@@ -11657,7 +11669,6 @@
     field public static final android.hardware.camera2.CameraMetadata.Key EDGE_MODE;
     field public static final android.hardware.camera2.CameraMetadata.Key FLASH_MODE;
     field public static final android.hardware.camera2.CameraMetadata.Key FLASH_STATE;
-    field public static final android.hardware.camera2.CameraMetadata.Key HOT_PIXEL_MAP;
     field public static final android.hardware.camera2.CameraMetadata.Key HOT_PIXEL_MODE;
     field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_COORDINATES;
     field public static final android.hardware.camera2.CameraMetadata.Key JPEG_GPS_PROCESSING_METHOD;
@@ -11694,6 +11705,8 @@
     field public static final android.hardware.camera2.CameraMetadata.Key SHADING_MODE;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACES;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_FACE_DETECT_MODE;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP;
+    field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_HOT_PIXEL_MAP_MODE;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_LENS_SHADING_MAP;
     field public static final android.hardware.camera2.CameraMetadata.Key STATISTICS_SCENE_FLICKER;
     field public static final android.hardware.camera2.CameraMetadata.Key TONEMAP_CURVE_BLUE;
@@ -13816,6 +13829,7 @@
     field public static final int RATING_4_STARS = 4; // 0x4
     field public static final int RATING_5_STARS = 5; // 0x5
     field public static final int RATING_HEART = 1; // 0x1
+    field public static final int RATING_NONE = 0; // 0x0
     field public static final int RATING_PERCENTAGE = 6; // 0x6
     field public static final int RATING_THUMB_UP_DOWN = 2; // 0x2
   }
@@ -14456,34 +14470,76 @@
 package android.media.session {
 
   public final class MediaController {
-    ctor public MediaController(android.media.session.MediaSessionToken);
     method public void addCallback(android.media.session.MediaController.Callback);
     method public void addCallback(android.media.session.MediaController.Callback, android.os.Handler);
+    method public static android.media.session.MediaController fromToken(android.media.session.MediaSessionToken);
+    method public android.media.session.TransportController getTransportController();
     method public void removeCallback(android.media.session.MediaController.Callback);
-    method public void sendCommand(java.lang.String, android.os.Bundle);
+    method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void sendMediaButton(int);
   }
 
   public static abstract class MediaController.Callback {
     ctor public MediaController.Callback();
     method public void onEvent(java.lang.String, android.os.Bundle);
-    method public void onMetadataUpdate(android.os.Bundle);
-    method public void onPlaybackStateChange(int);
     method public void onRouteChanged(android.os.Bundle);
   }
 
+  public final class MediaMetadata implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.graphics.Bitmap getBitmap(java.lang.String);
+    method public long getLong(java.lang.String);
+    method public android.media.Rating getRating(java.lang.String);
+    method public java.lang.String getString(java.lang.String);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final java.lang.String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+    field public static final java.lang.String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
+    field public static final java.lang.String METADATA_KEY_ART = "android.media.metadata.ART";
+    field public static final java.lang.String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST";
+    field public static final java.lang.String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
+    field public static final java.lang.String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR";
+    field public static final java.lang.String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
+    field public static final java.lang.String METADATA_KEY_DATE = "android.media.metadata.DATE";
+    field public static final java.lang.String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+    field public static final java.lang.String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
+    field public static final java.lang.String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
+    field public static final java.lang.String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
+    field public static final java.lang.String METADATA_KEY_RATING = "android.media.metadata.RATING";
+    field public static final java.lang.String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
+    field public static final java.lang.String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+    field public static final java.lang.String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING";
+    field public static final java.lang.String METADATA_KEY_WRITER = "android.media.metadata.WRITER";
+    field public static final java.lang.String METADATA_KEY_YEAR = "android.media.metadata.YEAR";
+  }
+
+  public static final class MediaMetadata.Builder {
+    ctor public MediaMetadata.Builder();
+    ctor public MediaMetadata.Builder(android.media.session.MediaMetadata);
+    method public android.media.session.MediaMetadata build();
+    method public android.media.session.MediaMetadata.Builder putBitmap(java.lang.String, android.graphics.Bitmap);
+    method public android.media.session.MediaMetadata.Builder putLong(java.lang.String, long);
+    method public android.media.session.MediaMetadata.Builder putRating(java.lang.String, android.media.Rating);
+    method public android.media.session.MediaMetadata.Builder putString(java.lang.String, java.lang.String);
+  }
+
   public final class MediaSession {
     method public void addCallback(android.media.session.MediaSession.Callback);
     method public void addCallback(android.media.session.MediaSession.Callback, android.os.Handler);
     method public android.media.session.MediaSessionToken getSessionToken();
+    method public android.media.session.TransportPerformer getTransportPerformer();
+    method public void publish();
     method public void release();
     method public void removeCallback(android.media.session.MediaSession.Callback);
-    method public void setPlaybackState(int);
+    method public void sendEvent(java.lang.String, android.os.Bundle);
+    method public android.media.session.TransportPerformer setTransportPerformerEnabled();
   }
 
   public static abstract class MediaSession.Callback {
     ctor public MediaSession.Callback();
-    method public void onCommand(java.lang.String, android.os.Bundle);
+    method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
     method public void onMediaButton(android.content.Intent);
     method public void onRequestRouteChange(android.os.Bundle);
   }
@@ -14499,6 +14555,137 @@
     field public static final android.os.Parcelable.Creator CREATOR;
   }
 
+  public final class PlaybackState implements android.os.Parcelable {
+    ctor public PlaybackState();
+    ctor public PlaybackState(android.media.session.PlaybackState);
+    method public int describeContents();
+    method public long getActions();
+    method public long getBufferPosition();
+    method public java.lang.String getErrorMessage();
+    method public long getPosition();
+    method public float getSpeed();
+    method public int getState();
+    method public void setActions(long);
+    method public void setBufferPosition(long);
+    method public void setErrorMessage(java.lang.String);
+    method public void setPosition(long);
+    method public void setSpeed(float);
+    method public void setState(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final long ACTION_FASTFORWARD = 64L; // 0x40L
+    field public static final long ACTION_NEXT_ITEM = 32L; // 0x20L
+    field public static final long ACTION_PAUSE = 2L; // 0x2L
+    field public static final long ACTION_PLAY = 4L; // 0x4L
+    field public static final long ACTION_PREVIOUS_ITEM = 16L; // 0x10L
+    field public static final long ACTION_RATING = 128L; // 0x80L
+    field public static final long ACTION_REWIND = 8L; // 0x8L
+    field public static final long ACTION_SEEK_TO = 256L; // 0x100L
+    field public static final long ACTION_STOP = 1L; // 0x1L
+    field public static final android.os.Parcelable.Creator CREATOR;
+    field public static final int PLAYSTATE_BUFFERING = 6; // 0x6
+    field public static final int PLAYSTATE_ERROR = 7; // 0x7
+    field public static final int PLAYSTATE_FAST_FORWARDING = 4; // 0x4
+    field public static final int PLAYSTATE_NONE = 0; // 0x0
+    field public static final int PLAYSTATE_PAUSED = 2; // 0x2
+    field public static final int PLAYSTATE_PLAYING = 3; // 0x3
+    field public static final int PLAYSTATE_REWINDING = 5; // 0x5
+    field public static final int PLAYSTATE_STOPPED = 1; // 0x1
+  }
+
+  public final class RouteInterface {
+    method public void addListener(android.media.session.RouteInterface.EventListener);
+    method public void addListener(android.media.session.RouteInterface.EventListener, android.os.Handler);
+    method public void removeListener(android.media.session.RouteInterface.EventListener);
+    method public void sendCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+  }
+
+  public static abstract class RouteInterface.EventListener {
+    ctor public RouteInterface.EventListener();
+    method public abstract void onEvent(java.lang.String, android.os.Bundle);
+  }
+
+  public static abstract class RouteInterface.Stub {
+    ctor public RouteInterface.Stub();
+    method public abstract java.lang.String getName();
+    method public abstract void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+    method public final void sendEvent(android.media.session.MediaSession, java.lang.String, android.os.Bundle);
+  }
+
+  public final class RouteTransportControls {
+    method public void addListener(android.media.session.RouteTransportControls.Listener);
+    method public void addListener(android.media.session.RouteTransportControls.Listener, android.os.Handler);
+    method public void fastForward(float);
+    method public static android.media.session.RouteTransportControls from(android.media.session.MediaController);
+    method public void getCapabilities(android.os.ResultReceiver);
+    method public void getCurrentPosition(android.os.ResultReceiver);
+    method public void pause();
+    method public void play();
+    method public void removeListener(android.media.session.RouteTransportControls.Listener);
+    field public static final java.lang.String NAME = "android.media.session.RouteTransportControls";
+  }
+
+  public static abstract class RouteTransportControls.Listener {
+    ctor public RouteTransportControls.Listener();
+    method public void onMetadataUpdate(android.os.Bundle);
+    method public void onPlaybackStateChange(int);
+  }
+
+  public static abstract class RouteTransportControls.Stub extends android.media.session.RouteInterface.Stub {
+    ctor public RouteTransportControls.Stub(android.media.session.MediaSession);
+    method public void fastForward(float);
+    method public long getCapabilities();
+    method public long getCurrentPosition();
+    method public java.lang.String getName();
+    method public void onCommand(java.lang.String, android.os.Bundle, android.os.ResultReceiver);
+    method public final void updatePlaybackState(int);
+  }
+
+  public final class TransportController {
+    method public void addStateListener(android.media.session.TransportController.TransportStateListener);
+    method public void addStateListener(android.media.session.TransportController.TransportStateListener, android.os.Handler);
+    method public void fastForward();
+    method public android.media.session.MediaMetadata getMetadata();
+    method public android.media.session.PlaybackState getPlaybackState();
+    method public int getRatingType();
+    method public void next();
+    method public void pause();
+    method public void play();
+    method public void previous();
+    method public void rate(android.media.Rating);
+    method public void removeStateListener(android.media.session.TransportController.TransportStateListener);
+    method public void rewind();
+    method public void seekTo(long);
+    method public void stop();
+  }
+
+  public static abstract class TransportController.TransportStateListener {
+    ctor public TransportController.TransportStateListener();
+    method public void onMetadataChanged(android.media.session.MediaMetadata);
+    method public void onPlaybackStateChanged(android.media.session.PlaybackState);
+  }
+
+  public final class TransportPerformer {
+    method public void addListener(android.media.session.TransportPerformer.Listener);
+    method public void addListener(android.media.session.TransportPerformer.Listener, android.os.Handler);
+    method public void removeListener(android.media.session.TransportPerformer.Listener);
+    method public final void setMetadata(android.media.session.MediaMetadata);
+    method public final void setPlaybackState(android.media.session.PlaybackState);
+  }
+
+  public static abstract class TransportPerformer.Listener {
+    ctor public TransportPerformer.Listener();
+    method public void onFastForward();
+    method public void onNext();
+    method public void onPause();
+    method public void onPlay();
+    method public void onPrevious();
+    method public void onRate(android.media.Rating);
+    method public void onRewind();
+    method public void onRouteFocusChange(int);
+    method public void onSeekTo(long);
+    method public void onStop();
+  }
+
 }
 
 package android.mtp {
@@ -18429,6 +18616,7 @@
     field public static final int JELLY_BEAN_MR1 = 17; // 0x11
     field public static final int JELLY_BEAN_MR2 = 18; // 0x12
     field public static final int KITKAT = 19; // 0x13
+    field public static final int L = 10000; // 0x2710
   }
 
   public final class Bundle implements java.lang.Cloneable android.os.Parcelable {
@@ -25300,12 +25488,16 @@
     method public void clearPackagePreferredActivities(java.lang.String);
     method public java.lang.String[] currentToCanonicalPackageNames(java.lang.String[]);
     method public void extendVerificationTimeout(int, int, long);
+    method public android.graphics.drawable.Drawable getActivityBanner(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
+    method public android.graphics.drawable.Drawable getActivityBanner(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.graphics.drawable.Drawable getActivityIcon(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.graphics.drawable.Drawable getActivityIcon(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.graphics.drawable.Drawable getActivityLogo(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException;
     method public android.graphics.drawable.Drawable getActivityLogo(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException;
     method public java.util.List<android.content.pm.PermissionGroupInfo> getAllPermissionGroups(int);
+    method public android.graphics.drawable.Drawable getApplicationBanner(android.content.pm.ApplicationInfo);
+    method public android.graphics.drawable.Drawable getApplicationBanner(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
     method public int getApplicationEnabledSetting(java.lang.String);
     method public android.graphics.drawable.Drawable getApplicationIcon(android.content.pm.ApplicationInfo);
     method public android.graphics.drawable.Drawable getApplicationIcon(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
@@ -28824,7 +29016,6 @@
     method protected float getBottomFadingEdgeStrength();
     method protected int getBottomPaddingOffset();
     method public float getCameraDistance();
-    method public final boolean getCastsShadow();
     method public android.graphics.Rect getClipBounds();
     method public final boolean getClipToOutline();
     method public java.lang.CharSequence getContentDescription();
@@ -29094,7 +29285,6 @@
     method public void setBackgroundResource(int);
     method public final void setBottom(int);
     method public void setCameraDistance(float);
-    method public void setCastsShadow(boolean);
     method public void setClickable(boolean);
     method public void setClipBounds(android.graphics.Rect);
     method public void setClipToOutline(boolean);
diff --git a/api/removed.txt b/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/api/removed.txt
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 01e7615..92cb52c 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -114,6 +114,8 @@
                 "       am stack resize <STACK_ID> <LEFT,TOP,RIGHT,BOTTOM>\n" +
                 "       am stack list\n" +
                 "       am stack info <STACK_ID>\n" +
+                "       am lock-task <TASK_ID>\n" +
+                "       am lock-task stop\n" +
                 "\n" +
                 "am start: start an Activity.  Options are:\n" +
                 "    -D: enable debugging\n" +
@@ -218,6 +220,8 @@
                 "\n" +
                 "am stack info: display the information about activity stack <STACK_ID>.\n" +
                 "\n" +
+                "am lock-task: bring <TASK_ID> to the front and don't allow other tasks to run\n" +
+                "\n" +
                 "<INTENT> specifications include these flags and arguments:\n" +
                 "    [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>]\n" +
                 "    [-c <CATEGORY> [-c <CATEGORY>] ...]\n" +
@@ -309,6 +313,8 @@
             runStopUser();
         } else if (op.equals("stack")) {
             runStack();
+        } else if (op.equals("lock-task")) {
+            runLockTask();
         } else {
             showError("Error: unknown command '" + op + "'");
         }
@@ -1641,4 +1647,19 @@
         } catch (RemoteException e) {
         }
     }
+
+    private void runLockTask() throws Exception {
+        String taskIdStr = nextArgRequired();
+        try {
+            if (taskIdStr.equals("stop")) {
+                mAm.stopLockTaskMode();
+            } else {
+                int taskId = Integer.valueOf(taskIdStr);
+                mAm.startLockTaskMode(taskId);
+            }
+            System.err.println("Activity manager is " + (mAm.isInLockTaskMode() ? "" : "not ") +
+                    "in lockTaskMode");
+        } catch (RemoteException e) {
+        }
+    }
 }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 287c463..606d803 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -5606,6 +5606,22 @@
         }
     }
 
+    /** @hide */
+    public void startLockTask() {
+        try {
+            ActivityManagerNative.getDefault().startLockTaskMode(mToken);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /** @hide */
+    public void stopLockTask() {
+        try {
+            ActivityManagerNative.getDefault().stopLockTaskMode();
+        } catch (RemoteException e) {
+        }
+    }
+
     /**
      * Interface for informing a translucent {@link Activity} once all visible activities below it
      * have completed drawing. This is necessary only after an {@link Activity} has been made
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 7f7616f..0787ef1 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -155,6 +155,13 @@
     public static final int START_SWITCHES_CANCELED = 4;
 
     /**
+     * Result for IActivityManaqer.startActivity: a new activity was attempted to be started
+     * while in Lock Task Mode.
+     * @hide
+     */
+    public static final int START_RETURN_LOCK_TASK_MODE_VIOLATION = 5;
+
+    /**
      * Flag for IActivityManaqer.startActivity: do special start mode where
      * a new activity is launched only if it is needed.
      * @hide
@@ -502,6 +509,12 @@
          */
         public int stackId;
 
+        /**
+         * The id the of the user the task was running as.
+         * @hide
+         */
+        public int userId;
+
         public RecentTaskInfo() {
         }
 
@@ -524,6 +537,7 @@
             TextUtils.writeToParcel(description, dest,
                     Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
             dest.writeInt(stackId);
+            dest.writeInt(userId);
         }
 
         public void readFromParcel(Parcel source) {
@@ -537,6 +551,7 @@
             origActivity = ComponentName.readFromParcel(source);
             description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
             stackId = source.readInt();
+            userId = source.readInt();
         }
 
         public static final Creator<RecentTaskInfo> CREATOR
@@ -560,7 +575,7 @@
      * {@link android.content.Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} flag.
      */
     public static final int RECENT_WITH_EXCLUDED = 0x0001;
-    
+
     /**
      * Provides a list that does not contain any
      * recent tasks that currently are not available to the user.
@@ -568,6 +583,13 @@
     public static final int RECENT_IGNORE_UNAVAILABLE = 0x0002;
 
     /**
+     * Provides a list that also contains recent tasks for user
+     * and related users.
+     * @hide
+     */
+    public static final int RECENT_INCLUDE_RELATED = 0x0004;
+
+    /**
      * Return a list of the tasks that the user has recently launched, with
      * the most recent being first and older ones after in order.
      *
@@ -2232,4 +2254,35 @@
             e.printStackTrace(pw);
         }
     }
+
+    /**
+     * @hide
+     */
+    public void startLockTaskMode(int taskId) {
+        try {
+            ActivityManagerNative.getDefault().startLockTaskMode(taskId);
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public void stopLockTaskMode() {
+        try {
+            ActivityManagerNative.getDefault().stopLockTaskMode();
+        } catch (RemoteException e) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public boolean isInLockTaskMode() {
+        try {
+            return ActivityManagerNative.getDefault().isInLockTaskMode();
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
 }
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index c7c81dd..373a8a3 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -2097,6 +2097,37 @@
             reply.writeStrongBinder(homeActivityToken);
             return true;
         }
+
+        case START_LOCK_TASK_BY_TASK_ID_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final int taskId = data.readInt();
+            startLockTaskMode(taskId);
+            reply.writeNoException();
+            return true;
+        }
+
+        case START_LOCK_TASK_BY_TOKEN_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            startLockTaskMode(token);
+            reply.writeNoException();
+            return true;
+        }
+
+        case STOP_LOCK_TASK_MODE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            stopLockTaskMode();
+            reply.writeNoException();
+            return true;
+        }
+
+        case IS_IN_LOCK_TASK_MODE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final boolean isInLockTaskMode = isInLockTaskMode();
+            reply.writeNoException();
+            reply.writeInt(isInLockTaskMode ? 1 : 0);
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -4820,5 +4851,53 @@
         return res;
     }
 
+    @Override
+    public void startLockTaskMode(int taskId) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeInt(taskId);
+        mRemote.transact(START_LOCK_TASK_BY_TASK_ID_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public void startLockTaskMode(IBinder token) throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(START_LOCK_TASK_BY_TOKEN_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public void stopLockTaskMode() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(STOP_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    @Override
+    public boolean isInLockTaskMode() throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(IS_IN_LOCK_TASK_MODE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        boolean isInLockTaskMode = reply.readInt() == 1;
+        data.recycle();
+        reply.recycle();
+        return isInLockTaskMode;
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index e71d47d..079cf7a 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -878,7 +878,7 @@
     }
 
     /**
-     * Like {@link #checkOp but instead of throwing a {@link SecurityException} it
+     * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
      * returns {@link #MODE_ERRORED}.
      */
     public int checkOpNoThrow(String op, int uid, String packageName) {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 061e5a5..8165fa1 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -727,6 +727,39 @@
     }
 
     @Override
+    public Drawable getActivityBanner(ComponentName activityName)
+            throws NameNotFoundException {
+        return getActivityInfo(activityName, 0).loadBanner(this);
+    }
+
+    @Override
+    public Drawable getActivityBanner(Intent intent)
+            throws NameNotFoundException {
+        if (intent.getComponent() != null) {
+            return getActivityBanner(intent.getComponent());
+        }
+
+        ResolveInfo info = resolveActivity(
+                intent, PackageManager.MATCH_DEFAULT_ONLY);
+        if (info != null) {
+            return info.activityInfo.loadBanner(this);
+        }
+
+        throw new NameNotFoundException(intent.toUri(0));
+    }
+
+    @Override
+    public Drawable getApplicationBanner(ApplicationInfo info) {
+        return info.loadBanner(this);
+    }
+
+    @Override
+    public Drawable getApplicationBanner(String packageName)
+            throws NameNotFoundException {
+        return getApplicationBanner(getApplicationInfo(packageName, 0));
+    }
+
+    @Override
     public Drawable getActivityLogo(ComponentName activityName)
             throws NameNotFoundException {
         return getActivityInfo(activityName, 0).loadLogo(this);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 0351292..344c3b2 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1479,13 +1479,13 @@
 
     private void validateServiceIntent(Intent service) {
         if (service.getComponent() == null && service.getPackage() == null) {
-            if (true || getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
+            if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
+                IllegalArgumentException ex = new IllegalArgumentException(
+                        "Service Intent must be explicit: " + service);
+                throw ex;
+            } else {
                 Log.w(TAG, "Implicit intents with startService are not safe: " + service
                         + " " + Debug.getCallers(2, 3));
-                //IllegalArgumentException ex = new IllegalArgumentException(
-                //        "Service Intent must be explicit: " + service);
-                //Log.e(TAG, "This will become an error", ex);
-                //throw ex;
             }
         }
     }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index f2cabf4..cb06a42 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -424,6 +424,18 @@
 
     public IBinder getHomeActivityToken() throws RemoteException;
 
+    /** @hide */
+    public void startLockTaskMode(int taskId) throws RemoteException;
+
+    /** @hide */
+    public void startLockTaskMode(IBinder token) throws RemoteException;
+
+    /** @hide */
+    public void stopLockTaskMode() throws RemoteException;
+
+    /** @hide */
+    public boolean isInLockTaskMode() throws RemoteException;
+
     /*
      * Private non-Binder interfaces
      */
@@ -719,4 +731,8 @@
     int GET_TAG_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+210;
     int START_USER_IN_BACKGROUND_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+211;
     int IS_IN_HOME_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+212;
+    int START_LOCK_TASK_BY_TASK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+213;
+    int START_LOCK_TASK_BY_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+214;
+    int STOP_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+215;
+    int IS_IN_LOCK_TASK_MODE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+216;
 }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index e06cf38..30c84f6 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -95,7 +95,7 @@
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_PROVISION_MANAGED_PROFILE
-        = "android.managedprovisioning.ACTION_PROVISION_MANAGED_PROFILE";
+        = "android.app.action.ACTION_PROVISION_MANAGED_PROFILE";
 
     /**
      * A String extra holding the name of the package of the mobile device management application
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 81a886a..134ffa9 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -242,6 +242,16 @@
     public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080;
 
     /**
+     * @hide Flag for {@link #bindService}: Treat the binding as hosting
+     * an activity, an unbinding as the activity going in the background.
+     * That is, when unbinding, the process when empty will go on the activity
+     * LRU list instead of the regular one, keeping it around more aggressively
+     * than it otherwise would be.  This is intended for use with IMEs to try
+     * to keep IME processes around for faster keyboard switching.
+     */
+    public static final int BIND_TREAT_LIKE_ACTIVITY = 0x08000000;
+
+    /**
      * @hide An idea that is not yet implemented.
      * Flag for {@link #bindService}: If binding from an activity, consider
      * this service to be visible like the binding activity is.  That is,
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 96479e2..0175d62 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3457,7 +3457,16 @@
      */
     public static final int FLAG_ACTIVITY_NEW_TASK = 0x10000000;
     /**
-     * <strong>Do not use this flag unless you are implementing your own
+     * This flag is used to create a new task and launch an activity into it.
+     * This flag is always paired with either {@link #FLAG_ACTIVITY_NEW_DOCUMENT}
+     * or {@link #FLAG_ACTIVITY_NEW_TASK}. In both cases these flags alone would
+     * search through existing tasks for ones matching this Intent. Only if no such
+     * task is found would a new task be created. When paired with
+     * FLAG_ACTIVITY_MULTIPLE_TASK both of these behaviors are modified to skip
+     * the search for a matching task and unconditionally start a new task.
+     *
+     * <strong>When used with {@link #FLAG_ACTIVITY_NEW_TASK} do not use this
+     * flag unless you are implementing your own
      * top-level application launcher.</strong>  Used in conjunction with
      * {@link #FLAG_ACTIVITY_NEW_TASK} to disable the
      * behavior of bringing an existing task to the foreground.  When set,
@@ -3469,12 +3478,18 @@
      * you should not use this flag unless you provide some way for a user to
      * return back to the tasks you have launched.</strong>
      *
-     * <p>This flag is ignored if
-     * {@link #FLAG_ACTIVITY_NEW_TASK} is not set.
+     * See {@link #FLAG_ACTIVITY_NEW_DOCUMENT} for details of this flag's use for
+     * creating new document tasks.
+     *
+     * <p>This flag is ignored if one of {@link #FLAG_ACTIVITY_NEW_TASK} or
+     * {@link #FLAG_ACTIVITY_NEW_TASK} is not also set.
      *
      * <p>See
      * <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
      * Stack</a> for more information about tasks.
+     *
+     * @see #FLAG_ACTIVITY_NEW_DOCUMENT
+     * @see #FLAG_ACTIVITY_NEW_TASK
      */
     public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000;
     /**
@@ -3581,6 +3596,34 @@
      */
     public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000;
     /**
+     * This flag is used to break out "documents" into separate tasks that can
+     * be reached via the Recents mechanism. Such a document is any kind of
+     * item for which an application may want to maintain multiple simultaneous
+     * instances. Examples might be text files, web pages, spreadsheets, or
+     * emails. Each such document will be in a separate task in the Recents list.
+     *
+     * <p>When set, the activity specified by this Intent will launch into a
+     * separate task rooted at that activity. The activity launched must be
+     * defined with {@link android.R.attr#launchMode} "standard" or "singleTop".
+     *
+     * <p>If FLAG_ACTIVITY_NEW_DOCUMENT is used without
+     * {@link #FLAG_ACTIVITY_MULTIPLE_TASK} then the activity manager will
+     * search for an existing task with a matching target activity and Intent
+     * data URI and relaunch that task, first finishing all activities down to
+     * the root activity and then calling the root activity's
+     * {@link android.app.Activity#onNewIntent(Intent)} method. If no existing
+     * task's root activity matches the Intent's data URI then a new task will
+     * be launched with the target activity as root.
+     *
+     * <p>When paired with {@link #FLAG_ACTIVITY_MULTIPLE_TASK} this will
+     * always create a new task. Thus the same document may be made to appear
+     * more than one time in Recents.
+     *
+     * @see #FLAG_ACTIVITY_MULTIPLE_TASK
+     */
+    public static final int FLAG_ACTIVITY_NEW_DOCUMENT =
+            FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET | FLAG_ACTIVITY_NEW_TASK;
+    /**
      * If set, this flag will prevent the normal {@link android.app.Activity#onUserLeaveHint}
      * callback from occurring on the current frontmost activity before it is
      * paused as the newly-started activity is brought to the front.
@@ -6246,6 +6289,7 @@
      * @see #FLAG_ACTIVITY_FORWARD_RESULT
      * @see #FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
      * @see #FLAG_ACTIVITY_MULTIPLE_TASK
+     * @see #FLAG_ACTIVITY_NEW_DOCUMENT
      * @see #FLAG_ACTIVITY_NEW_TASK
      * @see #FLAG_ACTIVITY_NO_ANIMATION
      * @see #FLAG_ACTIVITY_NO_HISTORY
@@ -7342,4 +7386,9 @@
         String htmlText = htmlTexts != null ? htmlTexts.get(which) : null;
         return new ClipData.Item(text, htmlText, null, uri);
     }
+
+    /** @hide */
+    public boolean isDocument() {
+        return (mFlags & FLAG_ACTIVITY_NEW_DOCUMENT) == FLAG_ACTIVITY_NEW_DOCUMENT;
+    }
 }
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index 4dbcf23..7e8f285 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -128,6 +128,17 @@
         return logo != 0 ? logo : applicationInfo.logo;
     }
     
+    /**
+     * Return the banner resource identifier to use for this component. If the
+     * component defines a banner, that is used; else, the application banner is
+     * used.
+     *
+     * @return The banner associated with this component.
+     */
+    public final int getBannerResource() {
+        return banner != 0 ? banner : applicationInfo.banner;
+    }
+
     protected void dumpFront(Printer pw, String prefix) {
         super.dumpFront(pw, prefix);
         pw.println(prefix + "enabled=" + enabled + " exported=" + exported
@@ -175,6 +186,13 @@
     /**
      * @hide
      */
+    @Override protected Drawable loadDefaultBanner(PackageManager pm) {
+        return applicationInfo.loadBanner(pm);
+    }
+
+    /**
+     * @hide
+     */
     @Override
     protected Drawable loadDefaultLogo(PackageManager pm) {
         return applicationInfo.loadLogo(pm);
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index a67326e..58f1c84 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -68,6 +68,12 @@
     
     /**
      * A drawable resource identifier (in the package's resources) of this
+     * component's banner.  From the "banner" attribute or, if not set, 0.
+     */
+    public int banner;
+
+    /**
+     * A drawable resource identifier (in the package's resources) of this
      * component's logo. Logos may be larger/wider than icons and are
      * displayed by certain UI elements in place of a name or name/icon
      * combination. From the "logo" attribute or, if not set, 0. 
@@ -92,6 +98,7 @@
         nonLocalizedLabel = orig.nonLocalizedLabel;
         if (nonLocalizedLabel != null) nonLocalizedLabel = nonLocalizedLabel.toString().trim();
         icon = orig.icon;
+        banner = orig.banner;
         logo = orig.logo;
         metaData = orig.metaData;
     }
@@ -146,6 +153,27 @@
     }
     
     /**
+     * Retrieve the current graphical banner associated with this item.  This
+     * will call back on the given PackageManager to load the banner from
+     * the application.
+     *
+     * @param pm A PackageManager from which the banner can be loaded; usually
+     * the PackageManager from which you originally retrieved this item.
+     *
+     * @return Returns a Drawable containing the item's banner.  If the item
+     * does not have a banner, this method will return null.
+     */
+    public Drawable loadBanner(PackageManager pm) {
+        if (banner != 0) {
+            Drawable dr = pm.getDrawable(packageName, banner, getApplicationInfo());
+            if (dr != null) {
+                return dr;
+            }
+        }
+        return loadDefaultBanner(pm);
+    }
+
+    /**
      * Retrieve the default graphical icon associated with this item.
      * 
      * @param pm A PackageManager from which the icon can be loaded; usually
@@ -159,7 +187,22 @@
     protected Drawable loadDefaultIcon(PackageManager pm) {
         return pm.getDefaultActivityIcon();
     }
-    
+
+    /**
+     * Retrieve the default graphical banner associated with this item.
+     *
+     * @param pm A PackageManager from which the banner can be loaded; usually
+     * the PackageManager from which you originally retrieved this item.
+     *
+     * @return Returns a Drawable containing the item's default banner
+     * or null if no default logo is available.
+     *
+     * @hide
+     */
+    protected Drawable loadDefaultBanner(PackageManager pm) {
+        return null;
+    }
+
     /**
      * Retrieve the current graphical logo associated with this item. This
      * will call back on the given PackageManager to load the logo from
@@ -224,10 +267,11 @@
             pw.println(prefix + "name=" + name);
         }
         pw.println(prefix + "packageName=" + packageName);
-        if (labelRes != 0 || nonLocalizedLabel != null || icon != 0) {
+        if (labelRes != 0 || nonLocalizedLabel != null || icon != 0 || banner != 0) {
             pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes)
                     + " nonLocalizedLabel=" + nonLocalizedLabel
-                    + " icon=0x" + Integer.toHexString(icon));
+                    + " icon=0x" + Integer.toHexString(icon)
+                    + " banner=0x" + Integer.toHexString(banner));
         }
     }
     
@@ -243,6 +287,7 @@
         dest.writeInt(icon);
         dest.writeInt(logo);
         dest.writeBundle(metaData);
+        dest.writeInt(banner);
     }
     
     protected PackageItemInfo(Parcel source) {
@@ -254,6 +299,7 @@
         icon = source.readInt();
         logo = source.readInt();
         metaData = source.readBundle();
+        banner = source.readInt();
     }
 
     /**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b648930..e86833b 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1233,6 +1233,26 @@
 
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports leanback UI. This is
+     * typically used in a living room television experience, but is a software
+     * feature unlike {@link #FEATURE_TELEVISION}. Devices running with this
+     * feature will use resources associated with the "television" UI mode.
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_LEANBACK = "android.software.leanback";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
+     * {@link #hasSystemFeature}: The device supports only leanback UI. Only
+     * applications designed for this experience should be run, though this is
+     * not enforced by the system.
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_LEANBACK_ONLY = "android.software.leanback_only";
+
+    /**
+     * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device supports WiFi (802.11) networking.
      */
     @SdkConstant(SdkConstantType.FEATURE)
@@ -1252,6 +1272,7 @@
      * room television experience: displayed on a big screen, where the user
      * is sitting far away from it, and the dominant form of input will be
      * something like a DPAD, not through touch or mouse.
+     * @deprecated use {@link #FEATURE_LEANBACK} instead.
      */
     @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_TELEVISION = "android.hardware.type.television";
@@ -2400,9 +2421,43 @@
             throws NameNotFoundException;
 
     /**
+     * Retrieve the banner associated with an activity. Given the full name of
+     * an activity, retrieves the information about it and calls
+     * {@link ComponentInfo#loadIcon ComponentInfo.loadIcon()} to return its
+     * banner. If the activity cannot be found, NameNotFoundException is thrown.
+     *
+     * @param activityName Name of the activity whose banner is to be retrieved.
+     * @return Returns the image of the banner, or null if the activity has no
+     *         banner specified.
+     * @throws NameNotFoundException Thrown if the resources for the given
+     *             activity could not be loaded.
+     * @see #getActivityBanner(Intent)
+     */
+    public abstract Drawable getActivityBanner(ComponentName activityName)
+            throws NameNotFoundException;
+
+    /**
+     * Retrieve the banner associated with an Intent. If intent.getClassName()
+     * is set, this simply returns the result of
+     * getActivityBanner(intent.getClassName()). Otherwise it resolves the
+     * intent's component and returns the banner associated with the resolved
+     * component. If intent.getClassName() cannot be found or the Intent cannot
+     * be resolved to a component, NameNotFoundException is thrown.
+     *
+     * @param intent The intent for which you would like to retrieve a banner.
+     * @return Returns the image of the banner, or null if the activity has no
+     *         banner specified.
+     * @throws NameNotFoundException Thrown if the resources for application
+     *             matching the given intent could not be loaded.
+     * @see #getActivityBanner(ComponentName)
+     */
+    public abstract Drawable getActivityBanner(Intent intent)
+            throws NameNotFoundException;
+
+    /**
      * Return the generic icon for an activity that is used when no specific
      * icon is defined.
-     *
+     * 
      * @return Drawable Image of the icon.
      */
     public abstract Drawable getDefaultActivityIcon();
@@ -2440,19 +2495,43 @@
             throws NameNotFoundException;
 
     /**
-     * Retrieve the logo associated with an activity.  Given the full name of
-     * an activity, retrieves the information about it and calls
-     * {@link ComponentInfo#loadLogo ComponentInfo.loadLogo()} to return its logo.
-     * If the activity cannot be found, NameNotFoundException is thrown.
+     * Retrieve the banner associated with an application.
+     *
+     * @param info Information about application being queried.
+     * @return Returns the image of the banner or null if the application has no
+     *         banner specified.
+     * @see #getApplicationBanner(String)
+     */
+    public abstract Drawable getApplicationBanner(ApplicationInfo info);
+
+    /**
+     * Retrieve the banner associated with an application. Given the name of the
+     * application's package, retrieves the information about it and calls
+     * getApplicationIcon() to return its banner. If the application cannot be
+     * found, NameNotFoundException is thrown.
+     *
+     * @param packageName Name of the package whose application banner is to be
+     *            retrieved.
+     * @return Returns the image of the banner or null if the application has no
+     *         banner specified.
+     * @throws NameNotFoundException Thrown if the resources for the given
+     *             application could not be loaded.
+     * @see #getApplicationBanner(ApplicationInfo)
+     */
+    public abstract Drawable getApplicationBanner(String packageName)
+            throws NameNotFoundException;
+
+    /**
+     * Retrieve the logo associated with an activity. Given the full name of an
+     * activity, retrieves the information about it and calls
+     * {@link ComponentInfo#loadLogo ComponentInfo.loadLogo()} to return its
+     * logo. If the activity cannot be found, NameNotFoundException is thrown.
      *
      * @param activityName Name of the activity whose logo is to be retrieved.
-     *
-     * @return Returns the image of the logo or null if the activity has no
-     * logo specified.
-     *
+     * @return Returns the image of the logo or null if the activity has no logo
+     *         specified.
      * @throws NameNotFoundException Thrown if the resources for the given
-     * activity could not be loaded.
-     *
+     *             activity could not be loaded.
      * @see #getActivityLogo(Intent)
      */
     public abstract Drawable getActivityLogo(ComponentName activityName)
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index c222003..f76aada 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -167,18 +167,20 @@
         final int labelRes;
         final int iconRes;
         final int logoRes;
+        final int bannerRes;
         
         String tag;
         TypedArray sa;
         
         ParsePackageItemArgs(Package _owner, String[] _outError,
-                int _nameRes, int _labelRes, int _iconRes, int _logoRes) {
+                int _nameRes, int _labelRes, int _iconRes, int _logoRes, int _bannerRes) {
             owner = _owner;
             outError = _outError;
             nameRes = _nameRes;
             labelRes = _labelRes;
             iconRes = _iconRes;
             logoRes = _logoRes;
+            bannerRes = _bannerRes;
         }
     }
     
@@ -190,10 +192,10 @@
         int flags;
         
         ParseComponentArgs(Package _owner, String[] _outError,
-                int _nameRes, int _labelRes, int _iconRes, int _logoRes,
+                int _nameRes, int _labelRes, int _iconRes, int _logoRes, int _bannerRes,
                 String[] _sepProcesses, int _processRes,
                 int _descriptionRes, int _enabledRes) {
-            super(_owner, _outError, _nameRes, _labelRes, _iconRes, _logoRes);
+            super(_owner, _outError, _nameRes, _labelRes, _iconRes, _logoRes, _bannerRes);
             sepProcesses = _sepProcesses;
             processRes = _processRes;
             descriptionRes = _descriptionRes;
@@ -1688,7 +1690,8 @@
                 com.android.internal.R.styleable.AndroidManifestPermissionGroup_name,
                 com.android.internal.R.styleable.AndroidManifestPermissionGroup_label,
                 com.android.internal.R.styleable.AndroidManifestPermissionGroup_icon,
-                com.android.internal.R.styleable.AndroidManifestPermissionGroup_logo)) {
+                com.android.internal.R.styleable.AndroidManifestPermissionGroup_logo,
+                com.android.internal.R.styleable.AndroidManifestPermissionGroup_banner)) {
             sa.recycle();
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
             return null;
@@ -1731,7 +1734,8 @@
                 com.android.internal.R.styleable.AndroidManifestPermission_name,
                 com.android.internal.R.styleable.AndroidManifestPermission_label,
                 com.android.internal.R.styleable.AndroidManifestPermission_icon,
-                com.android.internal.R.styleable.AndroidManifestPermission_logo)) {
+                com.android.internal.R.styleable.AndroidManifestPermission_logo,
+                com.android.internal.R.styleable.AndroidManifestPermission_banner)) {
             sa.recycle();
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
             return null;
@@ -1800,7 +1804,8 @@
                 com.android.internal.R.styleable.AndroidManifestPermissionTree_name,
                 com.android.internal.R.styleable.AndroidManifestPermissionTree_label,
                 com.android.internal.R.styleable.AndroidManifestPermissionTree_icon,
-                com.android.internal.R.styleable.AndroidManifestPermissionTree_logo)) {
+                com.android.internal.R.styleable.AndroidManifestPermissionTree_logo,
+                com.android.internal.R.styleable.AndroidManifestPermissionTree_banner)) {
             sa.recycle();
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
             return null;
@@ -1845,7 +1850,8 @@
                     com.android.internal.R.styleable.AndroidManifestInstrumentation_name,
                     com.android.internal.R.styleable.AndroidManifestInstrumentation_label,
                     com.android.internal.R.styleable.AndroidManifestInstrumentation_icon,
-                    com.android.internal.R.styleable.AndroidManifestInstrumentation_logo);
+                    com.android.internal.R.styleable.AndroidManifestInstrumentation_logo,
+                    com.android.internal.R.styleable.AndroidManifestInstrumentation_banner);
             mParseInstrumentationArgs.tag = "<instrumentation>";
         }
         
@@ -1961,6 +1967,8 @@
                 com.android.internal.R.styleable.AndroidManifestApplication_icon, 0);
         ai.logo = sa.getResourceId(
                 com.android.internal.R.styleable.AndroidManifestApplication_logo, 0);
+        ai.banner = sa.getResourceId(
+                com.android.internal.R.styleable.AndroidManifestApplication_banner, 0);
         ai.theme = sa.getResourceId(
                 com.android.internal.R.styleable.AndroidManifestApplication_theme, 0);
         ai.descriptionRes = sa.getResourceId(
@@ -2256,7 +2264,7 @@
 
     private boolean parsePackageItemInfo(Package owner, PackageItemInfo outInfo,
             String[] outError, String tag, TypedArray sa,
-            int nameRes, int labelRes, int iconRes, int logoRes) {
+            int nameRes, int labelRes, int iconRes, int logoRes, int bannerRes) {
         String name = sa.getNonConfigurationString(nameRes, 0);
         if (name == null) {
             outError[0] = tag + " does not specify android:name";
@@ -2280,6 +2288,11 @@
             outInfo.logo = logoVal;
         }
 
+        int bannerVal = sa.getResourceId(bannerRes, 0);
+        if (bannerVal != 0) {
+            outInfo.banner = bannerVal;
+        }
+
         TypedValue v = sa.peekValue(labelRes);
         if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
             outInfo.nonLocalizedLabel = v.coerceToString();
@@ -2303,6 +2316,7 @@
                     com.android.internal.R.styleable.AndroidManifestActivity_label,
                     com.android.internal.R.styleable.AndroidManifestActivity_icon,
                     com.android.internal.R.styleable.AndroidManifestActivity_logo,
+                    com.android.internal.R.styleable.AndroidManifestActivity_banner,
                     mSeparateProcesses,
                     com.android.internal.R.styleable.AndroidManifestActivity_process,
                     com.android.internal.R.styleable.AndroidManifestActivity_description,
@@ -2588,6 +2602,7 @@
                     com.android.internal.R.styleable.AndroidManifestActivityAlias_label,
                     com.android.internal.R.styleable.AndroidManifestActivityAlias_icon,
                     com.android.internal.R.styleable.AndroidManifestActivityAlias_logo,
+                    com.android.internal.R.styleable.AndroidManifestActivityAlias_banner,
                     mSeparateProcesses,
                     0,
                     com.android.internal.R.styleable.AndroidManifestActivityAlias_description,
@@ -2622,6 +2637,7 @@
         info.flags = target.info.flags;
         info.icon = target.info.icon;
         info.logo = target.info.logo;
+        info.banner = target.info.banner;
         info.labelRes = target.info.labelRes;
         info.nonLocalizedLabel = target.info.nonLocalizedLabel;
         info.launchMode = target.info.launchMode;
@@ -2735,6 +2751,7 @@
                     com.android.internal.R.styleable.AndroidManifestProvider_label,
                     com.android.internal.R.styleable.AndroidManifestProvider_icon,
                     com.android.internal.R.styleable.AndroidManifestProvider_logo,
+                    com.android.internal.R.styleable.AndroidManifestProvider_banner,
                     mSeparateProcesses,
                     com.android.internal.R.styleable.AndroidManifestProvider_process,
                     com.android.internal.R.styleable.AndroidManifestProvider_description,
@@ -3041,6 +3058,7 @@
                     com.android.internal.R.styleable.AndroidManifestService_label,
                     com.android.internal.R.styleable.AndroidManifestService_icon,
                     com.android.internal.R.styleable.AndroidManifestService_logo,
+                    com.android.internal.R.styleable.AndroidManifestService_banner,
                     mSeparateProcesses,
                     com.android.internal.R.styleable.AndroidManifestService_process,
                     com.android.internal.R.styleable.AndroidManifestService_description,
@@ -3338,6 +3356,9 @@
         outInfo.logo = sa.getResourceId(
                 com.android.internal.R.styleable.AndroidManifestIntentFilter_logo, 0);
 
+        outInfo.banner = sa.getResourceId(
+                com.android.internal.R.styleable.AndroidManifestIntentFilter_banner, 0);
+
         sa.recycle();
 
         int outerDepth = parser.getDepth();
@@ -3707,6 +3728,11 @@
                 outInfo.logo = logoVal;
             }
 
+            int bannerVal = args.sa.getResourceId(args.bannerRes, 0);
+            if (bannerVal != 0) {
+                outInfo.banner = bannerVal;
+            }
+
             TypedValue v = args.sa.peekValue(args.labelRes);
             if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
                 outInfo.nonLocalizedLabel = v.coerceToString();
@@ -4131,6 +4157,7 @@
         public CharSequence nonLocalizedLabel;
         public int icon;
         public int logo;
+        public int banner;
         public int preferred;
     }
 
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 875e8de..4a743a5 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -140,12 +140,33 @@
         mContext.registerReceiver(mExternalReceiver, sdFilter);
     }
 
+    private final void handlePackageEvent(Intent intent, int userId) {
+        // Don't regenerate the services map when the package is removed or its
+        // ASEC container unmounted as a step in replacement.  The subsequent
+        // _ADDED / _AVAILABLE call will regenerate the map in the final state.
+        final String action = intent.getAction();
+        // it's a new-component action if it isn't some sort of removal
+        final boolean isRemoval = Intent.ACTION_PACKAGE_REMOVED.equals(action)
+                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action);
+        // if it's a removal, is it part of an update-in-place step?
+        final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
+
+        if (isRemoval && replacing) {
+            // package is going away, but it's the middle of an upgrade: keep the current
+            // state and do nothing here.  This clause is intentionally empty.
+        } else {
+            // either we're adding/changing, or it's a removal without replacement, so
+            // we need to recalculate the set of available services
+            generateServicesMap(userId);
+        }
+    }
+
     private final BroadcastReceiver mPackageReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             final int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
             if (uid != -1) {
-                generateServicesMap(UserHandle.getUserId(uid));
+                handlePackageEvent(intent, UserHandle.getUserId(uid));
             }
         }
     };
@@ -154,7 +175,7 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             // External apps can't coexist with multi-user, so scan owner
-            generateServicesMap(UserHandle.USER_OWNER);
+            handlePackageEvent(intent, UserHandle.USER_OWNER);
         }
     };
 
diff --git a/core/java/android/hardware/ICameraService.aidl b/core/java/android/hardware/ICameraService.aidl
index 542af6a..4c50dda 100644
--- a/core/java/android/hardware/ICameraService.aidl
+++ b/core/java/android/hardware/ICameraService.aidl
@@ -61,4 +61,12 @@
     int removeListener(ICameraServiceListener listener);
 
     int getCameraCharacteristics(int cameraId, out CameraMetadataNative info);
+
+    /**
+     * The java stubs for this method are not intended to be used.  Please use
+     * the native stub in frameworks/av/include/camera/ICameraService.h instead.
+     * The BinderHolder output is being used as a placeholder, and will not be
+     * well-formatted in the generated java method.
+     */
+    int getCameraVendorTagDescriptor(out BinderHolder desc);
 }
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index d27485b..4c04caa 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -148,7 +148,7 @@
      * <p>All camera devices support ON, and all camera devices with
      * flash units support ON_AUTO_FLASH and
      * ON_ALWAYS_FLASH.</p>
-     * <p>Full-capability camera devices always support OFF mode,
+     * <p>FULL mode camera devices always support OFF mode,
      * which enables application control of camera exposure time,
      * sensitivity, and frame duration.</p>
      *
@@ -244,7 +244,7 @@
      * given camera device. This entry lists the valid modes for
      * {@link CaptureRequest#CONTROL_AWB_MODE android.control.awbMode} for this camera device.</p>
      * <p>All camera devices will support ON mode.</p>
-     * <p>Full-capability camera devices will always support OFF mode,
+     * <p>FULL mode camera devices will always support OFF mode,
      * which enables application control of white balance, by using
      * {@link CaptureRequest#COLOR_CORRECTION_TRANSFORM android.colorCorrection.transform} and {@link CaptureRequest#COLOR_CORRECTION_GAINS android.colorCorrection.gains}({@link CaptureRequest#COLOR_CORRECTION_MODE android.colorCorrection.mode} must be set to TRANSFORM_MATRIX).</p>
      *
@@ -280,6 +280,17 @@
             new Key<Boolean>("android.flash.info.available", boolean.class);
 
     /**
+     * <p>The set of hot pixel correction modes that are supported by this
+     * camera device.</p>
+     * <p>This tag lists valid modes for {@link CaptureRequest#HOT_PIXEL_MODE android.hotPixel.mode}.</p>
+     * <p>FULL mode camera devices will always support FAST.</p>
+     *
+     * @see CaptureRequest#HOT_PIXEL_MODE
+     */
+    public static final Key<byte[]> HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES =
+            new Key<byte[]>("android.hotPixel.availableHotPixelModes", byte[].class);
+
+    /**
      * <p>Supported resolutions for the JPEG thumbnail</p>
      * <p>Below condiditions will be satisfied for this size list:</p>
      * <ul>
@@ -1088,6 +1099,18 @@
             new Key<Integer>("android.statistics.info.maxFaceCount", int.class);
 
     /**
+     * <p>The set of hot pixel map output modes supported by this camera device.</p>
+     * <p>This tag lists valid output modes for {@link CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE android.statistics.hotPixelMapMode}.</p>
+     * <p>If no hotpixel map is available for this camera device, this will contain
+     * only OFF.  If the hotpixel map is available, this should include both
+     * the ON and OFF options.</p>
+     *
+     * @see CaptureRequest#STATISTICS_HOT_PIXEL_MAP_MODE
+     */
+    public static final Key<boolean[]> STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES =
+            new Key<boolean[]>("android.statistics.info.availableHotPixelMapModes", boolean[].class);
+
+    /**
      * <p>Maximum number of supported points in the
      * tonemap curve that can be used for {@link CaptureRequest#TONEMAP_CURVE_RED android.tonemap.curveRed}, or
      * {@link CaptureRequest#TONEMAP_CURVE_GREEN android.tonemap.curveGreen}, or {@link CaptureRequest#TONEMAP_CURVE_BLUE android.tonemap.curveBlue}.</p>
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index 2ac50e4..0fcd598 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -48,6 +48,8 @@
  */
 public final class CameraManager {
 
+    private static final String TAG = "CameraManager";
+
     /**
      * This should match the ICameraService definition
      */
@@ -79,6 +81,14 @@
         mCameraService = CameraBinderDecorator.newInstance(cameraServiceRaw);
 
         try {
+            CameraBinderDecorator.throwOnError(
+                    CameraMetadataNative.nativeSetupGlobalVendorTagDescriptor());
+        } catch(CameraRuntimeException e) {
+            throw new IllegalStateException("Failed to setup camera vendor tags",
+                    e.asChecked());
+        }
+
+        try {
             mCameraService.addListener(new CameraServiceListener());
         } catch(CameraRuntimeException e) {
             throw new IllegalStateException("Failed to register a camera service listener",
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index a62df0f..a3fbfbe 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -1199,7 +1199,10 @@
     /**
      * <p>The frame rate must not be reduced relative to sensor raw output
      * for this option.</p>
-     * <p>No hot pixel correction is applied.</p>
+     * <p>No hot pixel correction is applied.
+     * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+     *
+     * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
      * @see CaptureRequest#HOT_PIXEL_MODE
      */
     public static final int HOT_PIXEL_MODE_OFF = 0;
@@ -1207,7 +1210,10 @@
     /**
      * <p>The frame rate must not be reduced relative to sensor raw output
      * for this option.</p>
-     * <p>Hot pixel correction is applied.</p>
+     * <p>Hot pixel correction is applied.
+     * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+     *
+     * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
      * @see CaptureRequest#HOT_PIXEL_MODE
      */
     public static final int HOT_PIXEL_MODE_FAST = 1;
@@ -1215,7 +1221,10 @@
     /**
      * <p>The frame rate may be reduced relative to sensor raw output
      * for this option.</p>
-     * <p>A high-quality hot pixel correction is applied.</p>
+     * <p>A high-quality hot pixel correction is applied.
+     * The hotpixel map may be returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.</p>
+     *
+     * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
      * @see CaptureRequest#HOT_PIXEL_MODE
      */
     public static final int HOT_PIXEL_MODE_HIGH_QUALITY = 2;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index a8caba0..fbac529 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -876,9 +876,13 @@
 
     /**
      * <p>Set operational mode for hot pixel correction.</p>
+     * <p>Valid modes for this camera device are listed in
+     * {@link CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES android.hotPixel.availableHotPixelModes}.</p>
      * <p>Hotpixel correction interpolates out, or otherwise removes, pixels
      * that do not accurately encode the incoming light (i.e. pixels that
      * are stuck at an arbitrary value).</p>
+     *
+     * @see CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES
      * @see #HOT_PIXEL_MODE_OFF
      * @see #HOT_PIXEL_MODE_FAST
      * @see #HOT_PIXEL_MODE_HIGH_QUALITY
@@ -1286,6 +1290,18 @@
             new Key<Integer>("android.statistics.faceDetectMode", int.class);
 
     /**
+     * <p>Operating mode for hotpixel map generation.</p>
+     * <p>If set to ON, a hotpixel map is returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.
+     * If set to OFF, no hotpixel map should be returned.</p>
+     * <p>This must be set to a valid mode from {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES android.statistics.info.availableHotPixelMapModes}.</p>
+     *
+     * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
+     * @see CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES
+     */
+    public static final Key<Boolean> STATISTICS_HOT_PIXEL_MAP_MODE =
+            new Key<Boolean>("android.statistics.hotPixelMapMode", boolean.class);
+
+    /**
      * <p>Whether the camera device will output the lens
      * shading map in output result metadata.</p>
      * <p>When set to ON,
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 0f2c7f7..ab1525e 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -1166,24 +1166,14 @@
             new Key<Integer>("android.flash.state", int.class);
 
     /**
-     * <p>List of <code>(x, y)</code> coordinates of hot/defective pixels on the
-     * sensor, where <code>(x, y)</code> lies between <code>(0, 0)</code>, which is the top-left
-     * of the pixel array, and the width,height of the pixel array given in
-     * {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}.  This may include hot pixels
-     * that lie outside of the active array bounds given by
-     * {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
-     *
-     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
-     * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
-     */
-    public static final Key<int[]> HOT_PIXEL_MAP =
-            new Key<int[]>("android.hotPixel.map", int[].class);
-
-    /**
      * <p>Set operational mode for hot pixel correction.</p>
+     * <p>Valid modes for this camera device are listed in
+     * {@link CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES android.hotPixel.availableHotPixelModes}.</p>
      * <p>Hotpixel correction interpolates out, or otherwise removes, pixels
      * that do not accurately encode the incoming light (i.e. pixels that
      * are stuck at an arbitrary value).</p>
+     *
+     * @see CameraCharacteristics#HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES
      * @see #HOT_PIXEL_MODE_OFF
      * @see #HOT_PIXEL_MODE_FAST
      * @see #HOT_PIXEL_MODE_HIGH_QUALITY
@@ -1971,6 +1961,33 @@
             new Key<Integer>("android.statistics.sceneFlicker", int.class);
 
     /**
+     * <p>Operating mode for hotpixel map generation.</p>
+     * <p>If set to ON, a hotpixel map is returned in {@link CaptureResult#STATISTICS_HOT_PIXEL_MAP android.statistics.hotPixelMap}.
+     * If set to OFF, no hotpixel map should be returned.</p>
+     * <p>This must be set to a valid mode from {@link CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES android.statistics.info.availableHotPixelMapModes}.</p>
+     *
+     * @see CaptureResult#STATISTICS_HOT_PIXEL_MAP
+     * @see CameraCharacteristics#STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES
+     */
+    public static final Key<Boolean> STATISTICS_HOT_PIXEL_MAP_MODE =
+            new Key<Boolean>("android.statistics.hotPixelMapMode", boolean.class);
+
+    /**
+     * <p>List of <code>(x, y)</code> coordinates of hot/defective pixels on the sensor.</p>
+     * <p>A coordinate <code>(x, y)</code> must lie between <code>(0, 0)</code>, and
+     * <code>(width - 1, height - 1)</code> (inclusive), which are the top-left and
+     * bottom-right of the pixel array, respectively. The width and
+     * height dimensions are given in {@link CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE android.sensor.info.pixelArraySize}.
+     * This may include hot pixels that lie outside of the active array
+     * bounds given by {@link CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE android.sensor.info.activeArraySize}.</p>
+     *
+     * @see CameraCharacteristics#SENSOR_INFO_ACTIVE_ARRAY_SIZE
+     * @see CameraCharacteristics#SENSOR_INFO_PIXEL_ARRAY_SIZE
+     */
+    public static final Key<int[]> STATISTICS_HOT_PIXEL_MAP =
+            new Key<int[]>("android.statistics.hotPixelMap", int[].class);
+
+    /**
      * <p>Tonemapping / contrast / gamma curve for the blue
      * channel, to use when {@link CaptureRequest#TONEMAP_MODE android.tonemap.mode} is
      * CONTRAST_CURVE.</p>
diff --git a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
index 2ddcb14..0d4a4cb 100644
--- a/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
+++ b/core/java/android/hardware/camera2/impl/CameraMetadataNative.java
@@ -105,6 +105,18 @@
     }
 
     /**
+     * Set the global client-side vendor tag descriptor to allow use of vendor
+     * tags in camera applications.
+     *
+     * @return int A native status_t value corresponding to one of the
+     * {@link CameraBinderDecorator} integer constants.
+     * @see CameraBinderDecorator#throwOnError
+     *
+     * @hide
+     */
+    public static native int nativeSetupGlobalVendorTagDescriptor();
+
+    /**
      * Set a camera metadata field to a value. The field definitions can be
      * found in {@link CameraCharacteristics}, {@link CaptureResult}, and
      * {@link CaptureRequest}.
diff --git a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
index e535e00..328ccbe 100644
--- a/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
+++ b/core/java/android/hardware/camera2/utils/CameraBinderDecorator.java
@@ -64,47 +64,7 @@
             // int return type => status_t => convert to exception
             if (m.getReturnType() == Integer.TYPE) {
                 int returnValue = (Integer) result;
-
-                switch (returnValue) {
-                    case NO_ERROR:
-                        return;
-                    case PERMISSION_DENIED:
-                        throw new SecurityException("Lacking privileges to access camera service");
-                    case ALREADY_EXISTS:
-                        // This should be handled at the call site. Typically this isn't bad,
-                        // just means we tried to do an operation that already completed.
-                        return;
-                    case BAD_VALUE:
-                        throw new IllegalArgumentException("Bad argument passed to camera service");
-                    case DEAD_OBJECT:
-                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
-                                CAMERA_DISCONNECTED));
-                    case EACCES:
-                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
-                                CAMERA_DISABLED));
-                    case EBUSY:
-                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
-                                CAMERA_IN_USE));
-                    case EUSERS:
-                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
-                                MAX_CAMERAS_IN_USE));
-                    case ENODEV:
-                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
-                                CAMERA_DISCONNECTED));
-                    case EOPNOTSUPP:
-                        UncheckedThrow.throwAnyException(new CameraRuntimeException(
-                                CAMERA_DEPRECATED_HAL));
-                }
-
-                /**
-                 * Trap the rest of the negative return values. If we have known
-                 * error codes i.e. ALREADY_EXISTS that aren't really runtime
-                 * errors, then add them to the top switch statement
-                 */
-                if (returnValue < 0) {
-                    throw new UnsupportedOperationException(String.format("Unknown error %d",
-                            returnValue));
-                }
+                throwOnError(returnValue);
             }
         }
 
@@ -131,6 +91,54 @@
     }
 
     /**
+     * Throw error codes returned by the camera service as exceptions.
+     *
+     * @param errorFlag error to throw as an exception.
+     */
+    public static void throwOnError(int errorFlag) {
+        switch (errorFlag) {
+            case NO_ERROR:
+                return;
+            case PERMISSION_DENIED:
+                throw new SecurityException("Lacking privileges to access camera service");
+            case ALREADY_EXISTS:
+                // This should be handled at the call site. Typically this isn't bad,
+                // just means we tried to do an operation that already completed.
+                return;
+            case BAD_VALUE:
+                throw new IllegalArgumentException("Bad argument passed to camera service");
+            case DEAD_OBJECT:
+                UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                        CAMERA_DISCONNECTED));
+            case EACCES:
+                UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                        CAMERA_DISABLED));
+            case EBUSY:
+                UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                        CAMERA_IN_USE));
+            case EUSERS:
+                UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                        MAX_CAMERAS_IN_USE));
+            case ENODEV:
+                UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                        CAMERA_DISCONNECTED));
+            case EOPNOTSUPP:
+                UncheckedThrow.throwAnyException(new CameraRuntimeException(
+                        CAMERA_DEPRECATED_HAL));
+        }
+
+        /**
+         * Trap the rest of the negative return values. If we have known
+         * error codes i.e. ALREADY_EXISTS that aren't really runtime
+         * errors, then add them to the top switch statement
+         */
+        if (errorFlag < 0) {
+            throw new UnsupportedOperationException(String.format("Unknown error %d",
+                    errorFlag));
+        }
+    }
+
+    /**
      * <p>
      * Wraps the type T with a proxy that will check 'status_t' return codes
      * from the native side of the camera service, and throw Java exceptions
diff --git a/core/java/android/net/EthernetDataTracker.java b/core/java/android/net/EthernetDataTracker.java
index 95faa77..6c61046 100644
--- a/core/java/android/net/EthernetDataTracker.java
+++ b/core/java/android/net/EthernetDataTracker.java
@@ -106,6 +106,24 @@
         mLinkCapabilities = new LinkCapabilities();
     }
 
+    private void interfaceUpdated() {
+        // we don't get link status indications unless the iface is up - bring it up
+        try {
+            mNMService.setInterfaceUp(mIface);
+            String hwAddr = null;
+            InterfaceConfiguration config = mNMService.getInterfaceConfig(mIface);
+            if (config != null) {
+                hwAddr = config.getHardwareAddress();
+            }
+            synchronized (this) {
+                mHwAddr = hwAddr;
+                mNetworkInfo.setExtraInfo(mHwAddr);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error upping interface " + mIface + ": " + e);
+        }
+    }
+
     private void interfaceAdded(String iface) {
         if (!iface.matches(sIfaceMatch))
             return;
@@ -118,12 +136,7 @@
             mIface = iface;
         }
 
-        // we don't get link status indications unless the iface is up - bring it up
-        try {
-            mNMService.setInterfaceUp(iface);
-        } catch (Exception e) {
-            Log.e(TAG, "Error upping interface " + iface + ": " + e);
-        }
+        interfaceUpdated();
 
         mNetworkInfo.setIsAvailable(true);
         Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);
@@ -159,7 +172,11 @@
 
         Log.d(TAG, "Removing " + iface);
         disconnect();
-        mIface = "";
+        synchronized (this) {
+            mIface = "";
+            mHwAddr = null;
+            mNetworkInfo.setExtraInfo(null);
+        }
     }
 
     private void runDhcp() {
@@ -220,15 +237,7 @@
             for (String iface : ifaces) {
                 if (iface.matches(sIfaceMatch)) {
                     mIface = iface;
-                    mNMService.setInterfaceUp(iface);
-                    InterfaceConfiguration config = mNMService.getInterfaceConfig(iface);
-                    mLinkUp = config.hasFlag("up");
-                    if (config != null && mHwAddr == null) {
-                        mHwAddr = config.getHardwareAddress();
-                        if (mHwAddr != null) {
-                            mNetworkInfo.setExtraInfo(mHwAddr);
-                        }
-                    }
+                    interfaceUpdated();
 
                     // if a DHCP client had previously been started for this interface, then stop it
                     NetworkUtils.stopDhcp(mIface);
@@ -418,4 +427,9 @@
     public void supplyMessenger(Messenger messenger) {
         // not supported on this network
     }
+
+    @Override
+    public String getNetworkInterfaceName() {
+        return mIface;
+    }
 }
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 22e1476..c8051aa 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -467,6 +467,19 @@
          * </ul>
          */
         public static final int KITKAT = 19;
+
+        /**
+         * L!
+         *
+         * <p>Applications targeting this or a later release will get these
+         * new changes in behavior:</p>
+         * <ul>
+         * <li> {@link android.content.Context#bindService Context.bindService} now
+         * requires an explicit Intent, and will throw an exception if given an explicit
+         * Intent.</li>
+         * </ul>
+         */
+        public static final int L = CUR_DEVELOPMENT;
     }
     
     /** The type of build, like "user" or "eng". */
diff --git a/core/java/android/print/PrinterCapabilitiesInfo.java b/core/java/android/print/PrinterCapabilitiesInfo.java
index b615600..806a89d8 100644
--- a/core/java/android/print/PrinterCapabilitiesInfo.java
+++ b/core/java/android/print/PrinterCapabilitiesInfo.java
@@ -475,6 +475,12 @@
          * @param colorModes The color mode bit mask.
          * @param defaultColorMode The default color mode.
          * @return This builder.
+         * <p>
+         * <strong>Note:</strong> On platform version 19 (Kitkat) specifying
+         * only PrintAttributes#COLOR_MODE_MONOCHROME leads to a print spooler
+         * crash. Hence, you should declare either both color modes or
+         * PrintAttributes#COLOR_MODE_COLOR.
+         * </p>
          *
          * @throws IllegalArgumentException If color modes contains an invalid
          *         mode bit or if the default color mode is invalid.
diff --git a/core/java/android/speech/SpeechRecognizer.java b/core/java/android/speech/SpeechRecognizer.java
index 94aedbd..91c3799 100644
--- a/core/java/android/speech/SpeechRecognizer.java
+++ b/core/java/android/speech/SpeechRecognizer.java
@@ -409,7 +409,7 @@
      * Internal wrapper of IRecognitionListener which will propagate the results to
      * RecognitionListener
      */
-    private class InternalListener extends IRecognitionListener.Stub {
+    private static class InternalListener extends IRecognitionListener.Stub {
         private RecognitionListener mInternalListener;
 
         private final static int MSG_BEGINNING_OF_SPEECH = 1;
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index be6f401..ed52803 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 The Android Open Source Project
+ * 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.
@@ -16,916 +16,10 @@
 
 package android.view;
 
-import android.graphics.Matrix;
-import android.graphics.Path;
-
-/**
- * <p>A display list records a series of graphics related operations and can replay
- * them later. Display lists are usually built by recording operations on a
- * {@link HardwareCanvas}. Replaying the operations from a display list avoids
- * executing application code on every frame, and is thus much more efficient.</p>
- *
- * <p>Display lists are used internally for all views by default, and are not
- * typically used directly. One reason to consider using a display is a custom
- * {@link View} implementation that needs to issue a large number of drawing commands.
- * When the view invalidates, all the drawing commands must be reissued, even if
- * large portions of the drawing command stream stay the same frame to frame, which
- * can become a performance bottleneck. To solve this issue, a custom View might split
- * its content into several display lists. A display list is updated only when its
- * content, and only its content, needs to be updated.</p>
- *
- * <p>A text editor might for instance store each paragraph into its own display list.
- * Thus when the user inserts or removes characters, only the display list of the
- * affected paragraph needs to be recorded again.</p>
- *
- * <h3>Hardware acceleration</h3>
- * <p>Display lists can only be replayed using a {@link HardwareCanvas}. They are not
- * supported in software. Always make sure that the {@link android.graphics.Canvas}
- * you are using to render a display list is hardware accelerated using
- * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p>
- *
- * <h3>Creating a display list</h3>
- * <pre class="prettyprint">
- *     HardwareRenderer renderer = myView.getHardwareRenderer();
- *     if (renderer != null) {
- *         DisplayList displayList = renderer.createDisplayList();
- *         HardwareCanvas canvas = displayList.start(width, height);
- *         try {
- *             // Draw onto the canvas
- *             // For instance: canvas.drawBitmap(...);
- *         } finally {
- *             displayList.end();
- *         }
- *     }
- * </pre>
- *
- * <h3>Rendering a display list on a View</h3>
- * <pre class="prettyprint">
- *     protected void onDraw(Canvas canvas) {
- *         if (canvas.isHardwareAccelerated()) {
- *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
- *             hardwareCanvas.drawDisplayList(mDisplayList);
- *         }
- *     }
- * </pre>
- *
- * <h3>Releasing resources</h3>
- * <p>This step is not mandatory but recommended if you want to release resources
- * held by a display list as soon as possible.</p>
- * <pre class="prettyprint">
- *     // Mark this display list invalid, it cannot be used for drawing anymore,
- *     // and release resources held by this display list
- *     displayList.clear();
- * </pre>
- *
- * <h3>Properties</h3>
- * <p>In addition, a display list offers several properties, such as
- * {@link #setScaleX(float)} or {@link #setLeft(int)}, that can be used to affect all
- * the drawing commands recorded within. For instance, these properties can be used
- * to move around a large number of images without re-issuing all the individual
- * <code>drawBitmap()</code> calls.</p>
- *
- * <pre class="prettyprint">
- *     private void createDisplayList() {
- *         mDisplayList = DisplayList.create("MyDisplayList");
- *         HardwareCanvas canvas = mDisplayList.start(width, height);
- *         try {
- *             for (Bitmap b : mBitmaps) {
- *                 canvas.drawBitmap(b, 0.0f, 0.0f, null);
- *                 canvas.translate(0.0f, b.getHeight());
- *             }
- *         } finally {
- *             displayList.end();
- *         }
- *     }
- *
- *     protected void onDraw(Canvas canvas) {
- *         if (canvas.isHardwareAccelerated()) {
- *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
- *             hardwareCanvas.drawDisplayList(mDisplayList);
- *         }
- *     }
- *
- *     private void moveContentBy(int x) {
- *          // This will move all the bitmaps recorded inside the display list
- *          // by x pixels to the right and redraw this view. All the commands
- *          // recorded in createDisplayList() won't be re-issued, only onDraw()
- *          // will be invoked and will execute very quickly
- *          mDisplayList.offsetLeftAndRight(x);
- *          invalidate();
- *     }
- * </pre>
- *
- * <h3>Threading</h3>
- * <p>Display lists must be created on and manipulated from the UI thread only.</p>
- *
- * @hide
+/** TODO: Remove once frameworks/webview is updated
+ *  @hide
  */
 public class DisplayList {
-    /**
-     * Flag used when calling
-     * {@link HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)}
-     * When this flag is set, draw operations lying outside of the bounds of the
-     * display list will be culled early. It is recommeneded to always set this
-     * flag.
-     *
-     * @hide
-     */
-    public static final int FLAG_CLIP_CHILDREN = 0x1;
-
-    // NOTE: The STATUS_* values *must* match the enum in DrawGlInfo.h
-
-    /**
-     * Indicates that the display list is done drawing.
-     *
-     * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
-     *
-     * @hide
-     */
+    /** @hide */
     public static final int STATUS_DONE = 0x0;
-
-    /**
-     * Indicates that the display list needs another drawing pass.
-     *
-     * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
-     *
-     * @hide
-     */
-    public static final int STATUS_DRAW = 0x1;
-
-    /**
-     * Indicates that the display list needs to re-execute its GL functors.
-     *
-     * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
-     * @see HardwareCanvas#callDrawGLFunction(long)
-     *
-     * @hide
-     */
-    public static final int STATUS_INVOKE = 0x2;
-
-    /**
-     * Indicates that the display list performed GL drawing operations.
-     *
-     * @see HardwareCanvas#drawDisplayList(DisplayList, android.graphics.Rect, int)
-     *
-     * @hide
-     */
-    public static final int STATUS_DREW = 0x4;
-
-    private boolean mValid;
-    private final long mNativeDisplayList;
-    private HardwareRenderer mRenderer;
-
-    private DisplayList(String name) {
-        mNativeDisplayList = nCreate();
-        nSetDisplayListName(mNativeDisplayList, name);
-    }
-
-    /**
-     * Creates a new display list that can be used to record batches of
-     * drawing operations.
-     *
-     * @param name The name of the display list, used for debugging purpose. May be null.
-     *
-     * @return A new display list.
-     *
-     * @hide
-     */
-    public static DisplayList create(String name) {
-        return new DisplayList(name);
-    }
-
-    /**
-     * Starts recording the display list. All operations performed on the
-     * returned canvas are recorded and stored in this display list.
-     *
-     * Calling this method will mark the display list invalid until
-     * {@link #end()} is called. Only valid display lists can be replayed.
-     *
-     * @param width The width of the display list's viewport
-     * @param height The height of the display list's viewport
-     *
-     * @return A canvas to record drawing operations.
-     *
-     * @see #end()
-     * @see #isValid()
-     */
-    public HardwareCanvas start(int width, int height) {
-        HardwareCanvas canvas = GLES20RecordingCanvas.obtain();
-        canvas.setViewport(width, height);
-        // The dirty rect should always be null for a display list
-        canvas.onPreDraw(null);
-        return canvas;
-    }
-
-    /**
-     * Ends the recording for this display list. A display list cannot be
-     * replayed if recording is not finished. Calling this method marks
-     * the display list valid and {@link #isValid()} will return true.
-     *
-     * @see #start(int, int)
-     * @see #isValid()
-     */
-    public void end(HardwareRenderer renderer, HardwareCanvas endCanvas) {
-        if (!(endCanvas instanceof GLES20RecordingCanvas)) {
-            throw new IllegalArgumentException("Passed an invalid canvas to end!");
-        }
-
-        GLES20RecordingCanvas canvas = (GLES20RecordingCanvas) endCanvas;
-        canvas.onPostDraw();
-        long displayListData = canvas.finishRecording();
-        if (renderer != mRenderer) {
-            // If we are changing renderers first destroy with the old
-            // renderer, then set with the new one
-            destroyDisplayListData();
-        }
-        mRenderer = renderer;
-        setDisplayListData(displayListData);
-        canvas.recycle();
-        mValid = true;
-    }
-
-    /**
-     * Reset native resources. This is called when cleaning up the state of display lists
-     * during destruction of hardware resources, to ensure that we do not hold onto
-     * obsolete resources after related resources are gone.
-     *
-     * @hide
-     */
-    public void destroyDisplayListData() {
-        if (!mValid) return;
-
-        setDisplayListData(0);
-        mRenderer = null;
-        mValid = false;
-    }
-
-    private void setDisplayListData(long newData) {
-        if (mRenderer != null) {
-            mRenderer.setDisplayListData(mNativeDisplayList, newData);
-        } else {
-            throw new IllegalStateException("Trying to set data without a renderer! data=" + newData);
-        }
-    }
-
-    /**
-     * Returns whether the display list is currently usable. If this returns false,
-     * the display list should be re-recorded prior to replaying it.
-     *
-     * @return boolean true if the display list is able to be replayed, false otherwise.
-     */
-    public boolean isValid() { return mValid; }
-
-    long getNativeDisplayList() {
-        if (!mValid) {
-            throw new IllegalStateException("The display list is not valid.");
-        }
-        return mNativeDisplayList;
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // DisplayList Property Setters
-    ///////////////////////////////////////////////////////////////////////////
-
-    /**
-     * Set the caching property on the display list, which indicates whether the display list
-     * holds a layer. Layer display lists should avoid creating an alpha layer, since alpha is
-     * handled in the drawLayer operation directly (and more efficiently).
-     *
-     * @param caching true if the display list represents a hardware layer, false otherwise.
-     *
-     * @hide
-     */
-    public void setCaching(boolean caching) {
-        nSetCaching(mNativeDisplayList, caching);
-    }
-
-    /**
-     * Set whether the display list should clip itself to its bounds. This property is controlled by
-     * the view's parent.
-     *
-     * @param clipToBounds true if the display list should clip to its bounds
-     */
-    public void setClipToBounds(boolean clipToBounds) {
-        nSetClipToBounds(mNativeDisplayList, clipToBounds);
-    }
-
-    /**
-     * Set whether the display list should collect and Z order all 3d composited descendents, and
-     * draw them in order with the default Z=0 content.
-     *
-     * @param isolatedZVolume true if the display list should collect and Z order descendents.
-     */
-    public void setIsolatedZVolume(boolean isolatedZVolume) {
-        nSetIsolatedZVolume(mNativeDisplayList, isolatedZVolume);
-    }
-
-    /**
-     * Sets whether the display list should be drawn immediately after the
-     * closest ancestor display list where isolateZVolume is true. If the
-     * display list itself satisfies this constraint, changing this attribute
-     * has no effect on drawing order.
-     *
-     * @param shouldProject true if the display list should be projected onto a
-     *            containing volume.
-     */
-    public void setProjectBackwards(boolean shouldProject) {
-        nSetProjectBackwards(mNativeDisplayList, shouldProject);
-    }
-
-    /**
-     * Sets whether the display list is a projection receiver - that its parent
-     * DisplayList should draw any descendent DisplayLists with
-     * ProjectBackwards=true directly on top of it. Default value is false.
-     */
-    public void setProjectionReceiver(boolean shouldRecieve) {
-        nSetProjectionReceiver(mNativeDisplayList, shouldRecieve);
-    }
-
-    /**
-     * Sets the outline, defining the shape that casts a shadow, and the path to
-     * be clipped if setClipToOutline is set.
-     *
-     * Deep copies the native path to simplify reference ownership.
-     *
-     * @param outline Convex, CW Path to store in the DisplayList. May be null.
-     */
-    public void setOutline(Path outline) {
-        long nativePath = (outline == null) ? 0 : outline.mNativePath;
-        nSetOutline(mNativeDisplayList, nativePath);
-    }
-
-    /**
-     * Enables or disables clipping to the outline.
-     *
-     * @param clipToOutline true if clipping to the outline.
-     */
-    public void setClipToOutline(boolean clipToOutline) {
-        nSetClipToOutline(mNativeDisplayList, clipToOutline);
-    }
-
-    /**
-     * Set whether the DisplayList should cast a shadow.
-     *
-     * The shape of the shadow casting area is defined by the outline of the display list, if set
-     * and non-empty, otherwise it will be the bounds rect.
-     */
-    public void setCastsShadow(boolean castsShadow) {
-        nSetCastsShadow(mNativeDisplayList, castsShadow);
-    }
-
-    /**
-     * Sets whether the DisplayList should be drawn with perspective applied from the global camera.
-     *
-     * If set to true, camera distance will be ignored. Defaults to false.
-     */
-    public void setUsesGlobalCamera(boolean usesGlobalCamera) {
-        nSetUsesGlobalCamera(mNativeDisplayList, usesGlobalCamera);
-    }
-
-    /**
-     * Set the static matrix on the display list. The specified matrix is combined with other
-     * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
-     *
-     * @param matrix A transform matrix to apply to this display list
-     *
-     * @see #getMatrix(android.graphics.Matrix)
-     * @see #getMatrix()
-     */
-    public void setStaticMatrix(Matrix matrix) {
-        nSetStaticMatrix(mNativeDisplayList, matrix.native_instance);
-    }
-
-    /**
-     * Set the Animation matrix on the display list. This matrix exists if an Animation is
-     * currently playing on a View, and is set on the display list during at draw() time. When
-     * the Animation finishes, the matrix should be cleared by sending <code>null</code>
-     * for the matrix parameter.
-     *
-     * @param matrix The matrix, null indicates that the matrix should be cleared.
-     *
-     * @hide
-     */
-    public void setAnimationMatrix(Matrix matrix) {
-        nSetAnimationMatrix(mNativeDisplayList,
-                (matrix != null) ? matrix.native_instance : 0);
-    }
-
-    /**
-     * Sets the translucency level for the display list.
-     *
-     * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
-     *
-     * @see View#setAlpha(float)
-     * @see #getAlpha()
-     */
-    public void setAlpha(float alpha) {
-        nSetAlpha(mNativeDisplayList, alpha);
-    }
-
-    /**
-     * Returns the translucency level of this display list.
-     *
-     * @return A value between 0.0f and 1.0f
-     *
-     * @see #setAlpha(float)
-     */
-    public float getAlpha() {
-        return nGetAlpha(mNativeDisplayList);
-    }
-
-    /**
-     * Sets whether the display list renders content which overlaps. Non-overlapping rendering
-     * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default
-     * display lists consider they do not have overlapping content.
-     *
-     * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
-     *                                true otherwise.
-     *
-     * @see android.view.View#hasOverlappingRendering()
-     * @see #hasOverlappingRendering()
-     */
-    public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
-        nSetHasOverlappingRendering(mNativeDisplayList, hasOverlappingRendering);
-    }
-
-    /**
-     * Indicates whether the content of this display list overlaps.
-     *
-     * @return True if this display list renders content which overlaps, false otherwise.
-     *
-     * @see #setHasOverlappingRendering(boolean)
-     */
-    public boolean hasOverlappingRendering() {
-        //noinspection SimplifiableIfStatement
-        return nHasOverlappingRendering(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the translation value for the display list on the X axis.
-     *
-     * @param translationX The X axis translation value of the display list, in pixels
-     *
-     * @see View#setTranslationX(float)
-     * @see #getTranslationX()
-     */
-    public void setTranslationX(float translationX) {
-        nSetTranslationX(mNativeDisplayList, translationX);
-    }
-
-    /**
-     * Returns the translation value for this display list on the X axis, in pixels.
-     *
-     * @see #setTranslationX(float)
-     */
-    public float getTranslationX() {
-        return nGetTranslationX(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the translation value for the display list on the Y axis.
-     *
-     * @param translationY The Y axis translation value of the display list, in pixels
-     *
-     * @see View#setTranslationY(float)
-     * @see #getTranslationY()
-     */
-    public void setTranslationY(float translationY) {
-        nSetTranslationY(mNativeDisplayList, translationY);
-    }
-
-    /**
-     * Returns the translation value for this display list on the Y axis, in pixels.
-     *
-     * @see #setTranslationY(float)
-     */
-    public float getTranslationY() {
-        return nGetTranslationY(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the translation value for the display list on the Z axis.
-     *
-     * @see View#setTranslationZ(float)
-     * @see #getTranslationZ()
-     */
-    public void setTranslationZ(float translationZ) {
-        nSetTranslationZ(mNativeDisplayList, translationZ);
-    }
-
-    /**
-     * Returns the translation value for this display list on the Z axis.
-     *
-     * @see #setTranslationZ(float)
-     */
-    public float getTranslationZ() {
-        return nGetTranslationZ(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the rotation value for the display list around the Z axis.
-     *
-     * @param rotation The rotation value of the display list, in degrees
-     *
-     * @see View#setRotation(float)
-     * @see #getRotation()
-     */
-    public void setRotation(float rotation) {
-        nSetRotation(mNativeDisplayList, rotation);
-    }
-
-    /**
-     * Returns the rotation value for this display list around the Z axis, in degrees.
-     *
-     * @see #setRotation(float)
-     */
-    public float getRotation() {
-        return nGetRotation(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the rotation value for the display list around the X axis.
-     *
-     * @param rotationX The rotation value of the display list, in degrees
-     *
-     * @see View#setRotationX(float)
-     * @see #getRotationX()
-     */
-    public void setRotationX(float rotationX) {
-        nSetRotationX(mNativeDisplayList, rotationX);
-    }
-
-    /**
-     * Returns the rotation value for this display list around the X axis, in degrees.
-     *
-     * @see #setRotationX(float)
-     */
-    public float getRotationX() {
-        return nGetRotationX(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the rotation value for the display list around the Y axis.
-     *
-     * @param rotationY The rotation value of the display list, in degrees
-     *
-     * @see View#setRotationY(float)
-     * @see #getRotationY()
-     */
-    public void setRotationY(float rotationY) {
-        nSetRotationY(mNativeDisplayList, rotationY);
-    }
-
-    /**
-     * Returns the rotation value for this display list around the Y axis, in degrees.
-     *
-     * @see #setRotationY(float)
-     */
-    public float getRotationY() {
-        return nGetRotationY(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the scale value for the display list on the X axis.
-     *
-     * @param scaleX The scale value of the display list
-     *
-     * @see View#setScaleX(float)
-     * @see #getScaleX()
-     */
-    public void setScaleX(float scaleX) {
-        nSetScaleX(mNativeDisplayList, scaleX);
-    }
-
-    /**
-     * Returns the scale value for this display list on the X axis.
-     *
-     * @see #setScaleX(float)
-     */
-    public float getScaleX() {
-        return nGetScaleX(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the scale value for the display list on the Y axis.
-     *
-     * @param scaleY The scale value of the display list
-     *
-     * @see View#setScaleY(float)
-     * @see #getScaleY()
-     */
-    public void setScaleY(float scaleY) {
-        nSetScaleY(mNativeDisplayList, scaleY);
-    }
-
-    /**
-     * Returns the scale value for this display list on the Y axis.
-     *
-     * @see #setScaleY(float)
-     */
-    public float getScaleY() {
-        return nGetScaleY(mNativeDisplayList);
-    }
-
-    /**
-     * Sets all of the transform-related values of the display list
-     *
-     * @param alpha The alpha value of the display list
-     * @param translationX The translationX value of the display list
-     * @param translationY The translationY value of the display list
-     * @param rotation The rotation value of the display list
-     * @param rotationX The rotationX value of the display list
-     * @param rotationY The rotationY value of the display list
-     * @param scaleX The scaleX value of the display list
-     * @param scaleY The scaleY value of the display list
-     *
-     * @hide
-     */
-    public void setTransformationInfo(float alpha,
-            float translationX, float translationY, float translationZ,
-            float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
-        nSetTransformationInfo(mNativeDisplayList, alpha,
-                translationX, translationY, translationZ,
-                rotation, rotationX, rotationY, scaleX, scaleY);
-    }
-
-    /**
-     * Sets the pivot value for the display list on the X axis
-     *
-     * @param pivotX The pivot value of the display list on the X axis, in pixels
-     *
-     * @see View#setPivotX(float)
-     * @see #getPivotX()
-     */
-    public void setPivotX(float pivotX) {
-        nSetPivotX(mNativeDisplayList, pivotX);
-    }
-
-    /**
-     * Returns the pivot value for this display list on the X axis, in pixels.
-     *
-     * @see #setPivotX(float)
-     */
-    public float getPivotX() {
-        return nGetPivotX(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the pivot value for the display list on the Y axis
-     *
-     * @param pivotY The pivot value of the display list on the Y axis, in pixels
-     *
-     * @see View#setPivotY(float)
-     * @see #getPivotY()
-     */
-    public void setPivotY(float pivotY) {
-        nSetPivotY(mNativeDisplayList, pivotY);
-    }
-
-    /**
-     * Returns the pivot value for this display list on the Y axis, in pixels.
-     *
-     * @see #setPivotY(float)
-     */
-    public float getPivotY() {
-        return nGetPivotY(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the camera distance for the display list. Refer to
-     * {@link View#setCameraDistance(float)} for more information on how to
-     * use this property.
-     *
-     * @param distance The distance in Z of the camera of the display list
-     *
-     * @see View#setCameraDistance(float)
-     * @see #getCameraDistance()
-     */
-    public void setCameraDistance(float distance) {
-        nSetCameraDistance(mNativeDisplayList, distance);
-    }
-
-    /**
-     * Returns the distance in Z of the camera of the display list.
-     *
-     * @see #setCameraDistance(float)
-     */
-    public float getCameraDistance() {
-        return nGetCameraDistance(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the left position for the display list.
-     *
-     * @param left The left position, in pixels, of the display list
-     *
-     * @see View#setLeft(int)
-     * @see #getLeft()
-     */
-    public void setLeft(int left) {
-        nSetLeft(mNativeDisplayList, left);
-    }
-
-    /**
-     * Returns the left position for the display list in pixels.
-     *
-     * @see #setLeft(int)
-     */
-    public float getLeft() {
-        return nGetLeft(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the top position for the display list.
-     *
-     * @param top The top position, in pixels, of the display list
-     *
-     * @see View#setTop(int)
-     * @see #getTop()
-     */
-    public void setTop(int top) {
-        nSetTop(mNativeDisplayList, top);
-    }
-
-    /**
-     * Returns the top position for the display list in pixels.
-     *
-     * @see #setTop(int)
-     */
-    public float getTop() {
-        return nGetTop(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the right position for the display list.
-     *
-     * @param right The right position, in pixels, of the display list
-     *
-     * @see View#setRight(int)
-     * @see #getRight()
-     */
-    public void setRight(int right) {
-        nSetRight(mNativeDisplayList, right);
-    }
-
-    /**
-     * Returns the right position for the display list in pixels.
-     *
-     * @see #setRight(int)
-     */
-    public float getRight() {
-        return nGetRight(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the bottom position for the display list.
-     *
-     * @param bottom The bottom position, in pixels, of the display list
-     *
-     * @see View#setBottom(int)
-     * @see #getBottom()
-     */
-    public void setBottom(int bottom) {
-        nSetBottom(mNativeDisplayList, bottom);
-    }
-
-    /**
-     * Returns the bottom position for the display list in pixels.
-     *
-     * @see #setBottom(int)
-     */
-    public float getBottom() {
-        return nGetBottom(mNativeDisplayList);
-    }
-
-    /**
-     * Sets the left and top positions for the display list
-     *
-     * @param left The left position of the display list, in pixels
-     * @param top The top position of the display list, in pixels
-     * @param right The right position of the display list, in pixels
-     * @param bottom The bottom position of the display list, in pixels
-     *
-     * @see View#setLeft(int)
-     * @see View#setTop(int)
-     * @see View#setRight(int)
-     * @see View#setBottom(int)
-     */
-    public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
-        nSetLeftTopRightBottom(mNativeDisplayList, left, top, right, bottom);
-    }
-
-    /**
-     * Offsets the left and right positions for the display list
-     *
-     * @param offset The amount that the left and right positions of the display
-     *               list are offset, in pixels
-     *
-     * @see View#offsetLeftAndRight(int)
-     */
-    public void offsetLeftAndRight(float offset) {
-        nOffsetLeftAndRight(mNativeDisplayList, offset);
-    }
-
-    /**
-     * Offsets the top and bottom values for the display list
-     *
-     * @param offset The amount that the top and bottom positions of the display
-     *               list are offset, in pixels
-     *
-     * @see View#offsetTopAndBottom(int)
-     */
-    public void offsetTopAndBottom(float offset) {
-        nOffsetTopAndBottom(mNativeDisplayList, offset);
-    }
-
-    /**
-     * Outputs the display list to the log. This method exists for use by
-     * tools to output display lists for selected nodes to the log.
-     *
-     * @hide
-     */
-    public void output() {
-        nOutput(mNativeDisplayList);
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Native methods
-    ///////////////////////////////////////////////////////////////////////////
-
-    private static native long nCreate();
-    private static native void nDestroyDisplayList(long displayList);
-    private static native void nSetDisplayListName(long displayList, String name);
-
-    // Properties
-
-    private static native void nOffsetTopAndBottom(long displayList, float offset);
-    private static native void nOffsetLeftAndRight(long displayList, float offset);
-    private static native void nSetLeftTopRightBottom(long displayList, int left, int top,
-            int right, int bottom);
-    private static native void nSetBottom(long displayList, int bottom);
-    private static native void nSetRight(long displayList, int right);
-    private static native void nSetTop(long displayList, int top);
-    private static native void nSetLeft(long displayList, int left);
-    private static native void nSetCameraDistance(long displayList, float distance);
-    private static native void nSetPivotY(long displayList, float pivotY);
-    private static native void nSetPivotX(long displayList, float pivotX);
-    private static native void nSetCaching(long displayList, boolean caching);
-    private static native void nSetClipToBounds(long displayList, boolean clipToBounds);
-    private static native void nSetProjectBackwards(long displayList, boolean shouldProject);
-    private static native void nSetProjectionReceiver(long displayList, boolean shouldRecieve);
-    private static native void nSetIsolatedZVolume(long displayList, boolean isolateZVolume);
-    private static native void nSetOutline(long displayList, long nativePath);
-    private static native void nSetClipToOutline(long displayList, boolean clipToOutline);
-    private static native void nSetCastsShadow(long displayList, boolean castsShadow);
-    private static native void nSetUsesGlobalCamera(long displayList, boolean usesGlobalCamera);
-    private static native void nSetAlpha(long displayList, float alpha);
-    private static native void nSetHasOverlappingRendering(long displayList,
-            boolean hasOverlappingRendering);
-    private static native void nSetTranslationX(long displayList, float translationX);
-    private static native void nSetTranslationY(long displayList, float translationY);
-    private static native void nSetTranslationZ(long displayList, float translationZ);
-    private static native void nSetRotation(long displayList, float rotation);
-    private static native void nSetRotationX(long displayList, float rotationX);
-    private static native void nSetRotationY(long displayList, float rotationY);
-    private static native void nSetScaleX(long displayList, float scaleX);
-    private static native void nSetScaleY(long displayList, float scaleY);
-    private static native void nSetTransformationInfo(long displayList, float alpha,
-            float translationX, float translationY, float translationZ,
-            float rotation, float rotationX, float rotationY, float scaleX, float scaleY);
-    private static native void nSetStaticMatrix(long displayList, long nativeMatrix);
-    private static native void nSetAnimationMatrix(long displayList, long animationMatrix);
-
-    private static native boolean nHasOverlappingRendering(long displayList);
-    private static native float nGetAlpha(long displayList);
-    private static native float nGetLeft(long displayList);
-    private static native float nGetTop(long displayList);
-    private static native float nGetRight(long displayList);
-    private static native float nGetBottom(long displayList);
-    private static native float nGetCameraDistance(long displayList);
-    private static native float nGetScaleX(long displayList);
-    private static native float nGetScaleY(long displayList);
-    private static native float nGetTranslationX(long displayList);
-    private static native float nGetTranslationY(long displayList);
-    private static native float nGetTranslationZ(long displayList);
-    private static native float nGetRotation(long displayList);
-    private static native float nGetRotationX(long displayList);
-    private static native float nGetRotationY(long displayList);
-    private static native float nGetPivotX(long displayList);
-    private static native float nGetPivotY(long displayList);
-    private static native void nOutput(long displayList);
-
-    ///////////////////////////////////////////////////////////////////////////
-    // Finalization
-    ///////////////////////////////////////////////////////////////////////////
-
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            destroyDisplayListData();
-            nDestroyDisplayList(mNativeDisplayList);
-        } finally {
-            super.finalize();
-        }
-    }
 }
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 6c6fc9b..c274fc4 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -359,7 +359,7 @@
     protected static native long nFinishRecording(long renderer);
 
     @Override
-    public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) {
+    public int drawDisplayList(RenderNode displayList, Rect dirty, int flags) {
         return nDrawDisplayList(mRenderer, displayList.getNativeDisplayList(),
                 dirty, flags);
     }
diff --git a/core/java/android/view/GLRenderer.java b/core/java/android/view/GLRenderer.java
index 81f778d..4d42c5d 100644
--- a/core/java/android/view/GLRenderer.java
+++ b/core/java/android/view/GLRenderer.java
@@ -1125,7 +1125,7 @@
 
                 dirty = beginFrame(canvas, dirty, surfaceState);
 
-                DisplayList displayList = buildDisplayList(view, canvas);
+                RenderNode displayList = buildDisplayList(view, canvas);
 
                 flushLayerChanges();
 
@@ -1137,7 +1137,7 @@
                 }
 
                 int saveCount = 0;
-                int status = DisplayList.STATUS_DONE;
+                int status = RenderNode.STATUS_DONE;
 
                 long start = getSystemTime();
                 try {
@@ -1201,7 +1201,7 @@
     }
     private static native void nSetDisplayListData(long displayList, long newData);
 
-    private DisplayList buildDisplayList(View view, HardwareCanvas canvas) {
+    private RenderNode buildDisplayList(View view, HardwareCanvas canvas) {
         if (mDrawDelta <= 0) {
             return view.mDisplayList;
         }
@@ -1214,7 +1214,7 @@
         canvas.clearLayerUpdates();
 
         Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
-        DisplayList displayList = view.getDisplayList();
+        RenderNode displayList = view.getDisplayList();
         Trace.traceEnd(Trace.TRACE_TAG_VIEW);
 
         endBuildDisplayListProfiling(buildDisplayListStartTime);
@@ -1279,7 +1279,7 @@
     }
 
     private int drawDisplayList(View.AttachInfo attachInfo, HardwareCanvas canvas,
-            DisplayList displayList, int status) {
+            RenderNode displayList, int status) {
 
         long drawDisplayListStartTime = 0;
         if (mProfileEnabled) {
@@ -1289,7 +1289,7 @@
         Trace.traceBegin(Trace.TRACE_TAG_VIEW, "drawDisplayList");
         try {
             status |= canvas.drawDisplayList(displayList, mRedrawClip,
-                    DisplayList.FLAG_CLIP_CHILDREN);
+                    RenderNode.FLAG_CLIP_CHILDREN);
         } finally {
             Trace.traceEnd(Trace.TRACE_TAG_VIEW);
         }
@@ -1305,7 +1305,7 @@
     }
 
     private void swapBuffers(int status) {
-        if ((status & DisplayList.STATUS_DREW) == DisplayList.STATUS_DREW) {
+        if ((status & RenderNode.STATUS_DREW) == RenderNode.STATUS_DREW) {
             long eglSwapBuffersStartTime = 0;
             if (mProfileEnabled) {
                 eglSwapBuffersStartTime = System.nanoTime();
@@ -1339,7 +1339,7 @@
     private void handleFunctorStatus(View.AttachInfo attachInfo, int status) {
         // If the draw flag is set, functors will be invoked while executing
         // the tree of display lists
-        if ((status & DisplayList.STATUS_DRAW) != 0) {
+        if ((status & RenderNode.STATUS_DRAW) != 0) {
             if (mRedrawClip.isEmpty()) {
                 attachInfo.mViewRootImpl.invalidate();
             } else {
@@ -1348,7 +1348,7 @@
             }
         }
 
-        if ((status & DisplayList.STATUS_INVOKE) != 0 ||
+        if ((status & RenderNode.STATUS_INVOKE) != 0 ||
                 attachInfo.mHandler.hasCallbacks(mFunctorsRunnable)) {
             attachInfo.mHandler.removeCallbacks(mFunctorsRunnable);
             mFunctorsRunnable.attachInfo = attachInfo;
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index a3c7b63..f695b20 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -42,7 +42,7 @@
      * Invoked before any drawing operation is performed in this canvas.
      * 
      * @param dirty The dirty rectangle to update, can be null.
-     * @return {@link DisplayList#STATUS_DREW} if anything was drawn (such as a call to clear
+     * @return {@link RenderNode#STATUS_DREW} if anything was drawn (such as a call to clear
      *         the canvas).
      *
      * @hide
@@ -58,12 +58,12 @@
 
     /**
      * Draws the specified display list onto this canvas. The display list can only
-     * be drawn if {@link android.view.DisplayList#isValid()} returns true.
+     * be drawn if {@link android.view.RenderNode#isValid()} returns true.
      *
      * @param displayList The display list to replay.
      */
-    public void drawDisplayList(DisplayList displayList) {
-        drawDisplayList(displayList, null, DisplayList.FLAG_CLIP_CHILDREN);
+    public void drawDisplayList(RenderNode displayList) {
+        drawDisplayList(displayList, null, RenderNode.FLAG_CLIP_CHILDREN);
     }
 
     /**
@@ -71,17 +71,17 @@
      *
      * @param displayList The display list to replay.
      * @param dirty The dirty region to redraw in the next pass, matters only
-     *        if this method returns {@link DisplayList#STATUS_DRAW}, can be null.
-     * @param flags Optional flags about drawing, see {@link DisplayList} for
+     *        if this method returns {@link RenderNode#STATUS_DRAW}, can be null.
+     * @param flags Optional flags about drawing, see {@link RenderNode} for
      *              the possible flags.
      *
-     * @return One of {@link DisplayList#STATUS_DONE}, {@link DisplayList#STATUS_DRAW}, or
-     *         {@link DisplayList#STATUS_INVOKE}, or'd with {@link DisplayList#STATUS_DREW}
+     * @return One of {@link RenderNode#STATUS_DONE}, {@link RenderNode#STATUS_DRAW}, or
+     *         {@link RenderNode#STATUS_INVOKE}, or'd with {@link RenderNode#STATUS_DREW}
      *         if anything was drawn.
      *
      * @hide
      */
-    public abstract int drawDisplayList(DisplayList displayList, Rect dirty, int flags);
+    public abstract int drawDisplayList(RenderNode displayList, Rect dirty, int flags);
 
     /**
      * Draws the specified layer onto this canvas.
@@ -102,28 +102,28 @@
      *
      * @param drawGLFunction A native function pointer
      *                       
-     * @return One of {@link DisplayList#STATUS_DONE}, {@link DisplayList#STATUS_DRAW} or
-     *         {@link DisplayList#STATUS_INVOKE}
+     * @return One of {@link RenderNode#STATUS_DONE}, {@link RenderNode#STATUS_DRAW} or
+     *         {@link RenderNode#STATUS_INVOKE}
      *
      * @hide
      */
     public int callDrawGLFunction(long drawGLFunction) {
         // Noop - this is done in the display list recorder subclass
-        return DisplayList.STATUS_DONE;
+        return RenderNode.STATUS_DONE;
     }
 
     /**
      * Invoke all the functors who requested to be invoked during the previous frame.
      * 
-     * @param dirty The region to redraw when the functors return {@link DisplayList#STATUS_DRAW}
+     * @param dirty The region to redraw when the functors return {@link RenderNode#STATUS_DRAW}
      *              
-     * @return One of {@link DisplayList#STATUS_DONE}, {@link DisplayList#STATUS_DRAW} or
-     *         {@link DisplayList#STATUS_INVOKE}
+     * @return One of {@link RenderNode#STATUS_DONE}, {@link RenderNode#STATUS_DRAW} or
+     *         {@link RenderNode#STATUS_INVOKE}
      *
      * @hide
      */
     public int invokeFunctors(Rect dirty) {
-        return DisplayList.STATUS_DONE;
+        return RenderNode.STATUS_DONE;
     }
 
     /**
diff --git a/core/java/android/view/HardwareLayer.java b/core/java/android/view/HardwareLayer.java
index 46e2690..4d78733 100644
--- a/core/java/android/view/HardwareLayer.java
+++ b/core/java/android/view/HardwareLayer.java
@@ -37,7 +37,7 @@
 
     private HardwareRenderer mRenderer;
     private Finalizer mFinalizer;
-    private DisplayList mDisplayList;
+    private RenderNode mDisplayList;
     private final int mLayerType;
 
     private HardwareLayer(HardwareRenderer renderer, long deferredUpdater, int type) {
@@ -122,11 +122,11 @@
         }
     }
 
-    public DisplayList startRecording() {
+    public RenderNode startRecording() {
         assertType(LAYER_TYPE_DISPLAY_LIST);
 
         if (mDisplayList == null) {
-            mDisplayList = DisplayList.create("HardwareLayer");
+            mDisplayList = RenderNode.create("HardwareLayer");
         }
         return mDisplayList;
     }
diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java
new file mode 100644
index 0000000..87ab20e
--- /dev/null
+++ b/core/java/android/view/RenderNode.java
@@ -0,0 +1,910 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.graphics.Matrix;
+import android.graphics.Path;
+
+/**
+ * <p>A display list records a series of graphics related operations and can replay
+ * them later. Display lists are usually built by recording operations on a
+ * {@link HardwareCanvas}. Replaying the operations from a display list avoids
+ * executing application code on every frame, and is thus much more efficient.</p>
+ *
+ * <p>Display lists are used internally for all views by default, and are not
+ * typically used directly. One reason to consider using a display is a custom
+ * {@link View} implementation that needs to issue a large number of drawing commands.
+ * When the view invalidates, all the drawing commands must be reissued, even if
+ * large portions of the drawing command stream stay the same frame to frame, which
+ * can become a performance bottleneck. To solve this issue, a custom View might split
+ * its content into several display lists. A display list is updated only when its
+ * content, and only its content, needs to be updated.</p>
+ *
+ * <p>A text editor might for instance store each paragraph into its own display list.
+ * Thus when the user inserts or removes characters, only the display list of the
+ * affected paragraph needs to be recorded again.</p>
+ *
+ * <h3>Hardware acceleration</h3>
+ * <p>Display lists can only be replayed using a {@link HardwareCanvas}. They are not
+ * supported in software. Always make sure that the {@link android.graphics.Canvas}
+ * you are using to render a display list is hardware accelerated using
+ * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p>
+ *
+ * <h3>Creating a display list</h3>
+ * <pre class="prettyprint">
+ *     HardwareRenderer renderer = myView.getHardwareRenderer();
+ *     if (renderer != null) {
+ *         DisplayList displayList = renderer.createDisplayList();
+ *         HardwareCanvas canvas = displayList.start(width, height);
+ *         try {
+ *             // Draw onto the canvas
+ *             // For instance: canvas.drawBitmap(...);
+ *         } finally {
+ *             displayList.end();
+ *         }
+ *     }
+ * </pre>
+ *
+ * <h3>Rendering a display list on a View</h3>
+ * <pre class="prettyprint">
+ *     protected void onDraw(Canvas canvas) {
+ *         if (canvas.isHardwareAccelerated()) {
+ *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
+ *             hardwareCanvas.drawDisplayList(mDisplayList);
+ *         }
+ *     }
+ * </pre>
+ *
+ * <h3>Releasing resources</h3>
+ * <p>This step is not mandatory but recommended if you want to release resources
+ * held by a display list as soon as possible.</p>
+ * <pre class="prettyprint">
+ *     // Mark this display list invalid, it cannot be used for drawing anymore,
+ *     // and release resources held by this display list
+ *     displayList.clear();
+ * </pre>
+ *
+ * <h3>Properties</h3>
+ * <p>In addition, a display list offers several properties, such as
+ * {@link #setScaleX(float)} or {@link #setLeft(int)}, that can be used to affect all
+ * the drawing commands recorded within. For instance, these properties can be used
+ * to move around a large number of images without re-issuing all the individual
+ * <code>drawBitmap()</code> calls.</p>
+ *
+ * <pre class="prettyprint">
+ *     private void createDisplayList() {
+ *         mDisplayList = DisplayList.create("MyDisplayList");
+ *         HardwareCanvas canvas = mDisplayList.start(width, height);
+ *         try {
+ *             for (Bitmap b : mBitmaps) {
+ *                 canvas.drawBitmap(b, 0.0f, 0.0f, null);
+ *                 canvas.translate(0.0f, b.getHeight());
+ *             }
+ *         } finally {
+ *             displayList.end();
+ *         }
+ *     }
+ *
+ *     protected void onDraw(Canvas canvas) {
+ *         if (canvas.isHardwareAccelerated()) {
+ *             HardwareCanvas hardwareCanvas = (HardwareCanvas) canvas;
+ *             hardwareCanvas.drawDisplayList(mDisplayList);
+ *         }
+ *     }
+ *
+ *     private void moveContentBy(int x) {
+ *          // This will move all the bitmaps recorded inside the display list
+ *          // by x pixels to the right and redraw this view. All the commands
+ *          // recorded in createDisplayList() won't be re-issued, only onDraw()
+ *          // will be invoked and will execute very quickly
+ *          mDisplayList.offsetLeftAndRight(x);
+ *          invalidate();
+ *     }
+ * </pre>
+ *
+ * <h3>Threading</h3>
+ * <p>Display lists must be created on and manipulated from the UI thread only.</p>
+ *
+ * @hide
+ */
+public class RenderNode {
+    /**
+     * Flag used when calling
+     * {@link HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)}
+     * When this flag is set, draw operations lying outside of the bounds of the
+     * display list will be culled early. It is recommeneded to always set this
+     * flag.
+     *
+     * @hide
+     */
+    public static final int FLAG_CLIP_CHILDREN = 0x1;
+
+    // NOTE: The STATUS_* values *must* match the enum in DrawGlInfo.h
+
+    /**
+     * Indicates that the display list is done drawing.
+     *
+     * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)
+     *
+     * @hide
+     */
+    public static final int STATUS_DONE = 0x0;
+
+    /**
+     * Indicates that the display list needs another drawing pass.
+     *
+     * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)
+     *
+     * @hide
+     */
+    public static final int STATUS_DRAW = 0x1;
+
+    /**
+     * Indicates that the display list needs to re-execute its GL functors.
+     *
+     * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)
+     * @see HardwareCanvas#callDrawGLFunction(long)
+     *
+     * @hide
+     */
+    public static final int STATUS_INVOKE = 0x2;
+
+    /**
+     * Indicates that the display list performed GL drawing operations.
+     *
+     * @see HardwareCanvas#drawDisplayList(RenderNode, android.graphics.Rect, int)
+     *
+     * @hide
+     */
+    public static final int STATUS_DREW = 0x4;
+
+    private boolean mValid;
+    private final long mNativeDisplayList;
+    private HardwareRenderer mRenderer;
+
+    private RenderNode(String name) {
+        mNativeDisplayList = nCreate();
+        nSetDisplayListName(mNativeDisplayList, name);
+    }
+
+    /**
+     * Creates a new display list that can be used to record batches of
+     * drawing operations.
+     *
+     * @param name The name of the display list, used for debugging purpose. May be null.
+     *
+     * @return A new display list.
+     *
+     * @hide
+     */
+    public static RenderNode create(String name) {
+        return new RenderNode(name);
+    }
+
+    /**
+     * Starts recording the display list. All operations performed on the
+     * returned canvas are recorded and stored in this display list.
+     *
+     * Calling this method will mark the display list invalid until
+     * {@link #end()} is called. Only valid display lists can be replayed.
+     *
+     * @param width The width of the display list's viewport
+     * @param height The height of the display list's viewport
+     *
+     * @return A canvas to record drawing operations.
+     *
+     * @see #end()
+     * @see #isValid()
+     */
+    public HardwareCanvas start(int width, int height) {
+        HardwareCanvas canvas = GLES20RecordingCanvas.obtain();
+        canvas.setViewport(width, height);
+        // The dirty rect should always be null for a display list
+        canvas.onPreDraw(null);
+        return canvas;
+    }
+
+    /**
+     * Ends the recording for this display list. A display list cannot be
+     * replayed if recording is not finished. Calling this method marks
+     * the display list valid and {@link #isValid()} will return true.
+     *
+     * @see #start(int, int)
+     * @see #isValid()
+     */
+    public void end(HardwareRenderer renderer, HardwareCanvas endCanvas) {
+        if (!(endCanvas instanceof GLES20RecordingCanvas)) {
+            throw new IllegalArgumentException("Passed an invalid canvas to end!");
+        }
+
+        GLES20RecordingCanvas canvas = (GLES20RecordingCanvas) endCanvas;
+        canvas.onPostDraw();
+        long displayListData = canvas.finishRecording();
+        if (renderer != mRenderer) {
+            // If we are changing renderers first destroy with the old
+            // renderer, then set with the new one
+            destroyDisplayListData();
+        }
+        mRenderer = renderer;
+        setDisplayListData(displayListData);
+        canvas.recycle();
+        mValid = true;
+    }
+
+    /**
+     * Reset native resources. This is called when cleaning up the state of display lists
+     * during destruction of hardware resources, to ensure that we do not hold onto
+     * obsolete resources after related resources are gone.
+     *
+     * @hide
+     */
+    public void destroyDisplayListData() {
+        if (!mValid) return;
+
+        setDisplayListData(0);
+        mRenderer = null;
+        mValid = false;
+    }
+
+    private void setDisplayListData(long newData) {
+        if (mRenderer != null) {
+            mRenderer.setDisplayListData(mNativeDisplayList, newData);
+        } else {
+            throw new IllegalStateException("Trying to set data without a renderer! data=" + newData);
+        }
+    }
+
+    /**
+     * Returns whether the display list is currently usable. If this returns false,
+     * the display list should be re-recorded prior to replaying it.
+     *
+     * @return boolean true if the display list is able to be replayed, false otherwise.
+     */
+    public boolean isValid() { return mValid; }
+
+    long getNativeDisplayList() {
+        if (!mValid) {
+            throw new IllegalStateException("The display list is not valid.");
+        }
+        return mNativeDisplayList;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // DisplayList Property Setters
+    ///////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Set the caching property on the display list, which indicates whether the display list
+     * holds a layer. Layer display lists should avoid creating an alpha layer, since alpha is
+     * handled in the drawLayer operation directly (and more efficiently).
+     *
+     * @param caching true if the display list represents a hardware layer, false otherwise.
+     *
+     * @hide
+     */
+    public void setCaching(boolean caching) {
+        nSetCaching(mNativeDisplayList, caching);
+    }
+
+    /**
+     * Set whether the display list should clip itself to its bounds. This property is controlled by
+     * the view's parent.
+     *
+     * @param clipToBounds true if the display list should clip to its bounds
+     */
+    public void setClipToBounds(boolean clipToBounds) {
+        nSetClipToBounds(mNativeDisplayList, clipToBounds);
+    }
+
+    /**
+     * Set whether the display list should collect and Z order all 3d composited descendents, and
+     * draw them in order with the default Z=0 content.
+     *
+     * @param isolatedZVolume true if the display list should collect and Z order descendents.
+     */
+    public void setIsolatedZVolume(boolean isolatedZVolume) {
+        nSetIsolatedZVolume(mNativeDisplayList, isolatedZVolume);
+    }
+
+    /**
+     * Sets whether the display list should be drawn immediately after the
+     * closest ancestor display list where isolateZVolume is true. If the
+     * display list itself satisfies this constraint, changing this attribute
+     * has no effect on drawing order.
+     *
+     * @param shouldProject true if the display list should be projected onto a
+     *            containing volume.
+     */
+    public void setProjectBackwards(boolean shouldProject) {
+        nSetProjectBackwards(mNativeDisplayList, shouldProject);
+    }
+
+    /**
+     * Sets whether the display list is a projection receiver - that its parent
+     * DisplayList should draw any descendent DisplayLists with
+     * ProjectBackwards=true directly on top of it. Default value is false.
+     */
+    public void setProjectionReceiver(boolean shouldRecieve) {
+        nSetProjectionReceiver(mNativeDisplayList, shouldRecieve);
+    }
+
+    /**
+     * Sets the outline, defining the shape that casts a shadow, and the path to
+     * be clipped if setClipToOutline is set.
+     *
+     * Deep copies the native path to simplify reference ownership.
+     *
+     * @param outline Convex, CW Path to store in the DisplayList. May be null.
+     */
+    public void setOutline(Path outline) {
+        long nativePath = (outline == null) ? 0 : outline.mNativePath;
+        nSetOutline(mNativeDisplayList, nativePath);
+    }
+
+    /**
+     * Enables or disables clipping to the outline.
+     *
+     * @param clipToOutline true if clipping to the outline.
+     */
+    public void setClipToOutline(boolean clipToOutline) {
+        nSetClipToOutline(mNativeDisplayList, clipToOutline);
+    }
+
+    /**
+     * Set the static matrix on the display list. The specified matrix is combined with other
+     * transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
+     *
+     * @param matrix A transform matrix to apply to this display list
+     *
+     * @see #getMatrix(android.graphics.Matrix)
+     * @see #getMatrix()
+     */
+    public void setStaticMatrix(Matrix matrix) {
+        nSetStaticMatrix(mNativeDisplayList, matrix.native_instance);
+    }
+
+    /**
+     * Set the Animation matrix on the display list. This matrix exists if an Animation is
+     * currently playing on a View, and is set on the display list during at draw() time. When
+     * the Animation finishes, the matrix should be cleared by sending <code>null</code>
+     * for the matrix parameter.
+     *
+     * @param matrix The matrix, null indicates that the matrix should be cleared.
+     *
+     * @hide
+     */
+    public void setAnimationMatrix(Matrix matrix) {
+        nSetAnimationMatrix(mNativeDisplayList,
+                (matrix != null) ? matrix.native_instance : 0);
+    }
+
+    /**
+     * Sets the translucency level for the display list.
+     *
+     * @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
+     *
+     * @see View#setAlpha(float)
+     * @see #getAlpha()
+     */
+    public void setAlpha(float alpha) {
+        nSetAlpha(mNativeDisplayList, alpha);
+    }
+
+    /**
+     * Returns the translucency level of this display list.
+     *
+     * @return A value between 0.0f and 1.0f
+     *
+     * @see #setAlpha(float)
+     */
+    public float getAlpha() {
+        return nGetAlpha(mNativeDisplayList);
+    }
+
+    /**
+     * Sets whether the display list renders content which overlaps. Non-overlapping rendering
+     * can use a fast path for alpha that avoids rendering to an offscreen buffer. By default
+     * display lists consider they do not have overlapping content.
+     *
+     * @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
+     *                                true otherwise.
+     *
+     * @see android.view.View#hasOverlappingRendering()
+     * @see #hasOverlappingRendering()
+     */
+    public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
+        nSetHasOverlappingRendering(mNativeDisplayList, hasOverlappingRendering);
+    }
+
+    /**
+     * Indicates whether the content of this display list overlaps.
+     *
+     * @return True if this display list renders content which overlaps, false otherwise.
+     *
+     * @see #setHasOverlappingRendering(boolean)
+     */
+    public boolean hasOverlappingRendering() {
+        //noinspection SimplifiableIfStatement
+        return nHasOverlappingRendering(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the translation value for the display list on the X axis.
+     *
+     * @param translationX The X axis translation value of the display list, in pixels
+     *
+     * @see View#setTranslationX(float)
+     * @see #getTranslationX()
+     */
+    public void setTranslationX(float translationX) {
+        nSetTranslationX(mNativeDisplayList, translationX);
+    }
+
+    /**
+     * Returns the translation value for this display list on the X axis, in pixels.
+     *
+     * @see #setTranslationX(float)
+     */
+    public float getTranslationX() {
+        return nGetTranslationX(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the translation value for the display list on the Y axis.
+     *
+     * @param translationY The Y axis translation value of the display list, in pixels
+     *
+     * @see View#setTranslationY(float)
+     * @see #getTranslationY()
+     */
+    public void setTranslationY(float translationY) {
+        nSetTranslationY(mNativeDisplayList, translationY);
+    }
+
+    /**
+     * Returns the translation value for this display list on the Y axis, in pixels.
+     *
+     * @see #setTranslationY(float)
+     */
+    public float getTranslationY() {
+        return nGetTranslationY(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the translation value for the display list on the Z axis.
+     *
+     * @see View#setTranslationZ(float)
+     * @see #getTranslationZ()
+     */
+    public void setTranslationZ(float translationZ) {
+        nSetTranslationZ(mNativeDisplayList, translationZ);
+    }
+
+    /**
+     * Returns the translation value for this display list on the Z axis.
+     *
+     * @see #setTranslationZ(float)
+     */
+    public float getTranslationZ() {
+        return nGetTranslationZ(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the rotation value for the display list around the Z axis.
+     *
+     * @param rotation The rotation value of the display list, in degrees
+     *
+     * @see View#setRotation(float)
+     * @see #getRotation()
+     */
+    public void setRotation(float rotation) {
+        nSetRotation(mNativeDisplayList, rotation);
+    }
+
+    /**
+     * Returns the rotation value for this display list around the Z axis, in degrees.
+     *
+     * @see #setRotation(float)
+     */
+    public float getRotation() {
+        return nGetRotation(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the rotation value for the display list around the X axis.
+     *
+     * @param rotationX The rotation value of the display list, in degrees
+     *
+     * @see View#setRotationX(float)
+     * @see #getRotationX()
+     */
+    public void setRotationX(float rotationX) {
+        nSetRotationX(mNativeDisplayList, rotationX);
+    }
+
+    /**
+     * Returns the rotation value for this display list around the X axis, in degrees.
+     *
+     * @see #setRotationX(float)
+     */
+    public float getRotationX() {
+        return nGetRotationX(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the rotation value for the display list around the Y axis.
+     *
+     * @param rotationY The rotation value of the display list, in degrees
+     *
+     * @see View#setRotationY(float)
+     * @see #getRotationY()
+     */
+    public void setRotationY(float rotationY) {
+        nSetRotationY(mNativeDisplayList, rotationY);
+    }
+
+    /**
+     * Returns the rotation value for this display list around the Y axis, in degrees.
+     *
+     * @see #setRotationY(float)
+     */
+    public float getRotationY() {
+        return nGetRotationY(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the scale value for the display list on the X axis.
+     *
+     * @param scaleX The scale value of the display list
+     *
+     * @see View#setScaleX(float)
+     * @see #getScaleX()
+     */
+    public void setScaleX(float scaleX) {
+        nSetScaleX(mNativeDisplayList, scaleX);
+    }
+
+    /**
+     * Returns the scale value for this display list on the X axis.
+     *
+     * @see #setScaleX(float)
+     */
+    public float getScaleX() {
+        return nGetScaleX(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the scale value for the display list on the Y axis.
+     *
+     * @param scaleY The scale value of the display list
+     *
+     * @see View#setScaleY(float)
+     * @see #getScaleY()
+     */
+    public void setScaleY(float scaleY) {
+        nSetScaleY(mNativeDisplayList, scaleY);
+    }
+
+    /**
+     * Returns the scale value for this display list on the Y axis.
+     *
+     * @see #setScaleY(float)
+     */
+    public float getScaleY() {
+        return nGetScaleY(mNativeDisplayList);
+    }
+
+    /**
+     * Sets all of the transform-related values of the display list
+     *
+     * @param alpha The alpha value of the display list
+     * @param translationX The translationX value of the display list
+     * @param translationY The translationY value of the display list
+     * @param rotation The rotation value of the display list
+     * @param rotationX The rotationX value of the display list
+     * @param rotationY The rotationY value of the display list
+     * @param scaleX The scaleX value of the display list
+     * @param scaleY The scaleY value of the display list
+     *
+     * @hide
+     */
+    public void setTransformationInfo(float alpha,
+            float translationX, float translationY, float translationZ,
+            float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
+        nSetTransformationInfo(mNativeDisplayList, alpha,
+                translationX, translationY, translationZ,
+                rotation, rotationX, rotationY, scaleX, scaleY);
+    }
+
+    /**
+     * Sets the pivot value for the display list on the X axis
+     *
+     * @param pivotX The pivot value of the display list on the X axis, in pixels
+     *
+     * @see View#setPivotX(float)
+     * @see #getPivotX()
+     */
+    public void setPivotX(float pivotX) {
+        nSetPivotX(mNativeDisplayList, pivotX);
+    }
+
+    /**
+     * Returns the pivot value for this display list on the X axis, in pixels.
+     *
+     * @see #setPivotX(float)
+     */
+    public float getPivotX() {
+        return nGetPivotX(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the pivot value for the display list on the Y axis
+     *
+     * @param pivotY The pivot value of the display list on the Y axis, in pixels
+     *
+     * @see View#setPivotY(float)
+     * @see #getPivotY()
+     */
+    public void setPivotY(float pivotY) {
+        nSetPivotY(mNativeDisplayList, pivotY);
+    }
+
+    /**
+     * Returns the pivot value for this display list on the Y axis, in pixels.
+     *
+     * @see #setPivotY(float)
+     */
+    public float getPivotY() {
+        return nGetPivotY(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the camera distance for the display list. Refer to
+     * {@link View#setCameraDistance(float)} for more information on how to
+     * use this property.
+     *
+     * @param distance The distance in Z of the camera of the display list
+     *
+     * @see View#setCameraDistance(float)
+     * @see #getCameraDistance()
+     */
+    public void setCameraDistance(float distance) {
+        nSetCameraDistance(mNativeDisplayList, distance);
+    }
+
+    /**
+     * Returns the distance in Z of the camera of the display list.
+     *
+     * @see #setCameraDistance(float)
+     */
+    public float getCameraDistance() {
+        return nGetCameraDistance(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the left position for the display list.
+     *
+     * @param left The left position, in pixels, of the display list
+     *
+     * @see View#setLeft(int)
+     * @see #getLeft()
+     */
+    public void setLeft(int left) {
+        nSetLeft(mNativeDisplayList, left);
+    }
+
+    /**
+     * Returns the left position for the display list in pixels.
+     *
+     * @see #setLeft(int)
+     */
+    public float getLeft() {
+        return nGetLeft(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the top position for the display list.
+     *
+     * @param top The top position, in pixels, of the display list
+     *
+     * @see View#setTop(int)
+     * @see #getTop()
+     */
+    public void setTop(int top) {
+        nSetTop(mNativeDisplayList, top);
+    }
+
+    /**
+     * Returns the top position for the display list in pixels.
+     *
+     * @see #setTop(int)
+     */
+    public float getTop() {
+        return nGetTop(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the right position for the display list.
+     *
+     * @param right The right position, in pixels, of the display list
+     *
+     * @see View#setRight(int)
+     * @see #getRight()
+     */
+    public void setRight(int right) {
+        nSetRight(mNativeDisplayList, right);
+    }
+
+    /**
+     * Returns the right position for the display list in pixels.
+     *
+     * @see #setRight(int)
+     */
+    public float getRight() {
+        return nGetRight(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the bottom position for the display list.
+     *
+     * @param bottom The bottom position, in pixels, of the display list
+     *
+     * @see View#setBottom(int)
+     * @see #getBottom()
+     */
+    public void setBottom(int bottom) {
+        nSetBottom(mNativeDisplayList, bottom);
+    }
+
+    /**
+     * Returns the bottom position for the display list in pixels.
+     *
+     * @see #setBottom(int)
+     */
+    public float getBottom() {
+        return nGetBottom(mNativeDisplayList);
+    }
+
+    /**
+     * Sets the left and top positions for the display list
+     *
+     * @param left The left position of the display list, in pixels
+     * @param top The top position of the display list, in pixels
+     * @param right The right position of the display list, in pixels
+     * @param bottom The bottom position of the display list, in pixels
+     *
+     * @see View#setLeft(int)
+     * @see View#setTop(int)
+     * @see View#setRight(int)
+     * @see View#setBottom(int)
+     */
+    public void setLeftTopRightBottom(int left, int top, int right, int bottom) {
+        nSetLeftTopRightBottom(mNativeDisplayList, left, top, right, bottom);
+    }
+
+    /**
+     * Offsets the left and right positions for the display list
+     *
+     * @param offset The amount that the left and right positions of the display
+     *               list are offset, in pixels
+     *
+     * @see View#offsetLeftAndRight(int)
+     */
+    public void offsetLeftAndRight(float offset) {
+        nOffsetLeftAndRight(mNativeDisplayList, offset);
+    }
+
+    /**
+     * Offsets the top and bottom values for the display list
+     *
+     * @param offset The amount that the top and bottom positions of the display
+     *               list are offset, in pixels
+     *
+     * @see View#offsetTopAndBottom(int)
+     */
+    public void offsetTopAndBottom(float offset) {
+        nOffsetTopAndBottom(mNativeDisplayList, offset);
+    }
+
+    /**
+     * Outputs the display list to the log. This method exists for use by
+     * tools to output display lists for selected nodes to the log.
+     *
+     * @hide
+     */
+    public void output() {
+        nOutput(mNativeDisplayList);
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Native methods
+    ///////////////////////////////////////////////////////////////////////////
+
+    private static native long nCreate();
+    private static native void nDestroyDisplayList(long displayList);
+    private static native void nSetDisplayListName(long displayList, String name);
+
+    // Properties
+
+    private static native void nOffsetTopAndBottom(long displayList, float offset);
+    private static native void nOffsetLeftAndRight(long displayList, float offset);
+    private static native void nSetLeftTopRightBottom(long displayList, int left, int top,
+            int right, int bottom);
+    private static native void nSetBottom(long displayList, int bottom);
+    private static native void nSetRight(long displayList, int right);
+    private static native void nSetTop(long displayList, int top);
+    private static native void nSetLeft(long displayList, int left);
+    private static native void nSetCameraDistance(long displayList, float distance);
+    private static native void nSetPivotY(long displayList, float pivotY);
+    private static native void nSetPivotX(long displayList, float pivotX);
+    private static native void nSetCaching(long displayList, boolean caching);
+    private static native void nSetClipToBounds(long displayList, boolean clipToBounds);
+    private static native void nSetProjectBackwards(long displayList, boolean shouldProject);
+    private static native void nSetProjectionReceiver(long displayList, boolean shouldRecieve);
+    private static native void nSetIsolatedZVolume(long displayList, boolean isolateZVolume);
+    private static native void nSetOutline(long displayList, long nativePath);
+    private static native void nSetClipToOutline(long displayList, boolean clipToOutline);
+    private static native void nSetAlpha(long displayList, float alpha);
+    private static native void nSetHasOverlappingRendering(long displayList,
+            boolean hasOverlappingRendering);
+    private static native void nSetTranslationX(long displayList, float translationX);
+    private static native void nSetTranslationY(long displayList, float translationY);
+    private static native void nSetTranslationZ(long displayList, float translationZ);
+    private static native void nSetRotation(long displayList, float rotation);
+    private static native void nSetRotationX(long displayList, float rotationX);
+    private static native void nSetRotationY(long displayList, float rotationY);
+    private static native void nSetScaleX(long displayList, float scaleX);
+    private static native void nSetScaleY(long displayList, float scaleY);
+    private static native void nSetTransformationInfo(long displayList, float alpha,
+            float translationX, float translationY, float translationZ,
+            float rotation, float rotationX, float rotationY, float scaleX, float scaleY);
+    private static native void nSetStaticMatrix(long displayList, long nativeMatrix);
+    private static native void nSetAnimationMatrix(long displayList, long animationMatrix);
+
+    private static native boolean nHasOverlappingRendering(long displayList);
+    private static native float nGetAlpha(long displayList);
+    private static native float nGetLeft(long displayList);
+    private static native float nGetTop(long displayList);
+    private static native float nGetRight(long displayList);
+    private static native float nGetBottom(long displayList);
+    private static native float nGetCameraDistance(long displayList);
+    private static native float nGetScaleX(long displayList);
+    private static native float nGetScaleY(long displayList);
+    private static native float nGetTranslationX(long displayList);
+    private static native float nGetTranslationY(long displayList);
+    private static native float nGetTranslationZ(long displayList);
+    private static native float nGetRotation(long displayList);
+    private static native float nGetRotationX(long displayList);
+    private static native float nGetRotationY(long displayList);
+    private static native float nGetPivotX(long displayList);
+    private static native float nGetPivotY(long displayList);
+    private static native void nOutput(long displayList);
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Finalization
+    ///////////////////////////////////////////////////////////////////////////
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            destroyDisplayListData();
+            nDestroyDisplayList(mNativeDisplayList);
+        } finally {
+            super.finalize();
+        }
+    }
+}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index e693b9e..5a8d2c8 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -167,13 +167,6 @@
     public static final int FX_SURFACE_DIM = 0x00020000;
 
     /**
-     * Surface creation flag: Creates a video plane Surface.
-     * This surface is backed by a hardware video plane. It is an error to lock
-     * a video plane surface, since it doesn't have a backing store.
-     */
-    public static final int FX_SURFACE_VIDEO_PLANE = 0x00040000;
-
-    /**
      * Mask used for FX values above.
      *
      */
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 1f211c2..23123dd 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -422,10 +422,7 @@
         mWindowType = type;
     }
 
-    /**
-     * @hide
-     */
-    protected void updateWindow(boolean force, boolean redrawNeeded) {
+    private void updateWindow(boolean force, boolean redrawNeeded) {
         if (!mHaveFrame) {
             return;
         }
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index a1fb123..2a488a0 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -163,7 +163,7 @@
         view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
 
         Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
-        DisplayList displayList = view.getDisplayList();
+        RenderNode displayList = view.getDisplayList();
         Trace.traceEnd(Trace.TRACE_TAG_VIEW);
 
         view.mRecreateDisplayList = false;
diff --git a/core/java/android/view/VideoPlaneView.java b/core/java/android/view/VideoPlaneView.java
deleted file mode 100644
index 81dcf9d..0000000
--- a/core/java/android/view/VideoPlaneView.java
+++ /dev/null
@@ -1,53 +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.view;
-
-import android.content.Context;
-import android.util.AttributeSet;
-
-/**
- * Provides a dedicated surface embedded inside of a view hierarchy much like a
- * {@link SurfaceView}, but the surface is actually backed by a hardware video
- * plane.
- *
- * TODO: Eventually this should be separate from SurfaceView.
- *
- * @hide
- */
-public class VideoPlaneView extends SurfaceView {
-    public VideoPlaneView(Context context) {
-        super(context);
-    }
-
-    public VideoPlaneView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public VideoPlaneView(Context context, AttributeSet attrs, int defStyleAttr) {
-        super(context, attrs, defStyleAttr);
-    }
-
-    public VideoPlaneView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
-        super(context, attrs, defStyleAttr, defStyleRes);
-    }
-
-    @Override
-    protected void updateWindow(boolean force, boolean redrawNeeded) {
-        mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_VIDEO_PLANE;
-        super.updateWindow(force, redrawNeeded);
-    }
-}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d72f810..ecd73af 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2386,17 +2386,6 @@
      */
     static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x80;
 
-    /**
-     * Flag indicating that an view will cast a shadow onto the Z=0 plane if elevated.
-     */
-    static final int PFLAG3_CASTS_SHADOW = 0x100;
-
-    /**
-     * Flag indicating that view will be transformed by the global camera if rotated in 3d, or given
-     * a non-0 Z translation.
-     */
-    static final int PFLAG3_USES_GLOBAL_CAMERA = 0x200;
-
     /* End of masks for mPrivateFlags3 */
 
     static final int DRAG_MASK = PFLAG2_DRAG_CAN_ACCEPT | PFLAG2_DRAG_HOVERED;
@@ -3269,7 +3258,7 @@
      * of the background drawable. It is cleared on temporary detach and reset
      * on cleanup.
      */
-    private DisplayList mBackgroundDisplayList;
+    private RenderNode mBackgroundDisplayList;
 
     private int mBackgroundResource;
     private boolean mBackgroundSizeChanged;
@@ -3559,7 +3548,7 @@
      * of the View content. It is cleared on temporary detach and reset on
      * cleanup.
      */
-    DisplayList mDisplayList;
+    RenderNode mDisplayList;
 
     /**
      * Set to true when the view is sending hover accessibility events because it
@@ -4039,11 +4028,6 @@
                 case R.styleable.View_layerType:
                     setLayerType(a.getInt(attr, LAYER_TYPE_NONE), null);
                     break;
-                case R.styleable.View_castsShadow:
-                    if (a.getBoolean(attr, false)) {
-                        mPrivateFlags3 |= PFLAG3_CASTS_SHADOW;
-                    }
-                    break;
                 case R.styleable.View_textDirection:
                     // Clear any text direction flag already set
                     mPrivateFlags2 &= ~PFLAG2_TEXT_DIRECTION_MASK;
@@ -10852,7 +10836,6 @@
      *
      * @param outline The new outline of the view. Must be non-null, and convex.
      *
-     * @see #setCastsShadow(boolean)
      * @see #getOutline(Path)
      * @see #getClipToOutline()
      * @see #setClipToOutline(boolean)
@@ -10916,95 +10899,6 @@
     }
 
     /**
-     * Returns whether the View will cast shadows when its
-     * {@link #setTranslationZ(float) z translation} is greater than 0, or it is
-     * rotated in 3D.
-     *
-     * @see #setTranslationZ(float)
-     * @see #setRotationX(float)
-     * @see #setRotationY(float)
-     * @see #setCastsShadow(boolean)
-     * @attr ref android.R.styleable#View_castsShadow
-     */
-    public final boolean getCastsShadow() {
-        return ((mPrivateFlags3 & PFLAG3_CASTS_SHADOW) != 0);
-    }
-
-    /**
-     * Set to true to enable this View to cast shadows.
-     * <p>
-     * If enabled, and the View has a z translation greater than 0, or is
-     * rotated in 3D, the shadow will be cast onto its parent at the z = 0
-     * plane.
-     * <p>
-     * The shape of the shadow being cast is defined by the
-     * {@link #setOutline(Path) outline} of the view, or the rectangular bounds
-     * of the view if the outline is not set or is empty.
-     *
-     * @see #setTranslationZ(float)
-     * @see #getCastsShadow()
-     * @attr ref android.R.styleable#View_castsShadow
-     */
-    public void setCastsShadow(boolean castsShadow) {
-        // TODO : Add a fast invalidation here.
-        if (getCastsShadow() != castsShadow) {
-            if (castsShadow) {
-                mPrivateFlags3 |= PFLAG3_CASTS_SHADOW;
-            } else {
-                mPrivateFlags3 &= ~PFLAG3_CASTS_SHADOW;
-            }
-            if (mDisplayList != null) {
-                mDisplayList.setCastsShadow(castsShadow);
-            }
-        }
-    }
-
-    /**
-     * Returns whether the View will be transformed by the global camera.
-     *
-     * @see #setUsesGlobalCamera(boolean)
-     *
-     * @hide
-     */
-    public final boolean getUsesGlobalCamera() {
-        return ((mPrivateFlags3 & PFLAG3_USES_GLOBAL_CAMERA) != 0);
-    }
-
-    /**
-     * Sets whether the View should be transformed by the global camera.
-     * <p>
-     * If the view has a Z translation or 3D rotation, perspective from the
-     * global camera will be applied. This enables an app to transform multiple
-     * views in 3D with coherent perspective projection among them all.
-     * <p>
-     * Setting this to true will cause {@link #setCameraDistance() camera distance}
-     * to be ignored, as the global camera's position will dictate perspective
-     * transform.
-     * <p>
-     * This should not be used in conjunction with {@link android.graphics.Camera}.
-     *
-     * @see #getUsesGlobalCamera()
-     * @see #setTranslationZ(float)
-     * @see #setRotationX(float)
-     * @see #setRotationY(float)
-     *
-     * @hide
-     */
-    public void setUsesGlobalCamera(boolean usesGlobalCamera) {
-        // TODO : Add a fast invalidation here.
-        if (getUsesGlobalCamera() != usesGlobalCamera) {
-            if (usesGlobalCamera) {
-                mPrivateFlags3 |= PFLAG3_USES_GLOBAL_CAMERA;
-            } else {
-                mPrivateFlags3 &= ~PFLAG3_USES_GLOBAL_CAMERA;
-            }
-            if (mDisplayList != null) {
-                mDisplayList.setUsesGlobalCamera(usesGlobalCamera);
-            }
-        }
-    }
-
-    /**
      * Hit rectangle in parent's coordinates
      *
      * @param outRect The hit rectangle of the view.
@@ -11567,7 +11461,7 @@
             }
 
             // Damage the entire IsolatedZVolume recieving this view's shadow.
-            if (getCastsShadow() && getTranslationZ() != 0) {
+            if (getTranslationZ() != 0) {
                 damageIsolatedZVolume();
             }
         }
@@ -11647,7 +11541,7 @@
         } else {
             damageInParent();
         }
-        if (invalidateParent && getCastsShadow() && getTranslationZ() != 0) {
+        if (invalidateParent && getTranslationZ() != 0) {
             damageIsolatedZVolume();
         }
     }
@@ -13802,7 +13696,7 @@
             }
 
             mHardwareLayer.setLayerPaint(mLayerPaint);
-            DisplayList displayList = mHardwareLayer.startRecording();
+            RenderNode displayList = mHardwareLayer.startRecording();
             if (getDisplayList(displayList, true) != displayList) {
                 throw new IllegalStateException("getDisplayList() didn't return"
                         + " the input displaylist for a hardware layer!");
@@ -13952,8 +13846,9 @@
      * the view will avoid creating a layer inside the resulting display list.
      * @return A new or reused DisplayList object.
      */
-    private DisplayList getDisplayList(DisplayList displayList, boolean isLayer) {
-        if (!canHaveDisplayList()) {
+    private RenderNode getDisplayList(RenderNode displayList, boolean isLayer) {
+        final HardwareRenderer renderer = getHardwareRenderer();
+        if (renderer == null || !canHaveDisplayList()) {
             return null;
         }
 
@@ -13977,7 +13872,7 @@
                 mRecreateDisplayList = true;
             }
             if (displayList == null) {
-                displayList = DisplayList.create(getClass().getName());
+                displayList = RenderNode.create(getClass().getName());
                 // If we're creating a new display list, make sure our parent gets invalidated
                 // since they will need to recreate their display list to account for this
                 // new child display list.
@@ -14032,13 +13927,21 @@
                     }
                 }
             } finally {
-                displayList.end(getHardwareRenderer(), canvas);
+                displayList.end(renderer, canvas);
                 displayList.setCaching(caching);
                 if (isLayer) {
                     displayList.setLeftTopRightBottom(0, 0, width, height);
                 } else {
                     setDisplayListProperties(displayList);
                 }
+
+                if (renderer != getHardwareRenderer()) {
+                    Log.w(VIEW_LOG_TAG, "View was detached during a draw() call!");
+                    // TODO: Should this be elevated to a crash?
+                    // For now have it behaves the same as it previously did, it
+                    // will result in the DisplayListData being destroyed later
+                    // than it could be but oh well...
+                }
             }
         } else if (!isLayer) {
             mPrivateFlags |= PFLAG_DRAWN | PFLAG_DRAWING_CACHE_VALID;
@@ -14056,7 +13959,7 @@
      *
      * @hide
      */
-    public DisplayList getDisplayList() {
+    public RenderNode getDisplayList() {
         mDisplayList = getDisplayList(mDisplayList, false);
         return mDisplayList;
     }
@@ -14662,7 +14565,7 @@
      * necessary when a display list is being re-created, because we need to make sure that
      * previously-set transform values
      */
-    void setDisplayListProperties(DisplayList displayList) {
+    void setDisplayListProperties(RenderNode displayList) {
         if (displayList != null) {
             displayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
             displayList.setHasOverlappingRendering(hasOverlappingRendering());
@@ -14676,8 +14579,6 @@
             }
             displayList.setOutline(mOutline);
             displayList.setClipToOutline(getClipToOutline());
-            displayList.setCastsShadow(getCastsShadow());
-            displayList.setUsesGlobalCamera(getUsesGlobalCamera());
             float alpha = 1;
             if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags &
                     ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
@@ -14807,7 +14708,7 @@
             mPrivateFlags &= ~PFLAG_INVALIDATED;
         }
 
-        DisplayList displayList = null;
+        RenderNode displayList = null;
         Bitmap cache = null;
         boolean hasDisplayList = false;
         if (caching) {
@@ -15286,7 +15187,7 @@
                 && mAttachInfo.mHardwareRenderer != null) {
             mBackgroundDisplayList = getDrawableDisplayList(background, mBackgroundDisplayList);
 
-            final DisplayList displayList = mBackgroundDisplayList;
+            final RenderNode displayList = mBackgroundDisplayList;
             if (displayList != null && displayList.isValid()) {
                 setBackgroundDisplayListProperties(displayList);
                 ((HardwareCanvas) canvas).drawDisplayList(displayList);
@@ -15310,7 +15211,7 @@
      *
      * @param displayList Valid display list for the background drawable
      */
-    private void setBackgroundDisplayListProperties(DisplayList displayList) {
+    private void setBackgroundDisplayListProperties(RenderNode displayList) {
         displayList.setTranslationX(mScrollX);
         displayList.setTranslationY(mScrollY);
     }
@@ -15323,9 +15224,9 @@
      * @param displayList Existing display list, or {@code null}
      * @return A valid display list for the specified drawable
      */
-    private DisplayList getDrawableDisplayList(Drawable drawable, DisplayList displayList) {
+    private RenderNode getDrawableDisplayList(Drawable drawable, RenderNode displayList) {
         if (displayList == null) {
-            displayList = DisplayList.create(drawable.getClass().getName());
+            displayList = RenderNode.create(drawable.getClass().getName());
         }
 
         final Rect bounds = drawable.getBounds();
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index e67659c..5112b9a 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -80,7 +80,7 @@
      * is a tap or a scroll. If the user does not move within this interval, it is
      * considered to be a tap.
      */
-    private static final int TAP_TIMEOUT = 180;
+    private static final int TAP_TIMEOUT = 100;
 
     /**
      * Defines the duration in milliseconds we will wait to see if a touch event
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 1892aa7..563ffb7 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -925,7 +925,7 @@
      */
     private void setValue(int propertyConstant, float value) {
         final View.TransformationInfo info = mView.mTransformationInfo;
-        final DisplayList displayList = mView.mDisplayList;
+        final RenderNode displayList = mView.mDisplayList;
         switch (propertyConstant) {
             case TRANSLATION_X:
                 info.mTranslationX = value;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 18517c5..185cb65 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1465,7 +1465,7 @@
                                     mWidth, mHeight);
                         }
                         mResizeBuffer.prepare(mWidth, mHeight, false);
-                        DisplayList layerDisplayList = mResizeBuffer.startRecording();
+                        RenderNode layerDisplayList = mResizeBuffer.startRecording();
                         HardwareCanvas layerCanvas = layerDisplayList.start(mWidth, mHeight);
                         final int restoreCount = layerCanvas.save();
 
@@ -1484,10 +1484,10 @@
                             mTranslator.translateCanvas(layerCanvas);
                         }
 
-                        DisplayList displayList = mView.mDisplayList;
+                        RenderNode displayList = mView.mDisplayList;
                         if (displayList != null && displayList.isValid()) {
                             layerCanvas.drawDisplayList(displayList, null,
-                                    DisplayList.FLAG_CLIP_CHILDREN);
+                                    RenderNode.FLAG_CLIP_CHILDREN);
                         } else {
                             mView.draw(layerCanvas);
                         }
@@ -2178,7 +2178,7 @@
      * @hide
      */
     void outputDisplayList(View view) {
-        DisplayList displayList = view.getDisplayList();
+        RenderNode displayList = view.getDisplayList();
         if (displayList != null) {
             displayList.output();
         }
@@ -5206,7 +5206,7 @@
     }
 
     private static void getGfxInfo(View view, int[] info) {
-        DisplayList displayList = view.mDisplayList;
+        RenderNode displayList = view.mDisplayList;
         info[0]++;
         if (displayList != null) {
             info[1] += 0; /* TODO: Memory used by display lists */
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 55956bf..53a4c0d0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -98,7 +98,7 @@
      * the given view hierarchy's {@link View#onDetachedFromWindow()
      * View.onDetachedFromWindow()} methods before returning.  This is not
      * for normal applications; using it correctly requires great care.
-     *
+     * 
      * @param view The view to be removed.
      */
     public void removeViewImmediate(View view);
@@ -112,7 +112,7 @@
          */
         @ViewDebug.ExportedProperty
         public int x;
-
+        
         /**
          * Y position for this window.  With the default gravity it is ignored.
          * When using {@link Gravity#TOP} or {@link Gravity#BOTTOM} it provides
@@ -161,7 +161,7 @@
          * be used by applications, and a special permission is required
          * to use them.
          * </ul>
-         *
+         * 
          * @see #TYPE_BASE_APPLICATION
          * @see #TYPE_APPLICATION
          * @see #TYPE_APPLICATION_STARTING
@@ -223,12 +223,12 @@
             @ViewDebug.IntToString(from = TYPE_PRIVATE_PRESENTATION, to = "TYPE_PRIVATE_PRESENTATION")
         })
         public int type;
-
+    
         /**
          * Start of window types that represent normal application windows.
          */
         public static final int FIRST_APPLICATION_WINDOW = 1;
-
+        
         /**
          * Window type: an application window that serves as the "base" window
          * of the overall application; all other application windows will
@@ -236,14 +236,14 @@
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_BASE_APPLICATION   = 1;
-
+        
         /**
          * Window type: a normal application window.  The {@link #token} must be
          * an Activity token identifying who the window belongs to.
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_APPLICATION        = 2;
-
+    
         /**
          * Window type: special application window that is displayed while the
          * application is starting.  Not for use by applications themselves;
@@ -252,12 +252,12 @@
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_APPLICATION_STARTING = 3;
-
+    
         /**
          * End of types of application windows.
          */
         public static final int LAST_APPLICATION_WINDOW = 99;
-
+    
         /**
          * Start of types of sub-windows.  The {@link #token} of these windows
          * must be set to the window they are attached to.  These types of
@@ -265,19 +265,19 @@
          * coordinate space is relative to their attached window.
          */
         public static final int FIRST_SUB_WINDOW        = 1000;
-
+    
         /**
          * Window type: a panel on top of an application window.  These windows
          * appear on top of their attached window.
          */
         public static final int TYPE_APPLICATION_PANEL  = FIRST_SUB_WINDOW;
-
+    
         /**
          * Window type: window for showing media (such as video).  These windows
          * are displayed behind their attached window.
          */
         public static final int TYPE_APPLICATION_MEDIA  = FIRST_SUB_WINDOW+1;
-
+    
         /**
          * Window type: a sub-panel on top of an application window.  These
          * windows are displayed on top their attached window and any
@@ -290,7 +290,7 @@
          * as a child of its container.
          */
         public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3;
-
+        
         /**
          * Window type: window for showing overlays on top of media windows.
          * These windows are displayed between TYPE_APPLICATION_MEDIA and the
@@ -299,18 +299,18 @@
          * @hide
          */
         public static final int TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW+4;
-
+    
         /**
          * End of types of sub-windows.
          */
         public static final int LAST_SUB_WINDOW         = 1999;
-
+        
         /**
          * Start of system-specific window types.  These are not normally
          * created by applications.
          */
         public static final int FIRST_SYSTEM_WINDOW     = 2000;
-
+    
         /**
          * Window type: the status bar.  There can be only one status bar
          * window; it is placed at the top of the screen, and all other
@@ -318,14 +318,14 @@
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW;
-
+    
         /**
          * Window type: the search bar.  There can be only one search bar
          * window; it is placed at the top of the screen.
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1;
-
+    
         /**
          * Window type: phone.  These are non-application windows providing
          * user interaction with the phone (in particular incoming calls).
@@ -334,26 +334,26 @@
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2;
-
+    
         /**
          * Window type: system window, such as low power alert. These windows
          * are always on top of application windows.
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3;
-
+        
         /**
          * Window type: keyguard window.
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4;
-
+        
         /**
          * Window type: transient notifications.
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5;
-
+        
         /**
          * Window type: system overlay windows, which need to be displayed
          * on top of everything else.  These windows must not take input
@@ -361,7 +361,7 @@
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6;
-
+        
         /**
          * Window type: priority phone UI, which needs to be displayed even if
          * the keyguard is active.  These windows must not take input
@@ -369,26 +369,26 @@
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7;
-
+        
         /**
          * Window type: panel that slides out from the status bar
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_SYSTEM_DIALOG      = FIRST_SYSTEM_WINDOW+8;
-
+    
         /**
          * Window type: dialogs that the keyguard shows
          * In multiuser systems shows on all users' windows.
          */
         public static final int TYPE_KEYGUARD_DIALOG    = FIRST_SYSTEM_WINDOW+9;
-
+        
         /**
          * Window type: internal system error windows, appear on top of
          * everything they can.
          * In multiuser systems shows only on the owning user's window.
          */
         public static final int TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10;
-
+        
         /**
          * Window type: internal input methods windows, which appear above
          * the normal UI.  Application windows may be resized or panned to keep
@@ -559,16 +559,16 @@
         /** @deprecated this is ignored, this value is set automatically when needed. */
         @Deprecated
         public static final int MEMORY_TYPE_PUSH_BUFFERS = 3;
-
+        
         /**
          * @deprecated this is ignored
          */
         @Deprecated
         public int memoryType;
-
+        
         /** Window flag: as long as this window is visible to the user, allow
-         *  the lock screen to activate while the screen is on.
-         *  This can be used independently, or in combination with
+         *  the lock screen to activate while the screen is on. 
+         *  This can be used independently, or in combination with 
          *  {@link #FLAG_KEEP_SCREEN_ON} and/or {@link #FLAG_SHOW_WHEN_LOCKED} */
         public static final int FLAG_ALLOW_LOCK_WHILE_SCREEN_ON     = 0x00000001;
 
@@ -586,47 +586,47 @@
          * instead go to whatever focusable window is behind it.  This flag
          * will also enable {@link #FLAG_NOT_TOUCH_MODAL} whether or not that
          * is explicitly set.
-         *
+         * 
          * <p>Setting this flag also implies that the window will not need to
          * interact with
-         * a soft input method, so it will be Z-ordered and positioned
+         * a soft input method, so it will be Z-ordered and positioned 
          * independently of any active input method (typically this means it
          * gets Z-ordered on top of the input method, so it can use the full
          * screen for its content and cover the input method if needed.  You
          * can use {@link #FLAG_ALT_FOCUSABLE_IM} to modify this behavior. */
         public static final int FLAG_NOT_FOCUSABLE      = 0x00000008;
-
+        
         /** Window flag: this window can never receive touch events. */
         public static final int FLAG_NOT_TOUCHABLE      = 0x00000010;
-
+        
         /** Window flag: even when this window is focusable (its
          * {@link #FLAG_NOT_FOCUSABLE} is not set), allow any pointer events
          * outside of the window to be sent to the windows behind it.  Otherwise
          * it will consume all pointer events itself, regardless of whether they
          * are inside of the window. */
         public static final int FLAG_NOT_TOUCH_MODAL    = 0x00000020;
-
+        
         /** Window flag: when set, if the device is asleep when the touch
          * screen is pressed, you will receive this first touch event.  Usually
          * the first touch event is consumed by the system since the user can
          * not see what they are pressing on.
          */
         public static final int FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040;
-
+        
         /** Window flag: as long as this window is visible to the user, keep
          *  the device's screen turned on and bright. */
         public static final int FLAG_KEEP_SCREEN_ON     = 0x00000080;
-
+        
         /** Window flag: place the window within the entire screen, ignoring
          *  decorations around the border (such as the status bar).  The
          *  window must correctly position its contents to take the screen
          *  decoration into account.  This flag is normally set for you
          *  by Window as described in {@link Window#setFlags}. */
         public static final int FLAG_LAYOUT_IN_SCREEN   = 0x00000100;
-
+        
         /** Window flag: allow window to extend outside of the screen. */
         public static final int FLAG_LAYOUT_NO_LIMITS   = 0x00000200;
-
+        
         /**
          * Window flag: hide all screen decorations (such as the status bar) while
          * this window is displayed.  This allows the window to use the entire
@@ -648,17 +648,17 @@
          * {@link android.R.style#Theme_DeviceDefault_Light_NoActionBar_Fullscreen}.</p>
          */
         public static final int FLAG_FULLSCREEN      = 0x00000400;
-
+        
         /** Window flag: override {@link #FLAG_FULLSCREEN} and force the
          *  screen decorations (such as the status bar) to be shown. */
         public static final int FLAG_FORCE_NOT_FULLSCREEN   = 0x00000800;
-
+        
         /** Window flag: turn on dithering when compositing this window to
          *  the screen.
          * @deprecated This flag is no longer used. */
         @Deprecated
         public static final int FLAG_DITHER             = 0x00001000;
-
+        
         /** Window flag: treat the content of the window as secure, preventing
          * it from appearing in screenshots or from being viewed on non-secure
          * displays.
@@ -667,21 +667,21 @@
          * secure surfaces and secure displays.
          */
         public static final int FLAG_SECURE             = 0x00002000;
-
+        
         /** Window flag: a special mode where the layout parameters are used
          * to perform scaling of the surface when it is composited to the
          * screen. */
         public static final int FLAG_SCALED             = 0x00004000;
-
+        
         /** Window flag: intended for windows that will often be used when the user is
          * holding the screen against their face, it will aggressively filter the event
          * stream to prevent unintended presses in this situation that may not be
-         * desired for a particular window, when such an event stream is detected, the
+         * desired for a particular window, when such an event stream is detected, the 
          * application will receive a CANCEL motion event to indicate this so applications
-         * can handle this accordingly by taking no action on the event
+         * can handle this accordingly by taking no action on the event 
          * until the finger is released. */
         public static final int FLAG_IGNORE_CHEEK_PRESSES    = 0x00008000;
-
+        
         /** Window flag: a special option only for use in combination with
          * {@link #FLAG_LAYOUT_IN_SCREEN}.  When requesting layout in the
          * screen your window may appear on top of or behind screen decorations
@@ -690,7 +690,7 @@
          * content is not covered by screen decorations.  This flag is normally
          * set for you by Window as described in {@link Window#setFlags}.*/
         public static final int FLAG_LAYOUT_INSET_DECOR = 0x00010000;
-
+        
         /** Window flag: invert the state of {@link #FLAG_NOT_FOCUSABLE} with
          * respect to how this window interacts with the current method.  That
          * is, if FLAG_NOT_FOCUSABLE is set and this flag is set, then the
@@ -701,7 +701,7 @@
          * to use more space and cover the input method.
          */
         public static final int FLAG_ALT_FOCUSABLE_IM = 0x00020000;
-
+        
         /** Window flag: if you have set {@link #FLAG_NOT_TOUCH_MODAL}, you
          * can set this flag to receive a single special MotionEvent with
          * the action
@@ -711,7 +711,7 @@
          * first down as an ACTION_OUTSIDE.
          */
         public static final int FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000;
-
+        
         /** Window flag: special flag to let windows be shown when the screen
          * is locked. This will let application windows take precedence over
          * key guard or any other lock screens. Can be used with
@@ -741,13 +741,13 @@
          * {@link android.R.style#Theme_DeviceDefault_Wallpaper_NoTitleBar}.</p>
          */
         public static final int FLAG_SHOW_WALLPAPER = 0x00100000;
-
+        
         /** Window flag: when set as a window is being added or made
          * visible, once the window has been shown then the system will
          * poke the power manager's user activity (as if the user had woken
          * up the device) to turn the screen on. */
         public static final int FLAG_TURN_SCREEN_ON = 0x00200000;
-
+        
         /** Window flag: when set the window will cause the keyguard to
          * be dismissed, only if it is not a secure lock keyguard.  Because such
          * a keyguard is not needed for security, it will never re-appear if
@@ -761,7 +761,7 @@
          * also been set.
          */
         public static final int FLAG_DISMISS_KEYGUARD = 0x00400000;
-
+        
         /** Window flag: when set the window will accept for touch events
          * outside of its bounds to be sent to other windows that also
          * support split touch.  When this flag is not set, the first pointer
@@ -773,7 +773,7 @@
          * to be split across multiple windows.
          */
         public static final int FLAG_SPLIT_TOUCH = 0x00800000;
-
+        
         /**
          * <p>Indicates whether this window should be hardware accelerated.
          * Requesting hardware acceleration does not guarantee it will happen.</p>
@@ -916,7 +916,7 @@
 
         /**
          * Various behavioral options/flags.  Default is none.
-         *
+         * 
          * @see #FLAG_ALLOW_LOCK_WHILE_SCREEN_ON
          * @see #FLAG_DIM_BEHIND
          * @see #FLAG_NOT_FOCUSABLE
@@ -1014,10 +1014,10 @@
          * as if it was.
          * Like {@link #FLAG_HARDWARE_ACCELERATED} except for trusted system windows
          * that need hardware acceleration (e.g. LockScreen), where hardware acceleration
-         * is generally disabled. This flag must be specified in addition to
+         * is generally disabled. This flag must be specified in addition to 
          * {@link #FLAG_HARDWARE_ACCELERATED} to enable hardware acceleration for system
          * windows.
-         *
+         * 
          * @hide
          */
         public static final int PRIVATE_FLAG_FAKE_HARDWARE_ACCELERATED = 0x00000001;
@@ -1028,7 +1028,7 @@
          * If certain parts of the UI that really do want to use hardware
          * acceleration, this flag can be set to force it.  This is basically
          * for the lock screen.  Anyone else using it, you are probably wrong.
-         *
+         * 
          * @hide
          */
         public static final int PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED = 0x00000002;
@@ -1086,11 +1086,6 @@
          * {@hide} */
         public static final int PRIVATE_FLAG_INHERIT_TRANSLUCENT_DECOR = 0x00000200;
 
-        /** Window flag: the window is backed by a video plane, instead of a
-         * regular surface.
-         * {@hide} */
-        public static final int PRIVATE_FLAG_VIDEO_PLANE = 0x00000400;
-
         /**
          * Control flags that are private to the platform.
          * @hide
@@ -1105,9 +1100,9 @@
          * flags and returns true if the combination of the two corresponds
          * to a window that needs to be behind the input method so that the
          * user can type into it.
-         *
+         * 
          * @param flags The current window manager flags.
-         *
+         * 
          * @return Returns true if such a window should be behind/interact
          * with an input method, false if not.
          */
@@ -1119,63 +1114,63 @@
             }
             return false;
         }
-
+        
         /**
          * Mask for {@link #softInputMode} of the bits that determine the
          * desired visibility state of the soft input area for this window.
          */
         public static final int SOFT_INPUT_MASK_STATE = 0x0f;
-
+        
         /**
          * Visibility state for {@link #softInputMode}: no state has been specified.
          */
         public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0;
-
+        
         /**
          * Visibility state for {@link #softInputMode}: please don't change the state of
          * the soft input area.
          */
         public static final int SOFT_INPUT_STATE_UNCHANGED = 1;
-
+        
         /**
          * Visibility state for {@link #softInputMode}: please hide any soft input
          * area when normally appropriate (when the user is navigating
          * forward to your window).
          */
         public static final int SOFT_INPUT_STATE_HIDDEN = 2;
-
+        
         /**
          * Visibility state for {@link #softInputMode}: please always hide any
          * soft input area when this window receives focus.
          */
         public static final int SOFT_INPUT_STATE_ALWAYS_HIDDEN = 3;
-
+        
         /**
          * Visibility state for {@link #softInputMode}: please show the soft
          * input area when normally appropriate (when the user is navigating
          * forward to your window).
          */
         public static final int SOFT_INPUT_STATE_VISIBLE = 4;
-
+        
         /**
          * Visibility state for {@link #softInputMode}: please always make the
          * soft input area visible when this window receives input focus.
          */
         public static final int SOFT_INPUT_STATE_ALWAYS_VISIBLE = 5;
-
+        
         /**
          * Mask for {@link #softInputMode} of the bits that determine the
          * way that the window should be adjusted to accommodate the soft
          * input window.
          */
         public static final int SOFT_INPUT_MASK_ADJUST = 0xf0;
-
+        
         /** Adjustment option for {@link #softInputMode}: nothing specified.
          * The system will try to pick one or
          * the other depending on the contents of the window.
          */
         public static final int SOFT_INPUT_ADJUST_UNSPECIFIED = 0x00;
-
+        
         /** Adjustment option for {@link #softInputMode}: set to allow the
          * window to be resized when an input
          * method is shown, so that its contents are not covered by the input
@@ -1188,7 +1183,7 @@
          * not resize, but will stay fullscreen.
          */
         public static final int SOFT_INPUT_ADJUST_RESIZE = 0x10;
-
+        
         /** Adjustment option for {@link #softInputMode}: set to have a window
          * pan when an input method is
          * shown, so it doesn't need to deal with resizing but just panned
@@ -1198,7 +1193,7 @@
          * the other depending on the contents of the window.
          */
         public static final int SOFT_INPUT_ADJUST_PAN = 0x20;
-
+        
         /** Adjustment option for {@link #softInputMode}: set to have a window
          * not adjust for a shown input method.  The window will not be resized,
          * and it will not be panned to make its focus visible.
@@ -1217,7 +1212,7 @@
         /**
          * Desired operating mode for any soft input area.  May be any combination
          * of:
-         *
+         * 
          * <ul>
          * <li> One of the visibility states
          * {@link #SOFT_INPUT_STATE_UNSPECIFIED}, {@link #SOFT_INPUT_STATE_UNCHANGED},
@@ -1234,7 +1229,7 @@
          * {@link android.R.attr#windowSoftInputMode} attribute.</p>
          */
         public int softInputMode;
-
+        
         /**
          * Placement of window within the screen as per {@link Gravity}.  Both
          * {@link Gravity#apply(int, int, int, android.graphics.Rect, int, int,
@@ -1251,7 +1246,7 @@
          * @see Gravity
          */
         public int gravity;
-
+    
         /**
          * The horizontal margin, as a percentage of the container's width,
          * between the container and the widget.  See
@@ -1260,7 +1255,7 @@
          * field is added with {@link #x} to supply the <var>xAdj</var> parameter.
          */
         public float horizontalMargin;
-
+    
         /**
          * The vertical margin, as a percentage of the container's height,
          * between the container and the widget.  See
@@ -1269,26 +1264,26 @@
          * field is added with {@link #y} to supply the <var>yAdj</var> parameter.
          */
         public float verticalMargin;
-
+    
         /**
          * The desired bitmap format.  May be one of the constants in
          * {@link android.graphics.PixelFormat}.  Default is OPAQUE.
          */
         public int format;
-
+    
         /**
          * A style resource defining the animations to use for this window.
          * This must be a system resource; it can not be an application resource
          * because the window manager does not have access to applications.
          */
         public int windowAnimations;
-
+    
         /**
          * An alpha value to apply to this entire window.
          * An alpha of 1.0 means fully opaque and 0.0 means fully transparent
          */
         public float alpha = 1.0f;
-
+    
         /**
          * When {@link #FLAG_DIM_BEHIND} is set, this is the amount of dimming
          * to apply.  Range is from 1.0 for completely opaque to 0.0 for no
@@ -1316,7 +1311,7 @@
          * to the hightest value when this window is in front.
          */
         public static final float BRIGHTNESS_OVERRIDE_FULL = 1.0f;
-
+    
         /**
          * This can be used to override the user's preferred brightness of
          * the screen.  A value of less than 0, the default, means to use the
@@ -1324,7 +1319,7 @@
          * dark to full bright.
          */
         public float screenBrightness = BRIGHTNESS_OVERRIDE_NONE;
-
+        
         /**
          * This can be used to override the standard behavior of the button and
          * keyboard backlights.  A value of less than 0, the default, means to
@@ -1358,7 +1353,7 @@
          * opaque windows have the #FLAG_FULLSCREEN bit set and are not covered
          * by other windows. All other situations default to the
          * {@link #ROTATION_ANIMATION_ROTATE} behavior.
-         *
+         * 
          * @see #ROTATION_ANIMATION_ROTATE
          * @see #ROTATION_ANIMATION_CROSSFADE
          * @see #ROTATION_ANIMATION_JUMPCUT
@@ -1370,18 +1365,18 @@
          * you.
          */
         public IBinder token = null;
-
+    
         /**
          * Name of the package owning this window.
          */
         public String packageName = null;
-
+        
         /**
          * Specific orientation value for a window.
          * May be any of the same values allowed
-         * for {@link android.content.pm.ActivityInfo#screenOrientation}.
-         * If not set, a default value of
-         * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED}
+         * for {@link android.content.pm.ActivityInfo#screenOrientation}. 
+         * If not set, a default value of 
+         * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED} 
          * will be used.
          */
         public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -1403,7 +1398,7 @@
 
         /**
          * Get callbacks about the system ui visibility changing.
-         *
+         * 
          * TODO: Maybe there should be a bitfield of optional callbacks that we need.
          *
          * @hide
@@ -1469,34 +1464,34 @@
             type = TYPE_APPLICATION;
             format = PixelFormat.OPAQUE;
         }
-
+        
         public LayoutParams(int _type) {
             super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
             type = _type;
             format = PixelFormat.OPAQUE;
         }
-
+    
         public LayoutParams(int _type, int _flags) {
             super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
             type = _type;
             flags = _flags;
             format = PixelFormat.OPAQUE;
         }
-
+    
         public LayoutParams(int _type, int _flags, int _format) {
             super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
             type = _type;
             flags = _flags;
             format = _format;
         }
-
+        
         public LayoutParams(int w, int h, int _type, int _flags, int _format) {
             super(w, h);
             type = _type;
             flags = _flags;
             format = _format;
         }
-
+        
         public LayoutParams(int w, int h, int xpos, int ypos, int _type,
                 int _flags, int _format) {
             super(w, h);
@@ -1506,18 +1501,18 @@
             flags = _flags;
             format = _format;
         }
-
+    
         public final void setTitle(CharSequence title) {
             if (null == title)
                 title = "";
-
+    
             mTitle = TextUtils.stringOrSpannedString(title);
         }
-
+    
         public final CharSequence getTitle() {
             return mTitle;
         }
-
+    
         public int describeContents() {
             return 0;
         }
@@ -1551,19 +1546,19 @@
             out.writeInt(inputFeatures);
             out.writeLong(userActivityTimeout);
         }
-
+        
         public static final Parcelable.Creator<LayoutParams> CREATOR
                     = new Parcelable.Creator<LayoutParams>() {
             public LayoutParams createFromParcel(Parcel in) {
                 return new LayoutParams(in);
             }
-
+    
             public LayoutParams[] newArray(int size) {
                 return new LayoutParams[size];
             }
         };
-
-
+    
+    
         public LayoutParams(Parcel in) {
             width = in.readInt();
             height = in.readInt();
@@ -1593,7 +1588,7 @@
             inputFeatures = in.readInt();
             userActivityTimeout = in.readLong();
         }
-
+    
         @SuppressWarnings({"PointlessBitwiseExpression"})
         public static final int LAYOUT_CHANGED = 1<<0;
         public static final int TYPE_CHANGED = 1<<1;
@@ -1627,10 +1622,10 @@
 
         // internal buffer to backup/restore parameters under compatibility mode.
         private int[] mCompatibilityParamsBackup = null;
-
+        
         public final int copyFrom(LayoutParams o) {
             int changes = 0;
-
+    
             if (width != o.width) {
                 width = o.width;
                 changes |= LAYOUT_CHANGED;
@@ -1729,7 +1724,7 @@
                 rotationAnimation = o.rotationAnimation;
                 changes |= ROTATION_ANIMATION_CHANGED;
             }
-
+    
             if (screenOrientation != o.screenOrientation) {
                 screenOrientation = o.screenOrientation;
                 changes |= SCREEN_ORIENTATION_CHANGED;
@@ -1759,7 +1754,7 @@
 
             return changes;
         }
-
+    
         @Override
         public String debug(String output) {
             output += "Contents of " + this + ":";
@@ -1770,7 +1765,7 @@
             Log.d("Debug", "WindowManager.LayoutParams={title=" + mTitle + "}");
             return "";
         }
-
+    
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder(256);
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 53d9e28..333e631 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -74,7 +74,7 @@
 import android.util.Log;
 import android.view.ActionMode;
 import android.view.ActionMode.Callback;
-import android.view.DisplayList;
+import android.view.RenderNode;
 import android.view.DragEvent;
 import android.view.Gravity;
 import android.view.HardwareCanvas;
@@ -138,11 +138,11 @@
     InputMethodState mInputMethodState;
 
     private static class TextDisplayList {
-        DisplayList displayList;
+        RenderNode displayList;
         boolean isDirty;
         public TextDisplayList(String name) {
             isDirty = true;
-            displayList = DisplayList.create(name);
+            displayList = RenderNode.create(name);
         }
         boolean needsRecord() { return isDirty || !displayList.isValid(); }
     }
@@ -289,7 +289,7 @@
     private void destroyDisplayListsData() {
         if (mTextDisplayLists != null) {
             for (int i = 0; i < mTextDisplayLists.length; i++) {
-                DisplayList displayList = mTextDisplayLists[i] != null
+                RenderNode displayList = mTextDisplayLists[i] != null
                         ? mTextDisplayLists[i].displayList : null;
                 if (displayList != null && displayList.isValid()) {
                     displayList.destroyDisplayListData();
@@ -1371,7 +1371,7 @@
                 }
 
                 final boolean blockDisplayListIsInvalid = mTextDisplayLists[blockIndex].needsRecord();
-                DisplayList blockDisplayList = mTextDisplayLists[blockIndex].displayList;
+                RenderNode blockDisplayList = mTextDisplayLists[blockIndex].displayList;
                 if (i >= indexFirstChangedBlock || blockDisplayListIsInvalid) {
                     final int blockBeginLine = endOfPreviousBlock + 1;
                     final int top = layout.getLineTop(blockBeginLine);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 10fd2f0..26d7f5f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -270,7 +270,6 @@
 
     boolean mWifiOn;
     StopwatchTimer mWifiOnTimer;
-    int mWifiOnUid = -1;
 
     boolean mGlobalWifiRunning;
     StopwatchTimer mGlobalWifiRunningTimer;
@@ -2912,10 +2911,6 @@
             mWifiOn = false;
             mWifiOnTimer.stopRunningLocked(elapsedRealtime);
         }
-        if (mWifiOnUid >= 0) {
-            getUidStatsLocked(mWifiOnUid).noteWifiStoppedLocked(elapsedRealtime);
-            mWifiOnUid = -1;
-        }
     }
 
     public void noteAudioOnLocked(int uid) {
@@ -5973,7 +5968,7 @@
 
                     if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
 
-                    final Uid u = getUidStatsLocked(entry.uid);
+                    final Uid u = getUidStatsLocked(mapUid(entry.uid));
                     u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
                             entry.rxPackets);
                     u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
@@ -6040,7 +6035,7 @@
 
                     if (entry.rxBytes == 0 || entry.txBytes == 0) continue;
 
-                    final Uid u = getUidStatsLocked(entry.uid);
+                    final Uid u = getUidStatsLocked(mapUid(entry.uid));
                     u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
                             entry.rxPackets);
                     u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
@@ -6240,6 +6235,7 @@
      * if needed.
      */
     public Uid.Proc getProcessStatsLocked(int uid, String name) {
+        uid = mapUid(uid);
         Uid u = getUidStatsLocked(uid);
         return u.getProcessStatsLocked(name);
     }
@@ -6249,6 +6245,7 @@
      * if needed.
      */
     public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
+        uid = mapUid(uid);
         Uid u = getUidStatsLocked(uid);
         return u.getPackageStatsLocked(pkg);
     }
@@ -6258,6 +6255,7 @@
      * if needed.
      */
     public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
+        uid = mapUid(uid);
         Uid u = getUidStatsLocked(uid);
         return u.getServiceStatsLocked(pkg, name);
     }
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 97ea7d8..4734712 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -41,11 +41,11 @@
             out List<IBinder> notificationKeys, out List<StatusBarNotification> notifications,
             out int[] switches, out List<IBinder> binders);
     void onPanelRevealed();
-    void onNotificationClick(String pkg, String tag, int id);
+    void onNotificationClick(String pkg, String tag, int id, int userId);
     void onNotificationError(String pkg, String tag, int id,
-            int uid, int initialPid, String message);
-    void onClearAllNotifications();
-    void onNotificationClear(String pkg, String tag, int id);
+            int uid, int initialPid, String message, int userId);
+    void onClearAllNotifications(int userId);
+    void onNotificationClear(String pkg, String tag, int id, int userId);
     void setSystemUiVisibility(int vis, int mask);
     void setHardKeyboardEnabled(boolean enabled);
     void toggleRecentApps();
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 26235f1..71550be 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -336,7 +336,12 @@
         final long deleteBefore = currentTimeMillis - mDeleteAgeMillis;
 
         final FileInfo info = new FileInfo(mPrefix);
-        for (String name : mBasePath.list()) {
+        String[] baseFiles = mBasePath.list();
+        if (baseFiles == null) {
+            return;
+        }
+
+        for (String name : baseFiles) {
             if (!info.parse(name)) continue;
 
             if (info.isActive()) {
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index e51345c..45ca7fc 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -75,7 +75,7 @@
     boolean switchToNextInputMethod(in IBinder token, boolean onlyCurrentIme);
     boolean shouldOfferSwitchingToNextInputMethod(in IBinder token);
     boolean setInputMethodEnabled(String id, boolean enabled);
-    oneway void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
+    void setAdditionalInputMethodSubtypes(String id, in InputMethodSubtype[] subtypes);
     int getInputMethodWindowVisibleHeight();
     oneway void notifyTextCommitted();
 }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index a09c314..51c5a86 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -42,7 +42,6 @@
 	android_database_SQLiteDebug.cpp \
 	android_emoji_EmojiFactory.cpp \
 	android_view_DisplayEventReceiver.cpp \
-	android_view_DisplayList.cpp \
 	android_view_Surface.cpp \
 	android_view_SurfaceControl.cpp \
 	android_view_SurfaceSession.cpp \
@@ -61,6 +60,7 @@
 	android_view_ThreadedRenderer.cpp \
 	android_view_MotionEvent.cpp \
 	android_view_PointerIcon.cpp \
+	android_view_RenderNode.cpp \
 	android_view_VelocityTracker.cpp \
 	android_text_AndroidCharacter.cpp \
 	android_text_AndroidBidi.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 94c3f44..9a7a5f9 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -119,7 +119,7 @@
 extern int register_android_graphics_Xfermode(JNIEnv* env);
 extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
 extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
-extern int register_android_view_DisplayList(JNIEnv* env);
+extern int register_android_view_RenderNode(JNIEnv* env);
 extern int register_android_view_GraphicBuffer(JNIEnv* env);
 extern int register_android_view_GLES20Canvas(JNIEnv* env);
 extern int register_android_view_GLRenderer(JNIEnv* env);
@@ -435,6 +435,14 @@
  * Various arguments, most determined by system properties, are passed in.
  * The "mOptions" vector is updated.
  *
+ * CAUTION: when adding options in here, be careful not to put the
+ * char buffer inside a nested scope.  Adding the buffer to the
+ * options using mOptions.add() does not copy the buffer, so if the
+ * buffer goes out of scope the option may be overwritten.  It's best
+ * to put the buffer at the top of the function so that it is more
+ * unlikely that someone will surround it in a scope at a later time
+ * and thus introduce a bug.
+ *
  * Returns 0 on success.
  */
 int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
@@ -469,7 +477,15 @@
       kEMIntFast,
       kEMJitCompiler,
     } executionMode = kEMDefault;
-
+    char profile_period[sizeof("-Xprofile-period:") + PROPERTY_VALUE_MAX];
+    char profile_duration[sizeof("-Xprofile-duration:") + PROPERTY_VALUE_MAX];
+    char profile_interval[sizeof("-Xprofile-interval:") + PROPERTY_VALUE_MAX];
+    char profile_backoff[sizeof("-Xprofile-backoff:") + PROPERTY_VALUE_MAX];
+    char langOption[sizeof("-Duser.language=") + 3];
+    char regionOption[sizeof("-Duser.region=") + 3];
+    char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:") + sizeof(propBuf)];
+    char jitOpBuf[sizeof("-Xjitop:") + PROPERTY_VALUE_MAX];
+    char jitMethodBuf[sizeof("-Xjitmethod:") + PROPERTY_VALUE_MAX];
 
     property_get("dalvik.vm.checkjni", propBuf, "");
     if (strcmp(propBuf, "true") == 0) {
@@ -670,7 +686,6 @@
         //mOptions.add(opt);
     }
 
-    char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:") + sizeof(propBuf)];
     property_get("dalvik.vm.lockprof.threshold", propBuf, "");
     if (strlen(propBuf) > 0) {
       strcpy(lockProfThresholdBuf, "-Xlockprofthreshold:");
@@ -680,7 +695,6 @@
     }
 
     /* Force interpreter-only mode for selected opcodes. Eg "1-0a,3c,f1-ff" */
-    char jitOpBuf[sizeof("-Xjitop:") + PROPERTY_VALUE_MAX];
     property_get("dalvik.vm.jit.op", propBuf, "");
     if (strlen(propBuf) > 0) {
         strcpy(jitOpBuf, "-Xjitop:");
@@ -690,7 +704,6 @@
     }
 
     /* Force interpreter-only mode for selected methods */
-    char jitMethodBuf[sizeof("-Xjitmethod:") + PROPERTY_VALUE_MAX];
     property_get("dalvik.vm.jit.method", propBuf, "");
     if (strlen(propBuf) > 0) {
         strcpy(jitMethodBuf, "-Xjitmethod:");
@@ -770,8 +783,6 @@
 
     /* Set the properties for locale */
     {
-        char langOption[sizeof("-Duser.language=") + 3];
-        char regionOption[sizeof("-Duser.region=") + 3];
         strcpy(langOption, "-Duser.language=");
         strcpy(regionOption, "-Duser.region=");
         readLocale(langOption, regionOption);
@@ -786,35 +797,30 @@
      * Set profiler options
      */
     if (libart) {
-      char period[sizeof("-Xprofile-period:") + PROPERTY_VALUE_MAX];
-      char duration[sizeof("-Xprofile-duration:") + PROPERTY_VALUE_MAX];
-      char interval[sizeof("-Xprofile-interval:") + PROPERTY_VALUE_MAX];
-      char backoff[sizeof("-Xprofile-backoff:") + PROPERTY_VALUE_MAX];
-
       // Number of seconds during profile runs.
-      strcpy(period, "-Xprofile-period:");
-      property_get("dalvik.vm.profile.period_secs", period+17, "10");
-      opt.optionString = period;
+      strcpy(profile_period, "-Xprofile-period:");
+      property_get("dalvik.vm.profile.period_secs", profile_period+17, "10");
+      opt.optionString = profile_period;
       mOptions.add(opt);
 
       // Length of each profile run (seconds).
-      strcpy(duration, "-Xprofile-duration:");
-      property_get("dalvik.vm.profile.duration_secs", duration+19, "30");
-      opt.optionString = duration;
+      strcpy(profile_duration, "-Xprofile-duration:");
+      property_get("dalvik.vm.profile.duration_secs", profile_duration+19, "30");
+      opt.optionString = profile_duration;
       mOptions.add(opt);
 
 
       // Polling interval during profile run (microseconds).
-      strcpy(interval, "-Xprofile-interval:");
-      property_get("dalvik.vm.profile.interval_us", interval+19, "10000");
-      opt.optionString = interval;
+      strcpy(profile_interval, "-Xprofile-interval:");
+      property_get("dalvik.vm.profile.interval_us", profile_interval+19, "10000");
+      opt.optionString = profile_interval;
       mOptions.add(opt);
 
       // Coefficient for period backoff.  The the period is multiplied
       // by this value after each profile run.
-      strcpy(backoff, "-Xprofile-backoff:");
-      property_get("dalvik.vm.profile.backoff_coeff", backoff+18, "2.0");
-      opt.optionString = backoff;
+      strcpy(profile_backoff, "-Xprofile-backoff:");
+      property_get("dalvik.vm.profile.backoff_coeff", profile_backoff+18, "2.0");
+      opt.optionString = profile_backoff;
       mOptions.add(opt);
     }
 
@@ -1173,7 +1179,7 @@
     REG_JNI(register_android_nio_utils),
     REG_JNI(register_android_graphics_Graphics),
     REG_JNI(register_android_view_DisplayEventReceiver),
-    REG_JNI(register_android_view_DisplayList),
+    REG_JNI(register_android_view_RenderNode),
     REG_JNI(register_android_view_GraphicBuffer),
     REG_JNI(register_android_view_GLES20Canvas),
     REG_JNI(register_android_view_GLRenderer),
diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
index da8f083..2cb1015 100644
--- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
+++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp
@@ -63,9 +63,14 @@
         size_t bytesRead = 0;
         // read the bytes
         do {
-            size_t requested = size;
-            if (requested > fCapacity)
+            jint requested = 0;
+            if (size > static_cast<size_t>(fCapacity)) {
                 requested = fCapacity;
+            } else {
+                // This is safe because requested is clamped to (jint)
+                // fCapacity.
+                requested = static_cast<jint>(size);
+            }
 
             jint n = env->CallIntMethod(fJavaInputStream,
                                         gInputStream_readMethodID, fJavaByteArray, 0, requested);
@@ -120,7 +125,7 @@
     JNIEnv*     fEnv;
     jobject     fJavaInputStream;   // the caller owns this object
     jbyteArray  fJavaByteArray;     // the caller owns this object
-    size_t      fCapacity;
+    jint        fCapacity;
     size_t      fBytesRead;
     bool        fIsAtEnd;
 };
@@ -174,14 +179,18 @@
         fCapacity = env->GetArrayLength(storage);
     }
 
-	virtual bool write(const void* buffer, size_t size) {
+    virtual bool write(const void* buffer, size_t size) {
         JNIEnv* env = fEnv;
         jbyteArray storage = fJavaByteArray;
 
         while (size > 0) {
-            size_t requested = size;
-            if (requested > fCapacity) {
+            jint requested = 0;
+            if (size > static_cast<size_t>(fCapacity)) {
                 requested = fCapacity;
+            } else {
+                // This is safe because requested is clamped to (jint)
+                // fCapacity.
+                requested = static_cast<jint>(size);
             }
 
             env->SetByteArrayRegion(storage, 0, requested,
@@ -216,7 +225,7 @@
     JNIEnv*     fEnv;
     jobject     fJavaOutputStream;  // the caller owns this object
     jbyteArray  fJavaByteArray;     // the caller owns this object
-    size_t      fCapacity;
+    jint        fCapacity;
 };
 
 SkWStream* CreateJavaOutputStreamAdaptor(JNIEnv* env, jobject stream,
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 189fe47..51990d5 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -615,7 +615,7 @@
                 return 0;
             }
         }
-        jfloat advancesArray[count];
+        jfloat* advancesArray = new jfloat[count];
         jfloat totalAdvance = 0;
 
         TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags,
@@ -624,6 +624,7 @@
         if (advances != NULL) {
             env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
         }
+        delete [] advancesArray;
         return totalAdvance;
     }
 
diff --git a/core/jni/android_hardware_camera2_CameraMetadata.cpp b/core/jni/android_hardware_camera2_CameraMetadata.cpp
index 3c7da1e..957f95c 100644
--- a/core/jni/android_hardware_camera2_CameraMetadata.cpp
+++ b/core/jni/android_hardware_camera2_CameraMetadata.cpp
@@ -19,13 +19,18 @@
 // #define LOG_NNDEBUG 0
 #define LOG_TAG "CameraMetadata-JNI"
 #include <utils/Log.h>
+#include <utils/RefBase.h>
+#include <string.h>
 
 #include "jni.h"
 #include "JNIHelp.h"
 #include "android_os_Parcel.h"
 #include "android_runtime/AndroidRuntime.h"
 
+#include <binder/IServiceManager.h>
 #include <camera/CameraMetadata.h>
+#include <camera/ICameraService.h>
+#include <camera/VendorTagDescriptor.h>
 #include <nativehelper/ScopedUtfChars.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 
@@ -112,6 +117,7 @@
 static void CameraMetadata_classInit(JNIEnv *env, jobject thiz);
 static jint CameraMetadata_getTagFromKey(JNIEnv *env, jobject thiz, jstring keyName);
 static jint CameraMetadata_getTypeFromTag(JNIEnv *env, jobject thiz, jint tag);
+static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz);
 
 // Less safe access to native pointer. Does NOT throw any Java exceptions if NULL.
 static CameraMetadata* CameraMetadata_getPointerNoThrow(JNIEnv *env, jobject thiz) {
@@ -372,6 +378,9 @@
   { "nativeGetTypeFromTag",
     "(I)I",
     (void *)CameraMetadata_getTypeFromTag },
+  { "nativeSetupGlobalVendorTagDescriptor",
+    "()I",
+    (void*)CameraMetadata_setupGlobalVendorTagDescriptor },
 // instance methods
   { "nativeAllocate",
     "()J",
@@ -556,4 +565,34 @@
     return tagType;
 }
 
+static jint CameraMetadata_setupGlobalVendorTagDescriptor(JNIEnv *env, jobject thiz) {
+    const String16 NAME("media.camera");
+    sp<ICameraService> cameraService;
+    status_t err = getService(NAME, /*out*/&cameraService);
+
+    if (err != OK) {
+        ALOGE("%s: Failed to get camera service, received error %s (%d)", __FUNCTION__,
+                strerror(-err), err);
+        return err;
+    }
+
+    sp<VendorTagDescriptor> desc;
+    err = cameraService->getCameraVendorTagDescriptor(/*out*/desc);
+
+    if (err == -EOPNOTSUPP) {
+        ALOGW("%s: Camera HAL too old; does not support vendor tags", __FUNCTION__);
+        VendorTagDescriptor::clearGlobalVendorTagDescriptor();
+
+        return OK;
+    } else if (err != OK) {
+        ALOGE("%s: Failed to setup vendor tag descriptors, received error %s (%d)",
+                __FUNCTION__, strerror(-err), err);
+        return err;
+    }
+
+    err = VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
+
+    return err;
+}
+
 } // extern "C"
diff --git a/core/jni/android_view_DisplayList.cpp b/core/jni/android_view_DisplayList.cpp
deleted file mode 100644
index c8952c1..0000000
--- a/core/jni/android_view_DisplayList.cpp
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#define LOG_TAG "OpenGLRenderer"
-
-#include <EGL/egl.h>
-
-#include "jni.h"
-#include "GraphicsJNI.h"
-#include <nativehelper/JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-
-#include <DisplayList.h>
-#include <DisplayListRenderer.h>
-
-namespace android {
-
-using namespace uirenderer;
-
-/**
- * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
- *       devices. This means all the logic must be compiled only when the
- *       preprocessor variable USE_OPENGL_RENDERER is defined.
- */
-#ifdef USE_OPENGL_RENDERER
-
-// ----------------------------------------------------------------------------
-// DisplayList view properties
-// ----------------------------------------------------------------------------
-
-static void android_view_DisplayList_setDisplayListName(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jstring name) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    if (name != NULL) {
-        const char* textArray = env->GetStringUTFChars(name, NULL);
-        displayList->setName(textArray);
-        env->ReleaseStringUTFChars(name, textArray);
-    }
-}
-
-static void android_view_DisplayList_output(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->output();
-}
-
-static jlong android_view_DisplayList_create(JNIEnv* env, jobject clazz) {
-    DisplayList* displayList = new DisplayList();
-    return reinterpret_cast<jlong>(displayList);
-}
-
-static void android_view_DisplayList_destroyDisplayList(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    DisplayList::destroyDisplayListDeferred(displayList);
-}
-
-// ----------------------------------------------------------------------------
-// DisplayList view properties
-// ----------------------------------------------------------------------------
-
-static void android_view_DisplayList_setCaching(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jboolean caching) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setCaching(caching);
-}
-
-static void android_view_DisplayList_setStaticMatrix(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jlong matrixPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
-    displayList->setStaticMatrix(matrix);
-}
-
-static void android_view_DisplayList_setAnimationMatrix(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jlong matrixPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
-    displayList->setAnimationMatrix(matrix);
-}
-
-static void android_view_DisplayList_setClipToBounds(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jboolean clipToBounds) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setClipToBounds(clipToBounds);
-}
-
-static void android_view_DisplayList_setIsolatedZVolume(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jboolean shouldIsolate) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setIsolatedZVolume(shouldIsolate);
-}
-
-static void android_view_DisplayList_setProjectBackwards(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jboolean shouldProject) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setProjectBackwards(shouldProject);
-}
-
-static void android_view_DisplayList_setProjectionReceiver(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jboolean shouldRecieve) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setProjectionReceiver(shouldRecieve);
-}
-
-static void android_view_DisplayList_setOutline(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jlong outlinePathPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    SkPath* outline = reinterpret_cast<SkPath*>(outlinePathPtr);
-    displayList->setOutline(outline);
-}
-
-static void android_view_DisplayList_setClipToOutline(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jboolean clipToOutline) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setClipToOutline(clipToOutline);
-}
-
-static void android_view_DisplayList_setCastsShadow(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jboolean castsShadow) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setCastsShadow(castsShadow);
-}
-
-static void android_view_DisplayList_setUsesGlobalCamera(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, jboolean usesGlobalCamera) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setUsesGlobalCamera(usesGlobalCamera);
-}
-
-static void android_view_DisplayList_setAlpha(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float alpha) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setAlpha(alpha);
-}
-
-static void android_view_DisplayList_setHasOverlappingRendering(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, bool hasOverlappingRendering) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setHasOverlappingRendering(hasOverlappingRendering);
-}
-
-static void android_view_DisplayList_setTranslationX(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float tx) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setTranslationX(tx);
-}
-
-static void android_view_DisplayList_setTranslationY(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float ty) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setTranslationY(ty);
-}
-
-static void android_view_DisplayList_setTranslationZ(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float tz) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setTranslationZ(tz);
-}
-
-static void android_view_DisplayList_setRotation(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float rotation) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setRotation(rotation);
-}
-
-static void android_view_DisplayList_setRotationX(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float rx) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setRotationX(rx);
-}
-
-static void android_view_DisplayList_setRotationY(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float ry) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setRotationY(ry);
-}
-
-static void android_view_DisplayList_setScaleX(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float sx) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setScaleX(sx);
-}
-
-static void android_view_DisplayList_setScaleY(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float sy) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setScaleY(sy);
-}
-
-static void android_view_DisplayList_setTransformationInfo(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float alpha,
-        float translationX, float translationY, float translationZ,
-        float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setAlpha(alpha);
-    displayList->setTranslationX(translationX);
-    displayList->setTranslationY(translationY);
-    displayList->setTranslationZ(translationZ);
-    displayList->setRotation(rotation);
-    displayList->setRotationX(rotationX);
-    displayList->setRotationY(rotationY);
-    displayList->setScaleX(scaleX);
-    displayList->setScaleY(scaleY);
-}
-
-static void android_view_DisplayList_setPivotX(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float px) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setPivotX(px);
-}
-
-static void android_view_DisplayList_setPivotY(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float py) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setPivotY(py);
-}
-
-static void android_view_DisplayList_setCameraDistance(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float distance) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setCameraDistance(distance);
-}
-
-static void android_view_DisplayList_setLeft(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, int left) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setLeft(left);
-}
-
-static void android_view_DisplayList_setTop(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, int top) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setTop(top);
-}
-
-static void android_view_DisplayList_setRight(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, int right) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setRight(right);
-}
-
-static void android_view_DisplayList_setBottom(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, int bottom) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setBottom(bottom);
-}
-
-static void android_view_DisplayList_setLeftTopRightBottom(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, int left, int top,
-        int right, int bottom) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->setLeftTopRightBottom(left, top, right, bottom);
-}
-
-static void android_view_DisplayList_offsetLeftAndRight(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float offset) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->offsetLeftRight(offset);
-}
-
-static void android_view_DisplayList_offsetTopAndBottom(JNIEnv* env,
-        jobject clazz, jlong displayListPtr, float offset) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    displayList->offsetTopBottom(offset);
-}
-
-static jboolean android_view_DisplayList_hasOverlappingRendering(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->hasOverlappingRendering();
-}
-
-static jfloat android_view_DisplayList_getAlpha(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getAlpha();
-}
-
-static jfloat android_view_DisplayList_getLeft(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getLeft();
-}
-
-static jfloat android_view_DisplayList_getTop(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getTop();
-}
-
-static jfloat android_view_DisplayList_getRight(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getRight();
-}
-
-static jfloat android_view_DisplayList_getBottom(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getBottom();
-}
-
-static jfloat android_view_DisplayList_getCameraDistance(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getCameraDistance();
-}
-
-static jfloat android_view_DisplayList_getScaleX(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getScaleX();
-}
-
-static jfloat android_view_DisplayList_getScaleY(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getScaleY();
-}
-
-static jfloat android_view_DisplayList_getTranslationX(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getTranslationX();
-}
-
-static jfloat android_view_DisplayList_getTranslationY(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getTranslationY();
-}
-
-static jfloat android_view_DisplayList_getRotation(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getRotation();
-}
-
-static jfloat android_view_DisplayList_getRotationX(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getRotationX();
-}
-
-static jfloat android_view_DisplayList_getRotationY(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getRotationY();
-}
-
-static jfloat android_view_DisplayList_getPivotX(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getPivotX();
-}
-
-static jfloat android_view_DisplayList_getPivotY(JNIEnv* env,
-        jobject clazz, jlong displayListPtr) {
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
-    return displayList->getPivotY();
-}
-
-#endif // USE_OPENGL_RENDERER
-
-// ----------------------------------------------------------------------------
-// JNI Glue
-// ----------------------------------------------------------------------------
-
-const char* const kClassPathName = "android/view/DisplayList";
-
-static JNINativeMethod gMethods[] = {
-#ifdef USE_OPENGL_RENDERER
-    { "nCreate",               "()J",    (void*) android_view_DisplayList_create },
-    { "nDestroyDisplayList",   "(J)V",   (void*) android_view_DisplayList_destroyDisplayList },
-    { "nSetDisplayListName",   "(JLjava/lang/String;)V",
-            (void*) android_view_DisplayList_setDisplayListName },
-    { "nOutput",               "(J)V",  (void*) android_view_DisplayList_output },
-
-    { "nSetCaching",           "(JZ)V",  (void*) android_view_DisplayList_setCaching },
-    { "nSetStaticMatrix",      "(JJ)V",  (void*) android_view_DisplayList_setStaticMatrix },
-    { "nSetAnimationMatrix",   "(JJ)V",  (void*) android_view_DisplayList_setAnimationMatrix },
-    { "nSetClipToBounds",      "(JZ)V",  (void*) android_view_DisplayList_setClipToBounds },
-    { "nSetIsolatedZVolume",   "(JZ)V",  (void*) android_view_DisplayList_setIsolatedZVolume },
-    { "nSetProjectBackwards",  "(JZ)V",  (void*) android_view_DisplayList_setProjectBackwards },
-    { "nSetProjectionReceiver","(JZ)V",  (void*) android_view_DisplayList_setProjectionReceiver },
-    { "nSetOutline",           "(JJ)V",  (void*) android_view_DisplayList_setOutline },
-    { "nSetClipToOutline",     "(JZ)V",  (void*) android_view_DisplayList_setClipToOutline },
-    { "nSetCastsShadow",       "(JZ)V",  (void*) android_view_DisplayList_setCastsShadow },
-    { "nSetUsesGlobalCamera",  "(JZ)V",  (void*) android_view_DisplayList_setUsesGlobalCamera },
-    { "nSetAlpha",             "(JF)V",  (void*) android_view_DisplayList_setAlpha },
-    { "nSetHasOverlappingRendering", "(JZ)V",
-            (void*) android_view_DisplayList_setHasOverlappingRendering },
-    { "nSetTranslationX",      "(JF)V",  (void*) android_view_DisplayList_setTranslationX },
-    { "nSetTranslationY",      "(JF)V",  (void*) android_view_DisplayList_setTranslationY },
-    { "nSetTranslationZ",      "(JF)V",  (void*) android_view_DisplayList_setTranslationZ },
-    { "nSetRotation",          "(JF)V",  (void*) android_view_DisplayList_setRotation },
-    { "nSetRotationX",         "(JF)V",  (void*) android_view_DisplayList_setRotationX },
-    { "nSetRotationY",         "(JF)V",  (void*) android_view_DisplayList_setRotationY },
-    { "nSetScaleX",            "(JF)V",  (void*) android_view_DisplayList_setScaleX },
-    { "nSetScaleY",            "(JF)V",  (void*) android_view_DisplayList_setScaleY },
-    { "nSetTransformationInfo","(JFFFFFFFFF)V",
-            (void*) android_view_DisplayList_setTransformationInfo },
-    { "nSetPivotX",            "(JF)V",  (void*) android_view_DisplayList_setPivotX },
-    { "nSetPivotY",            "(JF)V",  (void*) android_view_DisplayList_setPivotY },
-    { "nSetCameraDistance",    "(JF)V",  (void*) android_view_DisplayList_setCameraDistance },
-    { "nSetLeft",              "(JI)V",  (void*) android_view_DisplayList_setLeft },
-    { "nSetTop",               "(JI)V",  (void*) android_view_DisplayList_setTop },
-    { "nSetRight",             "(JI)V",  (void*) android_view_DisplayList_setRight },
-    { "nSetBottom",            "(JI)V",  (void*) android_view_DisplayList_setBottom },
-    { "nSetLeftTopRightBottom","(JIIII)V", (void*) android_view_DisplayList_setLeftTopRightBottom },
-    { "nOffsetLeftAndRight",   "(JF)V",  (void*) android_view_DisplayList_offsetLeftAndRight },
-    { "nOffsetTopAndBottom",   "(JF)V",  (void*) android_view_DisplayList_offsetTopAndBottom },
-
-    { "nHasOverlappingRendering", "(J)Z",  (void*) android_view_DisplayList_hasOverlappingRendering },
-    { "nGetAlpha",                "(J)F",  (void*) android_view_DisplayList_getAlpha },
-    { "nGetLeft",                 "(J)F",  (void*) android_view_DisplayList_getLeft },
-    { "nGetTop",                  "(J)F",  (void*) android_view_DisplayList_getTop },
-    { "nGetRight",                "(J)F",  (void*) android_view_DisplayList_getRight },
-    { "nGetBottom",               "(J)F",  (void*) android_view_DisplayList_getBottom },
-    { "nGetCameraDistance",       "(J)F",  (void*) android_view_DisplayList_getCameraDistance },
-    { "nGetScaleX",               "(J)F",  (void*) android_view_DisplayList_getScaleX },
-    { "nGetScaleY",               "(J)F",  (void*) android_view_DisplayList_getScaleY },
-    { "nGetTranslationX",         "(J)F",  (void*) android_view_DisplayList_getTranslationX },
-    { "nGetTranslationY",         "(J)F",  (void*) android_view_DisplayList_getTranslationY },
-    { "nGetRotation",             "(J)F",  (void*) android_view_DisplayList_getRotation },
-    { "nGetRotationX",            "(J)F",  (void*) android_view_DisplayList_getRotationX },
-    { "nGetRotationY",            "(J)F",  (void*) android_view_DisplayList_getRotationY },
-    { "nGetPivotX",               "(J)F",  (void*) android_view_DisplayList_getPivotX },
-    { "nGetPivotY",               "(J)F",  (void*) android_view_DisplayList_getPivotY },
-#endif
-};
-
-#ifdef USE_OPENGL_RENDERER
-    #define FIND_CLASS(var, className) \
-            var = env->FindClass(className); \
-            LOG_FATAL_IF(! var, "Unable to find class " className);
-
-    #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
-            var = env->GetMethodID(clazz, methodName, methodDescriptor); \
-            LOG_FATAL_IF(! var, "Unable to find method " methodName);
-#else
-    #define FIND_CLASS(var, className)
-    #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor)
-#endif
-
-int register_android_view_DisplayList(JNIEnv* env) {
-    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
-}
-
-};
-
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index a4e6679..aa6a035 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -879,7 +879,7 @@
         jobject clazz, jlong rendererPtr, jlong displayListPtr,
         jobject dirty, jint flags) {
     OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
     android::uirenderer::Rect bounds;
     status_t status = renderer->drawDisplayList(displayList, bounds, flags);
     if (status != DrawGlInfo::kStatusDone && dirty != NULL) {
@@ -975,7 +975,7 @@
 android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
 #ifdef USE_OPENGL_RENDERER
     int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
-    android::uirenderer::DisplayList::outputLogBuffer(fd);
+    android::uirenderer::RenderNode::outputLogBuffer(fd);
 #endif // USE_OPENGL_RENDERER
 }
 
diff --git a/core/jni/android_view_GLRenderer.cpp b/core/jni/android_view_GLRenderer.cpp
index b7e795e..228a92e 100644
--- a/core/jni/android_view_GLRenderer.cpp
+++ b/core/jni/android_view_GLRenderer.cpp
@@ -143,7 +143,7 @@
 static void android_view_GLRenderer_setDisplayListData(JNIEnv* env, jobject clazz,
         jlong displayListPtr, jlong newDataPtr) {
     using namespace android::uirenderer;
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
     DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr);
     displayList->setData(newData);
 }
diff --git a/core/jni/android_view_HardwareLayer.cpp b/core/jni/android_view_HardwareLayer.cpp
index 5b21e94..ad2e9ff 100644
--- a/core/jni/android_view_HardwareLayer.cpp
+++ b/core/jni/android_view_HardwareLayer.cpp
@@ -120,7 +120,7 @@
         jlong layerUpdaterPtr, jlong displayListPtr,
         jint left, jint top, jint right, jint bottom) {
     DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(layerUpdaterPtr);
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
     layer->setDisplayList(displayList, left, top, right, bottom);
 }
 
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
new file mode 100644
index 0000000..823f8d7
--- /dev/null
+++ b/core/jni/android_view_RenderNode.cpp
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include <EGL/egl.h>
+
+#include "jni.h"
+#include "GraphicsJNI.h"
+#include <nativehelper/JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+
+#include <DisplayList.h>
+#include <DisplayListRenderer.h>
+
+namespace android {
+
+using namespace uirenderer;
+
+/**
+ * Note: OpenGLRenderer JNI layer is generated and compiled only on supported
+ *       devices. This means all the logic must be compiled only when the
+ *       preprocessor variable USE_OPENGL_RENDERER is defined.
+ */
+#ifdef USE_OPENGL_RENDERER
+
+// ----------------------------------------------------------------------------
+// DisplayList view properties
+// ----------------------------------------------------------------------------
+
+static void android_view_RenderNode_setDisplayListName(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jstring name) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    if (name != NULL) {
+        const char* textArray = env->GetStringUTFChars(name, NULL);
+        displayList->setName(textArray);
+        env->ReleaseStringUTFChars(name, textArray);
+    }
+}
+
+static void android_view_RenderNode_output(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->output();
+}
+
+static jlong android_view_RenderNode_create(JNIEnv* env, jobject clazz) {
+    RenderNode* displayList = new RenderNode();
+    return reinterpret_cast<jlong>(displayList);
+}
+
+static void android_view_RenderNode_destroyDisplayList(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    RenderNode::destroyDisplayListDeferred(displayList);
+}
+
+// ----------------------------------------------------------------------------
+// DisplayList view properties
+// ----------------------------------------------------------------------------
+
+static void android_view_RenderNode_setCaching(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jboolean caching) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setCaching(caching);
+}
+
+static void android_view_RenderNode_setStaticMatrix(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jlong matrixPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
+    displayList->properties().setStaticMatrix(matrix);
+}
+
+static void android_view_RenderNode_setAnimationMatrix(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jlong matrixPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixPtr);
+    displayList->properties().setAnimationMatrix(matrix);
+}
+
+static void android_view_RenderNode_setClipToBounds(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jboolean clipToBounds) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setClipToBounds(clipToBounds);
+}
+
+static void android_view_RenderNode_setIsolatedZVolume(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jboolean shouldIsolate) {
+    // No-op, TODO: Remove Java usage of this method
+}
+
+static void android_view_RenderNode_setProjectBackwards(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jboolean shouldProject) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setProjectBackwards(shouldProject);
+}
+
+static void android_view_RenderNode_setProjectionReceiver(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jboolean shouldRecieve) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setProjectionReceiver(shouldRecieve);
+}
+
+static void android_view_RenderNode_setOutline(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jlong outlinePathPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    SkPath* outline = reinterpret_cast<SkPath*>(outlinePathPtr);
+    displayList->properties().setOutline(outline);
+}
+
+static void android_view_RenderNode_setClipToOutline(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, jboolean clipToOutline) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setClipToOutline(clipToOutline);
+}
+
+static void android_view_RenderNode_setAlpha(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float alpha) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setAlpha(alpha);
+}
+
+static void android_view_RenderNode_setHasOverlappingRendering(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, bool hasOverlappingRendering) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setHasOverlappingRendering(hasOverlappingRendering);
+}
+
+static void android_view_RenderNode_setTranslationX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float tx) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setTranslationX(tx);
+}
+
+static void android_view_RenderNode_setTranslationY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float ty) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setTranslationY(ty);
+}
+
+static void android_view_RenderNode_setTranslationZ(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float tz) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setTranslationZ(tz);
+}
+
+static void android_view_RenderNode_setRotation(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float rotation) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setRotation(rotation);
+}
+
+static void android_view_RenderNode_setRotationX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float rx) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setRotationX(rx);
+}
+
+static void android_view_RenderNode_setRotationY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float ry) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setRotationY(ry);
+}
+
+static void android_view_RenderNode_setScaleX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float sx) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setScaleX(sx);
+}
+
+static void android_view_RenderNode_setScaleY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float sy) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setScaleY(sy);
+}
+
+static void android_view_RenderNode_setTransformationInfo(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float alpha,
+        float translationX, float translationY, float translationZ,
+        float rotation, float rotationX, float rotationY, float scaleX, float scaleY) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setAlpha(alpha);
+    displayList->properties().setTranslationX(translationX);
+    displayList->properties().setTranslationY(translationY);
+    displayList->properties().setTranslationZ(translationZ);
+    displayList->properties().setRotation(rotation);
+    displayList->properties().setRotationX(rotationX);
+    displayList->properties().setRotationY(rotationY);
+    displayList->properties().setScaleX(scaleX);
+    displayList->properties().setScaleY(scaleY);
+}
+
+static void android_view_RenderNode_setPivotX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float px) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setPivotX(px);
+}
+
+static void android_view_RenderNode_setPivotY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float py) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setPivotY(py);
+}
+
+static void android_view_RenderNode_setCameraDistance(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float distance) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setCameraDistance(distance);
+}
+
+static void android_view_RenderNode_setLeft(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, int left) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setLeft(left);
+}
+
+static void android_view_RenderNode_setTop(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, int top) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setTop(top);
+}
+
+static void android_view_RenderNode_setRight(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, int right) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setRight(right);
+}
+
+static void android_view_RenderNode_setBottom(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, int bottom) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setBottom(bottom);
+}
+
+static void android_view_RenderNode_setLeftTopRightBottom(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, int left, int top,
+        int right, int bottom) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().setLeftTopRightBottom(left, top, right, bottom);
+}
+
+static void android_view_RenderNode_offsetLeftAndRight(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float offset) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().offsetLeftRight(offset);
+}
+
+static void android_view_RenderNode_offsetTopAndBottom(JNIEnv* env,
+        jobject clazz, jlong displayListPtr, float offset) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    displayList->properties().offsetTopBottom(offset);
+}
+
+static jboolean android_view_RenderNode_hasOverlappingRendering(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().hasOverlappingRendering();
+}
+
+static jfloat android_view_RenderNode_getAlpha(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getAlpha();
+}
+
+static jfloat android_view_RenderNode_getLeft(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getLeft();
+}
+
+static jfloat android_view_RenderNode_getTop(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getTop();
+}
+
+static jfloat android_view_RenderNode_getRight(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getRight();
+}
+
+static jfloat android_view_RenderNode_getBottom(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getBottom();
+}
+
+static jfloat android_view_RenderNode_getCameraDistance(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getCameraDistance();
+}
+
+static jfloat android_view_RenderNode_getScaleX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getScaleX();
+}
+
+static jfloat android_view_RenderNode_getScaleY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getScaleY();
+}
+
+static jfloat android_view_RenderNode_getTranslationX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getTranslationX();
+}
+
+static jfloat android_view_RenderNode_getTranslationY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getTranslationY();
+}
+
+static jfloat android_view_RenderNode_getRotation(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getRotation();
+}
+
+static jfloat android_view_RenderNode_getRotationX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getRotationX();
+}
+
+static jfloat android_view_RenderNode_getRotationY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getRotationY();
+}
+
+static jfloat android_view_RenderNode_getPivotX(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getPivotX();
+}
+
+static jfloat android_view_RenderNode_getPivotY(JNIEnv* env,
+        jobject clazz, jlong displayListPtr) {
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
+    return displayList->properties().getPivotY();
+}
+
+#endif // USE_OPENGL_RENDERER
+
+// ----------------------------------------------------------------------------
+// JNI Glue
+// ----------------------------------------------------------------------------
+
+const char* const kClassPathName = "android/view/RenderNode";
+
+static JNINativeMethod gMethods[] = {
+#ifdef USE_OPENGL_RENDERER
+    { "nCreate",               "()J",    (void*) android_view_RenderNode_create },
+    { "nDestroyDisplayList",   "(J)V",   (void*) android_view_RenderNode_destroyDisplayList },
+    { "nSetDisplayListName",   "(JLjava/lang/String;)V",
+            (void*) android_view_RenderNode_setDisplayListName },
+    { "nOutput",               "(J)V",  (void*) android_view_RenderNode_output },
+
+    { "nSetCaching",           "(JZ)V",  (void*) android_view_RenderNode_setCaching },
+    { "nSetStaticMatrix",      "(JJ)V",  (void*) android_view_RenderNode_setStaticMatrix },
+    { "nSetAnimationMatrix",   "(JJ)V",  (void*) android_view_RenderNode_setAnimationMatrix },
+    { "nSetClipToBounds",      "(JZ)V",  (void*) android_view_RenderNode_setClipToBounds },
+    { "nSetIsolatedZVolume",   "(JZ)V",  (void*) android_view_RenderNode_setIsolatedZVolume },
+    { "nSetProjectBackwards",  "(JZ)V",  (void*) android_view_RenderNode_setProjectBackwards },
+    { "nSetProjectionReceiver","(JZ)V",  (void*) android_view_RenderNode_setProjectionReceiver },
+    { "nSetOutline",           "(JJ)V",  (void*) android_view_RenderNode_setOutline },
+    { "nSetClipToOutline",     "(JZ)V",  (void*) android_view_RenderNode_setClipToOutline },
+    { "nSetAlpha",             "(JF)V",  (void*) android_view_RenderNode_setAlpha },
+    { "nSetHasOverlappingRendering", "(JZ)V",
+            (void*) android_view_RenderNode_setHasOverlappingRendering },
+    { "nSetTranslationX",      "(JF)V",  (void*) android_view_RenderNode_setTranslationX },
+    { "nSetTranslationY",      "(JF)V",  (void*) android_view_RenderNode_setTranslationY },
+    { "nSetTranslationZ",      "(JF)V",  (void*) android_view_RenderNode_setTranslationZ },
+    { "nSetRotation",          "(JF)V",  (void*) android_view_RenderNode_setRotation },
+    { "nSetRotationX",         "(JF)V",  (void*) android_view_RenderNode_setRotationX },
+    { "nSetRotationY",         "(JF)V",  (void*) android_view_RenderNode_setRotationY },
+    { "nSetScaleX",            "(JF)V",  (void*) android_view_RenderNode_setScaleX },
+    { "nSetScaleY",            "(JF)V",  (void*) android_view_RenderNode_setScaleY },
+    { "nSetTransformationInfo","(JFFFFFFFFF)V",
+            (void*) android_view_RenderNode_setTransformationInfo },
+    { "nSetPivotX",            "(JF)V",  (void*) android_view_RenderNode_setPivotX },
+    { "nSetPivotY",            "(JF)V",  (void*) android_view_RenderNode_setPivotY },
+    { "nSetCameraDistance",    "(JF)V",  (void*) android_view_RenderNode_setCameraDistance },
+    { "nSetLeft",              "(JI)V",  (void*) android_view_RenderNode_setLeft },
+    { "nSetTop",               "(JI)V",  (void*) android_view_RenderNode_setTop },
+    { "nSetRight",             "(JI)V",  (void*) android_view_RenderNode_setRight },
+    { "nSetBottom",            "(JI)V",  (void*) android_view_RenderNode_setBottom },
+    { "nSetLeftTopRightBottom","(JIIII)V", (void*) android_view_RenderNode_setLeftTopRightBottom },
+    { "nOffsetLeftAndRight",   "(JF)V",  (void*) android_view_RenderNode_offsetLeftAndRight },
+    { "nOffsetTopAndBottom",   "(JF)V",  (void*) android_view_RenderNode_offsetTopAndBottom },
+
+    { "nHasOverlappingRendering", "(J)Z",  (void*) android_view_RenderNode_hasOverlappingRendering },
+    { "nGetAlpha",                "(J)F",  (void*) android_view_RenderNode_getAlpha },
+    { "nGetLeft",                 "(J)F",  (void*) android_view_RenderNode_getLeft },
+    { "nGetTop",                  "(J)F",  (void*) android_view_RenderNode_getTop },
+    { "nGetRight",                "(J)F",  (void*) android_view_RenderNode_getRight },
+    { "nGetBottom",               "(J)F",  (void*) android_view_RenderNode_getBottom },
+    { "nGetCameraDistance",       "(J)F",  (void*) android_view_RenderNode_getCameraDistance },
+    { "nGetScaleX",               "(J)F",  (void*) android_view_RenderNode_getScaleX },
+    { "nGetScaleY",               "(J)F",  (void*) android_view_RenderNode_getScaleY },
+    { "nGetTranslationX",         "(J)F",  (void*) android_view_RenderNode_getTranslationX },
+    { "nGetTranslationY",         "(J)F",  (void*) android_view_RenderNode_getTranslationY },
+    { "nGetRotation",             "(J)F",  (void*) android_view_RenderNode_getRotation },
+    { "nGetRotationX",            "(J)F",  (void*) android_view_RenderNode_getRotationX },
+    { "nGetRotationY",            "(J)F",  (void*) android_view_RenderNode_getRotationY },
+    { "nGetPivotX",               "(J)F",  (void*) android_view_RenderNode_getPivotX },
+    { "nGetPivotY",               "(J)F",  (void*) android_view_RenderNode_getPivotY },
+#endif
+};
+
+#ifdef USE_OPENGL_RENDERER
+    #define FIND_CLASS(var, className) \
+            var = env->FindClass(className); \
+            LOG_FATAL_IF(! var, "Unable to find class " className);
+
+    #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
+            var = env->GetMethodID(clazz, methodName, methodDescriptor); \
+            LOG_FATAL_IF(! var, "Unable to find method " methodName);
+#else
+    #define FIND_CLASS(var, className)
+    #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor)
+#endif
+
+int register_android_view_RenderNode(JNIEnv* env) {
+    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
+}
+
+};
+
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 2b20758..28cee4b 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -106,7 +106,7 @@
 static void android_view_ThreadedRenderer_setDisplayListData(JNIEnv* env, jobject clazz,
         jlong proxyPtr, jlong displayListPtr, jlong newDataPtr) {
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
     DisplayListData* newData = reinterpret_cast<DisplayListData*>(newDataPtr);
     proxy->setDisplayListData(displayList, newData);
 }
@@ -115,7 +115,7 @@
         jlong proxyPtr, jlong displayListPtr, jint dirtyLeft, jint dirtyTop,
         jint dirtyRight, jint dirtyBottom) {
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
-    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
+    RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
     proxy->drawDisplayList(displayList, dirtyLeft, dirtyTop, dirtyRight, dirtyBottom);
 }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b99cb90..c2159fb 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1271,9 +1271,10 @@
     <!-- @hide Fuller form of {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
          that removes restrictions on where broadcasts can be sent and allows other
          types of interactions. -->
+    <!-- TODO: Remove the system protection level.-->
     <permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
         android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
-        android:protectionLevel="signature"
+        android:protectionLevel="signature|system"
         android:label="@string/permlab_interactAcrossUsersFull"
         android:description="@string/permdesc_interactAcrossUsersFull" />
 
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 0b9ac7f..5cb5709 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Laat die houer toe om die opstellingsprogram wat deur die diensverskaffer voorsien word, op te roep. Behoort nooit vir gewone programme nodig te wees nie."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"luister vir waarnemings oor netwerktoestande"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Laat \'n program luister vir waarnemings oor netwerktoestande. Behoort nooit nodig te wees vir normale programme nie."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"verander invoertoestelkalibrasie"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Laat die program toe om die kalibrasieparameters van die raakskerm te wysig. Dit behoort nooit vir normale programme nodig te wees nie."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Stel wagwoordreëls"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Beheer lengte en watter karakters wat in die skermontsluit-wagwoorde gebruik word."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor pogings om skerm te ontsluit"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 5701852..5509121 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ያዢው በድምጸ-ተያያዥ ሞደም የቀረበው የውቅር መተግበሪያውን እንዲጠራው ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አያስፈልግም።"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"በአውታረ መረብ ሁኔታዎች ላይ የተስተዋሉ ነገሮችን ያዳምጣል"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"አንድ መተግበሪያ በአውታረ መረብ ሁኔታዎች ላይ የተስተዋሉ ነገሮችን እንዲያዳምጥ ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ አስፈላጊ ሊሆን አይገባም።"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"የግቤት መሣሪያ ማስተካከያ ቀይር"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"መተግበሪያው የማያ ንካ የማስተካከያ ልኬቶቹን እንዲቀይር ያስችለዋል። ለመደበኛ መተግበሪያዎች በጭራሽ ሊያስፈልግ አይገባም።"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"የይለፍ ቃል ደንቦች አዘጋጅ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"በማያ-መክፈት የተፈቀዱ የይለፍ ቃል ርዝመት እና ቁምፊዎች ተቆጣጠር።"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"የማሳያ-ክፈት ሙከራዎችን አሳይ"</string>
@@ -1123,9 +1125,9 @@
     <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> እያሄደ ነው"</string>
     <string name="app_running_notification_text" msgid="4653586947747330058">"ተጨማሪ መረጃ ለማግኘት ወይም መተግበሪያውን ለማቆም ይንኩ።"</string>
     <string name="ok" msgid="5970060430562524910">"እሺ"</string>
-    <string name="cancel" msgid="6442560571259935130">"ሰርዝ"</string>
+    <string name="cancel" msgid="6442560571259935130">"ይቅር"</string>
     <string name="yes" msgid="5362982303337969312">"እሺ"</string>
-    <string name="no" msgid="5141531044935541497">"ሰርዝ"</string>
+    <string name="no" msgid="5141531044935541497">"ይቅር"</string>
     <string name="dialog_alert_title" msgid="2049658708609043103">"ትኩረት"</string>
     <string name="loading" msgid="7933681260296021180">"በመጫን ላይ…"</string>
     <string name="capital_on" msgid="1544682755514494298">"በ"</string>
@@ -1227,7 +1229,7 @@
     <string name="sms_short_code_details" msgid="3492025719868078457">"ይሄ በተንቀሳቃሽ ስልክ መለያዎ ላይ "<font fgcolor="#ffffb060">"ክፍያዎችን ሊያስከትል ይችላል"</font>"።"</string>
     <string name="sms_premium_short_code_details" msgid="5523826349105123687"><font fgcolor="#ffffb060">"ይሄ በተንቀሳቃሽ ስልክ መለያዎ ላይ ክፍያዎችን ያስከትላል።"</font></string>
     <string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"ላክ"</string>
-    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"ሰርዝ"</string>
+    <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"ይቅር"</string>
     <string name="sms_short_code_remember_choice" msgid="5289538592272218136">"ምርጫዬን አስታውስ"</string>
     <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"ይሄንን በኋላ ላይ በቅንብሮች &gt; መተግበሪያዎች ውስጥ ሊቀይሩት ይችላሉ"</string>
     <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"ሁልጊዜ ፍቀድ"</string>
@@ -1425,7 +1427,7 @@
     <string name="date_picker_increment_year_button" msgid="6318697384310808899">"ዓመት ጨምር"</string>
     <string name="date_picker_decrement_year_button" msgid="4482021813491121717">"ዓመት ቀንስ"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
-    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ተወው"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ይቅር"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ሰርዝ"</string>
     <string name="keyboardview_keycode_done" msgid="1992571118466679775">"ተከናውኗል"</string>
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ሞድ ለውጥ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 798ea7a..d17b1d1 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"للسماح للمالك باستدعاء تطبيق التهيئة الذي يوفره مشغل شبكة الجوال. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"الاستماع إلى ملاحظات حول أحوال الشبكة"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"للسماح للتطبيق بالاستماع إلى ملاحظات حول أحوال الشبكة. لا حاجة إلى هذا مع التطبيقات العادية."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"تغيير معايرة أجهزة الإدخال"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"يتيح للتطبيق إمكانية تعديل معلمات المعايرة في شاشة اللمس. يجب عدم اللجوء إليه مع التطبيقات العادية."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"تعيين قواعد كلمة المرور"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"يمكنك التحكم في الطول والأحرف المسموح بها في كلمات مرور إلغاء تأمين الشاشة."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"مراقبة محاولات إلغاء قفل الشاشة"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index f76ad7f..691aff26 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Разрешава на притежателя да извиква предоставеното от оператора приложение за конфигуриране. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"слушане за наблюдения на мрежовите условия"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Разрешава на приложението да слуша за наблюдения на мрежовите условия. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"промяна на калибрирането на устройството за въвеждане"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Разрешава на приложението да променя параметрите на калибриране на сензорния екран. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Задаване на правила за паролата"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролирайте дължината и разрешените знаци за паролите за отключване на екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Наблюдаване на опитите за отключване на екрана"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index dc8128a..682e0ea 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permet que el titular invoqui l\'aplicació de configuració proporcionada per l\'operador. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"conèixer les observacions sobre les condicions de la xarxa"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet que una aplicació conegui les observacions sobre les condicions de la xarxa. No s\'ha de necessitar mai per a aplicacions normals."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"canviar el calibratge del dispositiu d\'entrada"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permet que l\'aplicació modifiqui els paràmetres de calibratge de la pantalla tàctil. S\'ha de procurar no fer servir mai aquesta opció per a les aplicacions normals."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir les normes de contrasenya"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controla la longitud i els caràcters permesos a les contrasenyes de desbloqueig de pantalla."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Controlar intents de desbloqueig de pantalla"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 9745cdc..37e228c 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Umožňuje vyvolání konfigurační aplikace poskytnuté operátorem. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"naslouchat informacím o stavu sítě"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Umožňuje aplikaci naslouchat informacím o stavu sítě. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"měnit kalibraci vstupního zařízení"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Umožňuje aplikaci měnit parametry kalibrace dotykové obrazovky. Běžné aplikace by toto oprávnění neměly nikdy potřebovat."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavit pravidla pro heslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Řídit délku hesel pro odemčení obrazovky a povolené znaky."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Sledovat pokusy o odemčení obrazovky"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index ca12213..5acf558 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Tillader, at brugeren aktiverer konfigurationsappen, der er forsynet af mobilselskabet. Dette bør aldrig være nødvendigt for almindelige apps."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"observer netværksforhold"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Tillader, at en applikation observerer netværksforhold. Bør aldrig være nødvendigt for almindelige apps."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"skift kalibrering for inputenheden"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Tillader, at appen ændrer kalibreringsparametrene for berøringsskærmen. Dette bør aldrig være nødvendigt for almindelige apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Indstil regler for adgangskode"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller længden samt tilladte tegn i adgangskoder til oplåsning af skærmen."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Overvåg forsøg på oplåsning af skærm"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 404d4cc..f87865d 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Ermöglicht dem Inhaber, die vom Mobilfunkanbieter bereitgestellte Konfigurations-App aufzurufen. Sollte für normale Apps nie benötigt werden."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Informationen zu den Netzwerkbedingungen erfassen"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ermöglicht der App, Informationen zu den Netzwerkbedingungen zu erfassen. Sollte für normale Apps nie benötigt werden."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"Kalibrierung für Eingabegerät ändern"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ermöglicht der App, die Kalibrierungsparameter des Touchscreens zu ändern. Für normale Apps sollte dies nie erforderlich sein."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Passwortregeln festlegen"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Zulässige Länge und Zeichen für Passwörter zum Entsperren des Bildschirms festlegen"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Versuche zum Entsperren des Displays überwachen"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 1c3e185..ffe25013 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Επιτρέπει στον κάτοχο την κλήση της εφαρμογής διαμόρφωσης που παρέχεται από την εταιρεία κινητής τηλεφωνίας. Δεν απαιτείται για κανονικές εφαρμογές."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"λήψη παρατηρήσεων σχετικά με την κατάσταση δικτύου"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Επιτρέπει σε μια εφαρμογή να λαμβάνει παρατηρήσεις σχετικά με την κατάσταση δικτύου. Δεν θα πρέπει να απαιτείται ποτέ για κανονικές εφαρμογές."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"αλλαγή βαθμονόμησης της συσκευής εισόδου"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Επιτρέπει στην εφαρμογή να τροποποιεί τις παραμέτρους βαθμονόμησης της οθόνης αφής. Δεν απαιτείται για τις κανονικές εφαρμογές."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ορισμός κανόνων κωδικού πρόσβασης"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Έλεγχος του μεγέθους και των χαρακτήρων που επιτρέπονται στους κωδικούς πρόσβασης ξεκλειδώματος οθόνης."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Παρακολούθηση προσπαθειών ξεκλειδώματος οθόνης"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index c4b3a2b..19ea67b 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"listen for observations on network conditions"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"change input device calibration"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index c4b3a2b..19ea67b 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"listen for observations on network conditions"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Allows an application to listen for observations on network conditions. Should never be needed for normal apps."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"change input device calibration"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Allows the app to modify the calibration parameters of the touch screen. Should never be needed for normal apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Set password rules"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Control the length and the characters allowed in screen-unlock passwords."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitor screen-unlock attempts"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1446aff..ec4ed33 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite al propietario ejecutar la aplicación de configuración proporcionada por el proveedor. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Detectar cambios en el estado de la red"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que una aplicación detecte cambios en el estado de la red. Las aplicaciones normales no deberían necesitar este permiso."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"Cambiar la calibración del dispositivo de entrada"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que la aplicación modifique los parámetros de calibración de la pantalla táctil. Las aplicaciones normales no deberían necesitar este permiso."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecer reglas de contraseña"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas para desbloquear la pantalla"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Supervisa los intentos para desbloquear la pantalla"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 6d4ee8e..cb68b67 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite ejecutar la aplicación de configuración proporcionada por el operador. No debe ser necesario para aplicaciones normales."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"detectar cambios en el estado de la red"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que una aplicación detecte cambios en el estado de la red. No debe ser necesario para aplicaciones normales."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"cambiar la calibración del dispositivo de entrada"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que la aplicación modifique los parámetros de calibración de la pantalla táctil. No debe ser necesario para las aplicaciones normales."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Establecimiento de reglas de contraseña"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar la longitud y los caracteres permitidos en las contraseñas de bloqueo de pantalla"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Control de intentos de bloqueo de pantalla"</string>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 629852f..039fa9c 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Lubab omanikul aktiveerida operaatoripoolse konfiguratsioonirakenduse. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"võrgutingimuste teabe kuulamine"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Lubab rakendusel kuulata võrgutingimuste teavet. Ei ole kunagi vajalik tavaliste rakenduste puhul."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"sisendseadme kalibreerimise muutmine"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Lubab rakendusel muuta puuteekraani kalibreerimisparameetreid. Ei tohiks kunagi olla vajalik tavaliste rakenduste puhul."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Parooli reeglite määramine"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrollige ekraaniluku avamise paroolide pikkust ja tähemärke."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekraani avamiskatsed"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index a73d136..857a1ea 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -256,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"حذف نصب میان‌برها"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"به برنامه اجازه می‌دهد میان‌برهای صفحه اصلی را بدون دخالت کاربر حذف کند."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"ترسیم مجدد مسیر تماس‌های خروجی"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"به برنامه اجازه می‌دهد عددی را که در طی یک تماس خروجی شماره‌گیری شده ببیند و این اختیار را دارد که تماس را به شماره دیگری هدایت کند یا کلاً تماس را قطع کند."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"به برنامه اجازه می‌دهد عددی را که در طی یک تماس خروجی شماره‌گیری شده، ببیند و این اختیار را دارد که تماس را به شماره دیگری هدایت کند یا کلاً تماس را قطع کند."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"دریافت پیام‌های نوشتاری (پیامک)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"به برنامه اجازه می‌دهد پیامک‌ها را دریافت و پردازش کند. این یعنی برنامه می‌تواند پیام‌های ارسالی به دستگاه شما را بدون نمایش آن‌ها به شما حذف یا کنترل کند."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"‏دریافت پیام‌های نوشتاری (MMS)"</string>
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"به دارنده اجازه می‌دهد که تنظیمات برنامه شرکت مخابراتی را لغو کند. هرگز برای برنامه‌های معمولی مورد نیاز نیست."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"گوش دادن برای بررسی شرایط شبکه"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"به برنامه امکان می‌دهد برای بررسی شرایط شبکه گوش دهد. این امکان هرگز نباید برای برنامه‌های معمولی مورد نیاز باشد."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"تغییر کالیبراسیون دستگاه ورودی"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"به برنامه امکان می‌دهد پارامترهای صفحه لمسی را کالیبره کند. هرگز نباید برای برنامه‌های عادی مورد نیاز باشد."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"تنظیم قوانین رمز ورود"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"‏طول و نویسه‎های مجاز در گذرواژه‌های بازکردن قفل صفحه را کنترل کنید."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"نمایش تلاش‌های قفل گشایی صفحه"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 4e9ddd1..fe3c4617 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Antaa luvanhaltijan käynnistää palveluntarjoajan määrityssovelluksen. Ei tavallisten sovelluksien käyttöön."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"verkon tilahavaintojen kuunteleminen"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Antaa sovellukselle luvan kuunnella verkon tilahavaintoja. Ei tavallisten sovellusten käyttöön."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"Muuttaa syöttölaitteen kalibrointia."</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Antaa sovelluksen muokata kosketusnäytön kalibrointiparametreja. Ei tavallisten sovellusten käyttöön."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Aseta salasanasäännöt"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Hallinnoi ruudun lukituksenpoistosalasanoissa sallittuja merkkejä ja salasanan pituutta."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Tarkkaile ruudun lukituksen poistoyrityksiä"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 79a1ab1..acf58ca 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permet à l\'application autorisée de faire appel à l\'application de configuration fournie par le fournisseur de services. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"détecter des observations sur les conditions du réseau"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet à une application de détecter les observations sur les conditions du réseau. Ne devrait jamais être nécessaire pour les applications standards."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"modifier le calibrage du périphérique d\'entrée"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permet à l\'application de modifier les paramètres de calibrage de l\'écran tactile. Ne devrait jamais être nécessaire pour les applications standards."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index f869af5..bcba168 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permet à l\'application autorisée de faire appel à l\'application de configuration fournie par l\'opérateur. Cette fonctionnalité ne devrait pas être nécessaire pour les applications standards."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"détecter des observations sur les conditions du réseau"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permet à une application de détecter des observations sur les conditions du réseau. Les applications standards ne devraient pas nécessiter cette autorisation."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"modifier le calibrage du périphérique d\'entrée"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permettre à l\'application de modifier les paramètres de calibrage de l\'écran tactile. Ne devrait jamais être nécessaire pour les applications standards."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Définir les règles du mot de passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Choisir le nombre et le type de caractères autorisés dans les mots de passe de déverrouillage de l\'écran"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gérer les tentatives de déverrouillage de l\'écran"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 00fdd7c..05e5941 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"धारक को वाहक के द्वारा उपलब्ध कराया गया कॉन्फ़िगरेशन ऐप्स  प्रारंभ करने देता है. सामान्‍य ऐप्स के लिए कभी भी आवश्‍यक नहीं होना चाहिए."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"नेटवर्क स्थितियों के अवलोकनों को सुनें"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ऐप्स  को नेटवर्क स्थितियों के अवलोकनों को सुनने देता है. सामान्य ऐप्स  के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट उपकरण कैलिब्रेशन बदलें"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ऐप्स को टच स्क्रीन के कैलिब्रेशन पैरामीटर को बदलने देती है. सामान्य ऐप्स के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"पासवर्ड नियम सेट करें"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"स्‍क्रीन-अनलॉक पासवर्ड में अनुमति प्राप्त लंबाई और वर्णों को नियंत्रित करें."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"स्‍क्रीन-अनलॉक के प्रयासों पर निगरानी रखें"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 6224106..19afc6c 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -657,7 +657,7 @@
     <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"čitanje sadržaja SD kartice"</string>
     <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Aplikaciji omogućuje čitanje sadržaja vaše USB pohrane."</string>
     <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Aplikaciji omogućuje čitanje sadržaja vaše SD kartice."</string>
-    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"izmjena/brisanje sadrž. USB-a"</string>
+    <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"izmjena/brisanje sadržaja USB-a"</string>
     <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"izmjena ili brisanje sadržaja SD kartice"</string>
     <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Dopušta pisanje u USB pohranu."</string>
     <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Aplikaciji omogućuje pisanje na SD karticu."</string>
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Dopušta nositelju pozivanje operaterove aplikacije za konfiguraciju. Ne bi smjelo biti potrebno za uobičajene aplikacije."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"praćenje motrenja mrežnih uvjeta"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Omogućuje aplikaciji praćenje motrenja mrežnih uvjeta. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"promjena kalibracije uređaja za unos"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Omogućuje aplikaciji izmjenu parametara kalibracije dodirnog zaslona. Ne bi trebalo biti potrebno za uobičajene aplikacije."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Postavi pravila zaporke"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Upravljajte duljinom zaporki za otključavanje zaslona i dopuštenim znakovima u tim zaporkama."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Nadgledaj pokušaje otključavanja zaslona"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index c0f9c27..1d6b16d 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Lehetővé teszi a használó számára a szolgáltató által biztosított konfigurációs alkalmazás hívását. A normál alkalmazásoknak erre soha nincs szükségük."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"hálózati körülményekkel kapcsolatos észrevételek figyelemmel kísérése"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Lehetővé teszi egy alkalmazás számára, hogy figyelemmel kísérje a hálózati körülményekkel kapcsolatos észrevételeket. A normál alkalmazásoknak erre soha nincs szükségük."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"beviteli eszköz kalibrációjának módosítása"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Lehetővé teszi, hogy alkalmazás módosítsa az érintőképernyő kalibrációs paramétereit. A normál alkalmazásoknál erre elvileg soha nincs szükség."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Jelszavakkal kapcsolatos szabályok beállítása"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"A képernyőzár-feloldási jelszavakban engedélyezett karakterek és hosszúság vezérlése."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Képernyőzár-feloldási kísérletek figyelése"</string>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 8a0f901..62464ba 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Թույլ է տալիս սեփականատիրոջը գործարկել օպերատորի կողմից տրամադրված կազմաձևման ծրագիրը: Սովորական ծրագրերի համար երբևէ չպետք է անհրաժեշտ լինի:"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"լսել դիտարկումներ ցանցային պայմանների վերաբերյալ"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Հավելվածին թույլ է տալիս լսել դիտարկումներ ցանցային պայմանների վերաբերյալ: Սովորական հավելվածների համար երբեք պետք չի գալիս:"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"փոփոխել մուտքի սարքի չափաբերումը"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Թույլ է տալիս ծրագրին փոփոխել հպէկրանի չափաբերման կարգավորումները: Սովորական ծրագրերի համար երբեք պետք չի գալու:"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Սահմանել գաղտնաբառի կանոնները"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Վերահսկել էկրանի ապակողպման գաղտնաբառերի թույլատրելի երկարությունն ու գրանշանները:"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Վերահսկել էկրանի ապակողպման փորձերը"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 07e6cb2..b3b0d2b 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Memungkinkan pemegang meminta aplikasi konfigurasi yang disediakan operator. Tidak pernah diperlukan aplikasi normal."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"mendengar untuk observasi kondisi jaringan"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Memungkinkan aplikasi mendengar untuk observasi kondisi jaringan. Tidak pernah dibutuhkan oleh aplikasi normal."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"mengubah kalibrasi perangkat masukan"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Memungkinkan aplikasi mengubah parameter kalibrasi layar sentuh. Tidak diperlukan oleh aplikasi normal."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setel aturan sandi"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrol panjang dan karakter yang diizinkan dalam sandi pembuka layar."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Upaya pembukaan kunci layar monitor"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 0f59bba..3faca1a 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Consente al titolare di richiamare l\'app di configurazione dell\'operatore-provider. Non dovrebbe essere mai necessaria per le normali applicazioni."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ascolto delle osservazioni sulle condizioni di rete"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Consente a un\'applicazione di ascoltare le osservazioni sulle condizioni di rete. Da non utilizzare mai con app normali."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"modifica calibrazione del dispositivo di immissione"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Consente all\'app di modificare i parametri di calibrazione del touch screen. Questa opzione non deve essere utilizzata per le app normali."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Impostazione regole password"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlla la lunghezza e i caratteri ammessi nelle password di sblocco dello schermo."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Controllo tentativi di sblocco dello schermo"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 128fbc7..c8f0dd5 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ההרשאה הזו מאפשרת לבעלים להפעיל את אפליקציית התצורה שסופקה על ידי ספק. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"קליטת מעקב אחר תנאי רשת"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"מאפשרת לאפליקציה לקלוט מעקב אחר תנאי רשת. לעולם לא אמורה להיות נחוצה עבור אפליקציות רגילות."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"שינוי הכיול של מכשיר קלט"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"מאפשרת לאפליקציה לשנות את פרמטרי הכיול של מסך המגע. לעולם לא אמורה להיות נחוצה לאפליקציות רגילות."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"הגדר כללי סיסמה"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"שלוט באורך ובתווים המותרים בסיסמאות לביטול נעילת מסך."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"עקוב אחר ניסיונות לביטול נעילת מסך"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 7892d69..4a26208 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"携帯通信会社が提供する設定アプリを呼び出すことを所有者に許可します。通常のアプリでは不要です。"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ネットワーク状況監視のためのリッスン"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ネットワーク状況を監視するためリッスンすることをアプリに許可します。通常のアプリで必要になることはありません。"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"入力デバイスの調整を変更"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"タッチスクリーンの調整パラメータの変更をアプリに許可します。通常のアプリでは必要ありません。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"パスワードルールの設定"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"画面ロック解除パスワードの長さと使用できる文字を制御します。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"画面ロック解除試行の監視"</string>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index a48ac95..5dbb83f 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"საშუალებას აძლევს მფლობელს გამოიწვიოს ოპერატორის მიერ მოწოდებული კონფიგურაციის აპი. ჩვეულებრივ აპს ეს წესით არასოდეს არ უნდა დაჭირდეს."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"განხორციელდეს ქსელის მდგომარეობის მონიტორინგი"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"საშუალებას აძლევს აპლიკაციებს განახორციელოს ქსელის მდგომარეობის მონიტორინგი. ეს ფუნქცია ჩვეულებრივ აპებს არ ჭირდება."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"შეყვანის მოწყობილობის კალიბრაციის ცვლილება"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"საშუალებას აძლევს აპს შეცვალოს სენსორული ეკრანის კალიბრაციის პარამეტრები. ჩვეულებრივ აპებს წესით არ უნდა დაჭირდეს."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"პაროლის წესების დაყენება"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"გააკონტროლეთ ეკრანის განბლოკვის პაროლში დაშვებული სიმბოლოები და მისი სიგრძე."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ეკრანის განბლოკვის მცდელობების გაკონტროლება"</string>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 488a439..21a7746 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"អនុញ្ញាត​ឲ្យ​ម្ចាស់​ដក​ហូត​កម្មវិធី​កំណត់​រចនាសម្ព័ន្ធ​ដែល​បាន​ផ្ដល់​ដោយ​ក្រុមហ៊ុន​បញ្ជូន។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"សង្កេត​មើល​លើ​លក្ខខណ្ឌ​បណ្ដាញ"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ឲ្យ​កម្មវិធី​សង្កេត​មើល​​លើ​លក្ខខណ្ឌ​បណ្ដាញ​។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"ប្ដូរ​​ចំណុច​ឧបករណ៍​បញ្ចូល"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ឲ្យ​​កម្មវិធី​កែ​ប៉ារ៉ាម៉ែត្រ​កែ​ចំណុច​​នៃ​ការ​ប៉ះ​អេក្រង់។ មិន​គួរ​ចាំបាច់​សម្រាប់​កម្មវិធី​ធម្មតា​ទេ។"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"កំណត់​ក្បួន​ពាក្យ​សម្ងាត់"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ពិនិត្យ​ប្រវែង និង​តួអក្សរ​ដែល​បាន​អនុញ្ញាត​ក្នុង​ពាក្យ​សម្ងាត់​ចាក់​សោ​អេក្រង់។"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ពិនិត្យ​ការ​ព្យាយាម​ដោះ​សោ​អេក្រង់"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 681aabf..9e46527 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"권한을 가진 프로그램이 이동통신사에서 제공한 구성 앱을 호출하도록 합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"네트워크 상태에 대한 관측 보고 수신"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"애플리케이션이 네트워크 상태에 대한 관측 보고를 수신하도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"입력 기기 보정 변경"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"앱이 터치 스크린의 보정 매개변수를 수정할 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"비밀번호 규칙 설정"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"화면 잠금해제 비밀번호에 허용되는 길이 및 문자 수를 제어합니다."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"화면 잠금해제 시도 모니터링"</string>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index 64dcbc6..56a05c3 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"ອະ​ນຸ​ຍາດ​ໃຫ້​ເຈົ້າຂອງຮ້ອງຂໍແອັບຯປັບຄ່າທີ່ສະໜອງໂດຍຜູ່ໃຫ້ບໍລິການ. ບໍ່ໜ້າຈະຕ້ອງການສຳລັບແອັບຯທົ່ວໄປ."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ຕິດຕາມເພື່ອສັງເກດສະພາບຂອງເຄືອຂ່າຍ"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"ອະນຸຍາດໃຫ້ແອັບພລິເຄຊັ່ນຕິດຕາມເພື່ອສັງເກດສະພາບຂອງເຄືອຂ່າຍ. ປົກກະຕິແລ້ວແອັບຯທຳມະດາຈະບໍ່ຕ້ອງການໃຊ້."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"ປ່ຽນ​ການ​ວັດ​ແທ້​ອຸ​ປະ​ກອນ​ປ້ອນ​ຂໍ້​ມູນ"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"ອະ​ນຸ​ຍາດ​ໃຫ້​ແອັບຯ​ແກ້​ໄຂ​ຄ່າ​ການວັດ​ແທ້​ໜ້າ​ຈ​ໍ​ສຳ​ຜັດ. ​ແອັບຯ​ທຳ​ມະ​ດາບໍ່​ຄວນ​ໃຊ້."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"ຕັ້ງຄ່າກົດຂອງລະຫັດຜ່ານ"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ຄວບຄຸມຄວາມຍາວຂອງໂຕອັກສອນທີ່ສາມາດໃຊ້ກັບລະຫັດປົດລັອກໜ້າຈໍ"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ຕິດຕາມການພະຍາຍາມປົດລັອກໜ້າຈໍ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index b379738..22fc1c4 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Turėtojui leidžiama iškviesti operatoriaus pateiktą konfigūravimo programą. Įprastoms programoms to neturėtų prireikti."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"vykdyti tinklo sąlygų stebėjimą"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Leidžiama programai vykdyti tinklo sąlygų stebėjimą. To niekada neturėtų prireikti naudojant įprastas programas."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"keisti įvesties įrenginio kalibravimą"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Leidžiama programai keisti jutiklinio ekrano kalibravimo parametrus. Neturėti prireikti naudojant įprastas programas."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nustatyti slaptažodžio taisykles"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Valdyti leidžiamą ekrano atrakinimo slaptažodžių ilgį ir leidžiamus naudoti simbolius."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Stebėti bandymus atrakinti ekraną"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 278b0d7..4a207d9 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Ļauj īpašniekam izsaukt operatora nodrošināto konfigurācijas lietotni. Parastām lietotnēm tas nekad nav nepieciešams."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"iegūt informāciju par tīkla stāvokļa novērojumiem"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ļauj lietojumprogrammai iegūt informāciju par tīkla stāvokļa novērojumiem. Parastām lietotnēm šī atļauja nekad nav nepieciešama."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"mainīt ievadierīces kalibrēšanu"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ļauj lietotnei pārveidot skārienekrāna kalibrēšanas parametrus. Parastām lietotnēm šī atļauja nekad nav nepieciešama."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Paroles kārtulu iestatīšana"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolē ekrāna atbloķēšanas parolē atļautās rakstzīmes un garumu."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekrāna atbloķēšanas mēģinājumu pārraudzīšana"</string>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index 3d0b3cb..5e60ce3 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Эзэмшигчид үүрэн компанийн нийлүүлсэн тохируулах апп-г өдөөх боломж олгоно. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Сүлжээний байдлын талаар ажиглалтуудыг хүлээн авах"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Аппликешнд сүлжээний байдлын талаар ажиглалтуудыг хүлээн авахыг зөвшөөрнө. Энгийн апп-уудад хэзээ ч ашиглагдахгүй."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"оролтын төхөөрөмжийн калибрешныг өөрчлөх"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Мэдрэгчтэй дэлгэцний калибрешн параметрийг өөрчлөхийг апп-д зөвшөөрнө. Энгийн апп-д шаардлагагүй."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Нууц үгний дүрмийг тохируулах"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Дэлгэц түгжих нууц үгэнд зөвшөөрөгдсөн тэмдэгт болон уртыг удирдах"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Дэлгэц тайлах оролдлогыг хянах"</string>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 37d0d0f..c1b7cdb 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Membenarkan pemegang menggunakan apl konfigurasi yang diberikan oleh pembawa. Tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"dengar pemerhatian mengenai keadaan rangkaian"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Membenarkan aplikasi mendengar pemerhatian tentang keadaan rangkaian. Tidak sekali-kali diperlukan untuk apl biasa."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"tukar penentukuran peranti input"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Membenarkan apl mengubah suai parameter penentukuran skrin sentuh. Ini tidak sekali-kali diperlukan untuk apl biasa."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Tetapkan peraturan kata laluan"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Mengawal panjang dan aksara yang dibenarkan dalam kata laluan buka kunci skrin."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Memantau percubaan buka kunci skrin"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 78df5e8..c1cd604 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Gir innehaveren tillatelse til å kalle opp den konfigurasjonsappen som ble levert av operatøren. Dette skal ikke være nødvendig for vanlige apper."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"lytte etter observasjoner om nettverksforhold"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Gir appen tillatelse til å lytte etter observasjoner om nettverksforhold. Dette skal ikke være nødvendig for vanlige apper."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"endre kalibreringen av inndataenheter"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Lar appen endre kalibrasjonsparametrene for berøringsskjermen. Denne tillatelsen bør aldri være nødvendig for vanlige apper."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Angi passordregler"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontroller tillatt lengde og tillatte tegn i passord for opplåsing av skjerm."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Overvåk forsøk på opplåsing av skjerm"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 8eaebf1..673df4e 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Hiermee kan de houder de door de provider geleverde configuratie-app aanroepen. Nooit vereist voor normale apps."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"controleren op waarnemingen met betrekking tot netwerkomstandigheden"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Hiermee kan een app controleren op waarnemingen met betrekking tot netwerkomstandigheden. Nooit vereist voor normale apps."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"kalibratie van invoerapparaat wijzigen"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Hiermee kan de app de kalibratieparameters van het aanraakscherm aanpassen. Nooit vereist voor normale apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Wachtwoordregels instellen"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"De lengte en tekens beheren die zijn toegestaan in wachtwoorden voor schermontgrendeling."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Pogingen voor schermontgrendeling bijhouden"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 77d5441..e9d701a 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Zezwala na wywoływanie aplikacji konfiguracyjnej udostępnionej przez operatora. Nieprzeznaczone dla zwykłych aplikacji."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"śledź stan sieci"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Pozwala aplikacji śledzić stan sieci. Nieprzeznaczone dla zwykłych aplikacji."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"zmiana kalibracji urządzenia wejściwego"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Zezwala aplikacji na modyfikowanie parametrów kalibracji ekranu dotykowego. Nieprzeznaczone dla zwykłych aplikacji."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Określ reguły hasła"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolowanie długości haseł odblokowania ekranu i dozwolonych w nich znaków"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitoruj próby odblokowania ekranu"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index e92961d..cf38b47 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite que o titular invoque a aplicação de configuração fornecida pela operadora. Nunca deverá ser necessário para aplicações normais."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ouvir observações sobre as condições da rede"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que uma aplicação ouça observações sobre as condições da rede. Nunca deverá ser necessário para aplicações normais."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"alterar a calibragem de entrada do dispositivo"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite à aplicação modificar os parâmetros de calibragem do ecrã tátil. Esta funcionalidade nunca deverá ser necessária para aplicações normais."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras de palavra-passe"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o comprimento e os caracteres permitidos nas palavras-passe de desbloqueio do ecrã."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizar tentativas de desbloqueio do ecrã"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index b3481b8..d048d51 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite que o proprietário invoque o aplicativo de configuração fornecido pela operadora. Não deve ser necessário para aplicativos comuns."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"detectar observações nas condições da rede"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite que o aplicativo detecte observações nas condições da rede. Não deve ser necessário para aplicativos comuns."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"alterar calibragem do dispositivo de entrada"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite que o aplicativo modifique os parâmetros de calibragem da tela sensível ao toque. Não deve ser necessário para aplicativos normais."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Definir regras para senha"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Controlar o tamanho e os caracteres permitidos nas senhas de desbloqueio de tela."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorar tentativas de desbloqueio da tela"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 9c2c793..8d007e4 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1170,6 +1170,10 @@
     <skip />
     <!-- no translation found for permdesc_accessNetworkConditions (6899102075825272211) -->
     <skip />
+    <!-- no translation found for permlab_setInputCalibration (4902620118878467615) -->
+    <skip />
+    <!-- no translation found for permdesc_setInputCalibration (4527511047549456929) -->
+    <skip />
     <!-- no translation found for policylab_limitPassword (4497420728857585791) -->
     <skip />
     <!-- no translation found for policydesc_limitPassword (3252114203919510394) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 016cb16..dd9dd9e 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Permite proprietarului să apeleze aplicația de configurare furnizată de operator. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ascultă observații despre starea rețelei"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Permite unei aplicații să asculte observații despre starea rețelei. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"schimbați calibrarea dispozitivului de intrare"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Permite aplicației să modifice parametrii de calibrare a ecranului tactil. Nu ar trebui să fie necesară pentru aplicațiile obișnuite."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Setaţi reguli pentru parolă"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Stabiliţi lungimea şi tipul de caractere permise în parolele pentru deblocarea ecranului."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Monitorizaţi încercările de deblocare a ecranului"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 5c9e697..f518a0c 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Владелец сможет запускать приложение настроек, предоставленное оператором. Это разрешение не используется обычными приложениями."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Использование данных о состоянии сети"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Приложение сможет использовать данные о состоянии сети. Это разрешение обычно используется только специальными приложениями."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"изменение параметров калибровки экрана"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Приложение сможет изменять параметры калибровки сенсорного экрана. Это разрешение обычно используется только специальными приложениями."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Правила выбора паролей"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролировать длину и символы при вводе паролей для снятия блокировки экрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Отслеживать попытки снятия блокировки экрана"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 039e1eb..f8e9782 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Umožňuje držiteľovi vyvolať aplikáciu pre konfiguráciu poskytnutú operátorom. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"zachytávať informácie o stave siete"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Umožňuje aplikácii zachytávať informácie o stave siete. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"zmeniť kalibráciu vstupného zariadenia"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Umožňuje aplikácii upraviť parametre kalibrácie dotykovej obrazovky. Bežné aplikácie by toto povolenie nemali nikdy potrebovať."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastaviť pravidlá pre heslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ovládanie dĺžky hesiel na odomknutie obrazovky a v nich používané znaky."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Sledovať pokusy o odomknutie obrazovky"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 6a909d6..cab43f2 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Lastniku omogoča sproženje operaterjeve aplikacije za konfiguracijo. Tega nikoli ni treba uporabiti za navadne aplikacije."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"spremljanje razmer v omrežju"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Aplikaciji omogoča spremljanje razmer v omrežju. Pri navadnih aplikacijah to ne bi smelo biti potrebno."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"sprememba umerjanja vhodne naprave"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Aplikaciji dovoli spreminjanje parametrov za umerjanje zaslona na dotik. Tega ni treba nikoli uporabiti za navadne aplikacije."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Nastavitev pravil za geslo"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Nadzor nad dolžino in znaki, ki so dovoljeni v geslih za odklepanje zaslona."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"nadzor nad poskusi odklepanja zaslona"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 9a53a2a7..7895ded 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Дозвољава власнику да позива апликацију са конфигурацијом коју одређује оператер. Уобичајене апликације никада не би требало да је користе."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"праћење података о условима на мрежи"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Дозвољава апликацији да прати податке о условима на мрежи. Не би никада требало да буде потребно за нормалне апликације."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"промени калибрацију улазног уређаја"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Дозвољава апликацији да модификује параметре калибрације додирног екрана. Не би требало да буде потребно за нормалне апликације."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Подешавање правила за лозинку"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролишите дужину и знакове дозвољене у лозинкама за откључавање екрана."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Надгледање покушаја откључавања екрана"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 2e2d3f2..c29f0a3 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Innehavaren tillåts att anropa konfigurationsappen från operatören. Ska inte behövas för vanliga appar."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"lyssna efter information om nätverksförhållanden"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Tillåter att appen lyssnar efter information om nätverksförhållanden. Vanliga appar bör aldrig behöva den här behörigheten."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"ändra kalibreringen för inmatningsenheten"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Tillåter att appen ändrar kalibreringsparametrarna för pekskärmen. Detta behövs aldrig för vanliga appar."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Ange lösenordsregler"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Bestäm hur många och vilka tecken som är tillåtna i skärmlåsets lösenord."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Övervaka försök att låsa upp skärmen"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 5b15a7f..3e11aa1 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -256,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ondoa njia za mikato"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Huruhusu programu kuondoa njia za mkato za Skrini ya kwanza bila mtumiaji kuingilia."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"panga upya simu zinazotoka"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Huruhusu programu kuona nambari inayopigwa wakati simu inapigwa ikiwa na chaguo la kuelekeza simu kwa nambari tofauti au kukata simu kabisa."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Huruhusu programu kuona nambari inayopigwa wakati simu inapigwa ikiwa na chaguo la kuelekeza simu kwenye nambari tofauti au kukata simu kabisa."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"pokea ujumbe wa maandishi wa SMS"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Inaruhusu programu kupokea na kuchakata ujumbe wa SMS. Hii inamaanisha programu hii inaweza kuchunguza na kufuta ujumbe uliotumwa katika kifaa chako bila ya kukuonyesha."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"pokea ujumbe wa maandishi wa MMS"</string>
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Inaruhusu kishikiliaji kuomba programu ya usakinishaji inayotolewa na mto huduma. Haipaswi kuhitajika kwa programu za kawaida."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"sikiliza matukio katika hali za mtandao"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Huruhusu programu kusikiliza matukio katika hali za mtandao. Haipaswi kuhitajika kamwe kwa programu za kawaida."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"badilisha urekebishaji wa kifaa cha kuingiza data"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Huruhusu programu kubadilisha vigezo vya urekebishaji vya skrini ya kugusa. Havipaswi kuhitajika kamwe kwa programu za kawaida."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Kuweka kanuni za nenosiri"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kudhibiti urefu na herufi zinazoruhusiwa katika manenosiri ya kufungua skrini."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Kuhesabu idadi ya mara ambazo skrini inajaribu kufunguliwa"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index a4c328e..e07bd7d 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -256,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"ถอนการติดตั้งทางลัด"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"อนุญาตให้แอปพลิเคชันลบทางลัดหน้าจอหลักโดยไม่ต้องให้ผู้ใช้จัดการ"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"จัดเส้นทางการโทรออกใหม่"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"อนุญาตให้แอปดูหมายเลขที่โทรในระหว่างการโทรออกโดยสามารถเลือกเปลี่ยนเส้นทางการโทรไปยังหมายเลขอื่นหรือยกเลิกการโทรไปเลย"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"อนุญาตให้แอปดูหมายเลขที่โทรในระหว่างการโทรออกโดยสามารถเลือกเปลี่ยนเส้นทางการโทรไปยังหมายเลขอื่นหรือยกเลิกการโทรไปเลยได้"</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"รับข้อความ (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"อนุญาตให้แอปพลิเคชันรับและประมวลผลข้อความ SMS ซึ่งหมายความว่าแอปพลิเคชันจะสามารถตรวจสอบหรือลบข้อความที่ส่งมายังอุปกรณ์ของคุณได้โดยไม่ต้องแสดงให้คุณเห็น"</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"รับข้อความ (MMS)"</string>
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"อนุญาตให้ผู้ใช้สามารถเรียกใช้แอปการกำหนดค่าของผู้ให้บริการ ซึ่งแอปทั่วไปไม่จำเป็นต้องใช้"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ฟังข้อสังเกตเกี่ยวกับสภาวะของเครือข่าย"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"อนุญาตให้แอปพลิเคชันฟังข้อสังเกตเกี่ยวกับสภาวะของเครือข่าย ไม่จำเป็นสำหรับแอปปกติ"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"เปลี่ยนการเทียบมาตรฐานอุปกรณ์อินพุต"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"อนุญาตให้แอปสามารถปรับพารามิเตอร์การเทียบมาตรฐานของหน้าจอสัมผัส ไม่ควรใช้สำหรับแอปทั่วไป"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"ตั้งค่ากฎรหัสผ่าน"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"ควบคุมความยาวและอักขระที่อนุญาตให้ใช้ในรหัสผ่านการปลดล็อกหน้าจอ"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"ตรวจสอบความพยายามในการปลดล็อกหน้าจอ"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4c54352..ec73999 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Nagbibigay-daan sa may-ari na paganahin ang app ng configuration na ibinigay ng carrier. Hindi dapat kailanganin para sa normal na apps kahit kailan."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"makinig sa mga obserbasyon sa mga kundisyon ng network"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Nagbibigay-daan sa isang application na makinig sa mga obserbasyon sa mga kundisyon ng network. Dapat na hindi kailanman kakailanganin para sa normal na apps."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"baguhin ang pag-calibrate ng input device"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Pinapayagan ang app na baguhin ang mga parameter sa pag-calibrate ng touch screen. Hindi dapat kailanganin sa normal na apps."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Magtakda ng mga panuntunan sa password"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kontrolin ang haba at mga character na pinapayagan sa mga password sa pag-unlock ng screen."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Subaybayan ang mga pagsubok sa pag-unlock ng screen"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index bf01a4e..902939e 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"İzin sahibine, operatör tarafından sağlanan yapılandırma uygulamasını çalıştırma izni verir. Normal uygulamalarda hiçbir zaman gerek duyulmaz."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"ağ koşullarındaki gözlemleri dinle"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Bir uygulamaya, ağ koşullarındaki gözlemleri dinleme izni verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"giriş cihazı kalibrasyonunu değiştir"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Uygulamaya, dokunmatik ekranın kalibrasyon parametrelerini değiştirme izni verir. Normal uygulamalar için hiçbir zaman gerekmez."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Şifre kuralları ayarla"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Ekran kilidini açma şifrelerinde izin verilen uzunluğu ve karakterleri denetleme."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Ekran kilidini açma denemelerini izle"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index dc79da7..fb96ca0 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Дозволяє власнику викликати надану оператором програму конфігурації. Ніколи не застосовується для звичайних програм."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"прослуховувати дані спостережень за станом мережі"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Дозволяє програмі прослуховувати дані спостережень за станом мережі. Ніколи не застосовується для звичайних програм."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"змінювати калібрування пристрою введення"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Програма може змінювати параметри калібрування сенсорного екрана. Ніколи не застосовується для звичайних програм."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Устан. правила пароля"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Контролювати довжину паролів для розблокування екрана та дозволені в них символи."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Відстежув. спроби розблок. екрана"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 5dcf41d..60b97c3 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -256,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"gỡ cài đặt lối tắt"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Cho phép ứng dụng xóa lối tắt trên Màn hình chính mà không cần sự can thiệp của người dùng."</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"định tuyến lại cuộc gọi đi"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Cho phép ứng dụng xem số được quay trong một cuộc gọi đi với tùy chọn chuyển hướng cuộc gọi đến một số khác hoặc hủy cuộc gọi đó hoàn toàn."</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Cho phép ứng dụng xem số được gọi trong một cuộc gọi đi với tùy chọn chuyển hướng cuộc gọi đến một số khác hoặc hủy cuộc gọi đó hoàn toàn."</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"nhận tin nhắn văn bản (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"Cho phép ứng dụng nhận và xử lý tin nhắn SMS. Điều này có nghĩa là ứng dụng có thể theo dõi hoặc xóa tin nhắn được gửi đến thiết bị của bạn mà không hiển thị chúng cho bạn."</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"nhận tin nhắn văn bản (MMS)"</string>
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Cho phép chủ sở hữu gọi ra ứng dụng cấu hình do nhà cung cấp dịch vụ cung cấp. Không cần thiết cho các ứng dụng thông thường."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"quan sát các điều kiện mạng"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Cho phép ứng dụng quan sát các điều kiện mạng. Không bao giờ cần cho ứng dụng thông thường."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"thay đổi hiệu chỉnh thiết bị đầu vào"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Cho phép ứng dụng sửa đổi các thông số hiệu chỉnh của màn hình cảm ứng. Không cần cho ứng dụng thông thường."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Đặt quy tắc mật khẩu"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Kiểm soát độ dài và ký tự được phép trong mật khẩu mở khóa màn hình."</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Giám sát những lần thử mở khóa màn hình"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 5a9c285..1b775e8 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允许应用调用运营商提供的配置应用。普通应用绝不需要此权限。"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"监听网络状况的观测信息"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允许应用监听网络状况的观测信息。普通应用绝不需要此权限。"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"更改输入设备校准设置"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"允许应用修改触摸屏的校准参数。普通应用绝不需要此权限。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"设置密码规则"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解锁密码所允许的长度和字符。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"监视屏幕解锁尝试次数"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index bfffe13..1273200 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允許應用程式調用流動網絡供應商提供的設定應用程式 (不建議一般應用程式使用)。"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"監聽對網絡狀況的觀察"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允許應用程式監聽對網絡狀況的觀察 (不建議一般應用程式使用)。"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"變更輸入裝置校正設定"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"允許應用程式修改觸控式螢幕的校正參數,而一般應用程式並不需要作出類似修改。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制屏幕解鎖密碼所允許的長度和字元。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"監控屏幕解鎖嘗試次數"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index d6bcb61..f4b96d0 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -256,7 +256,7 @@
     <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"解除安裝捷徑"</string>
     <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"允許應用程式自動移除主螢幕捷徑。"</string>
     <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"重設撥號路徑"</string>
-    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"允許應用程式在撥打電話期間查看撥出的電話號碼,並選擇改撥其他號碼或完全中斷通話。"</string>
+    <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"允許應用程式在撥打電話期間查看撥出的電話號碼,並可選擇改撥其他號碼或中斷通話。"</string>
     <string name="permlab_receiveSms" msgid="8673471768947895082">"接收簡訊 (SMS)"</string>
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"允許應用程式接收和處理簡訊。這項設定可讓應用程式監控傳送至您裝置的訊息,或在您閱讀訊息前擅自刪除訊息。"</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"接收簡訊 (MMS)"</string>
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"允許應用程式叫用行動通訊業者提供的設定應用程式 (一般應用程式並不需要)。"</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"監聽網路狀況觀察資訊"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"允許應用程式監聽網路狀況觀察資訊 (一般應用程式並不需要)。"</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"變更輸入裝置校正設定"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"允許應用程式修改觸控螢幕的校正參數 (一般應用程式並不需要)。"</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"設定密碼規則"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"控制螢幕解鎖密碼所允許的長度和字元。"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"監視螢幕解鎖嘗試次數"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index a44c04c..c7faf48 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -689,6 +689,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"Ivumela umnikazi ukuthi abuyisele uhlelo lokusebenza lokulungiselelwa. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"Lalela okubonwayo kuzimo zenethiwekhi"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"Ivumela uhlelo lokusebenza ukuthi lulalele okubonwa kuzimo zenethiwekhi. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"guqula ukulinganisa kokufaka kwedivayisi"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"Ivumela uhlelo lokusebenza ukuthi lushintshe imingcele yokulinganisa yesikrini esithintwayo. Akumele idingelwe izinhlelo zokusebenza ezijwayelekile."</string>
     <string name="policylab_limitPassword" msgid="4497420728857585791">"Misa imithetho yephasiwedi"</string>
     <string name="policydesc_limitPassword" msgid="3252114203919510394">"Lawula ubude nezinhlamvu ezivunyelwe kumaphasiwedi okuvula isikrini"</string>
     <string name="policylab_watchLogin" msgid="914130646942199503">"Gaka imizamo yokuvula isikrini"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 2043960..8482fdb 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2132,10 +2132,6 @@
         <!-- scale of the view in the y direction. -->
         <attr name="scaleY" format="float" />
 
-        <!-- Defines whether the View casts a shadow when it has a 3D rotation or Z
-             translation.-->
-        <attr name="castsShadow" format="boolean" />
-
         <!-- Determines which side the vertical scroll bar should be placed on. -->
         <attr name="verticalScrollbarPosition">
             <!-- Place the scroll bar wherever the system default determines. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 2efbca2..0a27840 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -62,6 +62,21 @@
          a reference to a Drawable resource containing the image definition. -->
     <attr name="icon" format="reference" />
 
+    <!-- A Drawable resource providing an extended graphical banner for its
+         associated item. Use with the application tag (to supply a default
+         banner for all application activities), or with the activity, tag to
+         supply a banner for a specific activity.
+
+         <p>The given banner will be used to display to the user a graphical
+         representation of an activity in the Leanback application launcher.
+         Since banners are displayed only in the Leanback launcher, they should
+         only be used with activities (and applications) that support Leanback
+         mode. These are activities that handle Intents of category
+         {@link android.content.Intent#CATEGORY_LEANBACK_LAUNCHER
+         Intent.CATEGORY_LEANBACK_LAUNCHER}.
+         <p>This must be a reference to a Drawable resource containing the image definition. -->
+    <attr name="banner" format="reference" />
+
     <!-- A Drawable resource providing an extended graphical logo for its
          associated item. Use with the application tag (to supply a default
          logo for all application components), or with the activity, receiver,
@@ -899,6 +914,7 @@
         <attr name="theme" />
         <attr name="label" />
         <attr name="icon" />
+        <attr name="banner" />
         <attr name="logo" />
         <attr name="description" />
         <attr name="permission" />
@@ -982,6 +998,7 @@
         <attr name="name" />
         <attr name="label" />
         <attr name="icon" />
+        <attr name="banner" />
         <attr name="logo" />
         <attr name="permissionGroup" />
         <attr name="description" />
@@ -1008,6 +1025,7 @@
         <attr name="name" />
         <attr name="label" />
         <attr name="icon" />
+        <attr name="banner" />
         <attr name="logo" />
         <attr name="description" />
         <attr name="permissionGroupFlags" />
@@ -1040,6 +1058,7 @@
         <attr name="name" />
         <attr name="label" />
         <attr name="icon" />
+        <attr name="banner" />
         <attr name="logo" />
     </declare-styleable>
     
@@ -1306,6 +1325,7 @@
         <attr name="label" />
         <attr name="description" />
         <attr name="icon" />
+        <attr name="banner" />
         <attr name="logo" />
         <attr name="process" />
         <attr name="authorities" />
@@ -1387,6 +1407,7 @@
         <attr name="label" />
         <attr name="description" />
         <attr name="icon" />
+        <attr name="banner" />
         <attr name="logo" />
         <attr name="permission" />
         <attr name="process" />
@@ -1429,6 +1450,7 @@
         <attr name="label" />
         <attr name="description" />
         <attr name="icon" />
+        <attr name="banner" />
         <attr name="logo" />
         <attr name="permission" />
         <attr name="process" />
@@ -1463,6 +1485,7 @@
         <attr name="label" />
         <attr name="description" />
         <attr name="icon" />
+        <attr name="banner" />
         <attr name="logo" />
         <attr name="launchMode" />
         <attr name="screenOrientation" />
@@ -1526,6 +1549,7 @@
         <attr name="label" />
         <attr name="description" />
         <attr name="icon" />
+        <attr name="banner" />
         <attr name="logo" />
         <attr name="permission" />
         <!-- Specify whether the activity-alias is enabled or not (that is, can be instantiated by the system).
@@ -1597,6 +1621,7 @@
          parent="AndroidManifestActivity AndroidManifestReceiver AndroidManifestService">
         <attr name="label" />
         <attr name="icon" />
+        <attr name="banner" />
         <attr name="logo" />
         <attr name="priority" />
     </declare-styleable>
@@ -1725,6 +1750,7 @@
         <attr name="targetPackage" />
         <attr name="label" />
         <attr name="icon" />
+        <attr name="banner" />
         <attr name="logo" />
         <attr name="handleProfiling" />
         <attr name="functionalTest" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index cfd4a63..4656f32 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1212,6 +1212,10 @@
     <!-- Whether UI for multi user should be shown -->
     <bool name="config_enableMultiUserUI">false</bool>
 
+    <!-- If true, then we do not ask user for permission for apps to connect to USB devices.
+         Do not set this to true for production devices. Doing so will cause you to fail CTS. -->
+    <bool name="config_disableUsbPermissionDialogs">false</bool>
+
     <!-- Minimum span needed to begin a touch scaling gesture.
          If the span is equal to or greater than this size, a scaling gesture
          will begin, where supported. (See android.view.ScaleGestureDetector)
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index d58e8ad..404b852 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2088,6 +2088,13 @@
   <public type="style" name="Theme.DeviceDefault.Light.NoActionBar.TranslucentDecor" id="0x010301e4" />
 
 <!-- ===============================================================
+     Resources added in version 20 of the platform
+     =============================================================== -->
+  <eat-comment />
+
+  <public type="attr" name="banner" id="0x10103f2" />
+
+<!-- ===============================================================
      Resources added in version 21 of the platform
      =============================================================== -->
   <eat-comment />
@@ -2104,7 +2111,6 @@
   <public type="attr" name="controlY2" />
   <public type="attr" name="sharedElementName" />
   <public type="attr" name="transitionGroup" />
-  <public type="attr" name="castsShadow" />
   <public type="attr" name="requiredForProfile"/>
   <public type="attr" name="pinned" />
 
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6624da4..efa873d 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -290,6 +290,7 @@
   <java-symbol type="bool" name="config_forceDefaultOrientation" />
   <java-symbol type="bool" name="config_wifi_batched_scan_supported" />
   <java-symbol type="bool" name="config_enableMultiUserUI"/>
+  <java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
 
   <java-symbol type="integer" name="config_cursorWindowSize" />
   <java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
diff --git a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
index 95f0e67..0e3c13a0 100644
--- a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
@@ -43,7 +43,10 @@
 import java.util.Arrays;
 import java.util.Random;
 
+import junit.framework.Assert;
+
 import libcore.io.IoUtils;
+import libcore.io.Libcore;
 
 /**
  * Tests for {@link FileRotator}.
@@ -367,6 +370,16 @@
         assertReadAll(rotate, "bar");
     }
 
+    public void testFileSystemInaccessible() throws Exception {
+        File inaccessibleDir = null;
+        String dirPath = getContext().getFilesDir() + File.separator + "inaccessible";
+        inaccessibleDir = new File(dirPath);
+        final FileRotator rotate = new FileRotator(inaccessibleDir, PREFIX, SECOND_IN_MILLIS, SECOND_IN_MILLIS);
+
+        // rotate should not throw on dir not mkdir-ed (or otherwise inaccessible)
+        rotate.maybeRotate(TEST_TIME);
+    }
+
     private void touch(String... names) throws IOException {
         for (String name : names) {
             final OutputStream out = new FileOutputStream(new File(mBasePath, name));
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java
index f493e9a..fc2897f 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerBaseTest.java
@@ -27,14 +27,14 @@
 import android.net.NetworkInfo;
 import android.net.wifi.WifiManager;
 import android.os.Environment;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
 import android.provider.Settings;
 import android.test.InstrumentationTestCase;
 import android.util.Log;
 
-import java.io.File;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.TimeoutException;
@@ -47,7 +47,6 @@
     protected DownloadManager mDownloadManager = null;
     protected String mFileType = "text/plain";
     protected Context mContext = null;
-    protected MultipleDownloadsCompletedReceiver mReceiver = null;
     protected static final int DEFAULT_FILE_SIZE = 10 * 1024;  // 10kb
     protected static final int FILE_BLOCK_READ_SIZE = 1024 * 1024;
 
@@ -65,70 +64,9 @@
     protected static final int MAX_WAIT_FOR_DOWNLOAD_TIME = 5 * 60 * 1000; // 5 minutes
     protected static final int MAX_WAIT_FOR_LARGE_DOWNLOAD_TIME = 15 * 60 * 1000; // 15 minutes
 
-    public static class MultipleDownloadsCompletedReceiver extends BroadcastReceiver {
-        private volatile int mNumDownloadsCompleted = 0;
-        private Set<Long> downloadIds = Collections.synchronizedSet(new HashSet<Long>());
+    private DownloadFinishedListener mListener;
+    private Thread mListenerThread;
 
-        /**
-         * {@inheritDoc}
-         */
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equalsIgnoreCase(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
-                synchronized(this) {
-                    long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
-                    Log.i(LOG_TAG, "Received Notification for download: " + id);
-                    if (!downloadIds.contains(id)) {
-                        ++mNumDownloadsCompleted;
-                        Log.i(LOG_TAG, "MultipleDownloadsCompletedReceiver got intent: " +
-                                intent.getAction() + " --> total count: " + mNumDownloadsCompleted);
-                        downloadIds.add(id);
-
-                        DownloadManager dm = (DownloadManager)context.getSystemService(
-                                Context.DOWNLOAD_SERVICE);
-
-                        Cursor cursor = dm.query(new Query().setFilterById(id));
-                        try {
-                            if (cursor.moveToFirst()) {
-                                int status = cursor.getInt(cursor.getColumnIndex(
-                                        DownloadManager.COLUMN_STATUS));
-                                Log.i(LOG_TAG, "Download status is: " + status);
-                            } else {
-                                fail("No status found for completed download!");
-                            }
-                        } finally {
-                            cursor.close();
-                        }
-                    } else {
-                        Log.i(LOG_TAG, "Notification for id: " + id + " has already been made.");
-                    }
-                }
-            }
-        }
-
-        /**
-         * Gets the number of times the {@link #onReceive} callback has been called for the
-         * {@link DownloadManager#ACTION_DOWNLOAD_COMPLETE} action, indicating the number of
-         * downloads completed thus far.
-         *
-         * @return the number of downloads completed so far.
-         */
-        public int numDownloadsCompleted() {
-            return mNumDownloadsCompleted;
-        }
-
-        /**
-         * Gets the list of download IDs.
-         * @return A Set<Long> with the ids of the completed downloads.
-         */
-        public Set<Long> getDownloadIds() {
-            synchronized(this) {
-                Set<Long> returnIds = new HashSet<Long>(downloadIds);
-                return returnIds;
-            }
-        }
-
-    }
 
     public static class WiFiChangedReceiver extends BroadcastReceiver {
         private Context mContext = null;
@@ -172,13 +110,138 @@
     }
 
     /**
+     * Broadcast receiver to listen for broadcast from DownloadManager indicating that downloads
+     * are finished.
+     */
+    private class DownloadFinishedListener extends BroadcastReceiver implements Runnable {
+        private Handler mHandler = null;
+        private Looper mLooper;
+        private Set<Long> mFinishedDownloads = new HashSet<Long>();
+
+        /**
+         * Event loop for the thread that listens to broadcasts.
+         */
+        @Override
+        public void run() {
+            Looper.prepare();
+            synchronized (this) {
+                mLooper = Looper.myLooper();
+                mHandler = new Handler();
+                notifyAll();
+            }
+            Looper.loop();
+        }
+
+        /**
+         * Handles the incoming notifications from DownloadManager.
+         */
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
+                long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
+                Log.i(LOG_TAG, "Received Notification for download: " + id);
+                synchronized (this) {
+                    if(!mFinishedDownloads.contains(id)) {
+                        mFinishedDownloads.add(id);
+                        notifyAll();
+                    } else {
+                        Log.i(LOG_TAG,
+                              String.format("Notification for %d was already received", id));
+                    }
+                }
+            }
+        }
+
+        /**
+         * Returns the handler for this thread. Need this to make sure that the events are handled
+         * in it is own thread and don't interfere with the instrumentation thread.
+         * @return Handler for the receiver thread.
+         * @throws InterruptedException
+         */
+        private Handler getHandler() throws InterruptedException {
+            synchronized (this) {
+                if (mHandler != null) return mHandler;
+                while (mHandler == null) {
+                    wait();
+                }
+                return mHandler;
+            }
+        }
+
+        /**
+         * Stops the thread that receives notification from DownloadManager.
+         */
+        public void cancel() {
+            synchronized(this) {
+                if (mLooper != null) {
+                    mLooper.quit();
+                }
+            }
+        }
+
+        /**
+         * Waits for a given download to finish, or until the timeout expires.
+         * @param id id of the download to wait for.
+         * @param timeout maximum time to wait, in milliseconds
+         * @return true if the download finished, false otherwise.
+         * @throws InterruptedException
+         */
+        public boolean waitForDownloadToFinish(long id, long timeout) throws InterruptedException {
+            long startTime = SystemClock.uptimeMillis();
+            synchronized (this) {
+                while (!mFinishedDownloads.contains(id)) {
+                    if (SystemClock.uptimeMillis() - startTime > timeout) {
+                        Log.i(LOG_TAG, String.format("Timeout while waiting for %d to finish", id));
+                        return false;
+                    } else {
+                        wait(timeout);
+                    }
+                }
+                return true;
+            }
+        }
+
+        /**
+         * Waits for multiple downloads to finish, or until timeout expires.
+         * @param ids ids of the downloads to wait for.
+         * @param timeout maximum time to wait, in milliseconds
+         * @return true of all the downloads finished, false otherwise.
+         * @throws InterruptedException
+         */
+        public boolean waitForMultipleDownloadsToFinish(Set<Long> ids, long timeout)
+                throws InterruptedException {
+            long startTime = SystemClock.uptimeMillis();
+            synchronized (this) {
+                while (!mFinishedDownloads.containsAll(ids)) {
+                    if (SystemClock.uptimeMillis() - startTime > timeout) {
+                        Log.i(LOG_TAG, "Timeout waiting for multiple downloads to finish");
+                        return false;
+                    } else {
+                        wait(timeout);
+                    }
+                }
+                return true;
+            }
+        }
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override
     public void setUp() throws Exception {
+        super.setUp();
         mContext = getInstrumentation().getContext();
         mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE);
-        mReceiver = registerNewMultipleDownloadsReceiver();
+        mListener = registerDownloadsListener();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mContext.unregisterReceiver(mListener);
+        mListener.cancel();
+        mListenerThread.join();
+        super.tearDown();
     }
 
     /**
@@ -198,12 +261,15 @@
      * that have completed.
      *
      * @return A new receiver that records and can be queried on how many downloads have completed.
+     * @throws InterruptedException
      */
-    protected MultipleDownloadsCompletedReceiver registerNewMultipleDownloadsReceiver() {
-        MultipleDownloadsCompletedReceiver receiver = new MultipleDownloadsCompletedReceiver();
-        mContext.registerReceiver(receiver, new IntentFilter(
-                DownloadManager.ACTION_DOWNLOAD_COMPLETE));
-        return receiver;
+    protected DownloadFinishedListener registerDownloadsListener() throws InterruptedException {
+        DownloadFinishedListener listener = new DownloadFinishedListener();
+        mListenerThread = new Thread(listener);
+        mListenerThread.start();
+        mContext.registerReceiver(listener, new IntentFilter(
+                DownloadManager.ACTION_DOWNLOAD_COMPLETE), null, listener.getHandler());
+        return listener;
     }
 
     /**
@@ -283,76 +349,35 @@
     }
 
     /**
-     * Helper to wait for a particular download to finish, or else a timeout to occur
-     *
-     * Does not wait for a receiver notification of the download.
-     *
-     * @param id The download id to query on (wait for)
-     */
-    protected void waitForDownloadOrTimeout_skipNotification(long id) throws TimeoutException,
-            InterruptedException {
-        doWaitForDownloadsOrTimeout(new Query().setFilterById(id),
-                WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
-    }
-
-    /**
-     * Helper to wait for a particular download to finish, or else a timeout to occur
-     *
-     * Also guarantees a notification has been posted for the download.
-     *
-     * @param id The download id to query on (wait for)
-     */
-    protected void waitForDownloadOrTimeout(long id) throws TimeoutException,
-            InterruptedException {
-        waitForDownloadOrTimeout(id, WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
-    }
-
-    /**
-     * Helper to wait for a particular download to finish, or else a timeout to occur
-     *
-     * Also guarantees a notification has been posted for the download.
+     * Helper to wait for a particular download to finish, or else a timeout to occur.
      *
      * @param id The download id to query on (wait for)
      * @param poll The amount of time to wait
      * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
      */
-    protected void waitForDownloadOrTimeout(long id, long poll, long timeoutMillis)
-            throws TimeoutException, InterruptedException {
-        doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
-        waitForReceiverNotifications(1);
+    protected boolean waitForDownload(long id, long timeoutMillis)
+            throws InterruptedException {
+        return mListener.waitForDownloadToFinish(id, timeoutMillis);
+    }
+
+    protected boolean waitForMultipleDownloads(Set<Long> ids, long timeout)
+            throws InterruptedException {
+        return mListener.waitForMultipleDownloadsToFinish(ids, timeout);
     }
 
     /**
-     * Helper to wait for all downloads to finish, or else a specified timeout to occur
-     *
-     * Makes no guaranee that notifications have been posted for all downloads.
-     *
-     * @param poll The amount of time to wait
-     * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
+     * Checks with the download manager if the give download is finished.
+     * @param id id of the download to check
+     * @return true if download is finished, false otherwise.
      */
-    protected void waitForDownloadsOrTimeout(long poll, long timeoutMillis) throws TimeoutException,
-            InterruptedException {
-        doWaitForDownloadsOrTimeout(new Query(), poll, timeoutMillis);
-    }
-
-    /**
-     * Helper to wait for all downloads to finish, or else a timeout to occur, but does not throw
-     *
-     * Also guarantees a notification has been posted for the download.
-     *
-     * @param id The id of the download to query against
-     * @param poll The amount of time to wait
-     * @param timeoutMillis The max time (in ms) to wait for the download(s) to complete
-     * @return true if download completed successfully (didn't timeout), false otherwise
-     */
-    private boolean waitForDownloadOrTimeoutNoThrow(long id, long poll, long timeoutMillis) {
-        try {
-            doWaitForDownloadsOrTimeout(new Query().setFilterById(id), poll, timeoutMillis);
-            waitForReceiverNotifications(1);
-        } catch (TimeoutException e) {
-            return false;
-        }
-        return true;
+    private boolean hasDownloadFinished(long id) {
+        Query q = new Query();
+        q.setFilterById(id);
+        q.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL);
+        Cursor cursor = mDownloadManager.query(q);
+        boolean finished = cursor.getCount() == 1;
+        cursor.close();
+        return finished;
     }
 
     /**
@@ -389,34 +414,6 @@
     }
 
     /**
-     * Helper to wait for all downloads to finish, or else a timeout to occur
-     *
-     * @param query The query to pass to the download manager
-     * @param poll The poll time to wait between checks
-     * @param timeoutMillis The max amount of time (in ms) to wait for the download(s) to complete
-     */
-    private void doWaitForDownloadsOrTimeout(Query query, long poll, long timeoutMillis)
-            throws TimeoutException {
-        int currentWaitTime = 0;
-        while (true) {
-            query.setFilterByStatus(DownloadManager.STATUS_PENDING | DownloadManager.STATUS_PAUSED
-                    | DownloadManager.STATUS_RUNNING);
-            Cursor cursor = mDownloadManager.query(query);
-
-            try {
-                if (cursor.getCount() == 0) {
-                    Log.i(LOG_TAG, "All downloads should be done...");
-                    break;
-                }
-                currentWaitTime = timeoutWait(currentWaitTime, poll, timeoutMillis,
-                        "Timed out waiting for all downloads to finish");
-            } finally {
-                cursor.close();
-            }
-        }
-    }
-
-    /**
      * Synchronously waits for external store to be mounted (eg: SD Card).
      *
      * @throws InterruptedException if interrupted
@@ -465,53 +462,50 @@
     }
 
     /**
-     * Synchronously waits for our receiver to receive notification for a given number of
-     * downloads.
+     * Synchronously waits for the download manager to start incrementing the number of
+     * bytes downloaded so far.
      *
-     * @param targetNumber The number of notifications for unique downloads to wait for; pass in
-     *         -1 to not wait for notification.
-     * @throws Exception if timed out while waiting
-     */
-    private void waitForReceiverNotifications(int targetNumber) throws TimeoutException {
-        int count = mReceiver.numDownloadsCompleted();
-        int currentWaitTime = 0;
-
-        while (count < targetNumber) {
-            Log.i(LOG_TAG, "Waiting for notification of downloads...");
-            currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
-                    MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for download notifications!"
-                    + " Received " + count + "notifications.");
-            count = mReceiver.numDownloadsCompleted();
-        }
-    }
-
-    /**
-     * Synchronously waits for a file to increase in size (such as to monitor that a download is
-     * progressing).
-     *
-     * @param file The file whose size to track.
+     * @param id DownloadManager download id that needs to be checked.
      * @throws Exception if timed out while waiting for the file to grow in size.
      */
-    protected void waitForFileToGrow(File file) throws Exception {
+    protected void waitToReceiveData(long id) throws Exception {
         int currentWaitTime = 0;
-
-        // File may not even exist yet, so wait until it does (or we timeout)
-        while (!file.exists()) {
-            Log.i(LOG_TAG, "Waiting for file to exist...");
-            currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
-                    MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be created.");
-        }
-
-        // Get original file size...
-        long originalSize = file.length();
-
-        while (file.length() <= originalSize) {
-            Log.i(LOG_TAG, "Waiting for file to be written to...");
+        long originalSize = getBytesDownloaded(id);
+        long currentSize = 0;
+        while ((currentSize = getBytesDownloaded(id)) <= originalSize) {
+            Log.i(LOG_TAG, String.format("orig: %d, cur: %d. Waiting for file to be written to...",
+                    originalSize, currentSize));
             currentWaitTime = timeoutWait(currentWaitTime, WAIT_FOR_DOWNLOAD_POLL_TIME,
                     MAX_WAIT_FOR_DOWNLOAD_TIME, "Timed out waiting for file to be written to.");
         }
     }
 
+    private long getBytesDownloaded(long id) {
+        DownloadManager.Query q = new DownloadManager.Query();
+        q.setFilterById(id);
+        Cursor response = mDownloadManager.query(q);
+        if (response.getCount() < 1) {
+            Log.i(LOG_TAG, String.format("Query to download manager returned nothing for id %d",id));
+            response.close();
+            return -1;
+        }
+        while(response.moveToNext()) {
+            int index = response.getColumnIndex(DownloadManager.COLUMN_ID);
+            if (id == response.getLong(index)) {
+                break;
+            }
+        }
+        int index = response.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR);
+        if (index < 0) {
+            Log.i(LOG_TAG, String.format("No downloaded bytes for id %d", id));
+            response.close();
+            return -1;
+        }
+        long size = response.getLong(index);
+        response.close();
+        return size;
+    }
+
     /**
      * Helper to remove all downloads that are registered with the DL Manager.
      *
@@ -536,19 +530,6 @@
     }
 
     /**
-     * Helper to verify an int value in a Cursor
-     *
-     * @param cursor The cursor containing the query results
-     * @param columnName The name of the column to query
-     * @param expected The expected int value
-     */
-    private void verifyInt(Cursor cursor, String columnName, int expected) {
-        int index = cursor.getColumnIndex(columnName);
-        int actual = cursor.getInt(index);
-        assertEquals(expected, actual);
-    }
-
-    /**
      * Performs a query based on ID and returns a Cursor for the query.
      *
      * @param id The id of the download in DL Manager; pass -1 to query all downloads
diff --git a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
index 06c6c34..ef48a18 100644
--- a/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
+++ b/core/tests/hosttests/test-apps/DownloadManagerTestApp/src/com/android/frameworks/downloadmanagertests/DownloadManagerTestApp.java
@@ -23,9 +23,6 @@
 import android.os.ParcelFileDescriptor;
 import android.util.Log;
 
-import com.android.frameworks.downloadmanagertests.DownloadManagerBaseTest;
-import com.android.frameworks.downloadmanagertests.DownloadManagerTestRunner;
-
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.File;
@@ -193,9 +190,7 @@
             int status = cursor.getInt(columnIndex);
             int currentWaitTime = 0;
 
-            // Wait until the download finishes; don't wait for a notification b/c
-            // the download may well have been completed before the last reboot.
-            waitForDownloadOrTimeout_skipNotification(dlRequest);
+            assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000));
 
             Log.i(LOG_TAG, "Verifying download information...");
             // Verify specific info about the file (size, name, etc)...
@@ -235,7 +230,7 @@
         dlRequest = mDownloadManager.enqueue(request);
 
         // Rather large file, so wait up to 15 mins...
-        waitForDownloadOrTimeout(dlRequest, WAIT_FOR_DOWNLOAD_POLL_TIME, 15 * 60 * 1000);
+        assertTrue(waitForDownload(dlRequest, 15 * 60 * 1000));
 
         Cursor cursor = getCursor(dlRequest);
         ParcelFileDescriptor pfd = null;
@@ -289,7 +284,7 @@
             dlRequest = mDownloadManager.enqueue(request);
             waitForDownloadToStart(dlRequest);
             // make sure we're starting to download some data...
-            waitForFileToGrow(downloadedFile);
+            waitToReceiveData(dlRequest);
 
             // download disable
             setWiFiStateOn(false);
@@ -317,7 +312,7 @@
             Log.i(LOG_TAG, "Turning on WiFi...");
             setWiFiStateOn(true);
             Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete...");
-            waitForDownloadsOrTimeout(dlRequest, 3 * 60 * 1000);
+            assertTrue(waitForDownload(dlRequest, 3 * 60 * 1000));
             ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
             verifyFileSize(pfd, filesize);
         } finally {
@@ -363,7 +358,7 @@
             dlRequest = mDownloadManager.enqueue(request);
             waitForDownloadToStart(dlRequest);
             // are we making any progress?
-            waitForFileToGrow(downloadedFile);
+            waitToReceiveData(dlRequest);
 
             // download disable
             Log.i(LOG_TAG, "Turning off WiFi...");
@@ -373,7 +368,7 @@
             // enable download...
             Log.i(LOG_TAG, "Turning on WiFi again...");
             setWiFiStateOn(true);
-            waitForFileToGrow(downloadedFile);
+            waitToReceiveData(dlRequest);
 
             // download disable
             Log.i(LOG_TAG, "Turning off WiFi...");
@@ -385,7 +380,7 @@
             setWiFiStateOn(true);
 
             Log.i(LOG_TAG, "Waiting up to 3 minutes for download to complete...");
-            waitForDownloadsOrTimeout(dlRequest, 3 * 60 * 1000);
+            assertTrue(waitForDownload(dlRequest, 3 * 60 * 1000));
             ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
             verifyFileSize(pfd, filesize);
         } finally {
@@ -433,7 +428,7 @@
             dlRequest = mDownloadManager.enqueue(request);
             waitForDownloadToStart(dlRequest);
             // are we making any progress?
-            waitForFileToGrow(downloadedFile);
+            waitToReceiveData(dlRequest);
 
             // download disable
             Log.i(LOG_TAG, "Turning on Airplane mode...");
@@ -444,7 +439,7 @@
             Log.i(LOG_TAG, "Turning off Airplane mode...");
             setAirplaneModeOn(false);
             // make sure we're starting to download some data...
-            waitForFileToGrow(downloadedFile);
+            waitToReceiveData(dlRequest);
 
             // reenable the connection to start up the download again
             Log.i(LOG_TAG, "Turning on Airplane mode again...");
@@ -456,7 +451,7 @@
             setAirplaneModeOn(false);
 
             Log.i(LOG_TAG, "Waiting up to 3 minutes for donwload to complete...");
-            waitForDownloadsOrTimeout(dlRequest, 180 * 1000);  // wait up to 3 mins before timeout
+            assertTrue(waitForDownload(dlRequest, 180 * 1000));  // wait up to 3 mins before timeout
             ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
             verifyFileSize(pfd, filesize);
         } finally {
@@ -476,7 +471,6 @@
     public void runDownloadMultipleSimultaneously() throws Exception {
         final int TOTAL_DOWNLOADS = 15;
         HashSet<Long> downloadIds = new HashSet<Long>(TOTAL_DOWNLOADS);
-        MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
 
         // Make sure there are no pending downloads currently going on
         removeAllCurrentDownloads();
@@ -494,8 +488,7 @@
                 downloadIds.add(dlRequest);
             }
 
-            waitForDownloadsOrTimeout(DEFAULT_WAIT_POLL_TIME, 15 * 60 * 2000);  // wait 15 mins max
-            assertEquals(TOTAL_DOWNLOADS, receiver.numDownloadsCompleted());
+            assertTrue(waitForMultipleDownloads(downloadIds, 15 * 60 * 2000));  // wait 15 mins max
         } finally {
             removeAllCurrentDownloads();
         }
diff --git a/docs/html/images/home/aw_dac.png b/docs/html/images/home/aw_dac.png
new file mode 100644
index 0000000..588ec11
--- /dev/null
+++ b/docs/html/images/home/aw_dac.png
Binary files differ
diff --git a/docs/html/images/screens_support/avds-config.png b/docs/html/images/screens_support/avds-config.png
index 97bd5f6..e609447 100644
--- a/docs/html/images/screens_support/avds-config.png
+++ b/docs/html/images/screens_support/avds-config.png
Binary files differ
diff --git a/docs/html/images/tools/as-camera-icon.png b/docs/html/images/tools/as-camera-icon.png
new file mode 100644
index 0000000..419a88d
--- /dev/null
+++ b/docs/html/images/tools/as-camera-icon.png
Binary files differ
diff --git a/docs/html/images/tools/as-error.png b/docs/html/images/tools/as-error.png
new file mode 100644
index 0000000..8865f54
--- /dev/null
+++ b/docs/html/images/tools/as-error.png
Binary files differ
diff --git a/docs/html/images/tools/as-fr-device.png b/docs/html/images/tools/as-fr-device.png
new file mode 100644
index 0000000..aec3bce
--- /dev/null
+++ b/docs/html/images/tools/as-fr-device.png
Binary files differ
diff --git a/docs/html/images/tools/as-fr-icon.png b/docs/html/images/tools/as-fr-icon.png
new file mode 100644
index 0000000..9252ca1
--- /dev/null
+++ b/docs/html/images/tools/as-fr-icon.png
Binary files differ
diff --git a/docs/html/images/tools/as-frag-ex.png b/docs/html/images/tools/as-frag-ex.png
new file mode 100644
index 0000000..775fa5e
--- /dev/null
+++ b/docs/html/images/tools/as-frag-ex.png
Binary files differ
diff --git a/docs/html/images/tools/as-grid-layout.png b/docs/html/images/tools/as-grid-layout.png
new file mode 100644
index 0000000..41b933a
--- /dev/null
+++ b/docs/html/images/tools/as-grid-layout.png
Binary files differ
diff --git a/docs/html/images/tools/as-i18n-icon.png b/docs/html/images/tools/as-i18n-icon.png
new file mode 100644
index 0000000..d35568f
--- /dev/null
+++ b/docs/html/images/tools/as-i18n-icon.png
Binary files differ
diff --git a/docs/html/images/tools/as-preview-chrome.png b/docs/html/images/tools/as-preview-chrome.png
new file mode 100644
index 0000000..716b8d7
--- /dev/null
+++ b/docs/html/images/tools/as-preview-chrome.png
Binary files differ
diff --git a/docs/html/images/tools/as-preview-icon.png b/docs/html/images/tools/as-preview-icon.png
new file mode 100644
index 0000000..59c7644
--- /dev/null
+++ b/docs/html/images/tools/as-preview-icon.png
Binary files differ
diff --git a/docs/html/images/tools/as-preview-nochrome.png b/docs/html/images/tools/as-preview-nochrome.png
new file mode 100644
index 0000000..1011e08
--- /dev/null
+++ b/docs/html/images/tools/as-preview-nochrome.png
Binary files differ
diff --git a/docs/html/images/tools/as-theme-db.png b/docs/html/images/tools/as-theme-db.png
new file mode 100644
index 0000000..beade0d
--- /dev/null
+++ b/docs/html/images/tools/as-theme-db.png
Binary files differ
diff --git a/docs/html/images/tools/as-theme-icon.png b/docs/html/images/tools/as-theme-icon.png
new file mode 100644
index 0000000..0e5fdf0
--- /dev/null
+++ b/docs/html/images/tools/as-theme-icon.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/adt-firstapp-setup.png b/docs/html/images/training/firstapp/adt-firstapp-setup.png
index bf95285..05e147d 100644
--- a/docs/html/images/training/firstapp/adt-firstapp-setup.png
+++ b/docs/html/images/training/firstapp/adt-firstapp-setup.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/adt-new-activity.png b/docs/html/images/training/firstapp/adt-new-activity.png
index c396793..2c32dcc 100644
--- a/docs/html/images/training/firstapp/adt-new-activity.png
+++ b/docs/html/images/training/firstapp/adt-new-activity.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/edittext_gravity.png b/docs/html/images/training/firstapp/edittext_gravity.png
index f78e676..bc4f7ee 100644
--- a/docs/html/images/training/firstapp/edittext_gravity.png
+++ b/docs/html/images/training/firstapp/edittext_gravity.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/edittext_wrap.png b/docs/html/images/training/firstapp/edittext_wrap.png
index 156776d..fe56731 100644
--- a/docs/html/images/training/firstapp/edittext_wrap.png
+++ b/docs/html/images/training/firstapp/edittext_wrap.png
Binary files differ
diff --git a/docs/html/images/training/firstapp/firstapp.png b/docs/html/images/training/firstapp/firstapp.png
index d69cd20..581e000 100644
--- a/docs/html/images/training/firstapp/firstapp.png
+++ b/docs/html/images/training/firstapp/firstapp.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 5d1788a..baeaa5b 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -17,17 +17,34 @@
             <ul>
                 <!-- set explicit widths as needed to prevent overflow issues -->
 
+
+                <li class="item carousel-home">
+                  <div class="content-left col-10" style="width:580px;">
+                    <a href="{@docRoot}design/patterns/new.html">
+                      <img src="{@docRoot}images/home/aw_dac.png" style="margin-top:50px" >
+                    </a>
+                  </div>
+                  <div class="content-right col-5" style="width:280px;">
+                    <h1>Introducing Android Wear</h1>
+                    <p>We’re extending the Android platform to wearables. You can start building richer wearable experiences for your apps today using the enhanced Notification APIs in this Developer Preview.</p>
+                    <p>We can’t wait to see what you will create.</p>
+                    <p><a href="{@docRoot}wear/index.html" class="button">Learn more</a></p>
+                  </div>
+                </li>
+
+
                 <li class="item carousel-home">
                     <div class="content-left col-11" style="padding-top:65px;">
                       <script src="//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
                       <div style="box-shadow: 3px 10px 18px 1px #999;width:600px;height:336px">
                         <div id="ytapiplayer">
-                          <a href="http://www.youtube.com/watch?v=WWArLD6nqrk"><img width=600 src="{@docRoot}images/video-kiwi.jpg"></a><!--You need Flash player 8+ and JavaScript enabled to view this video. -->
+                          <a href="http://www.youtube.com/watch?v=i2uvYI6blEE"><img width=600 
+                          src="https://i1.ytimg.com/vi/i2uvYI6blEE/maxresdefault.jpg"></a><!--You need Flash player 8+ and JavaScript enabled to view this video. -->
                         </div>
                         <script type="text/javascript">
                             var params = { allowScriptAccess: "always" };
                             var atts = { id: "ytapiplayer" };
-                            swfobject.embedSWF("//www.youtube.com/v/WWArLD6nqrk?enablejsapi=1&playerapiid=ytplayer&version=3&HD=1;rel=0;showinfo=0;modestbranding;origin=developer.android.com;autohide=1",
+                            swfobject.embedSWF("//www.youtube.com/v/i2uvYI6blEE?enablejsapi=1&playerapiid=ytplayer&version=3&HD=1;rel=0;showinfo=0;modestbranding;origin=developer.android.com;autohide=1",
                               "ytapiplayer", "600", "336", "8", null, null, params, atts);
 
                             // Callback used to pause/resume carousel based on video state
@@ -56,9 +73,8 @@
                       </div>
                     </div>
                     <div class="content-right col-4">
-                    <h1 style="white-space:nowrap;line-height:1.2em;">Developer Story: <br />Kiwi, Inc.</h1>
-                    <p>Game developer Kiwi has had five titles in the top 25 grossing on Google Play. Hear how Google Play
-                      has helped them double revenue every six months.</p>
+                    <h1 style="white-space:nowrap;line-height:1.2em;">Developer Story: <br />Box Inc.</h1>
+                    <p>Box is a cloud-based platform and app for users to share business information. See how they got over 5 million downloads by leveraging the flexibility in the Android platform.</p>
                       <p><a href="{@docRoot}distribute/googleplay/spotlight/index.html" class="button">Watch more videos </a></p>
                     </div>
                 </li>
diff --git a/docs/html/reference/android/preview/support/package-summary.html b/docs/html/reference/android/preview/support/package-summary.html
new file mode 100644
index 0000000..d367f87
--- /dev/null
+++ b/docs/html/reference/android/preview/support/package-summary.html
@@ -0,0 +1,478 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>Preview Notifications Reference | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="http://fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="http://www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+
+<body class="gc-documentation 
+  develop">
+  <div id="doc-api-level" class="" style="display:none"></div>
+  <a name="top"></a>
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12" id="doc-col">
+
+<div id="api-info-block">
+<div class="api-level">
+  
+  
+  
+
+</div>
+</div>
+
+
+<div id="naMessage"></div>
+
+<div id="jd-content" class="api apilevel-">
+
+
+
+
+
+
+
+  
+
+
+
+
+    <h2>android.preview.support.v4.app</h2>
+    <div class="jd-sumtable">
+    
+  <table class="jd-sumtable-expando">
+        <tr class=" api apilevel-" >
+              <td class="jd-linkcol"><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></td>
+              <td class="jd-descrcol" width="100%">Compatibility library for NotificationManager with fallbacks for older platforms.&nbsp;</td>
+          </tr>
+  </table>
+    </div>
+
+
+
+
+    <h2>android.preview.support.wearable.notifications</h2>
+    <div class="jd-sumtable">
+    
+  <table class="jd-sumtable-expando">
+        <tr class="alt-color api apilevel-" >
+              <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></td>
+              <td class="jd-descrcol" width="100%">A RemoteInput specifies a response to be collected from the user as part of an intent being
+ sent.&nbsp;</td>
+          </tr>
+        <tr class=" api apilevel-" >
+              <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html">RemoteInput.Builder</a></td>
+              <td class="jd-descrcol" width="100%">Builder class for <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code> objects.&nbsp;</td>
+          </tr>
+        <tr class="alt-color api apilevel-" >
+              <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></td>
+              <td class="jd-descrcol" width="100%">Helper providing extensions to android notifications for use with wearable devices.&nbsp;</td>
+          </tr>
+        <tr class=" api apilevel-" >
+              <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></td>
+              <td class="jd-descrcol" width="100%">Subclass of <code><a href="/reference/android/support/v4/app/NotificationCompat.Action.html">NotificationCompat.Action</a></code> which adds support for additional
+ wearable extensions.&nbsp;</td>
+          </tr>
+        <tr class="alt-color api apilevel-" >
+              <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></td>
+              <td class="jd-descrcol" width="100%">Builder class for <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code> objects.&nbsp;</td>
+          </tr>
+        <tr class=" api apilevel-" >
+              <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></td>
+              <td class="jd-descrcol" width="100%">Builder object that wraps a <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> to provide
+ methods for adding wearable extensions to a notification.&nbsp;</td>
+          </tr>
+  </table>
+    </div>
+  
+
+
+
+
+
+
+
+
+
+
+  
+
+
+  
+
+
+  
+
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is licensed under <a
+  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
+  For details and restrictions, see the <a href="/license.html">
+  Content License</a>.
+  </div>
+  <div id="build_info">
+    
+    Android &nbsp;r &mdash; 
+<script src="/timestamp.js" type="text/javascript"></script>
+<script>document.write(BUILD_TIMESTAMP)</script>
+
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div><!-- end jd-content -->
+</div><!-- doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+</body>
+</html>
diff --git a/docs/html/reference/android/preview/support/v4/app/NotificationManagerCompat.html b/docs/html/reference/android/preview/support/v4/app/NotificationManagerCompat.html
new file mode 100644
index 0000000..94b5977
--- /dev/null
+++ b/docs/html/reference/android/preview/support/v4/app/NotificationManagerCompat.html
@@ -0,0 +1,1266 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>NotificationManagerCompat | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="http://fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="http://www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  develop" itemscope itemtype="http://schema.org/Article">
+  <div id="doc-api-level" class="" style="display:none"></div>
+  <a name="top"></a>
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12"  id="doc-col">
+
+<div id="api-info-block">
+
+
+
+  
+   
+  
+  
+  
+  
+
+
+<div class="sum-details-links">
+
+Summary:
+
+
+
+
+
+  <a href="#constants">Constants</a>
+  
+
+
+
+
+
+
+
+  &#124; <a href="#pubmethods">Methods</a>
+  
+
+
+
+  &#124; <a href="#inhmethods">Inherited Methods</a>
+
+&#124; <a href="#" onclick="return toggleAllClassInherited()" id="toggleAllClassInherited">[Expand All]</a>
+
+</div><!-- end sum-details-links -->
+<div class="api-level">
+  
+  
+  
+
+</div>
+</div><!-- end api-info-block -->
+
+
+<!-- ======== START OF CLASS DATA ======== -->
+
+<div id="jd-header">
+    public
+     
+     
+    
+    class
+<h1 itemprop="name">NotificationManagerCompat</h1>
+
+
+
+  
+    extends <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a><br/>
+  
+  
+  
+
+  
+  
+  
+
+
+</div><!-- end header -->
+
+<div id="naMessage"></div>
+
+<div id="jd-content" class="api apilevel-">
+<table class="jd-inheritance-table">
+
+
+    <tr>
+         	
+        <td colspan="2" class="jd-inheritance-class-cell"><a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a></td>
+    </tr>
+    
+
+    <tr>
+        
+            <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
+         	
+        <td colspan="1" class="jd-inheritance-class-cell">android.preview.support.v4.app.NotificationManagerCompat</td>
+    </tr>
+    
+
+</table>
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Class Overview</h2>
+<p itemprop="articleBody">Compatibility library for NotificationManager with fallbacks for older platforms.
+
+ <p>To use this class, call the static function <code><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html#from(android.content.Context)">from(Context)</a></code> to get a
+ <code><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></code> object, and then call one of its
+ methods to post or cancel notifications.
+</p>
+
+
+
+
+
+</div><!-- jd-descr -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Summary</h2>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<!-- =========== ENUM CONSTANT SUMMARY =========== -->
+<table id="constants" class="jd-sumtable"><tr><th colspan="12">Constants</th></tr>
+
+
+    
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><a href="http://developer.android.com/reference/java/lang/String.html">String</a></td>
+        <td class="jd-linkcol"><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html#ACTION_BIND_SIDE_CHANNEL">ACTION_BIND_SIDE_CHANNEL</a></td>
+        <td class="jd-descrcol" width="100%">Intent action to register for on a service to receive side channel
+ notifications.</td>
+    </tr>
+    
+    
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><a href="http://developer.android.com/reference/java/lang/String.html">String</a></td>
+        <td class="jd-linkcol"><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html#EXTRA_USE_SIDE_CHANNEL">EXTRA_USE_SIDE_CHANNEL</a></td>
+        <td class="jd-descrcol" width="100%">Notification extras key: if set to true, the posted notification should use
+ the side channel for delivery instead of using notification manager.</td>
+    </tr>
+    
+    
+
+</table>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="pubmethods" class="jd-sumtable"><tr><th colspan="12">Public 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/preview/support/v4/app/NotificationManagerCompat.html#cancel(int)">cancel</a></span>(int id)</nobr>
+        
+        <div class="jd-descrdiv">Cancel a previously shown notification.</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/preview/support/v4/app/NotificationManagerCompat.html#cancel(java.lang.String, int)">cancel</a></span>(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> tag, int id)</nobr>
+        
+        <div class="jd-descrdiv">Cancel a previously shown notification.</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/preview/support/v4/app/NotificationManagerCompat.html#cancelAll()">cancelAll</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">Cancel all previously shown notifications.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            <a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html#from(android.content.Context)">from</a></span>(<a href="http://developer.android.com/reference/android/content/Context.html">Context</a> context)</nobr>
+        
+        <div class="jd-descrdiv">Get a <code><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></code> instance for a provided context.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            <a href="http://developer.android.com/reference/java/util/Set.html">Set</a>&lt;<a href="http://developer.android.com/reference/java/lang/String.html">String</a>&gt;</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html#getEnabledListenerPackages(android.content.Context)">getEnabledListenerPackages</a></span>(<a href="http://developer.android.com/reference/android/content/Context.html">Context</a> context)</nobr>
+        
+        <div class="jd-descrdiv">Get the list of packages that have an enabled notification listener component within them,
+ with caching for performance.</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/preview/support/v4/app/NotificationManagerCompat.html#notify(int, android.app.Notification)">notify</a></span>(int id, <a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notification)</nobr>
+        
+        <div class="jd-descrdiv">Post a notification to be shown in the status bar, stream, etc.</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/preview/support/v4/app/NotificationManagerCompat.html#notify(java.lang.String, int, android.app.Notification)">notify</a></span>(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> tag, int id, <a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notification)</nobr>
+        
+        <div class="jd-descrdiv">Post a notification to be shown in the status bar, stream, etc.</div>
+  
+  </td></tr>
+
+
+
+</table>
+
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="inhmethods" class="jd-sumtable"><tr><th>
+  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
+  <div style="clear:left;">Inherited Methods</div></th></tr>
+
+
+<tr class="api apilevel-" >
+<td colspan="12">
+  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-java.lang.Object" class="jd-expando-trigger closed"
+          ><img id="inherited-methods-java.lang.Object-trigger"
+          src="/assets/images/triangle-closed.png"
+          class="jd-expando-trigger-img" /></a>
+From class
+
+  <a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a>
+
+<div id="inherited-methods-java.lang.Object">
+  <div id="inherited-methods-java.lang.Object-list"
+        class="jd-inheritedlinks">
+  </div>
+  <div id="inherited-methods-java.lang.Object-summary" style="display: none;">
+    <table class="jd-sumtable-expando">
+    
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">clone</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">equals</span>(<a href="http://developer.android.com/reference/java/lang/Object.html">Object</a> arg0)</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">finalize</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Class.html">Class</a>&lt;?&gt;</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">getClass</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">hashCode</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notify</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notifyAll</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/String.html">String</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">toString</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0, int arg1)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0)</nobr>
+        
+  </td></tr>
+
+
+</table>
+  </div>
+</div>
+</td></tr>
+
+
+</table>
+
+
+</div><!-- jd-descr (summary) -->
+
+<!-- Details -->
+
+
+
+
+
+
+
+
+<!-- XML Attributes -->
+
+
+<!-- Enum Values -->
+
+
+<!-- Constants -->
+
+
+<!-- ========= ENUM CONSTANTS DETAIL ======== -->
+<h2>Constants</h2>
+
+
+
+
+<A NAME="ACTION_BIND_SIDE_CHANNEL"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+        final 
+        <a href="http://developer.android.com/reference/java/lang/String.html">String</a>
+      </span>
+        ACTION_BIND_SIDE_CHANNEL
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Intent action to register for on a service to receive side channel
+ notifications. The listening service must be in the same package as an enabled
+ <code><a href="/">ERROR(/android.service.notification.NotificationListenerService)</a></code>.
+</p></div>
+
+    
+        <div class="jd-tagdata">
+        <span class="jd-tagtitle">Constant Value: </span>
+        <span>
+            
+                "android.support.app.notification.BIND_SIDE_CHANNEL"
+            
+        </span>
+        </div>
+    
+    </div>
+</div>
+
+
+
+<A NAME="EXTRA_USE_SIDE_CHANNEL"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+        final 
+        <a href="http://developer.android.com/reference/java/lang/String.html">String</a>
+      </span>
+        EXTRA_USE_SIDE_CHANNEL
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Notification extras key: if set to true, the posted notification should use
+ the side channel for delivery instead of using notification manager.
+</p></div>
+
+    
+        <div class="jd-tagdata">
+        <span class="jd-tagtitle">Constant Value: </span>
+        <span>
+            
+                "android.preview.support.useSideChannel"
+            
+        </span>
+        </div>
+    
+    </div>
+</div>
+
+
+
+
+<!-- Fields -->
+
+
+<!-- Public ctors -->
+
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<!-- Protected ctors -->
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+<!-- Public methdos -->
+
+<h2>Public Methods</h2>
+
+
+
+<A NAME="cancel(int)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">cancel</span>
+      <span class="normal">(int id)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Cancel a previously shown notification. </p></div>
+
+    </div>
+</div>
+
+
+<A NAME="cancel(java.lang.String, int)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">cancel</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> tag, int id)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Cancel a previously shown notification. </p></div>
+
+    </div>
+</div>
+
+
+<A NAME="cancelAll()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">cancelAll</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>Cancel all previously shown notifications. </p></div>
+
+    </div>
+</div>
+
+
+<A NAME="from(android.content.Context)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        <a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a>
+      </span>
+      <span class="sympad">from</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/content/Context.html">Context</a> context)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Get a <code><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></code> instance for a provided context. </p></div>
+
+    </div>
+</div>
+
+
+<A NAME="getEnabledListenerPackages(android.content.Context)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        <a href="http://developer.android.com/reference/java/util/Set.html">Set</a>&lt;<a href="http://developer.android.com/reference/java/lang/String.html">String</a>&gt;
+      </span>
+      <span class="sympad">getEnabledListenerPackages</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/content/Context.html">Context</a> context)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Get the list of packages that have an enabled notification listener component within them,
+ with caching for performance.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="notify(int, android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">notify</span>
+      <span class="normal">(int id, <a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notification)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Post a notification to be shown in the status bar, stream, etc. </p></div>
+
+    </div>
+</div>
+
+
+<A NAME="notify(java.lang.String, int, android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">notify</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> tag, int id, <a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notification)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Post a notification to be shown in the status bar, stream, etc. </p></div>
+
+    </div>
+</div>
+
+
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+
+
+
+<!-- ========= END OF CLASS DATA ========= -->
+<A NAME="navbar_top"></A>
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is licensed under <a
+  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
+  For details and restrictions, see the <a href="/license.html">
+  Content License</a>.
+  </div>
+  <div id="build_info">
+    
+    Android &nbsp;r &mdash; 
+<script src="/timestamp.js" type="text/javascript"></script>
+<script>document.write(BUILD_TIMESTAMP)</script>
+
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div> <!-- jd-content -->
+
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+</body>
+</html>
diff --git a/docs/html/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html b/docs/html/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html
new file mode 100644
index 0000000..307fc2a
--- /dev/null
+++ b/docs/html/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html
@@ -0,0 +1,1089 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>RemoteInput.Builder | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="http://fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="http://www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  develop" itemscope itemtype="http://schema.org/Article">
+  <div id="doc-api-level" class="" style="display:none"></div>
+  <a name="top"></a>
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12"  id="doc-col">
+
+<div id="api-info-block">
+
+
+
+  
+   
+  
+  
+  
+  
+
+
+<div class="sum-details-links">
+
+Summary:
+
+
+
+
+
+
+
+
+
+  <a href="#pubctors">Ctors</a>
+  
+
+
+
+  &#124; <a href="#pubmethods">Methods</a>
+  
+
+
+
+  &#124; <a href="#inhmethods">Inherited Methods</a>
+
+&#124; <a href="#" onclick="return toggleAllClassInherited()" id="toggleAllClassInherited">[Expand All]</a>
+
+</div><!-- end sum-details-links -->
+<div class="api-level">
+  
+  
+  
+
+</div>
+</div><!-- end api-info-block -->
+
+
+<!-- ======== START OF CLASS DATA ======== -->
+
+<div id="jd-header">
+    public
+    static 
+     
+    
+    class
+<h1 itemprop="name">RemoteInput.Builder</h1>
+
+
+
+  
+    extends <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a><br/>
+  
+  
+  
+
+  
+  
+  
+
+
+</div><!-- end header -->
+
+<div id="naMessage"></div>
+
+<div id="jd-content" class="api apilevel-">
+<table class="jd-inheritance-table">
+
+
+    <tr>
+         	
+        <td colspan="2" class="jd-inheritance-class-cell"><a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a></td>
+    </tr>
+    
+
+    <tr>
+        
+            <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
+         	
+        <td colspan="1" class="jd-inheritance-class-cell">android.preview.support.wearable.notifications.RemoteInput.Builder</td>
+    </tr>
+    
+
+</table>
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Class Overview</h2>
+<p itemprop="articleBody">Builder class for <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code> objects.
+</p>
+
+
+
+
+
+</div><!-- jd-descr -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Summary</h2>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<table id="pubctors" class="jd-sumtable"><tr><th colspan="12">Public Constructors</th></tr>
+
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            </nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html#RemoteInput.Builder(java.lang.String)">RemoteInput.Builder</a></span>(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> returnKey)</nobr>
+        
+        <div class="jd-descrdiv">Create a builder object for <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code> objects.</div>
+  
+  </td></tr>
+
+
+
+</table>
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="pubmethods" class="jd-sumtable"><tr><th colspan="12">Public Methods</th></tr>
+
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html#build()">build</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">Combine all of the options that have been set and return a new <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code>
+ object.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html">RemoteInput.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html#setAllowFreeFormInput(boolean)">setAllowFreeFormInput</a></span>(boolean allowFreeFormInput)</nobr>
+        
+        <div class="jd-descrdiv">Specifies whether the user can provide arbitrary values.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html">RemoteInput.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html#setChoices(java.lang.String[])">setChoices</a></span>(<a href="http://developer.android.com/reference/java/lang/String.html">String[]</a> choices)</nobr>
+        
+        <div class="jd-descrdiv">Specifies choices available to the user to satisfy this input.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html">RemoteInput.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html#setLabel(java.lang.String)">setLabel</a></span>(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> label)</nobr>
+        
+        <div class="jd-descrdiv">Set a label to be displayed to the user when collecting this input.</div>
+  
+  </td></tr>
+
+
+
+</table>
+
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="inhmethods" class="jd-sumtable"><tr><th>
+  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
+  <div style="clear:left;">Inherited Methods</div></th></tr>
+
+
+<tr class="api apilevel-" >
+<td colspan="12">
+  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-java.lang.Object" class="jd-expando-trigger closed"
+          ><img id="inherited-methods-java.lang.Object-trigger"
+          src="/assets/images/triangle-closed.png"
+          class="jd-expando-trigger-img" /></a>
+From class
+
+  <a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a>
+
+<div id="inherited-methods-java.lang.Object">
+  <div id="inherited-methods-java.lang.Object-list"
+        class="jd-inheritedlinks">
+  </div>
+  <div id="inherited-methods-java.lang.Object-summary" style="display: none;">
+    <table class="jd-sumtable-expando">
+    
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">clone</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">equals</span>(<a href="http://developer.android.com/reference/java/lang/Object.html">Object</a> arg0)</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">finalize</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Class.html">Class</a>&lt;?&gt;</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">getClass</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">hashCode</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notify</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notifyAll</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/String.html">String</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">toString</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0, int arg1)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0)</nobr>
+        
+  </td></tr>
+
+
+</table>
+  </div>
+</div>
+</td></tr>
+
+
+</table>
+
+
+</div><!-- jd-descr (summary) -->
+
+<!-- Details -->
+
+
+
+
+
+
+
+
+<!-- XML Attributes -->
+
+
+<!-- Enum Values -->
+
+
+<!-- Constants -->
+
+
+<!-- Fields -->
+
+
+<!-- Public ctors -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<h2>Public Constructors</h2>
+
+
+
+<A NAME="RemoteInput.Builder(java.lang.String)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        
+      </span>
+      <span class="sympad">RemoteInput.Builder</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> returnKey)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Create a builder object for <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code> objects.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>returnKey</td>
+          <td>the extras key to be set with input collected from the user
+         when the intent is sent.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
+
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<!-- Protected ctors -->
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+<!-- Public methdos -->
+
+<h2>Public Methods</h2>
+
+
+
+<A NAME="build()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a>
+      </span>
+      <span class="sympad">build</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>Combine all of the options that have been set and return a new <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code>
+ object.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="setAllowFreeFormInput(boolean)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html">RemoteInput.Builder</a>
+      </span>
+      <span class="sympad">setAllowFreeFormInput</span>
+      <span class="normal">(boolean allowFreeFormInput)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Specifies whether the user can provide arbitrary values.  The
+ default is <code>true</code>.  If this is set to <code>false</code>, a
+ non-null non-empty value should be passed to <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html#setChoices(java.lang.String[])">setChoices(String[])</a></code>.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="setChoices(java.lang.String[])"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html">RemoteInput.Builder</a>
+      </span>
+      <span class="sympad">setChoices</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/java/lang/String.html">String[]</a> choices)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Specifies choices available to the user to satisfy this input.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="setLabel(java.lang.String)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html">RemoteInput.Builder</a>
+      </span>
+      <span class="sympad">setLabel</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> label)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Set a label to be displayed to the user when collecting this input.
+</p></div>
+
+    </div>
+</div>
+
+
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+
+
+
+<!-- ========= END OF CLASS DATA ========= -->
+<A NAME="navbar_top"></A>
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is licensed under <a
+  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
+  For details and restrictions, see the <a href="/license.html">
+  Content License</a>.
+  </div>
+  <div id="build_info">
+    
+    Android &nbsp;r &mdash; 
+<script src="/timestamp.js" type="text/javascript"></script>
+<script>document.write(BUILD_TIMESTAMP)</script>
+
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div> <!-- jd-content -->
+
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+</body>
+</html>
diff --git a/docs/html/reference/android/preview/support/wearable/notifications/RemoteInput.html b/docs/html/reference/android/preview/support/wearable/notifications/RemoteInput.html
new file mode 100644
index 0000000..e8aa651
--- /dev/null
+++ b/docs/html/reference/android/preview/support/wearable/notifications/RemoteInput.html
@@ -0,0 +1,1292 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>RemoteInput | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="http://fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="http://www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  develop" itemscope itemtype="http://schema.org/Article">
+  <div id="doc-api-level" class="" style="display:none"></div>
+  <a name="top"></a>
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12"  id="doc-col">
+
+<div id="api-info-block">
+
+
+
+  
+   
+  
+  
+  
+  
+
+  
+   
+  
+  
+   
+  
+  
+  
+
+
+<div class="sum-details-links">
+
+Summary:
+
+  <a href="#nestedclasses">Nested Classes</a>
+  
+
+
+
+
+
+
+  &#124; <a href="#inhconstants">Inherited Constants</a>
+  
+
+
+  &#124; <a href="#lfields">Fields</a>
+  
+
+
+
+
+
+  &#124; <a href="#pubmethods">Methods</a>
+  
+
+
+
+  &#124; <a href="#inhmethods">Inherited Methods</a>
+
+&#124; <a href="#" onclick="return toggleAllClassInherited()" id="toggleAllClassInherited">[Expand All]</a>
+
+</div><!-- end sum-details-links -->
+<div class="api-level">
+  
+  
+  
+
+</div>
+</div><!-- end api-info-block -->
+
+
+<!-- ======== START OF CLASS DATA ======== -->
+
+<div id="jd-header">
+    public
+     
+     
+    
+    class
+<h1 itemprop="name">RemoteInput</h1>
+
+
+
+  
+    extends <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a><br/>
+  
+  
+  
+
+  
+  
+      implements 
+      
+        <a href="http://developer.android.com/reference/android/os/Parcelable.html">Parcelable</a> 
+      
+  
+  
+
+
+</div><!-- end header -->
+
+<div id="naMessage"></div>
+
+<div id="jd-content" class="api apilevel-">
+<table class="jd-inheritance-table">
+
+
+    <tr>
+         	
+        <td colspan="2" class="jd-inheritance-class-cell"><a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a></td>
+    </tr>
+    
+
+    <tr>
+        
+            <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
+         	
+        <td colspan="1" class="jd-inheritance-class-cell">android.preview.support.wearable.notifications.RemoteInput</td>
+    </tr>
+    
+
+</table>
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Class Overview</h2>
+<p itemprop="articleBody">A RemoteInput specifies a response to be collected from the user as part of an intent being
+ sent. For example, when used with a notification Action, a response may be collected
+ when the user triggers the action, and the results sent as data along with the action's
+ PendingIntent. The result value is set in the extras of the triggered Intent with the key
+ <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html#returnKey">returnKey</a></code>.
+
+ <p>Use the builder class <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html">RemoteInput.Builder</a></code> to create this object.
+
+ <p>Example which adds a RemoteInput to an Action:
+
+ <pre class="prettyprint">
+ WearableNotifications.Action action = new WearableNotifications.Action.Builder(
+         R.drawable.reply, &quot;Reply&quot;, actionIntent)
+         .addRemoteInput(new RemoteInput.Builder(EXTRA_QUICK_REPLY_TEXT)
+                 .setLabel("Quick reply").build())
+         .build();</pre>
+</p>
+
+
+
+
+
+</div><!-- jd-descr -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Summary</h2>
+
+
+
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+<table id="nestedclasses" class="jd-sumtable"><tr><th colspan="12">Nested Classes</th></tr>
+
+
+  
+    <tr class="alt-color api apilevel-" >
+      <td class="jd-typecol"><nobr>
+        
+         
+         
+        
+        class</nobr></td>
+      <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html">RemoteInput.Builder</a></td>
+      <td class="jd-descrcol" width="100%">Builder class for <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code> objects.&nbsp;</td>
+    </tr>
+    
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<!-- =========== ENUM CONSTANT SUMMARY =========== -->
+<table id="inhconstants" class="jd-sumtable"><tr><th>
+  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
+  <div style="clear:left;">Inherited Constants</div></th></tr>
+
+
+
+
+<tr class="api apilevel-" >
+<td colspan="12">
+
+  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-constants-android.os.Parcelable" class="jd-expando-trigger closed"
+          ><img id="inherited-constants-android.os.Parcelable-trigger"
+          src="/assets/images/triangle-closed.png"
+          class="jd-expando-trigger-img" /></a>From interface
+android.os.Parcelable
+<div id="inherited-constants-android.os.Parcelable">
+  <div id="inherited-constants-android.os.Parcelable-list"
+        class="jd-inheritedlinks">
+  </div>
+  <div id="inherited-constants-android.os.Parcelable-summary" style="display: none;">
+    <table class="jd-sumtable-expando">
+    
+
+    
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol">CONTENTS_FILE_DESCRIPTOR</td>
+        <td class="jd-descrcol" width="100%"></td>
+    </tr>
+    
+    
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol">PARCELABLE_WRITE_RETURN_VALUE</td>
+        <td class="jd-descrcol" width="100%"></td>
+    </tr>
+    
+    
+</table>
+  </div>
+</div>
+</td></tr>
+
+
+</table>
+
+
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+<table id="lfields" class="jd-sumtable"><tr><th colspan="12">Fields</th></tr>
+
+
+    
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          static
+          final
+          <a href="http://developer.android.com/reference/android/os/Parcelable.Creator.html">Creator</a>&lt;<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a>&gt;</nobr></td>
+          <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html#CREATOR">CREATOR</a></td>
+          <td class="jd-descrcol" width="100%"></td>
+      </tr>
+      
+    
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          
+          final
+          boolean</nobr></td>
+          <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html#allowFreeFormInput">allowFreeFormInput</a></td>
+          <td class="jd-descrcol" width="100%">Indicates whether or not the user may provide an arbitrary value for
+ this input.</td>
+      </tr>
+      
+    
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          
+          final
+          <a href="http://developer.android.com/reference/java/lang/String.html">String[]</a></nobr></td>
+          <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html#choices">choices</a></td>
+          <td class="jd-descrcol" width="100%">The choices available to the user.</td>
+      </tr>
+      
+    
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          
+          final
+          <a href="http://developer.android.com/reference/java/lang/String.html">String</a></nobr></td>
+          <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html#label">label</a></td>
+          <td class="jd-descrcol" width="100%">The label to be displayed to the user when collecting this input.</td>
+      </tr>
+      
+    
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          
+          final
+          <a href="http://developer.android.com/reference/java/lang/String.html">String</a></nobr></td>
+          <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html#returnKey">returnKey</a></td>
+          <td class="jd-descrcol" width="100%">The extras key to be populated with input from the user when the
+ intent is sent.</td>
+      </tr>
+      
+    
+
+</table>
+
+
+
+
+
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="pubmethods" class="jd-sumtable"><tr><th colspan="12">Public Methods</th></tr>
+
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html#describeContents()">describeContents</a></span>()</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/preview/support/wearable/notifications/RemoteInput.html#writeToParcel(android.os.Parcel, int)">writeToParcel</a></span>(<a href="http://developer.android.com/reference/android/os/Parcel.html">Parcel</a> out, int flags)</nobr>
+        
+  </td></tr>
+
+
+
+</table>
+
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="inhmethods" class="jd-sumtable"><tr><th>
+  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
+  <div style="clear:left;">Inherited Methods</div></th></tr>
+
+
+<tr class="api apilevel-" >
+<td colspan="12">
+  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-java.lang.Object" class="jd-expando-trigger closed"
+          ><img id="inherited-methods-java.lang.Object-trigger"
+          src="/assets/images/triangle-closed.png"
+          class="jd-expando-trigger-img" /></a>
+From class
+
+  <a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a>
+
+<div id="inherited-methods-java.lang.Object">
+  <div id="inherited-methods-java.lang.Object-list"
+        class="jd-inheritedlinks">
+  </div>
+  <div id="inherited-methods-java.lang.Object-summary" style="display: none;">
+    <table class="jd-sumtable-expando">
+    
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">clone</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">equals</span>(<a href="http://developer.android.com/reference/java/lang/Object.html">Object</a> arg0)</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">finalize</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Class.html">Class</a>&lt;?&gt;</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">getClass</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">hashCode</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notify</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notifyAll</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/String.html">String</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">toString</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0, int arg1)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0)</nobr>
+        
+  </td></tr>
+
+
+</table>
+  </div>
+</div>
+</td></tr>
+
+
+
+<tr class="api apilevel-" >
+<td colspan="12">
+  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-android.os.Parcelable" class="jd-expando-trigger closed"
+          ><img id="inherited-methods-android.os.Parcelable-trigger"
+          src="/assets/images/triangle-closed.png"
+          class="jd-expando-trigger-img" /></a>
+From interface
+
+  <a href="http://developer.android.com/reference/android/os/Parcelable.html">android.os.Parcelable</a>
+
+<div id="inherited-methods-android.os.Parcelable">
+  <div id="inherited-methods-android.os.Parcelable-list"
+        class="jd-inheritedlinks">
+  </div>
+  <div id="inherited-methods-android.os.Parcelable-summary" style="display: none;">
+    <table class="jd-sumtable-expando">
+    
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            abstract
+            
+            
+            
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">describeContents</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            abstract
+            
+            
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">writeToParcel</span>(<a href="http://developer.android.com/reference/android/os/Parcel.html">Parcel</a> arg0, int arg1)</nobr>
+        
+  </td></tr>
+
+
+</table>
+  </div>
+</div>
+</td></tr>
+
+
+</table>
+
+
+</div><!-- jd-descr (summary) -->
+
+<!-- Details -->
+
+
+
+
+
+
+
+
+<!-- XML Attributes -->
+
+
+<!-- Enum Values -->
+
+
+<!-- Constants -->
+
+
+<!-- Fields -->
+
+
+<!-- ========= FIELD DETAIL ======== -->
+<h2>Fields</h2>
+
+
+
+
+<A NAME="CREATOR"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+        final 
+        <a href="http://developer.android.com/reference/android/os/Parcelable.Creator.html">Creator</a>&lt;<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a>&gt;
+      </span>
+        CREATOR
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    
+    </div>
+</div>
+
+
+
+<A NAME="allowFreeFormInput"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+        final 
+        boolean
+      </span>
+        allowFreeFormInput
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Indicates whether or not the user may provide an arbitrary value for
+ this input.  If set to false, then the user should select one of the
+ provided choices.  It is an error to set this to <code>false</code> and
+ not provide <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html#choices">choices</a></code>.
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
+<A NAME="choices"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+        final 
+        <a href="http://developer.android.com/reference/java/lang/String.html">String[]</a>
+      </span>
+        choices
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>The choices available to the user.  May be null if there are no choices
+ to present to the user.
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
+<A NAME="label"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+        final 
+        <a href="http://developer.android.com/reference/java/lang/String.html">String</a>
+      </span>
+        label
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>The label to be displayed to the user when collecting this input.
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
+<A NAME="returnKey"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+        final 
+        <a href="http://developer.android.com/reference/java/lang/String.html">String</a>
+      </span>
+        returnKey
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>The extras key to be populated with input from the user when the
+ intent is sent.
+</p></div>
+
+    
+    </div>
+</div>
+
+
+
+
+<!-- Public ctors -->
+
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<!-- Protected ctors -->
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+<!-- Public methdos -->
+
+<h2>Public Methods</h2>
+
+
+
+<A NAME="describeContents()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        int
+      </span>
+      <span class="sympad">describeContents</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>
+</div>
+
+
+<A NAME="writeToParcel(android.os.Parcel, int)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">writeToParcel</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/os/Parcel.html">Parcel</a> out, int flags)</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>
+
+
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+
+
+
+<!-- ========= END OF CLASS DATA ========= -->
+<A NAME="navbar_top"></A>
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is licensed under <a
+  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
+  For details and restrictions, see the <a href="/license.html">
+  Content License</a>.
+  </div>
+  <div id="build_info">
+    
+    Android &nbsp;r &mdash; 
+<script src="/timestamp.js" type="text/javascript"></script>
+<script>document.write(BUILD_TIMESTAMP)</script>
+
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div> <!-- jd-content -->
+
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+</body>
+</html>
diff --git a/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html b/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html
new file mode 100644
index 0000000..884de4a
--- /dev/null
+++ b/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html
@@ -0,0 +1,1044 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>WearableNotifications.Action.Builder | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="http://fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="http://www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  develop" itemscope itemtype="http://schema.org/Article">
+  <div id="doc-api-level" class="" style="display:none"></div>
+  <a name="top"></a>
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12"  id="doc-col">
+
+<div id="api-info-block">
+
+
+
+  
+   
+  
+  
+  
+  
+
+
+<div class="sum-details-links">
+
+Summary:
+
+
+
+
+
+
+
+
+
+  <a href="#pubctors">Ctors</a>
+  
+
+
+
+  &#124; <a href="#pubmethods">Methods</a>
+  
+
+
+
+  &#124; <a href="#inhmethods">Inherited Methods</a>
+
+&#124; <a href="#" onclick="return toggleAllClassInherited()" id="toggleAllClassInherited">[Expand All]</a>
+
+</div><!-- end sum-details-links -->
+<div class="api-level">
+  
+  
+  
+
+</div>
+</div><!-- end api-info-block -->
+
+
+<!-- ======== START OF CLASS DATA ======== -->
+
+<div id="jd-header">
+    public
+    static 
+     
+    
+    class
+<h1 itemprop="name">WearableNotifications.Action.Builder</h1>
+
+
+
+  
+    extends <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a><br/>
+  
+  
+  
+
+  
+  
+  
+
+
+</div><!-- end header -->
+
+<div id="naMessage"></div>
+
+<div id="jd-content" class="api apilevel-">
+<table class="jd-inheritance-table">
+
+
+    <tr>
+         	
+        <td colspan="2" class="jd-inheritance-class-cell"><a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a></td>
+    </tr>
+    
+
+    <tr>
+        
+            <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
+         	
+        <td colspan="1" class="jd-inheritance-class-cell">android.preview.support.wearable.notifications.WearableNotifications.Action.Builder</td>
+    </tr>
+    
+
+</table>
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Class Overview</h2>
+<p itemprop="articleBody">Builder class for <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code> objects.
+
+ <p>Example:
+
+ <pre class="prettyprint">
+ WearableNotifications.Builder builder = new WearableNotifications.Builder(mContext)
+         .addAction(new WearableNotifications.Action.Builder(
+                 R.drawable.navigate, &quot;Navigate&quot, pendingIntent)
+                 .build());
+ Notification notif = builder.build();</pre>
+</p>
+
+
+
+
+
+</div><!-- jd-descr -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Summary</h2>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<table id="pubctors" class="jd-sumtable"><tr><th colspan="12">Public Constructors</th></tr>
+
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            </nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html#WearableNotifications.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent)">WearableNotifications.Action.Builder</a></span>(int icon, <a href="http://developer.android.com/reference/java/lang/CharSequence.html">CharSequence</a> title, <a href="http://developer.android.com/reference/android/app/PendingIntent.html">PendingIntent</a> intent)</nobr>
+        
+        <div class="jd-descrdiv">Construct a new builder for an <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code> object.</div>
+  
+  </td></tr>
+
+
+
+</table>
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="pubmethods" class="jd-sumtable"><tr><th colspan="12">Public Methods</th></tr>
+
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html#addRemoteInput(android.preview.support.wearable.notifications.RemoteInput)">addRemoteInput</a></span>(<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a> remoteInput)</nobr>
+        
+        <div class="jd-descrdiv">Add an input to be collected from the user when this action is sent.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html#build()">build</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">Combine all of the options that have been set and return a new <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code>
+ object.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/android/os/Bundle.html">Bundle</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html#getExtras()">getExtras</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">Get the current metadata Bundle used by this Builder, creating a new one
+ as necessary.</div>
+  
+  </td></tr>
+
+
+
+</table>
+
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="inhmethods" class="jd-sumtable"><tr><th>
+  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
+  <div style="clear:left;">Inherited Methods</div></th></tr>
+
+
+<tr class="api apilevel-" >
+<td colspan="12">
+  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-java.lang.Object" class="jd-expando-trigger closed"
+          ><img id="inherited-methods-java.lang.Object-trigger"
+          src="/assets/images/triangle-closed.png"
+          class="jd-expando-trigger-img" /></a>
+From class
+
+  <a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a>
+
+<div id="inherited-methods-java.lang.Object">
+  <div id="inherited-methods-java.lang.Object-list"
+        class="jd-inheritedlinks">
+  </div>
+  <div id="inherited-methods-java.lang.Object-summary" style="display: none;">
+    <table class="jd-sumtable-expando">
+    
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">clone</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">equals</span>(<a href="http://developer.android.com/reference/java/lang/Object.html">Object</a> arg0)</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">finalize</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Class.html">Class</a>&lt;?&gt;</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">getClass</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">hashCode</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notify</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notifyAll</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/String.html">String</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">toString</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0, int arg1)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0)</nobr>
+        
+  </td></tr>
+
+
+</table>
+  </div>
+</div>
+</td></tr>
+
+
+</table>
+
+
+</div><!-- jd-descr (summary) -->
+
+<!-- Details -->
+
+
+
+
+
+
+
+
+<!-- XML Attributes -->
+
+
+<!-- Enum Values -->
+
+
+<!-- Constants -->
+
+
+<!-- Fields -->
+
+
+<!-- Public ctors -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<h2>Public Constructors</h2>
+
+
+
+<A NAME="WearableNotifications.Action.Builder(int, java.lang.CharSequence, android.app.PendingIntent)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        
+      </span>
+      <span class="sympad">WearableNotifications.Action.Builder</span>
+      <span class="normal">(int icon, <a href="http://developer.android.com/reference/java/lang/CharSequence.html">CharSequence</a> title, <a href="http://developer.android.com/reference/android/app/PendingIntent.html">PendingIntent</a> intent)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Construct a new builder for an <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code> object.
+</p></div>
+
+    </div>
+</div>
+
+
+
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<!-- Protected ctors -->
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+<!-- Public methdos -->
+
+<h2>Public Methods</h2>
+
+
+
+<A NAME="addRemoteInput(android.preview.support.wearable.notifications.RemoteInput)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a>
+      </span>
+      <span class="sympad">addRemoteInput</span>
+      <span class="normal">(<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a> remoteInput)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Add an input to be collected from the user when this action is sent.
+ Response values are sent as extras to this Action's pending intent when
+ sent.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="build()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a>
+      </span>
+      <span class="sympad">build</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>Combine all of the options that have been set and return a new <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code>
+ object.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="getExtras()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="http://developer.android.com/reference/android/os/Bundle.html">Bundle</a>
+      </span>
+      <span class="sympad">getExtras</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>Get the current metadata Bundle used by this Builder, creating a new one
+ as necessary.
+
+ <p>The returned Bundle is shared with this Builder.
+</p></div>
+
+    </div>
+</div>
+
+
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+
+
+
+<!-- ========= END OF CLASS DATA ========= -->
+<A NAME="navbar_top"></A>
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is licensed under <a
+  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
+  For details and restrictions, see the <a href="/license.html">
+  Content License</a>.
+  </div>
+  <div id="build_info">
+    
+    Android &nbsp;r &mdash; 
+<script src="/timestamp.js" type="text/javascript"></script>
+<script>document.write(BUILD_TIMESTAMP)</script>
+
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div> <!-- jd-content -->
+
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+</body>
+</html>
diff --git a/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html b/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html
new file mode 100644
index 0000000..e073881
--- /dev/null
+++ b/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html
@@ -0,0 +1,1052 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>WearableNotifications.Action | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="http://fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="http://www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  develop" itemscope itemtype="http://schema.org/Article">
+  <div id="doc-api-level" class="" style="display:none"></div>
+  <a name="top"></a>
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12"  id="doc-col">
+
+<div id="api-info-block">
+
+
+
+  
+  
+  
+   
+  
+  
+
+  
+   
+  
+  
+  
+  
+
+
+<div class="sum-details-links">
+
+Summary:
+
+  <a href="#nestedclasses">Nested Classes</a>
+  
+
+
+
+
+
+
+
+  &#124; <a href="#lfields">Fields</a>
+  
+
+
+  &#124; <a href="#inhfields">Inherited Fields</a>
+  
+
+
+
+
+  &#124; <a href="#pubmethods">Methods</a>
+  
+
+
+
+  &#124; <a href="#inhmethods">Inherited Methods</a>
+
+&#124; <a href="#" onclick="return toggleAllClassInherited()" id="toggleAllClassInherited">[Expand All]</a>
+
+</div><!-- end sum-details-links -->
+<div class="api-level">
+  
+  
+  
+
+</div>
+</div><!-- end api-info-block -->
+
+
+<!-- ======== START OF CLASS DATA ======== -->
+
+<div id="jd-header">
+    public
+    static 
+     
+    
+    class
+<h1 itemprop="name">WearableNotifications.Action</h1>
+
+
+
+  
+  
+  
+
+  
+    extends NotificationCompat.Action<br/>
+  
+  
+  
+
+  
+  
+  
+
+
+</div><!-- end header -->
+
+<div id="naMessage"></div>
+
+<div id="jd-content" class="api apilevel-">
+<table class="jd-inheritance-table">
+
+
+    <tr>
+         	
+        <td colspan="3" class="jd-inheritance-class-cell"><a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a></td>
+    </tr>
+    
+
+    <tr>
+        
+            <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
+         	
+        <td colspan="2" class="jd-inheritance-class-cell">android.support.v4.app.NotificationCompat.Action</td>
+    </tr>
+    
+
+    <tr>
+        
+            <td class="jd-inheritance-space">&nbsp;</td>
+        
+            <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
+         	
+        <td colspan="1" class="jd-inheritance-class-cell">android.preview.support.wearable.notifications.WearableNotifications.Action</td>
+    </tr>
+    
+
+</table>
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Class Overview</h2>
+<p itemprop="articleBody">Subclass of <code><a href="/reference/android/support/v4/app/NotificationCompat.Action.html">NotificationCompat.Action</a></code> which adds support for additional
+ wearable extensions.
+
+ <p>To create a new Action, use the <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></code> class and then call
+ <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addAction(android.preview.support.wearable.notifications.WearableNotifications.Action)">addAction(WearableNotifications.Action)</a></code> to add the action to a notification.
+
+ <p>Example:
+
+ <pre class="prettyprint">
+ WearableNotifications.Builder builder = new WearableNotifications.Builder(mContext)
+         .addAction(new WearableNotifications.Action.Builder(
+                 R.drawable.navigate, &quot;Navigate&quot, pendingIntent)
+                 .build())
+         .setLocalOnly(true);
+ Notification notif = builder.build();</pre>
+</p>
+
+
+
+
+
+</div><!-- jd-descr -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Summary</h2>
+
+
+
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+<table id="nestedclasses" class="jd-sumtable"><tr><th colspan="12">Nested Classes</th></tr>
+
+
+  
+    <tr class="alt-color api apilevel-" >
+      <td class="jd-typecol"><nobr>
+        
+         
+         
+        
+        class</nobr></td>
+      <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></td>
+      <td class="jd-descrcol" width="100%">Builder class for <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code> objects.&nbsp;</td>
+    </tr>
+    
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+<table id="lfields" class="jd-sumtable"><tr><th colspan="12">Fields</th></tr>
+
+
+    
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          
+          final
+          <a href="http://developer.android.com/reference/android/os/Bundle.html">Bundle</a></nobr></td>
+          <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html#extras">extras</a></td>
+          <td class="jd-descrcol" width="100%"></td>
+      </tr>
+      
+    
+
+</table>
+
+
+
+
+
+<!-- =========== FIELD SUMMARY =========== -->
+<table id="inhfields" class="jd-sumtable"><tr><th>
+  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
+  <div style="clear:left;">Inherited Fields</div></th></tr>
+
+
+<tr class="api apilevel-" >
+<td colspan="12">
+
+  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-fields-android.support.v4.app.NotificationCompat.Action" class="jd-expando-trigger closed"
+          ><img id="inherited-fields-android.support.v4.app.NotificationCompat.Action-trigger"
+          src="/assets/images/triangle-closed.png"
+          class="jd-expando-trigger-img" /></a>From class
+android.support.v4.app.NotificationCompat.Action
+<div id="inherited-fields-android.support.v4.app.NotificationCompat.Action">
+  <div id="inherited-fields-android.support.v4.app.NotificationCompat.Action-list"
+        class="jd-inheritedlinks">
+  </div>
+  <div id="inherited-fields-android.support.v4.app.NotificationCompat.Action-summary" style="display: none;">
+    <table class="jd-sumtable-expando">
+    
+
+    
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          
+          
+          <a href="http://developer.android.com/reference/android/app/PendingIntent.html">PendingIntent</a></nobr></td>
+          <td class="jd-linkcol">actionIntent</td>
+          <td class="jd-descrcol" width="100%"></td>
+      </tr>
+      
+    
+      <tr class=" api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          
+          
+          int</nobr></td>
+          <td class="jd-linkcol">icon</td>
+          <td class="jd-descrcol" width="100%"></td>
+      </tr>
+      
+    
+      <tr class="alt-color api apilevel-" >
+          <td class="jd-typecol"><nobr>
+          public
+          
+          
+          <a href="http://developer.android.com/reference/java/lang/CharSequence.html">CharSequence</a></nobr></td>
+          <td class="jd-linkcol">title</td>
+          <td class="jd-descrcol" width="100%"></td>
+      </tr>
+      
+    
+</table>
+  </div>
+</div>
+</td></tr>
+
+
+
+
+</table>
+
+
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="pubmethods" class="jd-sumtable"><tr><th colspan="12">Public Methods</th></tr>
+
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput[]</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html#getRemoteInputs()">getRemoteInputs</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">Get a list of inputs to be collected from the user when this action is sent.</div>
+  
+  </td></tr>
+
+
+
+</table>
+
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="inhmethods" class="jd-sumtable"><tr><th>
+  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
+  <div style="clear:left;">Inherited Methods</div></th></tr>
+
+
+
+
+<tr class="api apilevel-" >
+<td colspan="12">
+  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-java.lang.Object" class="jd-expando-trigger closed"
+          ><img id="inherited-methods-java.lang.Object-trigger"
+          src="/assets/images/triangle-closed.png"
+          class="jd-expando-trigger-img" /></a>
+From class
+
+  <a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a>
+
+<div id="inherited-methods-java.lang.Object">
+  <div id="inherited-methods-java.lang.Object-list"
+        class="jd-inheritedlinks">
+  </div>
+  <div id="inherited-methods-java.lang.Object-summary" style="display: none;">
+    <table class="jd-sumtable-expando">
+    
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">clone</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">equals</span>(<a href="http://developer.android.com/reference/java/lang/Object.html">Object</a> arg0)</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">finalize</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Class.html">Class</a>&lt;?&gt;</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">getClass</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">hashCode</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notify</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notifyAll</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/String.html">String</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">toString</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0, int arg1)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0)</nobr>
+        
+  </td></tr>
+
+
+</table>
+  </div>
+</div>
+</td></tr>
+
+
+</table>
+
+
+</div><!-- jd-descr (summary) -->
+
+<!-- Details -->
+
+
+
+
+
+
+
+
+<!-- XML Attributes -->
+
+
+<!-- Enum Values -->
+
+
+<!-- Constants -->
+
+
+<!-- Fields -->
+
+
+<!-- ========= FIELD DETAIL ======== -->
+<h2>Fields</h2>
+
+
+
+
+<A NAME="extras"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+        final 
+        <a href="http://developer.android.com/reference/android/os/Bundle.html">Bundle</a>
+      </span>
+        extras
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p></p></div>
+
+    
+    </div>
+</div>
+
+
+
+
+<!-- Public ctors -->
+
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<!-- Protected ctors -->
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+<!-- Public methdos -->
+
+<h2>Public Methods</h2>
+
+
+
+<A NAME="getRemoteInputs()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput[]</a>
+      </span>
+      <span class="sympad">getRemoteInputs</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>Get a list of inputs to be collected from the user when this action is sent.
+</p></div>
+
+    </div>
+</div>
+
+
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+
+
+
+<!-- ========= END OF CLASS DATA ========= -->
+<A NAME="navbar_top"></A>
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is licensed under <a
+  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
+  For details and restrictions, see the <a href="/license.html">
+  Content License</a>.
+  </div>
+  <div id="build_info">
+    
+    Android &nbsp;r &mdash; 
+<script src="/timestamp.js" type="text/javascript"></script>
+<script>document.write(BUILD_TIMESTAMP)</script>
+
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div> <!-- jd-content -->
+
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+</body>
+</html>
diff --git a/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html b/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html
new file mode 100644
index 0000000..25e4520
--- /dev/null
+++ b/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html
@@ -0,0 +1,1756 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>WearableNotifications.Builder | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="http://fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="http://www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  develop" itemscope itemtype="http://schema.org/Article">
+  <div id="doc-api-level" class="" style="display:none"></div>
+  <a name="top"></a>
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12"  id="doc-col">
+
+<div id="api-info-block">
+
+
+
+  
+   
+  
+  
+  
+  
+
+
+<div class="sum-details-links">
+
+Summary:
+
+
+
+
+
+
+
+
+
+  <a href="#pubctors">Ctors</a>
+  
+
+
+
+  &#124; <a href="#pubmethods">Methods</a>
+  
+
+
+
+  &#124; <a href="#inhmethods">Inherited Methods</a>
+
+&#124; <a href="#" onclick="return toggleAllClassInherited()" id="toggleAllClassInherited">[Expand All]</a>
+
+</div><!-- end sum-details-links -->
+<div class="api-level">
+  
+  
+  
+
+</div>
+</div><!-- end api-info-block -->
+
+
+<!-- ======== START OF CLASS DATA ======== -->
+
+<div id="jd-header">
+    public
+    static 
+    final 
+    
+    class
+<h1 itemprop="name">WearableNotifications.Builder</h1>
+
+
+
+  
+    extends <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a><br/>
+  
+  
+  
+
+  
+  
+  
+
+
+</div><!-- end header -->
+
+<div id="naMessage"></div>
+
+<div id="jd-content" class="api apilevel-">
+<table class="jd-inheritance-table">
+
+
+    <tr>
+         	
+        <td colspan="2" class="jd-inheritance-class-cell"><a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a></td>
+    </tr>
+    
+
+    <tr>
+        
+            <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
+         	
+        <td colspan="1" class="jd-inheritance-class-cell">android.preview.support.wearable.notifications.WearableNotifications.Builder</td>
+    </tr>
+    
+
+</table>
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Class Overview</h2>
+<p itemprop="articleBody">Builder object that wraps a <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> to provide
+ methods for adding wearable extensions to a notification.
+
+ <p>Methods on the wrapped <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> and this object
+ can be called in any order, but the final Notification must be built with
+ the <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#build()">build()</a></code> method of this class.
+
+ <p>Note: Notifications created using this builder should be posted to the notification
+ system using the <code>NotificationManagerCompat.notify(...)</code> methods instead of
+ <code>NotificationManager.notify(...)</code>.
+
+ <p>Example:
+
+ <pre class="prettyprint">
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
+         .setContentTitle(&quot;New mail from &quot; + sender.toString())
+         .setContentText(subject)
+         .setSmallIcon(R.drawable.new_mail);
+ Notification notif = new WearableNotifications.Builder(builder)
+         .setLocalOnly(true)
+         .setMinPriority()
+         .build();
+ NotificationManagerCompat.from(mContext).notify(0, notif);</pre>
+</p>
+
+
+
+
+
+</div><!-- jd-descr -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Summary</h2>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<!-- ======== CONSTRUCTOR SUMMARY ======== -->
+<table id="pubctors" class="jd-sumtable"><tr><th colspan="12">Public Constructors</th></tr>
+
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            </nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#WearableNotifications.Builder(android.content.Context)">WearableNotifications.Builder</a></span>(<a href="http://developer.android.com/reference/android/content/Context.html">Context</a> context)</nobr>
+        
+        <div class="jd-descrdiv">Construct a builder to be used for adding wearable extensions to notifications.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            </nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#WearableNotifications.Builder(android.support.v4.app.NotificationCompat.Builder)">WearableNotifications.Builder</a></span>(NotificationCompat.Builder builder)</nobr>
+        
+        <div class="jd-descrdiv">Construct a builder to be used for adding wearable extensions to notifications to
+ a <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code>.</div>
+  
+  </td></tr>
+
+
+
+</table>
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="pubmethods" class="jd-sumtable"><tr><th colspan="12">Public Methods</th></tr>
+
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addAction(android.preview.support.wearable.notifications.WearableNotifications.Action)">addAction</a></span>(<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a> action)</nobr>
+        
+        <div class="jd-descrdiv">Add an action to this notification.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addPage(android.app.Notification)">addPage</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> page)</nobr>
+        
+        <div class="jd-descrdiv">Add an additional page of content to display with this notification.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addPages(java.util.Collection<android.app.Notification>)">addPages</a></span>(<a href="http://developer.android.com/reference/java/util/Collection.html">Collection</a>&lt;<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a>&gt; pages)</nobr>
+        
+        <div class="jd-descrdiv">Add additional pages of content to display with this notification.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)">addRemoteInputForContentIntent</a></span>(<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a> input)</nobr>
+        
+        <div class="jd-descrdiv">Adds a <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code> for the content intent.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#build()">build</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">Combine all of the options that have been set by both this builder and
+ the wrapped <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> object and return a new
+ <code><a href="/http://developer.android.com/reference/android/app/Notification.html">Notification</a></code> object.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            NotificationCompat.Builder</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#getCompatBuilder()">getCompatBuilder</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">Return the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> being wrapped by this object.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/android/os/Bundle.html">Bundle</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#getExtras()">getExtras</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">Get the current metadata Bundle used by this Builder, creating a new one
+ as necessary.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setBigActionIcon(int, java.lang.CharSequence)">setBigActionIcon</a></span>(int icon, <a href="http://developer.android.com/reference/java/lang/CharSequence.html">CharSequence</a> subtext)</nobr>
+        
+        <div class="jd-descrdiv">Add a big action display to this notification.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setBigActionIcon(int)">setBigActionIcon</a></span>(int icon)</nobr>
+        
+        <div class="jd-descrdiv">Add a big action display to this notification.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setGroup(java.lang.String, int)">setGroup</a></span>(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> groupKey, int groupOrder)</nobr>
+        
+        <div class="jd-descrdiv">Set this notification to be part of a group of notifications sharing the same key.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setGroup(java.lang.String)">setGroup</a></span>(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> groupKey)</nobr>
+        
+        <div class="jd-descrdiv">Set this notification to be part of a group of notifications sharing the same key.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setHintHideIcon(boolean)">setHintHideIcon</a></span>(boolean hintHideIcon)</nobr>
+        
+        <div class="jd-descrdiv">Set a hint that this notification's icon should not be displayed.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setLocalOnly(boolean)">setLocalOnly</a></span>(boolean localOnly)</nobr>
+        
+        <div class="jd-descrdiv">Set whether or not this notification is only relevant to the current device.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setMinPriority()">setMinPriority</a></span>()</nobr>
+        
+        <div class="jd-descrdiv">Set the priority of this notification to be minimum priority level
+ (<code><a href="/http://developer.android.com/reference/android/app/Notification.html#PRIORITY_MIN">PRIORITY_MIN</a></code>).</div>
+  
+  </td></tr>
+
+
+
+</table>
+
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="inhmethods" class="jd-sumtable"><tr><th>
+  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
+  <div style="clear:left;">Inherited Methods</div></th></tr>
+
+
+<tr class="api apilevel-" >
+<td colspan="12">
+  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-java.lang.Object" class="jd-expando-trigger closed"
+          ><img id="inherited-methods-java.lang.Object-trigger"
+          src="/assets/images/triangle-closed.png"
+          class="jd-expando-trigger-img" /></a>
+From class
+
+  <a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a>
+
+<div id="inherited-methods-java.lang.Object">
+  <div id="inherited-methods-java.lang.Object-list"
+        class="jd-inheritedlinks">
+  </div>
+  <div id="inherited-methods-java.lang.Object-summary" style="display: none;">
+    <table class="jd-sumtable-expando">
+    
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">clone</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">equals</span>(<a href="http://developer.android.com/reference/java/lang/Object.html">Object</a> arg0)</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">finalize</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Class.html">Class</a>&lt;?&gt;</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">getClass</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">hashCode</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notify</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notifyAll</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/String.html">String</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">toString</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0, int arg1)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0)</nobr>
+        
+  </td></tr>
+
+
+</table>
+  </div>
+</div>
+</td></tr>
+
+
+</table>
+
+
+</div><!-- jd-descr (summary) -->
+
+<!-- Details -->
+
+
+
+
+
+
+
+
+<!-- XML Attributes -->
+
+
+<!-- Enum Values -->
+
+
+<!-- Constants -->
+
+
+<!-- Fields -->
+
+
+<!-- Public ctors -->
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<h2>Public Constructors</h2>
+
+
+
+<A NAME="WearableNotifications.Builder(android.content.Context)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        
+      </span>
+      <span class="sympad">WearableNotifications.Builder</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/content/Context.html">Context</a> context)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Construct a builder to be used for adding wearable extensions to notifications. Both the
+ wrapped builder (accessible via <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#getCompatBuilder()">getCompatBuilder()</a></code> and this builder can be used
+ simultaneously, but the build() method from this object must be called in the end.
+
+ <p>Note: Notifications created using this builder should be posted to the notification
+ system using the <code>NotificationManagerCompat.notify(...)</code> methods instead of
+ <code>NotificationManager.notify(...)</code>.
+
+ <p>Example:
+
+ <pre class="prettyprint">
+ WearableNotifications.Builder builder = new WearableNotifications.Builder(mContext)
+         .setLocalOnly(true);
+ builder.getCompatBuilder()
+         .setContentTitle(&quot;New mail from &quot; + sender.toString())
+         .setContentText(subject)
+         .setSmallIcon(R.drawable.new_mail);
+ Notification notif = builder.build();
+ NotificationManagerCompat.from(mContext).notify(0, notif);</pre>
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="WearableNotifications.Builder(android.support.v4.app.NotificationCompat.Builder)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        
+      </span>
+      <span class="sympad">WearableNotifications.Builder</span>
+      <span class="normal">(NotificationCompat.Builder builder)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Construct a builder to be used for adding wearable extensions to notifications to
+ a <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code>. Both the wrapped builder and this
+ builder can be used simultaneously, but the build() method from this object must be
+ called in the end.
+
+ <p>Note: Notifications created using this builder should be posted to the notification
+ system using the <code>NotificationManagerCompat.notify(...)</code> methods instead of
+ <code>NotificationManager.notify(...)</code>.
+
+ <p>Example:
+
+ <pre class="prettyprint">
+ NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
+         .setContentTitle(&quot;New mail from &quot; + sender.toString())
+         .setContentText(subject)
+         .setSmallIcon(R.drawable.new_mail);
+ Notification notif = new WearableNotifications.Builder(builder)
+         .setLocalOnly(true)
+         .build();
+ NotificationManagerCompat.from(mContext).notify(0, notif);</pre>
+</p></div>
+
+    </div>
+</div>
+
+
+
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<!-- Protected ctors -->
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+<!-- Public methdos -->
+
+<h2>Public Methods</h2>
+
+
+
+<A NAME="addAction(android.preview.support.wearable.notifications.WearableNotifications.Action)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a>
+      </span>
+      <span class="sympad">addAction</span>
+      <span class="normal">(<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a> action)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Add an action to this notification. Actions are typically displayed by
+ the system as a button adjacent to the notification content. This method
+ accepts <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code> extension wrappers. Actions added by this function
+ are appended when <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#build()">build()</a></code> is called.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">See Also</h5>
+      <ul class="nolist"><li><code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code></li>
+      </ul>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="addPage(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a>
+      </span>
+      <span class="sympad">addPage</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> page)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>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.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">See Also</h5>
+      <ul class="nolist"><li><code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getPages(android.app.Notification)">getPages(Notification)</a></code></li>
+      </ul>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="addPages(java.util.Collection<android.app.Notification>)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a>
+      </span>
+      <span class="sympad">addPages</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/java/util/Collection.html">Collection</a>&lt;<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a>&gt; pages)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>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.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">See Also</h5>
+      <ul class="nolist"><li><code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getPages(android.app.Notification)">getPages(Notification)</a></code></li>
+      </ul>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a>
+      </span>
+      <span class="sympad">addRemoteInputForContentIntent</span>
+      <span class="normal">(<a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a> input)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Adds a <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code> for the content intent.  The collected
+ data will be overlayed onto the content intent.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="build()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a>
+      </span>
+      <span class="sympad">build</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>Combine all of the options that have been set by both this builder and
+ the wrapped <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> object and return a new
+ <code><a href="/http://developer.android.com/reference/android/app/Notification.html">Notification</a></code> object.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="getCompatBuilder()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        NotificationCompat.Builder
+      </span>
+      <span class="sympad">getCompatBuilder</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>Return the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> being wrapped by this object.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="getExtras()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="http://developer.android.com/reference/android/os/Bundle.html">Bundle</a>
+      </span>
+      <span class="sympad">getExtras</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>Get the current metadata Bundle used by this Builder, creating a new one
+ as necessary.
+
+ <p>The returned Bundle is shared with this Builder.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="setBigActionIcon(int, java.lang.CharSequence)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a>
+      </span>
+      <span class="sympad">setBigActionIcon</span>
+      <span class="normal">(int icon, <a href="http://developer.android.com/reference/java/lang/CharSequence.html">CharSequence</a> subtext)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Add a big action display to this notification. Big actions show a hint to users
+ about the action taken when the content intent is triggered.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>icon</td>
+          <td>Icon to display for the content action.</td>
+        </tr>
+        <tr>
+          <th>subtext</td>
+          <td>Optional subtext to display with the big action icon.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="setBigActionIcon(int)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a>
+      </span>
+      <span class="sympad">setBigActionIcon</span>
+      <span class="normal">(int icon)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Add a big action display to this notification. Big actions show a hint to users
+ about the action taken when the content intent is triggered.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>icon</td>
+          <td>Icon to display for the content action.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="setGroup(java.lang.String, int)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a>
+      </span>
+      <span class="sympad">setGroup</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> groupKey, int groupOrder)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Set this notification to be part of a group of notifications sharing the same key.
+ Grouped notifications may display in a cluster or stack on devices which
+ support such rendering.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>groupKey</td>
+          <td>The group key of the group. Unique within a package.</td>
+        </tr>
+        <tr>
+          <th>groupOrder</td>
+          <td>The 0-indexed sort order within the group. Can also be set
+         to the sentinel value <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#GROUP_ORDER_SUMMARY">GROUP_ORDER_SUMMARY</a></code> to mark this
+         notification as being the group summary.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="setGroup(java.lang.String)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a>
+      </span>
+      <span class="sympad">setGroup</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/java/lang/String.html">String</a> groupKey)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Set this notification to be part of a group of notifications sharing the same key.
+ Grouped notifications may display in a cluster or stack on devices which
+ support such rendering. Use the default ordering within a group.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>groupKey</td>
+          <td>The group key of the group. Unique within a package.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="setHintHideIcon(boolean)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a>
+      </span>
+      <span class="sympad">setHintHideIcon</span>
+      <span class="normal">(boolean hintHideIcon)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Set a hint that this notification's icon should not be displayed.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="setLocalOnly(boolean)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a>
+      </span>
+      <span class="sympad">setLocalOnly</span>
+      <span class="normal">(boolean localOnly)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Set whether or not this notification is only relevant to the current device.
+
+ <p>Some notifications can be bridged to other devices for remote display.
+ This hint can be set to recommend this notification not be bridged.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">See Also</h5>
+      <ul class="nolist"><li><code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getLocalOnly(android.app.Notification)">getLocalOnly(Notification)</a></code></li>
+      </ul>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="setMinPriority()"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+         
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a>
+      </span>
+      <span class="sympad">setMinPriority</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>Set the priority of this notification to be minimum priority level
+ (<code><a href="/http://developer.android.com/reference/android/app/Notification.html#PRIORITY_MIN">PRIORITY_MIN</a></code>). When set via WearableNotifications, these
+ minimum priority notifications will bypass the notification manager on platforms
+ that do not support ambient level notifications.
+</p></div>
+
+    </div>
+</div>
+
+
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+
+
+
+<!-- ========= END OF CLASS DATA ========= -->
+<A NAME="navbar_top"></A>
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is licensed under <a
+  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
+  For details and restrictions, see the <a href="/license.html">
+  Content License</a>.
+  </div>
+  <div id="build_info">
+    
+    Android &nbsp;r &mdash; 
+<script src="/timestamp.js" type="text/javascript"></script>
+<script>document.write(BUILD_TIMESTAMP)</script>
+
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div> <!-- jd-content -->
+
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+</body>
+</html>
diff --git a/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.html b/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.html
new file mode 100644
index 0000000..45b77c6
--- /dev/null
+++ b/docs/html/reference/android/preview/support/wearable/notifications/WearableNotifications.html
@@ -0,0 +1,2029 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>WearableNotifications | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="http://fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="http://www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  develop" itemscope itemtype="http://schema.org/Article">
+  <div id="doc-api-level" class="" style="display:none"></div>
+  <a name="top"></a>
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12"  id="doc-col">
+
+<div id="api-info-block">
+
+
+
+  
+   
+  
+  
+  
+  
+
+
+<div class="sum-details-links">
+
+Summary:
+
+  <a href="#nestedclasses">Nested Classes</a>
+  
+
+
+
+
+
+  &#124; <a href="#constants">Constants</a>
+  
+
+
+
+
+
+
+
+  &#124; <a href="#pubmethods">Methods</a>
+  
+
+
+
+  &#124; <a href="#inhmethods">Inherited Methods</a>
+
+&#124; <a href="#" onclick="return toggleAllClassInherited()" id="toggleAllClassInherited">[Expand All]</a>
+
+</div><!-- end sum-details-links -->
+<div class="api-level">
+  
+  
+  
+
+</div>
+</div><!-- end api-info-block -->
+
+
+<!-- ======== START OF CLASS DATA ======== -->
+
+<div id="jd-header">
+    public
+     
+    final 
+    
+    class
+<h1 itemprop="name">WearableNotifications</h1>
+
+
+
+  
+    extends <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a><br/>
+  
+  
+  
+
+  
+  
+  
+
+
+</div><!-- end header -->
+
+<div id="naMessage"></div>
+
+<div id="jd-content" class="api apilevel-">
+<table class="jd-inheritance-table">
+
+
+    <tr>
+         	
+        <td colspan="2" class="jd-inheritance-class-cell"><a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a></td>
+    </tr>
+    
+
+    <tr>
+        
+            <td class="jd-inheritance-space">&nbsp;&nbsp;&nbsp;&#x21b3;</td>
+         	
+        <td colspan="1" class="jd-inheritance-class-cell">android.preview.support.wearable.notifications.WearableNotifications</td>
+    </tr>
+    
+
+</table>
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Class Overview</h2>
+<p itemprop="articleBody">Helper providing extensions to android notifications for use with wearable devices.
+
+ <p>To build notifications with wearable extensions, use the <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></code> class.
+ Notifications created using Builder should be posted to the notification system
+ using the <code>NotificationManagerCompat.notify(...)</code> methods instead of
+ <code>NotificationManager.notify(...)</code>.
+
+ <p>Once a notification is built, a variety of methods are provide in this utility to access
+ the value of various notification fields in a backwards compatible manner.
+</p>
+
+
+
+
+
+</div><!-- jd-descr -->
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<div class="jd-descr">
+
+
+<h2>Summary</h2>
+
+
+
+<!-- ======== NESTED CLASS SUMMARY ======== -->
+<table id="nestedclasses" class="jd-sumtable"><tr><th colspan="12">Nested Classes</th></tr>
+
+
+  
+    <tr class="alt-color api apilevel-" >
+      <td class="jd-typecol"><nobr>
+        
+         
+         
+        
+        class</nobr></td>
+      <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></td>
+      <td class="jd-descrcol" width="100%">Subclass of <code><a href="/reference/android/support/v4/app/NotificationCompat.Action.html">NotificationCompat.Action</a></code> which adds support for additional
+ wearable extensions.&nbsp;</td>
+    </tr>
+    
+    
+    <tr class=" api apilevel-" >
+      <td class="jd-typecol"><nobr>
+        
+         
+         
+        
+        class</nobr></td>
+      <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></td>
+      <td class="jd-descrcol" width="100%">Builder object that wraps a <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> to provide
+ methods for adding wearable extensions to a notification.&nbsp;</td>
+    </tr>
+    
+    
+
+
+
+
+
+
+
+
+
+
+
+
+
+<!-- =========== ENUM CONSTANT SUMMARY =========== -->
+<table id="constants" class="jd-sumtable"><tr><th colspan="12">Constants</th></tr>
+
+
+    
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#GROUP_ORDER_DEFAULT">GROUP_ORDER_DEFAULT</a></td>
+        <td class="jd-descrcol" width="100%">Default value for the group sort order.</td>
+    </tr>
+    
+    
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol">int</td>
+        <td class="jd-linkcol"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#GROUP_ORDER_SUMMARY">GROUP_ORDER_SUMMARY</a></td>
+        <td class="jd-descrcol" width="100%">Sentinel value provided to the groupOrder parameter <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setGroup(android.app.Notification, java.lang.String)">setGroup(Notification, String)</a></code> to indicate that
+ this member of a notification group is the summary of the group.</td>
+    </tr>
+    
+    
+
+</table>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="pubmethods" class="jd-sumtable"><tr><th colspan="12">Public Methods</th></tr>
+
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getAction(android.app.Notification, int)">getAction</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, int actionIndex)</nobr>
+        
+        <div class="jd-descrdiv">Get a <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code> wrapper for the notification at index <code>actionIndex</code>
+ in the <code><a href="/http://developer.android.com/reference/android/app/Notification.html#actions">actions</a></code> array.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getActionCount(android.app.Notification)">getActionCount</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</nobr>
+        
+        <div class="jd-descrdiv">Get the number of actions present on this notification.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getBigActionIcon(android.app.Notification)">getBigActionIcon</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</nobr>
+        
+        <div class="jd-descrdiv">Get the big action icon to be displayed with this notification.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            <a href="http://developer.android.com/reference/java/lang/CharSequence.html">CharSequence</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getBigActionSubtext(android.app.Notification)">getBigActionSubtext</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</nobr>
+        
+        <div class="jd-descrdiv">Get the big action icon subtext to be shown with a big action icon.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput[]</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getContentIntentRemoteInputs(android.app.Notification)">getContentIntentRemoteInputs</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</nobr>
+        
+        <div class="jd-descrdiv">Gets the <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code>s associated with the content intent.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            <a href="http://developer.android.com/reference/android/os/Bundle.html">Bundle</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getExtras(android.app.Notification)">getExtras</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</nobr>
+        
+        <div class="jd-descrdiv">Gets the <code><a href="/http://developer.android.com/reference/android/app/Notification.html#extras">extras</a></code> field from a notification in a backwards
+ compatible manner.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            <a href="http://developer.android.com/reference/java/lang/String.html">String</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getGroupKey(android.app.Notification)">getGroupKey</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</nobr>
+        
+        <div class="jd-descrdiv">Get the key used to group this notification into a cluster or stack
+ with other notifications.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getGroupOrder(android.app.Notification)">getGroupOrder</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</nobr>
+        
+        <div class="jd-descrdiv">Get the sort order of this notification within a group of notifications
+ with the same group key set.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getHintHideIcon(android.app.Notification)">getHintHideIcon</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</nobr>
+        
+        <div class="jd-descrdiv">Get a hint that this notification's icon should not be displayed.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getLocalOnly(android.app.Notification)">getLocalOnly</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</nobr>
+        
+        <div class="jd-descrdiv">Get whether or not this notification is only relevant to the current device.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            <a href="http://developer.android.com/reference/android/app/Notification.html">Notification[]</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#getPages(android.app.Notification)">getPages</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</nobr>
+        
+        <div class="jd-descrdiv">Get the array of additional pages of content for displaying this notification.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setBigActionIcon(android.app.Notification, int)">setBigActionIcon</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, int icon)</nobr>
+        
+        <div class="jd-descrdiv">Add a big action display to this notification.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setBigActionIcon(android.app.Notification, int, java.lang.CharSequence)">setBigActionIcon</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, int icon, <a href="http://developer.android.com/reference/java/lang/CharSequence.html">CharSequence</a> subtext)</nobr>
+        
+        <div class="jd-descrdiv">Add a big action display to this notification.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setContentIntentRemoteInputs(android.app.Notification, android.preview.support.wearable.notifications.RemoteInput[])">setContentIntentRemoteInputs</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput[]</a> inputs)</nobr>
+        
+        <div class="jd-descrdiv">Sets <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code>s to be collected when the user triggers the
+ <code>contentIntent</code>.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setGroup(android.app.Notification, java.lang.String)">setGroup</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, <a href="http://developer.android.com/reference/java/lang/String.html">String</a> groupKey)</nobr>
+        
+        <div class="jd-descrdiv">Set this notification to be part of a group of notifications sharing the same key.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setGroup(android.app.Notification, java.lang.String, int)">setGroup</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, <a href="http://developer.android.com/reference/java/lang/String.html">String</a> groupKey, int groupOrder)</nobr>
+        
+        <div class="jd-descrdiv">Set this notification to be part of a group of notifications sharing the same key.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setHintHideIcon(android.app.Notification, boolean)">setHintHideIcon</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, boolean hintHideIcon)</nobr>
+        
+        <div class="jd-descrdiv">Set a hint that this notification's icon should not be displayed.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setLocalOnly(android.app.Notification, boolean)">setLocalOnly</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, boolean localOnly)</nobr>
+        
+        <div class="jd-descrdiv">Set whether or not this notification is only relevant to the current device.</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setMinPriority(android.app.Notification)">setMinPriority</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</nobr>
+        
+        <div class="jd-descrdiv">Set the priority of this notification to be minimum priority level
+ (<code><a href="/http://developer.android.com/reference/android/app/Notification.html#PRIORITY_MIN">PRIORITY_MIN</a></code>).</div>
+  
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            static
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad"><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setPages(android.app.Notification, android.app.Notification[])">setPages</a></span>(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, <a href="http://developer.android.com/reference/android/app/Notification.html">Notification[]</a> pages)</nobr>
+        
+        <div class="jd-descrdiv">Set additional pages of content to display with this notification.</div>
+  
+  </td></tr>
+
+
+
+</table>
+
+
+
+
+
+
+
+<!-- ========== METHOD SUMMARY =========== -->
+<table id="inhmethods" class="jd-sumtable"><tr><th>
+  <a href="#" class="toggle-all" onclick="return toggleAllInherited(this, null)">[Expand]</a>
+  <div style="clear:left;">Inherited Methods</div></th></tr>
+
+
+<tr class="api apilevel-" >
+<td colspan="12">
+  <a href="#" onclick="return toggleInherited(this, null)" id="inherited-methods-java.lang.Object" class="jd-expando-trigger closed"
+          ><img id="inherited-methods-java.lang.Object-trigger"
+          src="/assets/images/triangle-closed.png"
+          class="jd-expando-trigger-img" /></a>
+From class
+
+  <a href="http://developer.android.com/reference/java/lang/Object.html">java.lang.Object</a>
+
+<div id="inherited-methods-java.lang.Object">
+  <div id="inherited-methods-java.lang.Object-list"
+        class="jd-inheritedlinks">
+  </div>
+  <div id="inherited-methods-java.lang.Object-summary" style="display: none;">
+    <table class="jd-sumtable-expando">
+    
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Object.html">Object</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">clone</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            boolean</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">equals</span>(<a href="http://developer.android.com/reference/java/lang/Object.html">Object</a> arg0)</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">finalize</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/Class.html">Class</a>&lt;?&gt;</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">getClass</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            int</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">hashCode</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notify</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">notifyAll</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            
+            
+            
+            <a href="http://developer.android.com/reference/java/lang/String.html">String</a></nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">toString</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>()</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class=" api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0, int arg1)</nobr>
+        
+  </td></tr>
+
+
+	 
+    <tr class="alt-color api apilevel-" >
+        <td class="jd-typecol"><nobr>
+            
+            
+            final
+            
+            
+            void</nobr>
+        </td>
+        <td class="jd-linkcol" width="100%"><nobr>
+        <span class="sympad">wait</span>(long arg0)</nobr>
+        
+  </td></tr>
+
+
+</table>
+  </div>
+</div>
+</td></tr>
+
+
+</table>
+
+
+</div><!-- jd-descr (summary) -->
+
+<!-- Details -->
+
+
+
+
+
+
+
+
+<!-- XML Attributes -->
+
+
+<!-- Enum Values -->
+
+
+<!-- Constants -->
+
+
+<!-- ========= ENUM CONSTANTS DETAIL ======== -->
+<h2>Constants</h2>
+
+
+
+
+<A NAME="GROUP_ORDER_DEFAULT"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+        final 
+        int
+      </span>
+        GROUP_ORDER_DEFAULT
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Default value for the group sort order.
+</p></div>
+
+    
+        <div class="jd-tagdata">
+        <span class="jd-tagtitle">Constant Value: </span>
+        <span>
+            
+                0
+                (0x00000000)
+            
+        </span>
+        </div>
+    
+    </div>
+</div>
+
+
+
+<A NAME="GROUP_ORDER_SUMMARY"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+        final 
+        int
+      </span>
+        GROUP_ORDER_SUMMARY
+    </h4>
+      <div class="api-level">
+        
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Sentinel value provided to the groupOrder parameter <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setGroup(android.app.Notification, java.lang.String)">setGroup(Notification, String)</a></code> to indicate that
+ this member of a notification group is the summary of the group.
+</p></div>
+
+    
+        <div class="jd-tagdata">
+        <span class="jd-tagtitle">Constant Value: </span>
+        <span>
+            
+                -1
+                (0xffffffff)
+            
+        </span>
+        </div>
+    
+    </div>
+</div>
+
+
+
+
+<!-- Fields -->
+
+
+<!-- Public ctors -->
+
+
+
+<!-- ========= CONSTRUCTOR DETAIL ======== -->
+<!-- Protected ctors -->
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+<!-- Public methdos -->
+
+<h2>Public Methods</h2>
+
+
+
+<A NAME="getAction(android.app.Notification, int)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a>
+      </span>
+      <span class="sympad">getAction</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, int actionIndex)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Get a <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code> wrapper for the notification at index <code>actionIndex</code>
+ in the <code><a href="/http://developer.android.com/reference/android/app/Notification.html#actions">actions</a></code> array.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="getActionCount(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        int
+      </span>
+      <span class="sympad">getActionCount</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Get the number of actions present on this notification.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">See Also</h5>
+      <ul class="nolist"><li><code><a href="/http://developer.android.com/reference/android/app/Notification.html#actions">actions</a></code></li>
+      </ul>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="getBigActionIcon(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        int
+      </span>
+      <span class="sympad">getBigActionIcon</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Get the big action icon to be displayed with this notification. Big actions show
+ a hint to users about the action taken when the content intent is triggered.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">See Also</h5>
+      <ul class="nolist"><li><code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setBigActionIcon(android.app.Notification, int)">setBigActionIcon(Notification, int)</a></code></li>
+      </ul>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="getBigActionSubtext(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        <a href="http://developer.android.com/reference/java/lang/CharSequence.html">CharSequence</a>
+      </span>
+      <span class="sympad">getBigActionSubtext</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Get the big action icon subtext to be shown with a big action icon.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">See Also</h5>
+      <ul class="nolist"><li><code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#setBigActionIcon(android.app.Notification, int)">setBigActionIcon(Notification, int)</a></code></li>
+      </ul>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="getContentIntentRemoteInputs(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput[]</a>
+      </span>
+      <span class="sympad">getContentIntentRemoteInputs</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Gets the <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code>s associated with the content intent.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="getExtras(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        <a href="http://developer.android.com/reference/android/os/Bundle.html">Bundle</a>
+      </span>
+      <span class="sympad">getExtras</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Gets the <code><a href="/http://developer.android.com/reference/android/app/Notification.html#extras">extras</a></code> field from a notification in a backwards
+ compatible manner. Extras field was supported from JellyBean (Api level 16)
+ forwards. This function will return null on older api levels.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="getGroupKey(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        <a href="http://developer.android.com/reference/java/lang/String.html">String</a>
+      </span>
+      <span class="sympad">getGroupKey</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Get the key used to group this notification into a cluster or stack
+ with other notifications. This key is unique within a package.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="getGroupOrder(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        int
+      </span>
+      <span class="sympad">getGroupOrder</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Get the sort order of this notification within a group of notifications
+ with the same group key set. Group orders are 0-indexed integers that are used
+ to sort notifications in ascending order. Can also be the sentinel value
+ <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#GROUP_ORDER_SUMMARY">GROUP_ORDER_SUMMARY</a></code> if this is the summary notification for a group.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="getHintHideIcon(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        boolean
+      </span>
+      <span class="sympad">getHintHideIcon</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Get a hint that this notification's icon should not be displayed.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="getLocalOnly(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        boolean
+      </span>
+      <span class="sympad">getLocalOnly</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Get whether or not this notification is only relevant to the current device.
+
+ <p>Some notifications can be bridged to other devices for remote display.
+ If this hint is set, it is recommended that this notification not be bridged.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="getPages(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        <a href="http://developer.android.com/reference/android/app/Notification.html">Notification[]</a>
+      </span>
+      <span class="sympad">getPages</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>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.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="setBigActionIcon(android.app.Notification, int)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setBigActionIcon</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, int icon)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Add a big action display to this notification. Big actions show a hint to users
+ about the action taken when the content intent is triggered.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>icon</td>
+          <td>Icon to display for the content action.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="setBigActionIcon(android.app.Notification, int, java.lang.CharSequence)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setBigActionIcon</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, int icon, <a href="http://developer.android.com/reference/java/lang/CharSequence.html">CharSequence</a> subtext)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Add a big action display to this notification. Big actions show a hint to users
+ about the action taken when the content intent is triggered.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>icon</td>
+          <td>Icon to display for the content action.</td>
+        </tr>
+        <tr>
+          <th>subtext</td>
+          <td>Optional subtext to display with the big action icon.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="setContentIntentRemoteInputs(android.app.Notification, android.preview.support.wearable.notifications.RemoteInput[])"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setContentIntentRemoteInputs</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput[]</a> inputs)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Sets <code><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></code>s to be collected when the user triggers the
+ <code>contentIntent</code>.  These function just as if they were attached to
+ an <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></code>.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="setGroup(android.app.Notification, java.lang.String)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setGroup</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, <a href="http://developer.android.com/reference/java/lang/String.html">String</a> groupKey)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Set this notification to be part of a group of notifications sharing the same key.
+ Grouped notifications may display in a cluster or stack on devices which
+ support such rendering. Use the default ordering within a group.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>groupKey</td>
+          <td>The group key of the group. Unique within a package.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="setGroup(android.app.Notification, java.lang.String, int)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setGroup</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, <a href="http://developer.android.com/reference/java/lang/String.html">String</a> groupKey, int groupOrder)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Set this notification to be part of a group of notifications sharing the same key.
+ Grouped notifications may display in a cluster or stack on devices which
+ support such rendering.</p></div>
+  <div class="jd-tagdata">
+      <h5 class="jd-tagtitle">Parameters</h5>
+      <table class="jd-tagtable">
+        <tr>
+          <th>groupKey</td>
+          <td>The group key of the group. Unique within a package.</td>
+        </tr>
+        <tr>
+          <th>groupOrder</td>
+          <td>The 0-indexed sort order within the group. Can also be set
+         to the sentinel value <code><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#GROUP_ORDER_SUMMARY">GROUP_ORDER_SUMMARY</a></code> to mark this
+         notification as being the group summary.
+</td>
+        </tr>
+      </table>
+  </div>
+
+    </div>
+</div>
+
+
+<A NAME="setHintHideIcon(android.app.Notification, boolean)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setHintHideIcon</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, boolean hintHideIcon)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Set a hint that this notification's icon should not be displayed.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="setLocalOnly(android.app.Notification, boolean)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setLocalOnly</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, boolean localOnly)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Set whether or not this notification is only relevant to the current device.
+
+ <p>Some notifications can be bridged to other devices for remote display.
+ This hint can be set to recommend this notification not be bridged.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="setMinPriority(android.app.Notification)"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setMinPriority</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Set the priority of this notification to be minimum priority level
+ (<code><a href="/http://developer.android.com/reference/android/app/Notification.html#PRIORITY_MIN">PRIORITY_MIN</a></code>). When set via WearableNotifications, these
+ minimum priority notifications will bypass the notification manager on platforms
+ that do not support ambient level notifications.
+</p></div>
+
+    </div>
+</div>
+
+
+<A NAME="setPages(android.app.Notification, android.app.Notification[])"></A>
+
+<div class="jd-details api apilevel-"> 
+    <h4 class="jd-details-title">
+      <span class="normal">
+        public 
+        static 
+         
+         
+         
+        void
+      </span>
+      <span class="sympad">setPages</span>
+      <span class="normal">(<a href="http://developer.android.com/reference/android/app/Notification.html">Notification</a> notif, <a href="http://developer.android.com/reference/android/app/Notification.html">Notification[]</a> pages)</span>
+    </h4>
+      <div class="api-level">
+        <div></div>
+        
+  
+
+      </div>
+    <div class="jd-details-descr">
+      
+  <div class="jd-tagdata jd-tagdescr"><p>Set additional pages of content to display with this notification. The current
+ notification forms the first page, and pages set using this function form
+ subsequent pages. This field can be used to separate a notification into multiple
+ sections.
+</p></div>
+
+    </div>
+</div>
+
+
+
+
+
+<!-- ========= METHOD DETAIL ======== -->
+
+
+
+<!-- ========= END OF CLASS DATA ========= -->
+<A NAME="navbar_top"></A>
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is licensed under <a
+  href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a>. 
+  For details and restrictions, see the <a href="/license.html">
+  Content License</a>.
+  </div>
+  <div id="build_info">
+    
+    Android &nbsp;r &mdash; 
+<script src="/timestamp.js" type="text/javascript"></script>
+<script>document.write(BUILD_TIMESTAMP)</script>
+
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div> <!-- jd-content -->
+
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+</body>
+</html>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index bc793f1..7b3d120 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -5,43 +5,43 @@
 page.metaDescription=Download the official Android SDK to develop apps for Android-powered devices.
 
 
-sdk.linux32_bundle_download=adt-bundle-linux-x86-20131030.zip
-sdk.linux32_bundle_bytes=496876498
-sdk.linux32_bundle_checksum=d389139ad9f59a43bdd34c94bc850509
+sdk.linux32_bundle_download=adt-bundle-linux-x86-20140311.zip
+sdk.linux32_bundle_bytes=527970712
+sdk.linux32_bundle_checksum=ad97a54f7e0d84d7d7fe86b56307009f
 
-sdk.linux64_bundle_download=adt-bundle-linux-x86_64-20131030.zip
-sdk.linux64_bundle_bytes=497171697
-sdk.linux64_bundle_checksum=99b51a4f0526434b083701a896550b72
+sdk.linux64_bundle_download=adt-bundle-linux-x86_64-20140311.zip
+sdk.linux64_bundle_bytes=528184435
+sdk.linux64_bundle_checksum=f60c023d574565fea7a52b42c69ae76b
 
-sdk.mac64_bundle_download=adt-bundle-mac-x86_64-20131030.zip
-sdk.mac64_bundle_bytes=470386961
-sdk.mac64_bundle_checksum=3e80e7a92b549029d91bdcf2ae82657f
+sdk.mac64_bundle_download=adt-bundle-mac-x86_64-20140311.zip
+sdk.mac64_bundle_bytes=501954506
+sdk.mac64_bundle_checksum=9569251f3403c0f6c22b6caa1d672112
 
-sdk.win32_bundle_download=adt-bundle-windows-x86-20131030.zip
-sdk.win32_bundle_bytes=503599460
-sdk.win32_bundle_checksum=cd490a531ec24667354f6473e999b988
+sdk.win32_bundle_download=adt-bundle-windows-x86-20140311.zip
+sdk.win32_bundle_bytes=535083737
+sdk.win32_bundle_checksum=b2aabf536ddc4ea5cbb24e0752a832d8
 
-sdk.win64_bundle_download=adt-bundle-windows-x86_64-20131030.zip
-sdk.win64_bundle_bytes=503735416
-sdk.win64_bundle_checksum=ddddbb1b9028015779d68dde01f96b14
+sdk.win64_bundle_download=adt-bundle-windows-x86_64-20140311.zip
+sdk.win64_bundle_bytes=535284227
+sdk.win64_bundle_checksum=eee71e07dcfd538db57e9d76349efb98
 
 
 
-sdk.linux_download=android-sdk_r22.6-linux.tgz
-sdk.linux_bytes=100992666
-sdk.linux_checksum=dde27b72715e52693c1ebc908742fc40
+sdk.linux_download=android-sdk_r22.6.1-linux.tgz
+sdk.linux_bytes=101052129
+sdk.linux_checksum=d95b400600e9b68ed7719e0fd1792e0b
 
-sdk.mac_download=android-sdk_r22.6-macosx.zip
-sdk.mac_bytes=74547402
-sdk.mac_checksum=10c0e2ab65444c4911d69356ca2343f5
+sdk.mac_download=android-sdk_r22.6.1-macosx.zip
+sdk.mac_bytes=74639176
+sdk.mac_checksum=99abc850398ccc220e3a1d6d0ab73ccf
 
-sdk.win_download=android-sdk_r22.6-windows.zip
-sdk.win_bytes=108862292
-sdk.win_checksum=6faa487d328be352a456c53d9cbf0e3d
+sdk.win_download=android-sdk_r22.6.1-windows.zip
+sdk.win_bytes=108914728
+sdk.win_checksum=88471340a8c99822ffb5efbe3c28167c
 
-sdk.win_installer=installer_r22.6-windows.exe
-sdk.win_installer_bytes=88856450
-sdk.win_installer_checksum=6e5351b414bd554f3ac4c79f9dd4d213
+sdk.win_installer=installer_r22.6.1-windows.exe
+sdk.win_installer_bytes=88907175
+sdk.win_installer_checksum=fd664527ed1b1b1bfe2d4546cafc7ada
 
 
 
diff --git a/docs/html/sdk/installing/installing-adt.jd b/docs/html/sdk/installing/installing-adt.jd
index 42cb92c..2767d02 100644
--- a/docs/html/sdk/installing/installing-adt.jd
+++ b/docs/html/sdk/installing/installing-adt.jd
@@ -1,8 +1,8 @@
 page.title=Installing the Eclipse Plugin
-adt.zip.version=22.6.0
-adt.zip.download=ADT-22.6.0.zip
-adt.zip.bytes=14585211
-adt.zip.checksum=d95c6d8e678881f6c89f063b58d4162f
+adt.zip.version=22.6.1
+adt.zip.download=ADT-22.6.1.zip
+adt.zip.bytes=14586662
+adt.zip.checksum=c3cd19a1936ba0b850f74ef2b3a98b65
 
 @jd:body
 
diff --git a/docs/html/sdk/installing/studio-layout.jd b/docs/html/sdk/installing/studio-layout.jd
new file mode 100644
index 0000000..f0e5d59
--- /dev/null
+++ b/docs/html/sdk/installing/studio-layout.jd
@@ -0,0 +1,148 @@
+page.title=Using the Layout Editor
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>See also</h2>
+<ul>
+<li><a href="{@docRoot}sdk/installing/studio.html">
+Getting Started with Android Studio</a></li>
+<li><a href="{@docRoot}sdk/installing/studio-tips.html">
+Android Studio Tips and Tricks</a></li>
+<li><a href="{@docRoot}sdk/installing/migrate.html">
+Migrating from Eclipse</a></li>
+</div>
+</div>
+
+<a class="notice-developers-video"
+href="https://developers.google.com/events/io/sessions/324603352">
+<div>
+    <h3>Video</h3>
+    <p>What's New in Android Developer Tools</p>
+</div>
+</a>
+
+<p>Android Studio offers an advanced layout editor that allows you to drag-and-drop widgets
+into your layout and preview your layout while editing the XML.</p>
+
+<p>Within the layout editor, you can switch between the <strong>Text</strong> view, where
+you edit the XML file as text, and the <strong>Design</strong> view. Just click the
+appropriate tab at the bottom of the window to display the desired editor.</p>
+
+<h2>Editing in the Text View</h2>
+
+<p>You can use the <strong>Text</strong> view to edit your layout file. This section describes
+some of the features that are available in the <strong>Text</strong> view.</p>
+
+<h3>Preview</h3>
+
+<p>While editing in the <strong>Text</strong> view, you can preview the layout on devices
+by opening the <strong>Preview</strong> pane available on the right side of the window.
+Within the <strong>Preview</strong> pane, you can modify the preview by changing various
+options at the top of the pane, including the preview device, layout theme, platform
+version and more. To see a preview of how your app would look with a particular device
+skin, click the preview icon
+<img src="{@docRoot}images/tools/as-preview-icon.png" style="vertical-align:bottom;margin:0;height:19px" />
+and choose the desired device, such as Nexus 4:</p>
+
+<img src="{@docRoot}images/tools/as-preview-chrome.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> Previewing your app.</p>
+
+<p>To preview the layout on multiple devices simultaneously, select <strong>Preview All
+Screen Sizes</strong> from the device drop-down. </p>
+
+<p>When you click in the preview image, the layout editor highlights the corresponding
+section in the XML, and vice-versa.</p>
+
+<h3>Interactive error detection and recovery</h3>
+
+<p>As you edit the <strong>Text</strong> view of your layout XML file, Android Studio flags
+typos and offers assistance.</p>
+
+<p>For example, suppose you are adding a button, and you misspell it as &quot;Buttonn&quot;.
+Android Studio helps you to correct it by displaying an error such as the following,
+where you can click on &quot;Change to Button&quot; to fix the error in the XML file:</p>
+
+<img src="{@docRoot}images/tools/as-error.png" alt="" />
+
+<p class="img-caption"><strong>Figure 2.</strong> Flagging errors.</p>
+
+<p>Android Studio also prompts you to supply missing information. For example, suppose you
+start adding a fragment to your layout XML file. First of all, Android Studio displays
+auto-complete suggestions as you type. Once it becomes clear that you are adding a fragment,
+Android Studio displays an error panel with links that you can click to supply the missing
+attributes. Clicking &quot;Automatically add all missing attributes&quot; in this case
+does just that&mdash;it completes the fragment definition in your layout XML file:</p>
+
+<img src="{@docRoot}images/tools/as-frag-ex.png" alt="" />
+
+<p class="img-caption"><strong>Figure 3.</strong> Supplying missing information</p>
+
+<h3>Picking a theme</h3>
+
+<p>To pick a theme for your app, click the Theme icon
+<img src="{@docRoot}images/tools/as-theme-icon.png" style="vertical-align:bottom;margin:0;height:19px" />.
+</p>
+
+<p>This displays the <strong>Select Theme</strong> dialog, where you can search for a
+particular theme and/or select one from the list on the right hand side. The theme you
+choose will be reflected in the previewed image.</p>
+
+<img src="{@docRoot}images/tools/as-theme-db.png" alt="" />
+
+<p class="img-caption"><strong>Figure 4.</strong> Specifying a theme.</p>
+
+<h3>Localization</h3>
+
+<p>Android Studio provides built-in localization support. When you click the
+localization icon
+<img src="{@docRoot}images/tools/as-i18n-icon.png" style="vertical-align:bottom;margin:0;height:19px" />,
+you can select a particular locale, add and edit translations, preview the locales your
+app supports (all locales or just a single locale), and preview right-to-left layout for
+languages that are RTL.</p>
+
+<p>See <a href="{@docRoot}training/basics/supporting-devices/languages.html">Supporting
+Different Languages</a> for a description of how to support different locales in your app.</p>
+<p>For example, here is a preview of a &quot;Hello World&quot; app for the
+<img src="{@docRoot}images/tools/as-fr-icon.png" style="vertical-align:bottom;margin:0;height:19px" />
+locale:</p>
+
+<img src="{@docRoot}images/tools/as-fr-device.png" alt="" />
+<p class="img-caption"><strong>Figure 5.</strong> Previewing locales.</p>
+
+<h2>Editing in the Design View</h2>
+
+<p>You can switch to the graphical editor by clicking <strong>Design</strong> at the
+bottom of the window. While editing in the <strong>Design</strong> view, you can show and
+hide the widgets available to drag-and-drop by clicking <strong>Palette</strong> on the
+left side of the window. Clicking <strong>Designer</strong> on the right side of the
+window reveals a panel with a layout hierarchy and a list of properties for each view in
+the layout.</p>
+
+<p>When you drag a widget into the graphical layout for your app, the display changes to
+help you place the widget. What you see depends on the type of layout. For example, if
+you're dragging a widget into a {@link android.widget.FrameLayout}, it displays a grid to
+help you place the widget, as shown in figure 6:</p>
+
+<img src="{@docRoot}images/tools/as-grid-layout.png" alt="" />
+
+<p class="img-caption"><strong>Figure 6.</strong> Using the grid layout to place a widget.</p>
+
+<p>Within the graphical editor, you can rearrange your app's UI by dragging widgets to
+the desired location.</p>
+
+<h3>Taking a snapshot</h3>
+
+<p>When you run your app on a connected device, you can take a snapshot of it by clicking
+the camera icon
+<img src="{@docRoot}images/tools/as-camera-icon.png" style="vertical-align:bottom;margin:0;height:19px" />
+to the left of the logging
+panel (at the bottom of the window by default). This takes a snapshot of your running app
+(or whatever is currently displayed on your device) and displays it in a window. Check
+<strong>Frame Screenshot</strong> to show your screenshot within the device skin of your
+choice. You can also specify whether you want the image to have screen glare and/or a drop
+shadow. Once you have the desired effect, you can save the image.</p>
+
+<p>You can use the same process to create a snapshot of your app's preview. Just click the
+camera icon in the preview area and follow the steps for adding a device skin.</p>
diff --git a/docs/html/sdk/installing/studio.jd b/docs/html/sdk/installing/studio.jd
index 5a7e270..feb7a6e 100644
--- a/docs/html/sdk/installing/studio.jd
+++ b/docs/html/sdk/installing/studio.jd
@@ -318,6 +318,12 @@
 
 
 <h2 id="Installing">Installing Android Studio</h2>
+<p>Android Studio requires JDK 6 or greater (JRE alone is not sufficient). To check if you 
+have JDK installed (and which version), open a terminal and type <code>javac -version</code>.
+If JDK is not available or the version is lower than 6,
+<a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">download
+JDK from here</a>.</p>
+<p>To install Android Studio:</p>
 <ol>
 <li>Download the <strong>Android Studio</strong> package from above.</li>
 <li>Install Android Studio and the SDK tools:
diff --git a/docs/html/tools/help/logcat.jd b/docs/html/tools/help/logcat.jd
index ede1905..b30971e 100644
--- a/docs/html/tools/help/logcat.jd
+++ b/docs/html/tools/help/logcat.jd
@@ -45,7 +45,7 @@
     <tr>
       <td><code>-b&nbsp;&lt;buffer&gt;</code></td>
 
-      <td>Loads an alternate log buffer for viewing, such as <code>event</code> or
+      <td>Loads an alternate log buffer for viewing, such as <code>events</code> or
       <code>radio</code>. The <code>main</code> buffer is used by default. See <a href= 
       "{@docRoot}tools/debugging/debugging-log.html#alternativeBuffers">Viewing Alternative Log Buffers</a>.</td>
     </tr>
diff --git a/docs/html/tools/sdk/eclipse-adt.jd b/docs/html/tools/sdk/eclipse-adt.jd
index d711e44..a821757 100644
--- a/docs/html/tools/sdk/eclipse-adt.jd
+++ b/docs/html/tools/sdk/eclipse-adt.jd
@@ -53,9 +53,59 @@
 <p>For a summary of all known issues in ADT, see <a
 href="http://tools.android.com/knownissues">http://tools.android.com/knownissues</a>.</p>
 
+
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>ADT 22.6.1</a> <em>(March 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+<dl>
+  <dt>Dependencies:</dt>
+
+  <dd>
+    <ul>
+      <li>Java 1.6 or higher is required.</li>
+      <li>Eclipse Indigo (Version 3.7.2) or higher is required.</li>
+      <li>This version of ADT is designed for use with
+        <a href="{@docRoot}tools/sdk/tools-notes.html">SDK Tools r22.6.1</a>.
+        If you haven't already installed SDK Tools r22.6.1 into your SDK, use the
+        Android SDK Manager to do so.</li>
+    </ul>
+  </dd>
+
+  <dt>General Notes:</dt>
+  <dd>
+    <ul>
+      <li>Fixed a problem where the Android Virtual Device Manager could not create new virtual
+          devices. (<a href="http://b.android.com/66661">Issue 66661</a>)</li>
+      <li><p>Fixed a problem with virtual devices created using ADT 22.3 or earlier.</p>
+          <p>If you created an Android Virtual Device using ADT 22.3 or earlier, the
+          AVD may be listed as <em>broken</em> in the AVD Manager in 22.6.1. To fix
+          this problem, select the virtual device on the AVD Manager and click
+          <strong>Repair</strong>.</p>
+      </li>
+      <li>Fixed a problem with the command line tools when creating virtual devices.
+          (<a href="http://b.android.com/66740">Issue 66740</a>)</li>
+      <li>Fixed a problem with the command line <code>lint</code> script.</li>
+    </ul>
+  </dd>
+
+  <dt>Known Issues:</dt>
+  <dd>
+    <p>When you create an Android virtual device using the Nexus 5 device definition,
+       you must enable the <em>Use Host GPU</em> option, otherwise the virtual device
+       will not start.</p>
+  </dd>
+</dl>
+</div>
+</div>
+
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>ADT 22.6.0</a> <em>(March 2014)</em>
   </p>
 
@@ -119,7 +169,7 @@
 
 <div class="toggle-content closed">
   <p><a href="#" onclick="return toggleContent(this)">
-    <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>ADT 22.3.0</a> <em>(October 2013)</em>
   </p>
 
diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd
index 99f0b38..675cde3 100644
--- a/docs/html/tools/sdk/tools-notes.jd
+++ b/docs/html/tools/sdk/tools-notes.jd
@@ -25,10 +25,57 @@
 <p>For a summary of all known issues in SDK Tools, see <a
 href="http://tools.android.com/knownissues">http://tools.android.com/knownissues</a>.</p>
 
-
 <div class="toggle-content opened">
   <p><a href="#" onclick="return toggleContent(this)">
     <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img"
+      alt=""/>SDK Tools, Revision 22.6.1</a> <em>(March 2014)</em>
+  </p>
+
+  <div class="toggle-content-toggleme">
+
+    <dl>
+    <dt>Dependencies:</dt>
+
+    <dd>
+      <ul>
+        <li>Android SDK Platform-tools revision 18 or later.</li>
+        <li>If you are developing in Eclipse with ADT, note that this version of SDK Tools is
+          designed for use with ADT 22.6.1 and later. If you haven't already, update your
+        <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT Plugin</a> to 22.6.1.</li>
+        <li>If you are developing outside Eclipse, you must have
+          <a href="http://ant.apache.org/">Apache Ant</a> 1.8 or later.</li>
+      </ul>
+    </dd>
+
+    <dt>General Notes:</dt>
+    <dd>
+      <ul>
+        <li>Fixed a problem where the Android Virtual Device Manager could not create new virtual
+            devices. (<a href="http://b.android.com/66661">Issue 66661</a>)</li>
+        <li><p>Fixed a problem with virtual devices created using ADT 22.3 or earlier.</p>
+            <p>If you created an Android Virtual Device using ADT 22.3 or earlier, the
+            AVD may be listed as <em>broken</em> in the AVD Manager in 22.6.1. To fix
+            this problem, select the virtual device on the AVD Manager and click
+            <strong>Repair</strong>.</p>
+        </li>
+        <li>Fixed a problem with the command line tools when creating virtual devices.
+            (<a href="http://b.android.com/66740">Issue 66740</a>)</li>
+        <li>Fixed a problem with the command line <code>lint</code> script.</li>
+      </ul>
+    </dd>
+
+    <dt>Known Issues:</dt>
+    <dd>
+      <p>When you create an Android virtual device using the Nexus 5 device definition,
+         you must enable the <em>Use Host GPU</em> option, otherwise the virtual device
+         will not start.</p>
+    </dd>
+  </div>
+</div>
+
+<div class="toggle-content closed">
+  <p><a href="#" onclick="return toggleContent(this)">
+    <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img"
       alt=""/>SDK Tools, Revision 22.6</a> <em>(March 2014)</em>
   </p>
 
diff --git a/docs/html/tools/tools_toc.cs b/docs/html/tools/tools_toc.cs
index a8424e6..382165c 100644
--- a/docs/html/tools/tools_toc.cs
+++ b/docs/html/tools/tools_toc.cs
@@ -34,7 +34,9 @@
               Migrating from Eclipse</a></li>
           <li><a href="<?cs var:toroot ?>sdk/installing/studio-tips.html">
               Tips and Tricks</a></li>
-        </ul>
+          <li><a href="<?cs var:toroot ?>sdk/installing/studio-layout.html">
+              Using the Layout Editor</a></li>
+          </ul>
       </li>
       <li><a href="<?cs var:toroot ?>sdk/exploring.html">
           <span class="en">Exploring the SDK</span></a></li>
diff --git a/docs/html/training/basics/firstapp/building-ui.jd b/docs/html/training/basics/firstapp/building-ui.jd
index 2615bee..179b3ac 100644
--- a/docs/html/training/basics/firstapp/building-ui.jd
+++ b/docs/html/training/basics/firstapp/building-ui.jd
@@ -75,16 +75,16 @@
 
 <h2 id="LinearLayout">Create a Linear Layout</h2>
 
-<p>Open the <code>activity_main.xml</code> file from the <code>res/layout/</code>
+<p>Open the <code>fragment_main.xml</code> file from the <code>res/layout/</code>
 directory.</p>
 
 <p class="note"><strong>Note:</strong> In Eclipse, when you open a layout file, you’re first shown
 the Graphical Layout editor. This is an editor that helps you build layouts using WYSIWYG tools. For this
-lesson, you’re going to work directly with the XML, so click the <em>activity_main.xml</em> tab at
+lesson, you’re going to work directly with the XML, so click the <em>fragment_main.xml</em> tab at
 the bottom of the screen to open the XML editor.</p>
 
 <p>The BlankActivity template you chose when you created this project includes the
-<code>activity_main.xml</code> file with a {@link
+<code>fragment_main.xml</code> file with a {@link
 android.widget.RelativeLayout} root view and a {@link android.widget.TextView} child view.</p>
 
 <p>First, delete the {@link android.widget.TextView &lt;TextView>} element and change the {@link
@@ -95,7 +95,6 @@
 The result looks like this:</p>
 
 <pre>
-&lt;?xml version="1.0" encoding="utf-8"?>
 &lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
diff --git a/docs/html/training/basics/firstapp/creating-project.jd b/docs/html/training/basics/firstapp/creating-project.jd
index 9516e37..50485db 100644
--- a/docs/html/training/basics/firstapp/creating-project.jd
+++ b/docs/html/training/basics/firstapp/creating-project.jd
@@ -120,8 +120,8 @@
     <strong>Finish</strong>.</li>
 </ol>
 
-<p>Your Android project is now set up with some default files and you’re ready to begin
-building the app. Continue to the <a href="running-app.html">next lesson</a>.</p>
+<p>Your Android project is now a basic "Hello World" app that contains some default files. 
+To run the app, continue to the <a href="running-app.html">next lesson</a>.</p>
 
 
 
@@ -155,8 +155,8 @@
 projects.</p></li>
 </ol>
 
-<p>Your Android project is now set up with several default configurations and you’re ready to begin
-building the app. Continue to the <a href="running-app.html">next lesson</a>.</p>
+<p>Your Android project is now a basic "Hello World" app that contains some default files. 
+To run the app, continue to the <a href="running-app.html">next lesson</a>.</p>
 
 <p class="note"><strong>Tip:</strong> Add the <code>platform-tools/</code> as well as the
 <code>tools/</code> directory to your <code>PATH</code> environment variable.</p>
diff --git a/docs/html/training/basics/firstapp/running-app.jd b/docs/html/training/basics/firstapp/running-app.jd
index 999d399..23cedba 100644
--- a/docs/html/training/basics/firstapp/running-app.jd
+++ b/docs/html/training/basics/firstapp/running-app.jd
@@ -62,7 +62,7 @@
 attributes. For your first app, it should look like this:</p>
 <pre>
 &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android" ... >
-    &lt;uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />
+    &lt;uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" />
     ...
 &lt;/manifest>
 </pre>
diff --git a/docs/html/training/basics/firstapp/starting-activity.jd b/docs/html/training/basics/firstapp/starting-activity.jd
index 712eabc..9aa25a3 100644
--- a/docs/html/training/basics/firstapp/starting-activity.jd
+++ b/docs/html/training/basics/firstapp/starting-activity.jd
@@ -45,7 +45,7 @@
 
 <h2 id="RespondToButton">Respond to the Send Button</h2>
 
-<p>To respond to the button's on-click event, open the <code>activity_main.xml</code>
+<p>To respond to the button's on-click event, open the <code>fragment_main.xml</code>
 layout file and add the <a
 href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a>
 attribute to the {@link android.widget.Button &lt;Button>} element:</p>
@@ -73,14 +73,6 @@
 }
 </pre>
 
-<p>This requires that you import the {@link android.view.View} class:</p>
-<pre>
-import android.view.View;
-</pre>
-
-<p class="note"><strong>Tip:</strong> In Eclipse, press Ctrl + Shift + O to import missing classes
-(Cmd + Shift + O on Mac).</p>
-
 <p>In order for the system to match this method to the method name given to <a
 href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a>,
 the signature must be exactly as shown. Specifically, the method must:</p>
@@ -111,6 +103,14 @@
 Intent intent = new Intent(this, DisplayMessageActivity.class);
 </pre>
 
+<p>This requires that you import the {@link android.content.Intent} class:</p>
+<pre>
+import android.content.Intent;
+</pre>
+
+<p class="note"><strong>Tip:</strong> In Eclipse, press Ctrl + Shift + O to import missing classes
+(Cmd + Shift + O on Mac).</p>
+
 <p>The constructor used here takes two parameters:</p>
 <ul>
   <li>A {@link
@@ -151,9 +151,8 @@
 </pre>
 
 <p class="note"><strong>Note:</strong>
-You now need import statements for <code>android.content.Intent</code>
-and <code>android.widget.EditText</code>. You'll define the <code>EXTRA_MESSAGE</code>
-constant in a moment.</p>
+You now need an import statement for <code>android.widget.EditText</code>. 
+You'll define the <code>EXTRA_MESSAGE</code> constant in a moment.</p>
 
 <p>An {@link android.content.Intent} can carry a collection of various data types as key-value
 pairs called <em>extras</em>. The {@link android.content.Intent#putExtra putExtra()} method takes the
@@ -165,7 +164,7 @@
 MainActivity} class:</p>
 
 <pre>
-public class MainActivity extends Activity {
+public class MainActivity extends ActionBarActivity {
     public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
     ...
 }
@@ -223,6 +222,7 @@
       <li><strong>Project</strong>: MyFirstApp</li>
       <li><strong>Activity Name</strong>: DisplayMessageActivity</li>
       <li><strong>Layout Name</strong>: activity_display_message</li>
+      <li><strong>Fragment Layout Name</strong>: fragment_display_message</li>
       <li><strong>Title</strong>: My Message</li>
       <li><strong>Hierarchial Parent</strong>: com.example.myfirstapp.MainActivity</li>
       <li><strong>Navigation Type</strong>: None</li>
@@ -240,49 +240,65 @@
 <ul>
   <li>The class
 already includes an implementation of the required {@link android.app.Activity#onCreate onCreate()}
-method.</li>
+method. You will update the implementation of this method later.</li>
   <li>There's also an implementation of the {@link android.app.Activity#onCreateOptionsMenu
 onCreateOptionsMenu()} method, but
 you won't need it for this app so you can remove it.</li>
   <li>There's also an implementation of {@link android.app.Activity#onOptionsItemSelected
   onOptionsItemSelected()} which handles the behavior for the action bar's <em>Up</em> behavior.
   Keep this one the way it is.</li>
+  <li>There's also a <code>PlaceholderFragment</code> class that extends 
+{@link android.app.Fragment}. You will not need this class in the final version of this
+activity.</li>
 </ul>
 
-<p>Because the {@link android.app.ActionBar} APIs are available only on {@link
-android.os.Build.VERSION_CODES#HONEYCOMB} (API level 11) and higher, you must add a condition
-around the {@link android.app.Activity#getActionBar()} method to check the current platform version.
-Additionally, you must add the {@code &#64;SuppressLint("NewApi")} tag to the
-{@link android.app.Activity#onCreate onCreate()} method to avoid <a
-href="{@docRoot}tools/help/lint.html">lint</a> errors.</p>
+<p>Fragments decompose application functionality and UI into reusable modules. For more 
+information on fragments, see the <a href="{@docRoot}guide/components/fragments.html">Fragments 
+API Guide</a>. The final version of this activity does not use fragments.</p>
 
 <p>The {@code DisplayMessageActivity} class should now look like this:</p>
 
 <pre>
-public class DisplayMessageActivity extends Activity {
+public class DisplayMessageActivity extends ActionBarActivity {
 
-    &#64;SuppressLint("NewApi")
     &#64;Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_display_message);
 
-        // Make sure we're running on Honeycomb or higher to use ActionBar APIs
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
-            // Show the Up button in the action bar.
-            getActionBar().setDisplayHomeAsUpEnabled(true);
+        if (savedInstanceState == null) {
+            getSupportFragmentManager().beginTransaction()
+                .add(R.id.container, new PlaceholderFragment()).commit();
         }
     }
 
     &#64;Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-        case android.R.id.home:
-            NavUtils.navigateUpFromSameTask(this);
+        // Handle action bar item clicks here. The action bar will
+        // automatically handle clicks on the Home/Up button, so long
+        // as you specify a parent activity in AndroidManifest.xml.
+        int id = item.getItemId();
+        if (id == R.id.action_settings) {
             return true;
         }
         return super.onOptionsItemSelected(item);
     }
+
+    /**
+     * A placeholder fragment containing a simple view.
+     */
+    public static class PlaceholderFragment extends Fragment {
+
+        public PlaceholderFragment() { }
+
+        &#64;Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                  Bundle savedInstanceState) {
+              View rootView = inflater.inflate(R.layout.fragment_display_message,
+                      container, false);
+              return rootView;
+        }
+    }
 }
 </pre>
 
@@ -422,7 +438,7 @@
 
 <img src="{@docRoot}images/training/firstapp/firstapp.png" />
 <p class="img-caption"><strong>Figure 2.</strong> Both activities in the final app, running
-on Android 4.0.
+on Android 4.4.
 
 <p>That's it, you've built your first Android app!</p>
 
diff --git a/docs/html/wear/css/wear.css b/docs/html/wear/css/wear.css
new file mode 100644
index 0000000..9d9d7a7
--- /dev/null
+++ b/docs/html/wear/css/wear.css
@@ -0,0 +1,442 @@
+/**
+ * UTILITIES
+ */
+
+.border-box {
+  box-sizing: border-box;
+}
+
+.vertical-center-outer {
+  display: table;
+  height: 100%;
+  width: 100%;
+}
+
+.vertical-center-inner {
+  display: table-cell;
+  vertical-align: middle;
+}
+
+/**
+ * TYPE STYLES
+ */
+
+.wear-h1 {
+  font-weight: 300;
+  font-size: 60px;
+  line-height: 78px;
+  text-align: center;
+  letter-spacing: -1px;
+}
+
+.wear-pre-h1 {
+  font-weight: 400;
+  font-size: 28px;
+  color: #93B73F;
+  line-height: 36px;
+  text-align: center;
+  letter-spacing: -1px;
+  text-transform: uppercase;
+
+}
+
+.wear-h1.hero {
+  text-align: left;
+}
+
+.wear-h2 {
+  font-weight: 300;
+  font-size: 42px;
+  line-height: 64px;
+  text-align: center;
+}
+
+
+.wear-subhead {
+  color: #999999;
+  font-size: 20px;
+  line-height: 28px;
+  text-align: center;
+}
+.wear-subhead.hero {
+  text-align: left;
+  color: white;
+}
+
+.wear-hero-description {
+  text-align: left;
+  margin: 1em 0;
+}
+
+.wear-hero-description p {
+  font-weight: 300;
+  margin: 0;
+  font-size: 18px;
+  line-height: 24px;
+}
+
+.wear-body .wear-small {
+  font-size: 14px;
+  line-height: 19px;
+}
+
+.wear-body.wear-align-center {
+  text-align: center;
+}
+
+.wear-align-left {
+  text-align: left;
+}
+
+/**
+ * LAYOUT
+ */
+
+.wear-body-content {
+  height: 100%;
+}
+
+.wear-section {
+  padding: 80px 10px 80px;
+  width: 100%;
+  margin-left: -10px;
+  text-rendering: optimizeLegibility;
+}
+
+#extending-android-to-wearables {
+  padding-top: 30px;
+}
+
+.wear-short-section {
+  padding: 40px 10px 28px;
+}
+
+.wear-gray-background {
+  background-color: #e9e9e9;
+}
+
+.wear-white-background {
+  background-color: white;
+}
+
+.wear-red-background {
+  color: white;
+  background-color: hsl(8, 70%, 54%);
+}
+
+.wear-subhead-red {
+  color: hsl(8, 71%, 84%);
+  text-align: left;
+}
+
+.wear-subhead-red p {
+  margin-top: 20px;
+}
+
+.wear-hero-container {
+  height: 800px;
+  height: 100vh;
+}
+
+.wear-hero {
+  height: 100%;
+  height: calc(100% - 72px);
+  min-height: 504px;
+  margin-top: -4px;
+  padding-top: 0;
+  padding-bottom: 0;
+  background-image: url(/wear/images/hero.jpg);
+  background-size: cover;
+  background-position: right center;
+  color: white;
+  position: relative;
+  overflow: hidden;
+}
+
+.wear-hero-scrim {
+  background: black;
+  opacity: .2;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  margin-left: -10px;
+}
+
+.wear-hero-wrap {
+  margin: 0 auto;
+  width: 940px;
+  clear: both;
+  height: 100%;
+  position: relative;
+}
+
+.wear-section-header {
+  margin-bottom: 40px;
+}
+
+.wear-hero-wrap .wear-section-header {
+  margin-bottom: 16px;
+}
+
+.wear-body {
+  font-size: 18px;
+  line-height: 24px;
+}
+
+.wear-button {
+  display: inline-block;
+  padding: 16px 32px;
+  font-size: 18px;
+  font-weight: 500;
+  line-height: 24px;
+  cursor: pointer;
+  color: white;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+       -o-user-select: none;
+  user-select: none;
+  -webkit-transition: .2s background-color ease-in-out;
+     -moz-transition: .2s background-color ease-in-out;
+       -o-transition: .2s background-color ease-in-out;
+  transition: .2s background-color ease-in-out;
+}
+
+.wear-primary {
+  background-color: hsl(8, 70%, 54%); /* #dc4b35 */
+  color: #f8f8f8;
+}
+
+.wear-button.wear-primary:hover {
+  background-color: hsl(8, 70%, 44%); /* #bf3722 */
+}
+
+.wear-button.wear-primary:active {
+  background-color: hsl(8, 70%, 36%); /* # */
+}
+
+.wear-button.wear-secondary {
+  background-color: hsl(8, 70%, 44%);
+}
+
+.wear-button.wear-secondary:hover {
+  background-color: hsl(8, 70%, 36%);
+}
+
+.wear-button.wear-secondary:active {
+  background-color: hsl(8, 70%, 30%);
+}
+
+a.wear-button,
+a.wear-button:hover,
+a.wear-button:visited {
+  color: white !important;
+}
+
+.wear-video-link {
+  display: inline-block;
+  padding: 16px 32px 16px 82px;
+  font-size: 18px;
+  font-weight: 400;
+  line-height: 24px;
+  cursor: pointer;
+  color: hsla(0, 0%, 100%, .8);
+  -webkit-user-select: none;
+     -moz-user-select: none;
+       -o-user-select: none;
+  user-select: none;
+  -webkit-transition: .2s color ease-in-out;
+     -moz-transition: .2s color ease-in-out;
+       -o-transition: .2s color ease-in-out;
+  transition: .2s color ease-in-out;
+}
+
+.wear-video-link:before {
+  height: 64px;
+  width: 64px;
+  display: inline-block;
+  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAFuklEQVR42u2dXWgcVRSAV9LWtBBTTZVWUhNqEQtq1QeroDRKFRFsROqTYPuo+JCiIoJKFC0USqlUfCiowRcfrBgVUUElefAPkW5T8aeaGn9aRbFsjP0x2cx8PuRMvFxmdjeb2Z17Z8+B85DsZPbO+eaec3/OPSkABdXsVI2gABSAqgJQAKoKQAGoKgAFoKoAFICqAlAAqgpAAai6DqDRAiwDeoFtwB7gPaAInABKwKToCWAMeB/YDdwJrAWWNLh9+QMAXABsBQ4A3wFTwAxQBmaBAAhjNJDPy3L938BXwAvArUCHAkh+kCXAVcA+YBw4bRg7MngtkgTlDPA98CywHmhTAP8/xCbgVeAvMZZpwDQllN7xB/AysKGlAQAXAvuBkzW85UVgCBgENlfQQbmuWAXELPAnsAvoaikAQBtwh/j3coLhS2LIfqCzzu/plL8fkvvFgZiR4L2lHrfkHQBgpQTFUwmGnwC212v0KjC2y/3jQPwDPA+05xYAcBHwubx1YZzhC02QBBBRbxgBzssdAOBy4JgRZE0ZTPuNr7FHDCbEhqNAd24AAN0yUbID7QSwsZChABut3hANXY8Bq70HIMb/Ocb4w81+66v0hmGrN0QQ1ngLQJYRvpWHMWWo4KDIaMnuCcVKgdlZAGL8t2J8vpPGrwChDLyWBMFlAA8D0z4ZvwKEs8D93gCQEc9Jy/jFgkdizaRDGUSs8wXAu1bQLQE9ngHosWbPAXDQeQAypT9rBd3+gociyxi2K9riLABZUj5iuZ6RgsciM2OzFxw2A7JrAO6VwGtKTwpG+Anoy9AVmb3gDHCPcwCAFcChRox6jPu9CazMeFQUAKNRL3AJwE2yopjq228BQPZ/d2bcCyaBTa4BeNGa8Q6naIA4GQWubiKEYWvBbp8zAGQt5VfL/fQ3GEAkTzXDLVkjokA2k5a7AuA2GaLNj/tTfvhq0pQgbcwLQtlQusYVALtlzSR191MjADNI9zbJDZWBR10BMGr5/4GMADQ0SAMDlht62xUAxy0AmzMEEMnhtIO0ZF2YAH5wITd0hQw/5wE04M1bjDyXZpC2hqMlYGnWAHqBf40APOEYgChI35VSWyasWfGqrAH0WVkOIw4CSC1IG2tDoSy7XJE1gPs8ArDoIG0BmJGk30wBDHgGYFFBOgbAtqwB7GxxAHerC8rOBU0Dt2gQzjYIb8gawDor+6HVhqFdrkzEwhabiAVOTMSkUb+06FLEUVfWgj5q0cW4g64AeNo66ZLlcnTDNmesBN4y8KArAG6QU42ttCEzBVzpCoAO4EfLDeV5SzIEvgHaXdqUP2BlQud1Ux55zj2uZUX02cPRnKalRLmu17qYmPWF5YbymJgVAh8Ay5wCII3ZEZOYm6fURGT2u9X43Mnk3CDHybmfmRVYXExPv9nKEcpLejqSC3SjdY2TBzTesHqB7wc0onTEV2KucxLApXKkJy9HlAI5anuJFwCkYQ/EuCJfD+mdBnYkXOssgHY53un7MdVZ4CVgqVcADAhjMafkfTioHc14P04yvvMApIEXy5F/+7S8y6UKolPyR4BVVf7Wi2IdawwIPhTrmAW+rmZ8bwBIQ7vloXwoVzNWS6UUrwAYy9YfOlqwKZDkgneA5Qu4l3cly84F9sqGhislywLmaozuYoGFXr0DII1ukxP1hxJ6QzR7HqLxRfumZaRzXZ3f4XXZyi7gCeB3kqsnzs+kSb9s5XHgMeD8RTxDLgq3rmeuYuFvNYCoR8wqujNi+L3UWBcu9wAMt3QZ8LiMlk5RuU50teq6kcEDgTolveIRYHUQBOek1O5cFu/ukLz7/ZJgNSm+OirebWpgaPS7slxfAr4EngGuX8jopqUBxGzyrAVuB54EXgc+lV4yLhO8cfn5E+ZqUD8kBu9sQvv0Hzj4rmoEBaAAVBWAAlBVAApAVQEoAFUFoABUFYACUFUACkC1CfofXVRJocowZVYAAAAASUVORK5CYII=);
+  background-size: contain;
+  position: absolute;
+  content: "";
+  opacity: .7;
+  margin-top: -19px;
+  margin-left: -64px;
+  -webkit-transition: .2s opacity ease-in-out;
+     -moz-transition: .2s opacity ease-in-out;
+       -o-transition: .2s opacity ease-in-out;
+  transition: .2s opacity ease-in-out;
+}
+
+.wear-video-link:hover {
+  color: hsla(0, 0%, 100%, 1);
+}
+
+.wear-video-link:hover:before {
+  opacity: 1;
+}
+
+.wear-social-image {
+  float: left;
+  margin-right: 14px;
+  height: 64px;
+  width: 64px;
+}
+
+.wear-social-copy {
+  padding-left: 78px;
+}
+
+.wear-scroll-down-affordance {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  text-align: center;
+  z-index: 10;
+}
+
+.wear-down-arrow {
+  padding: 24px;
+  display: inline-block;
+  opacity: .5;
+  -webkit-transition: .2s opacity ease-in-out;
+     -moz-transition: .2s opacity ease-in-out;
+       -o-transition: .2s opacity ease-in-out;
+  transition: .2s opacity ease-in-out;
+
+  -webkit-animation-name: pulse-opacity;
+  -webkit-animation-duration: 4s;
+}
+
+.wear-down-arrow:hover {
+  opacity: 1;
+}
+
+.wear-down-arrow img {
+  height: 28px;
+  width: 28px;
+  margin: 0 auto;
+  display: block;
+}
+
+.wear-divider {
+  display: inline-block;
+  height: 2px;
+  background-color: white;
+  position: relative;
+  margin: 10px 0;
+}
+
+/* 3 CLOLUMN LAYOUT */
+
+.wear-breakout {
+  margin-top: 40px;
+  margin-bottom: 40px;
+}
+
+.wear-breakout img {
+  margin-bottom: 20px;
+}
+
+.wear-partners img {
+  margin-bottom: 20px;
+}
+
+.wear-breakout p {
+  padding: 0 23px;
+}
+
+.wear-inset-video-container {
+  position: relative;
+}
+
+.wear-inset-video-container img.gif {
+  max-width: 222px;
+  position: absolute;
+  top: 40px;
+  left: 40px;
+}
+
+img.wear-bezel-only {
+  height:302px;
+  width:302px;
+}
+
+.wear-breakout.wear-partners img {
+  margin-bottom: 20px;
+}
+
+.col-3-wide {
+  display: inline;
+  float: left;
+  margin-left: 10px;
+  margin-right: 10px;
+}
+
+.col-3-wide {
+  width: 302px;
+}
+
+/**
+ * ANIMATION
+ */
+
+@-webkit-keyframes pulse-opacity {
+  0% {
+    opacity: .5;
+  }
+  20% {
+    opacity: .5;
+  }
+  40% {
+    opacity: 1;
+  }
+  60% {
+    opacity: .5;
+  }
+  80% {
+    opacity: 1;
+  }
+  100% {
+    opacity: .5;
+  }
+}
+
+
+
+/**
+ * VIDEO
+ */
+
+#video-container {
+  display:none;
+  position:fixed;
+  top:0;
+  left:-10px; 
+  width:102%;
+  height:100%;
+  background-color:rgba(0,0,0,0.7);
+  z-index:99;
+}
+
+#video-frame {
+  width:940px;
+  height:526.4px;
+  margin:80px auto 0;
+  display:none;
+}
+
+.video-close {
+cursor: pointer;
+position: relative;
+left: 940px;
+top: 0;
+pointer-events: all;
+}
+
+#icon-video-close {
+background-image: url("../images/close.png");
+background-position: 0 0;
+height: 48px;
+width: 48px;
+display:block;
+}
\ No newline at end of file
diff --git a/docs/html/wear/design/index.html b/docs/html/wear/design/index.html
new file mode 100644
index 0000000..4bbbf29
--- /dev/null
+++ b/docs/html/wear/design/index.html
@@ -0,0 +1,602 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>Design Principles of Android Wear | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="//www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  " itemscope itemtype="http://schema.org/Article">
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文 (中国)</option>
+                <option value="zh-tw">中文 (台灣)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12" id="doc-col" >
+
+
+  
+    
+      
+        <h1 itemprop="name" >Design Principles of Android Wear</h1>
+      
+    
+  
+
+
+  
+  <div id="jd-content">
+
+
+    <div class="jd-descr" itemprop="articleBody">
+    <style>
+h3 {
+ padding:30px 0 10px;
+}
+</style>
+<p>
+Android Wear devices provide just the right information at just the right time, allowing you to be connected to the virtual world and present in the real world.</p>
+
+<img src="/wear/images/05_images.png" height="200" width="169" style="float:right;clear:right;margin:0 0 60px 60px" />
+
+<p>Here you’ll find some guidelines for designing great user experiences on the Android Wear platform. Designing for Android Wear is substantially different than designing for phones or tablets, so we’ll start by describing how your content can work in tandem with the overall Android Wear vision.</p>
+
+
+<img src="/wear/images/02_notifications.png" height="200" width="169" style="float:right;clear:right;margin:0 0 20px 60px" />
+
+
+
+<p>Android Wear experiences are:</p>
+
+<ul>
+  <li><strong>Contextually aware and smart.</strong> These devices bring a new level of awareness to computing. Rather than requiring attention and input from users, Android Wear devices are aware of their situation and state, and helpfully display the right information at the right time. <em>Timely, relevant, specific</em>.</li>
+
+  <li><strong>Glanceable.</strong> Wearable devices are used all throughout the day, even when they sit in our peripheral vision. Effective apps provide the maximum payload of information with a minimum of fuss, optimized to provide tiny snippets of relevant information throughout the day. <em>Short, sharp, immediate.</em></li>
+
+  <li><strong>Zero/low interaction.</strong> Staying true to the strengths afforded by a smaller form factor, Android Wear focuses on simple interactions, only requiring input by the user when absolutely necessary. Most inputs are based around touch swipes or voice, and inputs requiring fine-grained motor skills are avoided. <em>Gestural, simple, fast.</em></li>
+
+  <li><strong>Helpful.</strong> Android Wear is like a great personal assistant: it knows you and your preferences, it only interrupts you when absolutely necessary, and it’s always on hand to provide a ready answer. <em>Efficient, respectful, responsive.</em></li>
+</ul>
+
+
+<p>
+By providing a smart connection to the rest of the world while respecting the user’s attention, Android Wear feels personal and global, simple and smart, unobtrusive and ever-ready. Notifications that respect these principles will feel most at home in the overall Android Wear experience.
+</p>
+
+
+
+<h2 id="Notifications" style="clear:both">Notification UI Patterns</h2>
+
+<p>Android notifications appear as cards in the main stream and form the core of the Android Wear experience. Many of the main <a href="http://developer.android.com/design/patterns/notifications.html">Android Design guidelines for notifications</a> apply in Android Wear. Be respectful of users' attention and aware of how unnecessary interruptions will reflect on your application’s reputation.</p>
+
+<p>Omit needless text from your notifications. Design for glanceability, not reading. Use words and phrases, not sentences. Show, don't tell: where possible use simple icons, glyphs, and visualizations to convey your message.</p>
+<img src="/wear/images/circle_message2.png" height="200" style="float:right;clear:right;margin:0 0 20px 60px" />
+
+<p>In some cases, particularly with messaging applications, cards will contain dynamic content which may not fit on a single screen. In these cases the content will be automatically truncated to fit on the card and the user may tap to expand, so the full message should be provided.</p>
+
+<p>Notification priority should reflect the urgency of your notification, with only time-sensitive notifications carrying a high priority. Active notifications – that is, those that cause the device to vibrate – should only be used in cases that need the user's urgent attention or action (e.g. a time-based reminder, a message from a friend). Non-urgent notifications (e.g. a transit times card, daily pedometer count, social network updates) should be silently added to the card stream.</p>
+
+
+
+
+<h3 id="NotifictionActions" style="clear:both">Actions</h3>
+
+<img src="/wear/images/circle_message2_reply.png" height="200" style="float:right;clear:right;margin:0 0 20px 40px" />
+
+<p>Actions appear to the right of your notification, allowing the user to act on your notification. Up to three actions are permitted. The most-used action should be placed first, so that it is a single swipe away from your content.</p>
+
+<p>Actions consist of an icon and a caption. Icons should be PNG files, white on transparent background, 64 × 64 DP. Captions should be verb-driven and short, and will be automatically truncated at one line.</p>
+
+<p>Actions are optional. Many useful notifications will not need to include actions at all.</p>
+
+<p>For developer details about action buttons, see <a href="/wear/notifications/creating.html">Creating
+Notifications for Android Wear</a>.</p>
+
+
+
+
+
+
+<h3 id="Images" style="clear:both">Images</h3>
+
+<img src="/wear/images/circle_badge_B.png" height="200" style="float:right;clear:right;margin:0 0 20px 40px" />
+
+
+<p>Images appear behind cards in the stream, providing context and additional glanceability. Your image should support the core message of the notification; for example, a card about a sports team could include the team color and logo; a message from a contact should display that person's profile photo.</p>
+
+<p>Bear in mind that the card will partially cover the lower part of the image. Images should be at least 320 × 320 pixels at hdpi. Image backgrounds move when horizontally swiped, so landscape-oriented images work better on notifications that include pages or actions.</p>
+
+<p>To add large images, use <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setLargeIcon(android.graphics.Bitmap)">setLargeIcon()</a></code> with any notification, as
+shown in <a href="/wear/notifications/creating.html">Creating
+Notifications for Android Wear</a>.</p>
+
+
+
+
+
+<h3 id="AppIcons" style="clear:both">Application Icons</h3>
+
+<img src="/wear/images/07_appicons.png" height="200" style="float:right;margin:0 0 20px 60px" />
+
+<p>Your application’s launcher icon will be automatically placed on the card, identifying your notification. Do not use the notification title or background image to identify or brand your application. Instead, allow your icon to identify itself and focus on delivering a clear, succinct message in the card and image. You can choose not to display this icon.
+</p>
+
+
+
+
+
+
+
+<h3 id="NotificationPages" style="clear:both">Pages</h3>
+
+<p>Pages are additional cards that can appear to the right of your main card in the stream. If your core message is longer than a short snippet, do not sacrifice glanceability by packing a lot of information into your primary notification. Instead, use pages to provide additional content.</p>
+
+<img src="/wear/images/08_pages.png" height="200" style="float:left;margin:0 0 20px 0px" />
+<img src="/wear/images/09_pages.png" height="200" style="float:left;margin:0 0 20px 60px" />
+<img src="/wear/images/10_pages.png" height="200" style="float:left;margin:0 0 20px 60px" />
+
+<p style="clear:left">Pages appear immediately to the right of the main notification card. They are typically used to provide additional details or alternate views of the main card’s content. For example:</p>
+<ul>
+  <li>A current weather card might provide an additional page showing a three-day forecast.</li>
+  <li>A next train departure card might provide an additional page showing subsequent departures times.</li>
+  <li>A daily step count card might provide an additional page showing the same measurement in calories and distance.</li>
+</ul>
+
+<p>There is no imposed limit on the number of pages you may add. However, notifications that provide actions should show no more than three pages to ensure that the actions remain easily accessible.</p>
+
+<p>Pages are optional. Many useful notifications will not need to include pages at all.</p>
+
+<p>For developer details about pages, see
+described in <a href="/wear/notifications/pages.html">Adding
+Pages to a Notification</a>.</p>
+
+
+
+
+
+<h3 id="NotificationStacks" style="clear:both">Notification Stacks</h3>
+
+<img src="/wear/images/11_bundles_B.png" height="200" style="float:right;margin:0 0 20px 60px" />
+<img src="/wear/images/11_bundles_A.png" height="200" style="float:right;margin:0 0 20px 60px" />
+
+<p>Stacks may be used to collect multiple notifications from the same application into a single stack of cards. Whereas pages are used to provide additional detail on a single notification, stacks are used to collect multiple sibling notifications together. A stack may be expanded by the user to access each individual card contained within.</p>
+
+<p>Stacks are a way of adding multiple useful notifications without overwhelming the user’s stream. If your application may produce multiple concurrent notifications, consider combining them into a stack.</p>
+
+<p>Each notification within a stack can contain separate pages and separate actions that are relevant to that specific notification. The user can access these actions after expanding that notification's card within the stack.</p>
+
+<p>For developer details about stacks, see
+described in <a href="/wear/notifications/stacks.html">Stacking
+Notifications</a>.</p>
+
+
+
+
+
+
+<h3 id="VoiceReplies" style="clear:both">Voice Replies</h3>
+
+
+<img src="/wear/images/circle_voice_B.png" height="200" style="float:right;margin:0 0 20px 40px" />
+<img src="/wear/images/circle_voice_A.png" height="200" style="float:right;margin:0 0 20px 40px" />
+
+<p>Voice replies are primarily used by messaging applications to provide a hands-free way of dictating a short message. You can also provide a up to five suggested replies or “canned responses” that are useful in a wide range of cases. These canned responses can be tapped by the user, allowing for a fast method of sending simple replies in cases where speaking may not be desirable.</p>
+
+<p>You should attempt to cover a range of simple, neutral replies in your choices. Longer voice replies may be automatically truncated in the Voice reply UI.</p>
+
+<p>For developer details about enabling voice replies, see
+described in <a href="/wear/notifications/remote-input.html">Receiving Voice Input from
+a Notification</a>.</p>
+
+    </div>
+
+      <div class="content-footer layout-content-row"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col col-9" style="padding-top:4px">
+          
+            <div class="g-plusone" data-size="medium"></div>
+          
+        </div>
+        
+        <div class="paging-links layout-content-col col-4">
+          
+        </div>
+        
+      </div>
+
+      
+      
+
+  </div> <!-- end jd-content -->
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is 
+  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+  Creative Commons Attribution 2.5</a>. For details and 
+  restrictions, see the <a href="/license.html">Content 
+  License</a>.
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
+</body>
+</html>
+
+
+
diff --git a/docs/html/wear/design/user-interface.html b/docs/html/wear/design/user-interface.html
new file mode 100644
index 0000000..f87b9da
--- /dev/null
+++ b/docs/html/wear/design/user-interface.html
@@ -0,0 +1,498 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>UI Overview | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="//www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<link rel="stylesheet" type="text/css" href="/wear/css/wear.css">
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  " itemscope itemtype="http://schema.org/Article">
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文 (中国)</option>
+                <option value="zh-tw">中文 (台灣)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12" id="doc-col" >
+
+
+  
+    
+      
+        <h1 itemprop="name" >UI Overview</h1>
+      
+    
+  
+
+
+  
+  <div id="jd-content">
+
+
+    <div class="jd-descr" itemprop="articleBody">
+    <style>
+h3 {
+ padding:30px 0 10px;
+}
+</style>
+
+<p>A new form factor deserves a new UI model. At a high level, the Android Wear UI consists of two
+main spaces centered around the core functions of <strong>Suggest</strong> and
+<strong>Demand</strong>. Your application will have an important role to play in both of these
+spaces.</p>
+
+
+
+<h3 id="Stream">Suggest: The Context Stream</h3>
+
+<div class="wear-inset-video-container" style="float:right;margin:0 -22px 60px 40px">
+  <img class="wear-bezel-only" src="/wear/images/screens/bezel.png" alt="">
+  <img class="gif" src="/wear/images/screens/stream.gif">
+</div>
+
+<p>The context stream is a vertical list of cards, each showing a useful or timely piece of
+information. Much like Google Now on Android phones and tablets, users swipe vertically to navigate
+from card to card for a brief and comprehensive update about what's important to them. Only one card
+is displayed on screen at a time, and background images are used to provide additional visual
+information. Your application can create cards and inject them into the stream when they are most
+likely to be useful.</p>
+
+<p>Cards in the stream are more than simple notifications. They can be swiped horizontally to
+reveal additional pages. Further horizontal swiping may reveal tappable buttons, allowing the user
+to take action on the notification. Cards can also be dismissed by swiping left to right, removing
+them from the stream until the next time they have useful information to display. In the emulator,
+hovering the mouse over the screen illuminates a blue bar at the top of the device
+that takes you home when clicked.</p>
+
+
+
+<h3 id="CueCard">Demand: The Cue Card</h3>
+
+<div class="wear-inset-video-container" style="float:right;margin:0 -22px 60px 40px">
+  <img class="wear-bezel-only" src="/wear/images/screens/bezel.png" alt="">
+  <img class="gif" src="/wear/images/screens/cuecard.gif">
+</div>
+
+<p>For cases where the context stream can't anticipate what the user would like to do, the cue card
+allows users to speak to their device. The cue card is opened by saying, "Ok Google" or by tapping
+on the "g" icon on the home screen. Swiping up on the cue card shows a list of actions, which can
+also be tapped.</p>
+
+<p>The list of actions includes Android intents for voice actions. The upcoming Android Wear SDK
+will enable developers to match their applications to these intents so users can perform actions
+using these voice commands. Multiple applications may register for a single voice intent, and users
+will have the opportunity to choose which application they prefer to use.</p>
+
+
+    </div>
+
+      <div class="content-footer layout-content-row"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col col-9" style="padding-top:4px">
+          
+            <div class="g-plusone" data-size="medium"></div>
+          
+        </div>
+        
+        <div class="paging-links layout-content-col col-4">
+          
+        </div>
+        
+      </div>
+
+      
+      
+
+  </div> <!-- end jd-content -->
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is 
+  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+  Creative Commons Attribution 2.5</a>. For details and 
+  restrictions, see the <a href="/license.html">Content 
+  License</a>.
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
+</body>
+</html>
+
+
+
diff --git a/docs/html/wear/images/01_notifications.png b/docs/html/wear/images/01_notifications.png
new file mode 100644
index 0000000..f9729d2
--- /dev/null
+++ b/docs/html/wear/images/01_notifications.png
Binary files differ
diff --git a/docs/html/wear/images/02_notifications.png b/docs/html/wear/images/02_notifications.png
new file mode 100644
index 0000000..417f4a6
--- /dev/null
+++ b/docs/html/wear/images/02_notifications.png
Binary files differ
diff --git a/docs/html/wear/images/03_actions.png b/docs/html/wear/images/03_actions.png
new file mode 100644
index 0000000..2e2ab0d
--- /dev/null
+++ b/docs/html/wear/images/03_actions.png
Binary files differ
diff --git a/docs/html/wear/images/04_images.png b/docs/html/wear/images/04_images.png
new file mode 100644
index 0000000..5c136d6
--- /dev/null
+++ b/docs/html/wear/images/04_images.png
Binary files differ
diff --git a/docs/html/wear/images/05_images.png b/docs/html/wear/images/05_images.png
new file mode 100644
index 0000000..54f2827
--- /dev/null
+++ b/docs/html/wear/images/05_images.png
Binary files differ
diff --git a/docs/html/wear/images/06_images.png b/docs/html/wear/images/06_images.png
new file mode 100644
index 0000000..fb53af5
--- /dev/null
+++ b/docs/html/wear/images/06_images.png
Binary files differ
diff --git a/docs/html/wear/images/07_appicons.png b/docs/html/wear/images/07_appicons.png
new file mode 100644
index 0000000..eb2867f
--- /dev/null
+++ b/docs/html/wear/images/07_appicons.png
Binary files differ
diff --git a/docs/html/wear/images/08_pages.png b/docs/html/wear/images/08_pages.png
new file mode 100644
index 0000000..9a8fb51
--- /dev/null
+++ b/docs/html/wear/images/08_pages.png
Binary files differ
diff --git a/docs/html/wear/images/09_pages.png b/docs/html/wear/images/09_pages.png
new file mode 100644
index 0000000..c0d90da
--- /dev/null
+++ b/docs/html/wear/images/09_pages.png
Binary files differ
diff --git a/docs/html/wear/images/10_pages.png b/docs/html/wear/images/10_pages.png
new file mode 100644
index 0000000..4a5f4ee
--- /dev/null
+++ b/docs/html/wear/images/10_pages.png
Binary files differ
diff --git a/docs/html/wear/images/11_bundles_A.png b/docs/html/wear/images/11_bundles_A.png
new file mode 100644
index 0000000..7199a1f
--- /dev/null
+++ b/docs/html/wear/images/11_bundles_A.png
Binary files differ
diff --git a/docs/html/wear/images/11_bundles_B.png b/docs/html/wear/images/11_bundles_B.png
new file mode 100644
index 0000000..bb751a2
--- /dev/null
+++ b/docs/html/wear/images/11_bundles_B.png
Binary files differ
diff --git a/docs/html/wear/images/12_voicereply.png b/docs/html/wear/images/12_voicereply.png
new file mode 100644
index 0000000..04f08cf
--- /dev/null
+++ b/docs/html/wear/images/12_voicereply.png
Binary files differ
diff --git a/docs/html/wear/images/13_voicereply.png b/docs/html/wear/images/13_voicereply.png
new file mode 100644
index 0000000..2939cad
--- /dev/null
+++ b/docs/html/wear/images/13_voicereply.png
Binary files differ
diff --git a/docs/html/wear/images/14_circle_voicereply.png b/docs/html/wear/images/14_circle_voicereply.png
new file mode 100644
index 0000000..15e27df
--- /dev/null
+++ b/docs/html/wear/images/14_circle_voicereply.png
Binary files differ
diff --git a/docs/html/wear/images/android-wear.png b/docs/html/wear/images/android-wear.png
new file mode 100644
index 0000000..081bc89
--- /dev/null
+++ b/docs/html/wear/images/android-wear.png
Binary files differ
diff --git a/docs/html/wear/images/blogger.png b/docs/html/wear/images/blogger.png
new file mode 100644
index 0000000..805958b
--- /dev/null
+++ b/docs/html/wear/images/blogger.png
Binary files differ
diff --git a/docs/html/wear/images/carrot.png b/docs/html/wear/images/carrot.png
new file mode 100644
index 0000000..7f2b20a
--- /dev/null
+++ b/docs/html/wear/images/carrot.png
Binary files differ
diff --git a/docs/html/wear/images/circle_badge_B.png b/docs/html/wear/images/circle_badge_B.png
new file mode 100644
index 0000000..8e0280a
--- /dev/null
+++ b/docs/html/wear/images/circle_badge_B.png
Binary files differ
diff --git a/docs/html/wear/images/circle_email.png b/docs/html/wear/images/circle_email.png
new file mode 100644
index 0000000..ef835be
--- /dev/null
+++ b/docs/html/wear/images/circle_email.png
Binary files differ
diff --git a/docs/html/wear/images/circle_email_action.png b/docs/html/wear/images/circle_email_action.png
new file mode 100644
index 0000000..d0abd0f
--- /dev/null
+++ b/docs/html/wear/images/circle_email_action.png
Binary files differ
diff --git a/docs/html/wear/images/circle_message2.png b/docs/html/wear/images/circle_message2.png
new file mode 100644
index 0000000..63b78395
--- /dev/null
+++ b/docs/html/wear/images/circle_message2.png
Binary files differ
diff --git a/docs/html/wear/images/circle_message2_reply.png b/docs/html/wear/images/circle_message2_reply.png
new file mode 100644
index 0000000..1de6d21
--- /dev/null
+++ b/docs/html/wear/images/circle_message2_reply.png
Binary files differ
diff --git a/docs/html/wear/images/circle_voice_A.png b/docs/html/wear/images/circle_voice_A.png
new file mode 100644
index 0000000..c4dd1ad
--- /dev/null
+++ b/docs/html/wear/images/circle_voice_A.png
Binary files differ
diff --git a/docs/html/wear/images/circle_voice_B.png b/docs/html/wear/images/circle_voice_B.png
new file mode 100644
index 0000000..3aa1d67
--- /dev/null
+++ b/docs/html/wear/images/circle_voice_B.png
Binary files differ
diff --git a/docs/html/wear/images/close.png b/docs/html/wear/images/close.png
new file mode 100644
index 0000000..bd473d2
--- /dev/null
+++ b/docs/html/wear/images/close.png
Binary files differ
diff --git a/docs/html/wear/images/features/s1.png b/docs/html/wear/images/features/s1.png
new file mode 100644
index 0000000..ba96cf8
--- /dev/null
+++ b/docs/html/wear/images/features/s1.png
Binary files differ
diff --git a/docs/html/wear/images/features/s2.png b/docs/html/wear/images/features/s2.png
new file mode 100644
index 0000000..af28496
--- /dev/null
+++ b/docs/html/wear/images/features/s2.png
Binary files differ
diff --git a/docs/html/wear/images/features/s3.png b/docs/html/wear/images/features/s3.png
new file mode 100644
index 0000000..6ae9868
--- /dev/null
+++ b/docs/html/wear/images/features/s3.png
Binary files differ
diff --git a/docs/html/wear/images/features/s4.png b/docs/html/wear/images/features/s4.png
new file mode 100644
index 0000000..125713d
--- /dev/null
+++ b/docs/html/wear/images/features/s4.png
Binary files differ
diff --git a/docs/html/wear/images/features/ts1.png b/docs/html/wear/images/features/ts1.png
new file mode 100644
index 0000000..5d4b1c1
--- /dev/null
+++ b/docs/html/wear/images/features/ts1.png
Binary files differ
diff --git a/docs/html/wear/images/features/ts2.png b/docs/html/wear/images/features/ts2.png
new file mode 100644
index 0000000..dc798c5
--- /dev/null
+++ b/docs/html/wear/images/features/ts2.png
Binary files differ
diff --git a/docs/html/wear/images/features/ts3.png b/docs/html/wear/images/features/ts3.png
new file mode 100644
index 0000000..0d68ebc
--- /dev/null
+++ b/docs/html/wear/images/features/ts3.png
Binary files differ
diff --git a/docs/html/wear/images/features/ts4.png b/docs/html/wear/images/features/ts4.png
new file mode 100644
index 0000000..e727ab5
--- /dev/null
+++ b/docs/html/wear/images/features/ts4.png
Binary files differ
diff --git a/docs/html/wear/images/fitness-24.png b/docs/html/wear/images/fitness-24.png
new file mode 100644
index 0000000..3cf2f3c
--- /dev/null
+++ b/docs/html/wear/images/fitness-24.png
Binary files differ
diff --git a/docs/html/wear/images/hero.jpg b/docs/html/wear/images/hero.jpg
new file mode 100644
index 0000000..40cc03c
--- /dev/null
+++ b/docs/html/wear/images/hero.jpg
Binary files differ
diff --git a/docs/html/wear/images/kitchen_still.jpg b/docs/html/wear/images/kitchen_still.jpg
new file mode 100644
index 0000000..4afe359
--- /dev/null
+++ b/docs/html/wear/images/kitchen_still.jpg
Binary files differ
diff --git a/docs/html/wear/images/laptop-bridge.png b/docs/html/wear/images/laptop-bridge.png
new file mode 100644
index 0000000..b481224
--- /dev/null
+++ b/docs/html/wear/images/laptop-bridge.png
Binary files differ
diff --git a/docs/html/wear/images/more_bottom.png b/docs/html/wear/images/more_bottom.png
new file mode 100644
index 0000000..632546a
--- /dev/null
+++ b/docs/html/wear/images/more_bottom.png
Binary files differ
diff --git a/docs/html/wear/images/more_mid.png b/docs/html/wear/images/more_mid.png
new file mode 100644
index 0000000..99bc999
--- /dev/null
+++ b/docs/html/wear/images/more_mid.png
Binary files differ
diff --git a/docs/html/wear/images/more_top.png b/docs/html/wear/images/more_top.png
new file mode 100644
index 0000000..8ead1d3
--- /dev/null
+++ b/docs/html/wear/images/more_top.png
Binary files differ
diff --git a/docs/html/wear/images/notification_phone@2x.png b/docs/html/wear/images/notification_phone@2x.png
new file mode 100644
index 0000000..e1e4297
--- /dev/null
+++ b/docs/html/wear/images/notification_phone@2x.png
Binary files differ
diff --git a/docs/html/wear/images/partners/asus.png b/docs/html/wear/images/partners/asus.png
new file mode 100644
index 0000000..37764b4
--- /dev/null
+++ b/docs/html/wear/images/partners/asus.png
Binary files differ
diff --git a/docs/html/wear/images/partners/broadcom.png b/docs/html/wear/images/partners/broadcom.png
new file mode 100644
index 0000000..b717142
--- /dev/null
+++ b/docs/html/wear/images/partners/broadcom.png
Binary files differ
diff --git a/docs/html/wear/images/partners/fossil.png b/docs/html/wear/images/partners/fossil.png
new file mode 100644
index 0000000..cd311b6
--- /dev/null
+++ b/docs/html/wear/images/partners/fossil.png
Binary files differ
diff --git a/docs/html/wear/images/partners/htc.png b/docs/html/wear/images/partners/htc.png
new file mode 100644
index 0000000..8236ac2
--- /dev/null
+++ b/docs/html/wear/images/partners/htc.png
Binary files differ
diff --git a/docs/html/wear/images/partners/intel.png b/docs/html/wear/images/partners/intel.png
new file mode 100644
index 0000000..79ca5af
--- /dev/null
+++ b/docs/html/wear/images/partners/intel.png
Binary files differ
diff --git a/docs/html/wear/images/partners/lg.png b/docs/html/wear/images/partners/lg.png
new file mode 100644
index 0000000..15d84e4
--- /dev/null
+++ b/docs/html/wear/images/partners/lg.png
Binary files differ
diff --git a/docs/html/wear/images/partners/mediatek.png b/docs/html/wear/images/partners/mediatek.png
new file mode 100644
index 0000000..2bf0f90
--- /dev/null
+++ b/docs/html/wear/images/partners/mediatek.png
Binary files differ
diff --git a/docs/html/wear/images/partners/mips.png b/docs/html/wear/images/partners/mips.png
new file mode 100644
index 0000000..04588f2
--- /dev/null
+++ b/docs/html/wear/images/partners/mips.png
Binary files differ
diff --git a/docs/html/wear/images/partners/motorola.png b/docs/html/wear/images/partners/motorola.png
new file mode 100644
index 0000000..8d1129f
--- /dev/null
+++ b/docs/html/wear/images/partners/motorola.png
Binary files differ
diff --git a/docs/html/wear/images/partners/qualcomm.png b/docs/html/wear/images/partners/qualcomm.png
new file mode 100644
index 0000000..cb52a98
--- /dev/null
+++ b/docs/html/wear/images/partners/qualcomm.png
Binary files differ
diff --git a/docs/html/wear/images/partners/samsung.png b/docs/html/wear/images/partners/samsung.png
new file mode 100644
index 0000000..b39629e
--- /dev/null
+++ b/docs/html/wear/images/partners/samsung.png
Binary files differ
diff --git a/docs/html/wear/images/screens/05_images.png b/docs/html/wear/images/screens/05_images.png
new file mode 100644
index 0000000..46ee5b3
--- /dev/null
+++ b/docs/html/wear/images/screens/05_images.png
Binary files differ
diff --git a/docs/html/wear/images/screens/08_pages.png b/docs/html/wear/images/screens/08_pages.png
new file mode 100644
index 0000000..62f2a8d
--- /dev/null
+++ b/docs/html/wear/images/screens/08_pages.png
Binary files differ
diff --git a/docs/html/wear/images/screens/11_stack_B.png b/docs/html/wear/images/screens/11_stack_B.png
new file mode 100644
index 0000000..f28accb
--- /dev/null
+++ b/docs/html/wear/images/screens/11_stack_B.png
Binary files differ
diff --git a/docs/html/wear/images/screens/13_voicereply_02.png b/docs/html/wear/images/screens/13_voicereply_02.png
new file mode 100644
index 0000000..290c7b5
--- /dev/null
+++ b/docs/html/wear/images/screens/13_voicereply_02.png
Binary files differ
diff --git a/docs/html/wear/images/screens/14_circle_voicereply.png b/docs/html/wear/images/screens/14_circle_voicereply.png
new file mode 100644
index 0000000..b2845d5
--- /dev/null
+++ b/docs/html/wear/images/screens/14_circle_voicereply.png
Binary files differ
diff --git a/docs/html/wear/images/screens/bezel.png b/docs/html/wear/images/screens/bezel.png
new file mode 100644
index 0000000..077a7e6
--- /dev/null
+++ b/docs/html/wear/images/screens/bezel.png
Binary files differ
diff --git a/docs/html/wear/images/screens/circle_message2.png b/docs/html/wear/images/screens/circle_message2.png
new file mode 100644
index 0000000..da18b8d
--- /dev/null
+++ b/docs/html/wear/images/screens/circle_message2.png
Binary files differ
diff --git a/docs/html/wear/images/screens/circle_voice_B.png b/docs/html/wear/images/screens/circle_voice_B.png
new file mode 100644
index 0000000..d367c27
--- /dev/null
+++ b/docs/html/wear/images/screens/circle_voice_B.png
Binary files differ
diff --git a/docs/html/wear/images/screens/cuecard.gif b/docs/html/wear/images/screens/cuecard.gif
new file mode 100644
index 0000000..4b3d2f3
--- /dev/null
+++ b/docs/html/wear/images/screens/cuecard.gif
Binary files differ
diff --git a/docs/html/wear/images/screens/fitness-24.png b/docs/html/wear/images/screens/fitness-24.png
new file mode 100644
index 0000000..18ae969
--- /dev/null
+++ b/docs/html/wear/images/screens/fitness-24.png
Binary files differ
diff --git a/docs/html/wear/images/screens/pages.ogv b/docs/html/wear/images/screens/pages.ogv
new file mode 100644
index 0000000..56a15e1
--- /dev/null
+++ b/docs/html/wear/images/screens/pages.ogv
Binary files differ
diff --git a/docs/html/wear/images/screens/pages_animated.gif b/docs/html/wear/images/screens/pages_animated.gif
new file mode 100644
index 0000000..d236b0a
--- /dev/null
+++ b/docs/html/wear/images/screens/pages_animated.gif
Binary files differ
diff --git a/docs/html/wear/images/screens/reservation_animated.gif b/docs/html/wear/images/screens/reservation_animated.gif
new file mode 100644
index 0000000..af98a3c
--- /dev/null
+++ b/docs/html/wear/images/screens/reservation_animated.gif
Binary files differ
diff --git a/docs/html/wear/images/screens/stream.gif b/docs/html/wear/images/screens/stream.gif
new file mode 100644
index 0000000..656a277
--- /dev/null
+++ b/docs/html/wear/images/screens/stream.gif
Binary files differ
diff --git a/docs/html/wear/images/screens/voice_02.png b/docs/html/wear/images/screens/voice_02.png
new file mode 100644
index 0000000..c18a0cf
--- /dev/null
+++ b/docs/html/wear/images/screens/voice_02.png
Binary files differ
diff --git a/docs/html/wear/images/screens/yoga.gif b/docs/html/wear/images/screens/yoga.gif
new file mode 100644
index 0000000..a3c26be
--- /dev/null
+++ b/docs/html/wear/images/screens/yoga.gif
Binary files differ
diff --git a/docs/html/wear/images/voice-23.png b/docs/html/wear/images/voice-23.png
new file mode 100644
index 0000000..06cba5b
--- /dev/null
+++ b/docs/html/wear/images/voice-23.png
Binary files differ
diff --git a/docs/html/wear/index.html b/docs/html/wear/index.html
new file mode 100644
index 0000000..5ea793b
--- /dev/null
+++ b/docs/html/wear/index.html
@@ -0,0 +1,702 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>Android Wear | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="//www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<link rel="stylesheet" type="text/css" href="/wear/css/wear.css">
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  " itemscope itemtype="http://schema.org/Article">
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文 (中国)</option>
+                <option value="zh-tw">中文 (台灣)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div id="body-content">
+
+
+
+
+<div class="fullpage" >
+
+
+  
+
+
+  
+  <div id="jd-content">
+
+
+    <div class="jd-descr" itemprop="articleBody">
+    <div id="video-container">
+  <div id="video-frame">
+    <div class="video-close">
+      <span id="icon-video-close">&nbsp;</span>
+    </div>
+    <script src="//ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
+    <div id="ytapiplayer">
+      <a href="http://www.youtube.com/watch?v=i2uvYI6blEE"><img width=600
+      src="https://i1.ytimg.com/vi/i2uvYI6blEE/maxresdefault.jpg"></a><!--You need Flash player 8+ and JavaScript enabled to view this video. -->
+    </div>
+  </div>
+</div>
+
+
+<div class="wear-body-content">
+  <div class="wear-hero-container">
+    <div class="wear-section wear-hero">
+      <div class="wear-hero-scrim"></div>
+      <div class="wear-hero-wrap">
+        <div class="vertical-center-outer">
+          <div class="vertical-center-inner">
+
+            <div class="col-10">
+              <div class="wear-section-header">
+                <div class="wear-h1 hero">Android Wear</div>
+                <div class="wear-subhead hero">Information that moves with you</div>
+              </div>
+              <div class="wear-hero-description">
+                <p>Small, powerful devices, worn on the body.
+                Useful information when you need it most.
+                Intelligent answers to spoken questions.
+                Tools to help reach fitness goals.
+                Your key to a multiscreen world.</p>
+              </div>
+
+              <div class="wear-body">
+                <a href="/wear/preview/start.html" class="wear-button wear-primary" style="margin-top: 40px;">
+                  Get the Developer Preview
+                </a>
+                <a id="watchVideo" href="https://youtube.googleapis.com/v/i2uvYI6blEE">
+                  <div class="wear-video-link">Watch the video</div>
+                </a>
+<script>
+$("#watchVideo").on("click", function(e) {
+  $("#video-container").fadeIn(400, function(){$("#video-frame").show()});
+
+  var params = { allowScriptAccess: "always"};
+  var atts = { id: "ytapiplayer" };
+  swfobject.embedSWF("//www.youtube.com/v/i2uvYI6blEE?enablejsapi=1&playerapiid=ytplayer&version=3&HD=1;rel=0;showinfo=0;modestbranding;origin=developer.android.com;autohide=1;autoplay=1",
+    "ytapiplayer", "940", "526.4", "8", null, null, params, atts);
+
+  e.preventDefault();
+});
+$("#icon-video-close").on("click", function() {
+  ytplayer = document.getElementById("ytapiplayer");
+  ytplayer.stopVideo();
+  $(ytplayer).hide();
+  $("#video-container").fadeOut(400);
+});
+</script>
+              </div>
+            </div>
+
+          </div>
+        </div>
+      </div> <!-- end .wrap -->
+      <div class="wear-scroll-down-affordance">
+        <a class="wear-down-arrow" href="#extending-android-to-wearables">
+          <img src="/wear/images/carrot.png" alt="Scroll down to read more">
+        </a>
+      </div>
+    </div> <!-- end .wear-section .wear-hero -->
+  </div> <!-- end .wear-hero-container -->
+
+    <div class="wear-rest-of-page">
+      <div class="wear-section" id="extending-android-to-wearables">
+        <div class="wrap">
+          <div class="wear-section-header">
+            <div class="wear-h1">Extending Android to Wearables</div>
+            <div class="wear-subhead">
+              Android Wear extends the Android platform to a new generation of wearable devices. <br>
+              The user experience is designed specifically for wearables.
+            </div>
+          </div>
+
+          <div class="wear-body">
+            <div class="wear-breakout cols">
+              <div class="col-3-wide">
+
+                <div class="wear-inset-video-container">
+                  <img class="wear-bezel-only" src="/wear/images/screens/bezel.png" alt="">
+                  <img class="gif" src="/wear/images/screens/reservation_animated.gif">
+                </div>
+
+                <p class="wear-small">
+                  Say “Ok Google” to ask questions and get stuff done.
+                </p>
+              </div>
+              <div class="col-3-wide">
+                <img src="/wear/images/screens/circle_message2.png" alt="Image of a Hangouts message">
+                <p class="wear-small">
+                  Get glanceable, actionable information at just the right time throughout the day.
+                </p>
+              </div>
+              <div class="col-3-wide">
+                <img src="/wear/images/screens/fitness-24.png" alt="Image showing ">
+                <p class="wear-small">
+                  A wide range of sensors is available to your applications, from accelerometers to heart rate monitors.
+                </p>
+              </div>
+            </div>
+
+            <p>
+              The Android Wear Developer Preview lets you create wearable experiences for your existing Android apps and see how they will appear on square and round Android wearables.
+            </p>
+
+            <p>
+              Later this year, we’ll be launching the Android Wear SDK, enabling even more customized experiences.
+            </p>
+          </div>
+        </div>  <!-- end .wrap -->
+      </div>  <!-- end .wear-section -->
+
+      <div class="wear-section wear-gray-background">
+        <div class="wrap">
+          <div class="wear-section-header">
+            <div class="wear-h1">Developer Preview</div>
+            <div class="wear-subhead">
+              Your app’s notifications will already appear on Android wearables. <br>
+              With the new Android Wear APIs you can customize and extend those notifications.
+            </div>
+          </div>
+
+
+          <div class="wear-body">
+            <div class="wear-breakout cols">
+              <div class="col-3-wide">
+                <img src="images/screens/14_circle_voicereply.png" alt="">
+                <p>Receive Voice Replies</p>
+                <p class="wear-small">
+                  Add actions to your notifications to allow users to reply by voice or touch. The system delivers the text to your app on the phone.
+                </p>
+                <p class="wear-small">
+                  <a href="/wear/notifications/remote-input.html">Learn about input actions</a>
+                </p>
+              </div>
+              <div class="col-3-wide">
+
+
+                <div class="wear-inset-video-container">
+                  <img class="wear-bezel-only" src="/wear/images/screens/bezel.png" alt="">
+                  <img class="gif" src="/wear/images/screens/pages_animated.gif">
+                </div>
+
+                <p>Add Notification Pages</p>
+                <p class="wear-small">
+                  Add additional pages to your notification that are visible on the wearable device to provide detailed information on the wrist.
+                </p>
+                <p class="wear-small">
+                  <a href="/wear/notifications/pages.html">Learn about pages</a>
+                </p>
+              </div>
+              <div class="col-3-wide">
+                <img src="images/screens/11_stack_B.png" alt="">
+                <p>Stack Multiple Notifications</p>
+                <p class="wear-small">
+                  Your app should consolidate similar notifications. On a wearable, you can stack them together so the details for each are immediately available.
+                </p>
+                <p class="wear-small">
+                  <a href="/wear/notifications/stacks.html">Learn about stacks</a>
+                </p>
+              </div>
+            </div>
+
+            <p>
+              You can also trigger your notifications contextually using existing Android APIs.  For example, use <a href="/training/location/geofencing.html">geofences</a> to provide glanceable information to your users when they are at home, or use the <a href="/training/location/activity-recognition.html">activity detection APIs</a> to send messages to your users’ wrists while they are bicycling.
+            </p>
+
+            <p>See the <a href="/wear/design/index.html">Android Wear Developer Preview Design Principles</a> for more suggestions on creating great wearable experiences.</p>
+
+          </div>
+        </div>  <!-- end .wrap -->
+      </div>  <!-- end .wear-section -->
+
+      <div class="wear-section" style="background-color:#f5f5f5">
+        <div class="wrap">
+          <div class="wear-section-header">
+            <div class="wear-pre-h1">Coming soon</div>
+            <div class="wear-h1">The Android Wear SDK</div>
+            <div class="wear-subhead">
+              The Developer Preview is just the beginning for Android Wear.
+            </div>
+          </div>
+
+          <div class="wear-body">
+            <p>
+              In the coming months we’ll be launching new APIs and features for Android wearables to create even more unique experiences for the wrist:
+            </p>
+
+            <div class="wear-breakout cols">
+              <div class="col-4">
+                <img src="/wear/images/features/ts1.png" alt="">
+                <p>Build Custom UI</p>
+                <p class="wear-small">
+                  Create custom card layouts and run activities directly on  wearables.
+                </p>
+              </div>
+              <div class="col-4">
+                <img src="/wear/images/features/ts2.png" alt="">
+                <p>Send Data</p>
+                <p class="wear-small">
+                  Send data and actions between a phone and a wearable with a data replication APIs and RPCs.
+                </p>
+              </div>
+              <div class="col-4">
+                <img src="/wear/images/features/ts3.png" alt="">
+                <p>Control Sensors</p>
+                <p class="wear-small">
+                  Gather sensor data and display it in real-time on Android wearables.
+                </p>
+              </div>
+              <div class="col-4">
+                <img src="/wear/images/features/ts4.png" alt="">
+                <p>Voice Actions</p>
+                <p class="wear-small">
+                  Register your app to handle voice actions, like "Ok Google, take a note.""
+                </p>
+              </div>
+            </div>
+
+          </div>
+        </div> <!-- end .wrap -->
+      </div> <!-- end .wear-section -->
+
+      <div class="wear-section wear-white-background">
+        <div class="wrap">
+          <div class="wear-section-header">
+            <div class="wear-h2">Building an Ecosystem</div>
+            <div class="wear-body wear-align-center">
+              <p class="wear-small">
+                We’re working with several partners to bring you watches powered by Android Wear later this year!
+              </p>
+            </div>
+          </div>
+
+          <div class="wear-partners cols">
+            <div class="col-4">
+              <img src="/wear/images/partners/asus.png" alt="Asus">
+            </div>
+            <div class="col-4">
+              <img src="/wear/images/partners/broadcom.png" alt="Broadcom">
+            </div>
+            <div class="col-4">
+              <img src="/wear/images/partners/fossil.png" alt="Fossil">
+            </div>
+            <div class="col-4">
+              <img src="/wear/images/partners/htc.png" alt="HTC">
+            </div>
+            <div class="col-4">
+              <img src="/wear/images/partners/intel.png" alt="Intel">
+            </div>
+            <div class="col-4">
+              <img src="/wear/images/partners/lg.png" alt="LG">
+            </div>
+            <div class="col-4">
+              <img src="/wear/images/partners/mediatek.png" alt="Mediatek">
+            </div>
+            <div class="col-4">
+              <img src="/wear/images/partners/mips.png" alt="MIPS">
+            </div>
+            <div class="col-4">
+              <img src="/wear/images/partners/motorola.png" alt="Motorola">
+            </div>
+            <div class="col-4">
+              <img src="/wear/images/partners/qualcomm.png" alt="Qualcomm">
+            </div>
+            <div class="col-4">
+              <img src="/wear/images/partners/samsung.png" alt="Samsung">
+            </div>
+          </div>
+        </div> <!-- end .wrap -->
+      </div> <!-- end .wear-section -->
+
+      <div class="wear-section wear-red-background">
+        <div class="wrap">
+          <div class="wear-section-header">
+            <div class="wear-h1 wear-align-left">Start working with Android Wear</div>
+            <div class="wear-subhead wear-subhead-red">
+              <p>
+                Your app’s notifications will already appear on Android wearables. <br>
+                With the new Android Wear APIs, you can customize and extend those notifications.
+              </p>
+              <p>
+                We’re excited about wearables and the experiences developers can create with them. <br>
+                We can’t wait to see what you do next.</p>
+            </div>
+          </div>
+          <div class="wear-body">
+            <a href="/wear/preview/start.html" class="wear-button wear-secondary" style="margin-top: 20px;">
+              Get the Developer Preview
+            </a>
+          </div>
+        </div>
+      </div>
+
+      <div class="wear-section">
+        <div class="wrap">
+          <div class="cols">
+            <div class="wear-body">
+              <div class="col-3-wide">
+                  <a href="/TODO">
+                    <img class="wear-social-image" src="//www.google.com/images/icons/product/youtube-128.png" alt="">
+                  </a>
+                <div class="wear-social-copy">
+                  <p>DevBytes</p>
+                  <p class="wear-small">
+                    Learn how to optimize your app notifications for wearable devices in this <a href="/TODO">DevBytes video</a> using the Android Wear Developer Preview.
+                  </p>
+                </div>
+              </div>
+              <div class="col-3-wide">
+                <a href="http://android-developers.blogspot.com/">
+                  <img class="wear-social-image" src="/wear/images/blogger.png" alt="">
+                </a>
+                <div class="wear-social-copy">
+                  <p>Blog Post</p>
+                  <p class="wear-small">
+                    Read more about the Android Wear Developer Preview announcement
+                    at the <a href="http://android-developers.blogspot.com/">Android Developers Blog</a>.
+                  </p>
+                </div>
+              </div>
+              <div class="col-3-wide">
+                <a href="http://g.co/androidweardev">
+                  <img class="wear-social-image" src="//www.google.com/images/icons/product/gplus-128.png" alt="+Android Wear Developers">
+                </a>
+                <div class="wear-social-copy">
+                  <p>G+ Community</p>
+                  <p class="wear-small">
+                    Follow us on Google+ to stay up-to-date on Android Wear development and join the discussion!
+                  </p>
+                  <p class="wear-small">
+                    <a href="http://g.co/androidweardev">+Android Wear Developers</a>
+                  </p>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div> <!-- end .wrap -->
+      </div> <!-- end .wear-section -->
+    </div> <!-- end .wear-rest-of-page -->
+  </div> <!-- end wear-body-content -->
+
+  <script>
+  $("a.wear-down-arrow").on("click", function(e) {
+    $("body").animate({
+      scrollTop: $(".wear-hero").height() + 76
+    }, 1000, "easeOutQuint");
+    e.preventDefault();
+  });
+  </script>
+    </div>
+
+      <div class="content-footer wrap"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col col-16" style="padding-top:4px">
+          <style>#___plusone_0 {float:right !important;}</style>
+            <div class="g-plusone" data-size="medium"></div>
+          
+        </div>
+        
+        <div class="paging-links layout-content-col col-4">
+          
+        </div>
+        
+      </div>
+
+      
+      
+
+  </div> <!-- end jd-content -->
+
+<div id="footer" class="wrap" style="width:940px">
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is 
+  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+  Creative Commons Attribution 2.5</a>. For details and 
+  restrictions, see the <a href="/license.html">Content 
+  License</a>.
+  </div>
+
+
+</div> <!-- end footer -->
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
+</body>
+</html>
+
+
+
diff --git a/docs/html/wear/license.html b/docs/html/wear/license.html
new file mode 100644
index 0000000..c7569bc
--- /dev/null
+++ b/docs/html/wear/license.html
@@ -0,0 +1,581 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>Developer Preview License Agreement | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="//www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  " itemscope itemtype="http://schema.org/Article">
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文 (中国)</option>
+                <option value="zh-tw">中文 (台灣)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12" id="doc-col" >
+
+
+  
+    
+      
+        <h1 itemprop="name" >Developer Preview License Agreement</h1>
+      
+    
+  
+
+
+  
+  <div id="jd-content">
+
+
+    <div class="jd-descr" itemprop="articleBody">
+    <div class="sdk-terms" style="height:auto;border:0;padding:0;width:700px">
+This is the Android Wear Developer Preview License Agreement.
+
+1. Introduction
+
+1.1 The Android Wear Developer Preview Kit (referred to in this License Agreement as the “Developer Preview” and specifically including the Android system files, packaged APIs, Developer Preview library files, and the Developer Preview companion app, if and when they are made available) is licensed to you subject to the terms of this License Agreement. This License Agreement forms a legally binding contract between you and Google in relation to your use of the Developer Preview.
+
+1.2 "Android Wear" means the Android Wear devices and the Android Wear software stack for use on Android Wear devices.
+
+1.3 "Android" means the Android software stack for devices, as made available under the Android Open Source Project, which is located at the following URL: http://source.android.com/, as updated from time to time.
+
+1.4 "Google" means Google Inc., a Delaware corporation with principal place of business at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States.
+
+2. Accepting this License Agreement
+
+2.1 In order to use the Developer Preview, you must first agree to this License Agreement. You may not use the Developer Preview if you do not accept this License Agreement.
+
+2.2 By clicking to accept, you hereby agree to the terms of this License Agreement.
+
+2.3 You may not use the Developer Preview and may not accept the License Agreement if you are a person barred from receiving the Developer Preview under the laws of the United States or other countries including the country in which you are resident or from which you use the Developer Preview.
+
+2.4 If you are agreeing to be bound by this License Agreement on behalf of your employer or other entity, you represent and warrant that you have full legal authority to bind your employer or such entity to this License Agreement. If you do not have the requisite authority, you may not accept the License Agreement or use the Developer Preview on behalf of your employer or other entity.
+
+3. Developer Preview License from Google
+
+3.1 Subject to the terms of this License Agreement, Google grants you a limited, worldwide, royalty-free, internal-use, non-assignable and non-exclusive license to use the Developer Preview solely to develop applications to run on the Android Wear platform for Android Wear devices.
+
+3.2 You agree that Google or third parties own all legal right, title and interest in and to the Developer Preview, including any Intellectual Property Rights that subsist in the Developer Preview. "Intellectual Property Rights" means any and all rights under patent law, copyright law, trade secret law, trademark law, and any and all other proprietary rights. Google reserves all rights not expressly granted to you.
+
+3.3 You may not use the Developer Preview for any purpose not expressly permitted by this License Agreement. Except to the extent required by applicable third party licenses, you may not: (a) copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the Developer Preview or any part of the Developer Preview; or (b) load any part of the Developer Preview onto a mobile handset or wearable computing device or any other hardware device except an Android Wear device, combine any part of the Developer Preview with other software, or distribute any software or device incorporating a part of the Developer Preview.
+
+3.4 You agree that you will not take any actions that may cause or result in the fragmentation of Android Wear, including but not limited to distributing, participating in the creation of, or promoting in any way a software development kit derived from the Developer Preview.
+
+3.5 Use, reproduction and distribution of components of the Developer Preview licensed under an open source software license are governed solely by the terms of that open source software license and not this License Agreement.
+
+3.6 You agree that the form and nature of the Developer Preview that Google provides may change without prior notice to you and that future versions of the Developer Preview may be incompatible with applications developed on previous versions of the Developer Preview. You agree that Google may stop (permanently or temporarily) providing the Developer Preview (or any features within the Developer Preview) to you or to users generally at Google's sole discretion, without prior notice to you.
+
+3.7 Nothing in this License Agreement gives you a right to use any of Google's trade names, trademarks, service marks, logos, domain names, or other distinctive brand features.
+
+3.8 You agree that you will not remove, obscure, or alter any proprietary rights notices (including copyright and trademark notices) that may be affixed to or contained within the Developer Preview.
+
+3.9 Your use of any Android system files, packaged APIs, or other components of the Developer Preview which are part of the Android Software Development Kit is subject to the terms of the Android Software Development Kit License Agreement located at http://developer.android.com/sdk/terms.html. These terms are hereby incorporated by reference into this License Agreement.
+
+4. Use of the Developer Preview by You
+
+4.1 Google agrees that it obtains no right, title or interest from you (or your licensors) under this License Agreement in or to any software applications that you develop using the Developer Preview, including any intellectual property rights that subsist in those applications.
+
+4.2 You agree to use the Developer Preview and write applications only for purposes that are permitted by (a) this License Agreement, (b) the Google Play Developer Program Policies located at https://play.google.com/about/developer-content-policy.html, and hereby incorporated into this License Agreement by reference), and (c) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries).  You agree to use reasonable efforts to comply with the Android Wear Platform Design Guide available on the Android Wear developer website
+
+4.3 You agree that if you use the Developer Preview to develop applications for general public users, you will protect the privacy and legal rights of those users. If the users provide you with user names, passwords, or other login information or personal information, you must make the users aware that the information will be available to your application, and you must provide legally adequate privacy notice and protection for those users. If your application stores personal or sensitive information provided by users, it must do so securely. If the user provides your application with Google Account information, your application may only use that information to access the user's Google Account when, and for the limited purposes for which, the user has given you permission to do so.
+
+4.4 You agree that you will not engage in any activity with the Developer Preview, including the development or distribution of an application, that interferes with, disrupts, damages, or accesses in an unauthorized manner the servers, networks, or other properties or services of any third party including, but not limited to, Google.
+
+4.5 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any data, content, or resources that you create, transmit or display through Android Wear and/or applications for Android Wear, and for the consequences of your actions (including any loss or damage which Google may suffer) by doing so.
+
+4.6 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any breach of your obligations under this License Agreement, any applicable third party contract or Terms of Service, or any applicable law or regulation, and for the consequences (including any loss or damage which Google or any third party may suffer) of any such breach.
+
+4.7 Unless otherwise specified in writing by Google, Google does not intend use of Android Wear to create obligations under the Health Insurance Portability and Accountability Act, as amended, (“HIPAA”), and makes no representations that Android Wear satisfies HIPAA requirements. If you are (or become) a Covered Entity or Business Associate under HIPAA, you agree not to use Android Wear for any purpose or in any manner involving Protected Health Information unless you have received prior written consent to such use from Google.
+
+4.8 The Developer Preview is in development, and your testing and feedback are an important part of the development process. By using the Developer Preview, you acknowledge that implementation of some features are still under development and that you should not rely on the Developer Preview, Android Wear devices, Android Wear system software, or Android Wear services having the full functionality of a stable release. You agree not to publicly distribute or ship any application using this Developer Preview as this Developer Preview will no longer be supported after the official SDK is released.
+
+5. Your Developer Credentials
+
+5.1 You agree that you are responsible for maintaining the confidentiality of any developer credentials that may be issued to you by Google or which you may choose yourself and that you will be solely responsible for all applications that are developed under your developer credentials.
+
+6. Privacy and Information
+
+6.1 In order to continually innovate and improve the Developer Preview, Google may collect certain usage statistics from the software including but not limited to a unique identifier, associated IP address, version number of the software, and information on which tools and/or services in the Developer Preview are being used and how they are being used. Before any of this information is collected, the Developer Preview will notify you and seek your consent. If you withhold consent, the information will not be collected.
+
+6.2 The data collected is examined in the aggregate to improve the Developer Preview and is maintained in accordance with Google's Privacy Policy lcoated at http://www.google.com/policies/privacy/.
+
+7. Third Party Applications
+
+7.1 If you use the Developer Preview to run applications developed by a third party or that access data, content or resources provided by a third party, you agree that Google is not responsible for those applications, data, content, or resources. You understand that all data, content or resources which you may access through such third party applications are the sole responsibility of the person from which they originated and that Google is not liable for any loss or damage that you may experience as a result of the use or access of any of those third party applications, data, content, or resources.
+
+7.2 You should be aware the data, content, and resources presented to you through such a third party application may be protected by intellectual property rights which are owned by the providers (or by other persons or companies on their behalf). You may not modify, rent, lease, loan, sell, distribute or create derivative works based on these data, content, or resources (either in whole or in part) unless you have been specifically given permission to do so by the relevant owners.
+
+7.3 You acknowledge that your use of such third party applications, data, content, or resources may be subject to separate terms between you and the relevant third party. In that case, this License Agreement does not affect your legal relationship with these third parties.
+
+8. Using Google APIs
+
+8.1 Google APIs
+
+8.1.1 If you use any API to retrieve data from Google, you acknowledge that the data may be protected by intellectual property rights which are owned by Google or those parties that provide the data (or by other persons or companies on their behalf). Your use of any such API may be subject to additional Terms of Service. You may not modify, rent, lease, loan, sell, distribute or create derivative works based on this data (either in whole or in part) unless allowed by the relevant Terms of Service.
+
+8.1.2 If you use any API to retrieve a user's data from Google, you acknowledge and agree that you shall retrieve data only with the user's explicit consent and only when, and for the limited purposes for which, the user has given you permission to do so.
+
+9. Terminating this License Agreement
+
+9.1 This License Agreement will continue to apply until terminated by either you or Google as set out below.
+
+9.2 If you want to terminate this License Agreement, you may do so by ceasing your use of the Developer Preview and any relevant developer credentials.
+
+9.3 Google may at any time, terminate this License Agreement with you if:
+(A) you have breached any provision of this License Agreement; or
+(B) Google is required to do so by law; or
+(C) the partner with whom Google offered certain parts of Developer Preview (such as APIs) to you has terminated its relationship with Google or ceased to offer certain parts of the Developer Preview to you; or
+(D) Google decides to no longer provide the Developer Preview or certain parts of the Developer Preview to users in the country in which you are resident or from which you use the service, or the provision of the Developer Preview or certain Developer Preview services to you by Google is, in Google's sole discretion, no longer commercially viable.
+
+9.4 When this License Agreement comes to an end, all of the legal rights, obligations and liabilities that you and Google have benefited from, been subject to (or which have accrued over time whilst this License Agreement has been in force) or which are expressed to continue indefinitely, shall be unaffected by this cessation, and the provisions of paragraph 14.7 shall continue to apply to such rights, obligations and liabilities indefinitely.
+
+10. DISCLAIMER OF WARRANTIES
+
+10.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE DEVELOPER PREVIEW IS AT YOUR SOLE RISK AND THAT THE DEVELOPER PREVIEW IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND FROM GOOGLE.
+
+10.2 YOUR USE OF THE DEVELOPER PREVIEW AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE DEVELOPER PREVIEW IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA THAT RESULTS FROM SUCH USE.
+
+10.3 GOOGLE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+
+11. LIMITATION OF LIABILITY
+
+11.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS OF DATA, WHETHER OR NOT GOOGLE OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.
+
+12. Indemnification
+
+12.1 To the maximum extent permitted by law, you agree to defend, indemnify and hold harmless Google, its affiliates and their respective directors, officers, employees and agents from and against any and all claims, actions, suits or proceedings, as well as any and all losses, liabilities, damages, costs and expenses (including reasonable attorneys’ fees) arising out of or accruing from (a) your use of the Developer Preview, (b) any application you develop on the Developer Preview that infringes any copyright, trademark, trade secret, trade dress, patent or other intellectual property right of any person or defames any person or violates their rights of publicity or privacy, and (c) any non-compliance by you with this License Agreement.
+
+13. Changes to the License Agreement
+
+13.1 Google may make changes to the License Agreement as it distributes new versions of the Developer Preview. When these changes are made, Google will make a new version of the License Agreement available on the website where the Developer Preview is made available.
+
+14. General Legal Terms
+
+14.1 This License Agreement constitutes the whole legal agreement between you and Google and governs your use of the Developer Preview (excluding any services which Google may provide to you under a separate written agreement), and completely replaces any prior agreements between you and Google in relation to the Developer Preview.
+
+14.2 You agree that if Google does not exercise or enforce any legal right or remedy which is contained in this License Agreement (or which Google has the benefit of under any applicable law), this will not be taken to be a formal waiver of Google's rights and that those rights or remedies will still be available to Google.
+
+14.3 If any court of law, having the jurisdiction to decide on this matter, rules that any provision of this License Agreement is invalid, then that provision will be removed from this License Agreement without affecting the rest of this License Agreement. The remaining provisions of this License Agreement will continue to be valid and enforceable.
+
+14.4 You acknowledge and agree that each member of the group of companies of which Google is the parent shall be third party beneficiaries to this License Agreement and that such other companies shall be entitled to directly enforce, and rely upon, any provision of this License Agreement that confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to this License Agreement.
+
+14.5 EXPORT RESTRICTIONS. THE DEVELOPER PREVIEW IS SUBJECT TO UNITED STATES EXPORT LAWS AND REGULATIONS. YOU MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND REGULATIONS THAT APPLY TO THE DEVELOPER PREVIEW. THESE LAWS INCLUDE RESTRICTIONS ON DESTINATIONS, END USERS AND END USE.
+
+14.6 The rights granted in this License Agreement may not be assigned or transferred by either you or Google without the prior written approval of the other party. Neither you nor Google shall be permitted to delegate their responsibilities or obligations under this License Agreement without the prior written approval of the other party.
+
+14.7 This License Agreement, and your relationship with Google under this License Agreement, shall be governed by the laws of the State of California without regard to its conflict of laws provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara, California to resolve any legal matter arising from this License Agreement. Notwithstanding this, you agree that Google shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.
+</div>
+
+    </div>
+
+      <div class="content-footer layout-content-row"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col col-9" style="padding-top:4px">
+          
+            <div class="g-plusone" data-size="medium"></div>
+          
+        </div>
+        
+        <div class="paging-links layout-content-col col-4">
+          
+        </div>
+        
+      </div>
+
+      
+      
+
+  </div> <!-- end jd-content -->
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is 
+  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+  Creative Commons Attribution 2.5</a>. For details and 
+  restrictions, see the <a href="/license.html">Content 
+  License</a>.
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
+</body>
+</html>
+
+
+
diff --git a/docs/html/wear/notifications/creating.html b/docs/html/wear/notifications/creating.html
new file mode 100644
index 0000000..e83b57a
--- /dev/null
+++ b/docs/html/wear/notifications/creating.html
@@ -0,0 +1,722 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>Creating Notifications for Android Wear | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="//www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  " itemscope itemtype="http://schema.org/Article">
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文 (中国)</option>
+                <option value="zh-tw">中文 (台灣)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12" id="doc-col" >
+
+
+  
+    
+      
+        <h1 itemprop="name" >Creating Notifications for Android Wear</h1>
+      
+    
+  
+
+
+  
+  <div id="jd-content">
+
+
+    <div class="jd-descr" itemprop="articleBody">
+    <p>When an Android device such as a phone or tablet is connected to an Android wearable,
+all notifications are shared between the devices by default. On the Android wearable, each
+notification appears as a new card in the <a href="/wear/design/user-interface.html#Stream"
+>context stream</a>.</p>
+
+<img src="/wear/images/notification_phone@2x.png" width="700" height="265" />
+
+
+<p>So without any effort, your app notifications are available to users on Android Wear.
+However, you can enhance the user experience in several ways. For instance,
+if users may respond to a notification by entering text, such as to reply to
+a message, you can add the ability for users to reply by voice directly from the
+wearable.</p>
+
+<p>To help you provide the best user experience
+for your notifications on Android Wear, this guide shows you how to
+build notifications using standard templates in
+the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> APIs, plus how to begin
+extending your notification's capabilities for the wearable user experience.</p>
+
+<p class="note"><strong>Note:</strong>
+Notifications using <code><a href="/reference/android/widget/RemoteViews.html">RemoteViews</a></code> are stripped of custom
+layouts and the system uses only the text and icons in the
+<code><a href="/reference/android/app/Notification.html">Notification</a></code> object to
+display the notification in a card. However, custom card layouts will be supported by
+the official Android Wear SDK that is coming later.</p>
+</div>
+
+
+
+
+<h2 id="Import">Import the Necessary Classes</h2>
+
+<p>To begin development, you must first complete the instructions in the <a
+href="/wear/preview/start">Get Started with the Developer Preview</a> document.
+As mentioned in that document, your app must include
+both the <a href="http://developer.android.com/tools/support-library/features.html#v4">v4 support
+library</a> and the Developer Preview support library. So to get started,
+you should include the following imports in your project code:</p>
+
+<pre>
+import android.preview.support.wearable.notifications.*;
+import android.preview.support.v4.app.NotificationManagerCompat;
+import android.support.v4.app.NotificationCompat;
+</pre>
+
+<p class="caution"><strong>Caution:</strong>
+The APIs in the current Android Wear Developer Preview are intended for <b>development and testing purposes only</b>, not for production apps. Google may change this Developer Preview significantly prior to the official release of the Android Wear SDK. You may not publicly distribute or ship any application using this Developer Preview, as this Developer Preview will no longer be supported after the official SDK is released (which will cause applications based only on the Developer Preview to break).</p>
+
+
+
+<h2 id="NotificationBuilder">Create Notifications with the Notification Builder</h2>
+
+<p>The <a href="http://developer.android.com/tools/support-library/features.html#v4">v4
+support library</a> allows you to create notifications using the latest notification features
+such as action buttons and large icons, while remaining compatible with Android 1.6 (API level
+4) and higher.</p>
+
+
+<p>For example, here's some code that creates and issues a notification using the
+<code><a href="/reference/android/support/v4/app/NotificationCompat.html">NotificationCompat</a></code> APIs combined with the new
+<a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">
+<code>NotificationManagerCompat</code></a> API:</p>
+
+
+<pre>
+int notificationId = 001;
+// Build intent for notification content
+Intent viewIntent = new Intent(this, ViewEventActivity.class);
+viewIntent.putExtra(EXTRA_EVENT_ID, eventId);
+PendingIntent viewPendingIntent =
+        PendingIntent.getActivity(this, 0, viewIntent, 0);
+
+NotificationCompat.Builder notificationBuilder =
+        new NotificationCompat.Builder(this)
+        .setSmallIcon(R.drawable.ic_event)
+        .setContentTitle(eventTitle)
+        .setContentText(eventLocation)
+        .setContentIntent(viewPendingIntent);
+
+// Get an instance of the NotificationManager service
+NotificationManagerCompat notificationManager =
+        NotificationManagerCompat.from(this);
+
+// Build the notification and issues it with notification manager.
+notificationManager.notify(notificationId, notificationBuilder.build());
+</pre>
+
+<p>When this notification appears on a handheld device, the user can invoke the
+<code><a href="/reference/android/app/PendingIntent.html">PendingIntent</a></code>
+specified by the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setContentIntent(android.app.PendingIntent)">setContentIntent()</a></code> method by touching the notification. When this
+notification appears on an Android wearable, the user can swipe the notification to the left to
+reveal the <strong>Open</strong> action, which invokes the intent on the handheld device.</p>
+
+
+
+
+
+
+<img src="/wear/images/circle_email_action.png" height="200" style="float:right;clear:right;margin:0 0 20px 60px" />
+
+<h2 id="ActionButtons">Add Action Buttons</h2>
+
+<p>In addition to the primary content action defined by
+<code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setContentIntent(android.app.PendingIntent)">setContentIntent()</a></code>, you can add other actions by passing a <code><a href="/reference/android/app/PendingIntent.html">PendingIntent</a></code> to
+the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#addAction(int, java.lang.CharSequence, android.app.PendingIntent)">addAction()</a></code> method.</p>
+
+<p>For example, the following code shows the same type of notification from above, but adds an
+action to view the event location on a map.</p>
+
+<pre style="clear:right">
+// Build an intent for an action to view a map
+Intent mapIntent = new Intent(Intent.ACTION_VIEW);
+Uri geoUri = Uri.parse("geo:0,0?q=" + Uri.encode(location));
+mapIntent.setData(geoUri);
+PendingIntent mapPendingIntent =
+        PendingIntent.getActivity(this, 0, mapIntent, 0);
+
+NotificationCompat.Builder notificationBuilder =
+        new NotificationCompat.Builder(this)
+        .setSmallIcon(R.drawable.ic_event)
+        .setContentTitle(eventTitle)
+        .setContentText(eventLocation)
+        .setContentIntent(viewPendingIntent)
+        <b>.addAction(R.drawable.ic_map,
+                getString(R.string.map), mapPendingIntent);</b>
+</pre>
+
+<p>On a handheld device, the action appears as an
+additional button attached to the notification. On an Android wearable, the action appears as
+a large button when the user swipes the notification to the left. When the user taps the action,
+the associated <code><a href="/reference/android/content/Intent.html">Intent</a></code> is invoked on the handheld device.</p>
+
+<p class="note"><strong>Tip:</strong> If your notifications includes a "Reply" action
+  (such as for a messaging app), you can enhance the behavior by enabling
+  voice input replies directly from the Android wearable. For more information, read
+  <a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification</a>.
+</p>
+
+<p>For details about designing action buttons (including the icon specifications), see the
+<a href="/wear/design/index.html#NotifictionActions">Design Principles of Android
+Wear</a>.</p>
+
+
+<h2 id="BigView">Add a Big View</h2>
+
+<img src="/wear/images/06_images.png" height="200" style="float:right;margin:0 0 20px 40px" />
+
+<p>You can insert extended text content
+to your notification by adding one of the "big view" styles to your notification. On a
+handheld device, users can see the big view content by expanding the notification,
+while on Android Wear, the big view content is visible by default.</p>
+
+<p>To add the extended content to your notification, call <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setStyle(android.support.v4.app.NotificationCompat.Style)">setStyle()</a></code> on the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> object, passing it an instance of either
+<code><a href="/reference/android/support/v4/app/NotificationCompat.BigTextStyle.html">BigTextStyle</a></code> or
+<code><a href="/reference/android/support/v4/app/NotificationCompat.InboxStyle.html">InboxStyle</a></code>.</p>
+
+<p>For example, the following code adds an instance of
+<code><a href="/reference/android/support/v4/app/NotificationCompat.BigTextStyle.html">NotificationCompat.BigTextStyle</a></code> to the event notification,
+in order to include the complete event description (which includes more text than can fit
+into the space provided for <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setContentText(java.lang.CharSequence)">setContentText()</a></code>).</p>
+
+
+<pre style="clear:right">
+// Specify the 'big view' content to display the long
+// event description that may not fit the normal content text.
+BigTextStyle bigStyle = new NotificationCompat.BigTextStyle();
+bigStyle.bigText(eventDescription);
+
+NotificationCompat.Builder notificationBuilder =
+        new NotificationCompat.Builder(this)
+        .setSmallIcon(R.drawable.ic_event)
+        .setLargeIcon(BitmapFractory.decodeResource(
+                getResources(), R.drawable.notif_background))
+        .setContentTitle(eventTitle)
+        .setContentText(eventLocation)
+        .setContentIntent(viewPendingIntent)
+        .addAction(R.drawable.ic_map,
+                getString(R.string.map), mapPendingIntent)
+        <b>.setStyle(bigStyle);</b>
+</pre>
+
+<p>Notice that you can add a large background image to any notification using the
+<code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setLargeIcon(android.graphics.Bitmap)">setLargeIcon()</a></code>
+method. For more information about designing notifications with large images, see the
+<a href="/wear/design/index.html#Images">Design Principles of Android
+Wear</a>.</p>
+
+
+
+<h2 id="NewFeatures">Add New Features for Wearables</h2>
+
+<p>The Android Wear preview support library provides new APIs that
+  allow you to enhance the user experience for notifications on a wearable device. For example,
+  you can add additional pages of content that users can view by swiping to the left, or add the ability
+for users to deliver your app a text response using voice input.</p>
+
+<p>To use these new APIs, pass your instance of
+<code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html">NotificationCompat.Builder</a></code> to the
+  <a href="/reference/android/preview/support/notifications/WearableNotifications.html"> <code>WearableNotifications.Builder()</code></a> constructor. You can then add new
+features to your notification using the
+  <a href="/wear/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"
+  ><code>WearableNotifications.Builder</code></a> methods. For example:</p>
+
+<pre>
+// Create a NotificationCompat.Builder for standard notification features
+NotificationCompat.Builder notificationBuilder =
+        new NotificationCompat.Builder(mContext)
+        .setContentTitle("New mail from " + sender.toString())
+        .setContentText(subject)
+        .setSmallIcon(R.drawable.new_mail);
+
+// Create a WearablesNotification.Builder to add special functionality for wearables
+Notification notification =
+        new WearableNotifications.Builder(notificationBuilder)
+        .setHintHideIcon(true)
+        .build();
+</pre>
+
+<p>The <a href="/reference/android/preview/support/notifications/WearableNotifications.Builder.html#setBigActionIcon(int)">
+  <code>setHintHideIcon()</code></a> method removes your app icon from the notification card.
+  This method is just one example of new notification features available from the
+  <a href="/wear/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"
+  ><code>WearableNotifications.Builder</code></a> class.</p>
+
+<p>When you want to deliver your notifications, be certain to always use the
+  <a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">
+    <code>NotificationManagerCompat</code></a> API:</p>
+
+<pre>
+// Get an instance of the NotificationManager service
+NotificationManagerCompat notificationManager =
+        NotificationManagerCompat.from(this);
+
+// Build the notification and issues it with notification manager.
+notificationManager.notify(notificationId, notification);
+</pre>
+
+<p>If you instead use the framework's <code><a href="/reference/android/app/NotificationManager.html">NotificationManager</a></code>, some
+features from <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"><code>WearableNotifications.Builder</code></a>
+will not work.</p>
+
+<p>To continue enhancing your notifications for wearables using
+  <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder"
+  ><code>WearableNotifications.Builder</code></a> and other APIs in the
+  preview support library, see the following developer guides:</p>
+
+  <dl>
+    <dt><a href="/wear/notifications/remote-input.html">Receiving Voice Input
+from a Notification</a></dt>
+      <dd>Add an action that receives voice input from the user and delivers the
+transcribed message to your app.</dd>
+    <dt><a href="/wear/notifications/pages.html">Adding Pages to a Notification</a></dt>
+      <dd>Add additional pages of information that are visible when the user
+swipes to the left.</dd>
+    <dt><a href="/wear/notifications/stacks.html">Stacking Notifications</a></dt>
+      <dd>Place all similar notifications from your app in a stack, allowing each to be
+viewed individually without adding multiple cards to the card stream.</dd>
+  </dl>
+
+
+<div class="next-docs">
+
+<div class="col-12">
+  <h2 class="norule">You might also want to read:</h2>
+  <dl>
+    <dt><a href="/training/notify-user/index.html">Notifying the User</a></dt>
+    <dd>Learn more about how to create notifications.</dd>
+    <dt><a href="/guide/components/intents-filters.html">Intents and Intent Filters</a></dt>
+    <dd>Learn everything you need to know about the <code><a href="/reference/android/content/Intent.html">Intent</a></code>
+APIs, used by notificaton actions.</dd>
+  </dl>
+</div>
+</div>
+
+
+</body>
+</html>
+
+    </div>
+
+      <div class="content-footer layout-content-row"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col col-9" style="padding-top:4px">
+          
+            <div class="g-plusone" data-size="medium"></div>
+          
+        </div>
+        
+        <div class="paging-links layout-content-col col-4">
+          
+        </div>
+        
+      </div>
+
+      
+      
+
+  </div> <!-- end jd-content -->
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is 
+  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+  Creative Commons Attribution 2.5</a>. For details and 
+  restrictions, see the <a href="/license.html">Content 
+  License</a>.
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
+</body>
+</html>
+
+
+
diff --git a/docs/html/wear/notifications/pages.html b/docs/html/wear/notifications/pages.html
new file mode 100644
index 0000000..abff8fa
--- /dev/null
+++ b/docs/html/wear/notifications/pages.html
@@ -0,0 +1,500 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>Adding Pages to a Notification | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="//www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  " itemscope itemtype="http://schema.org/Article">
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文 (中国)</option>
+                <option value="zh-tw">中文 (台灣)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12" id="doc-col" >
+
+
+  
+    
+      
+        <h1 itemprop="name" >Adding Pages to a Notification</h1>
+      
+    
+  
+
+
+  
+  <div id="jd-content">
+
+
+    <div class="jd-descr" itemprop="articleBody">
+    <img src="/wear/images/09_pages.png" height="200" style="float:right;margin:0 0 20px 40px" />
+<img src="/wear/images/08_pages.png" height="200" style="float:right;margin:0 0 20px 40px" />
+
+<p>When you'd like to provide more information without requiring users
+to open your app on their phones, you can
+add one or more pages to the notification on Android Wear. The additional pages
+appear immediately to the right of the main notification card.
+For information about when to use and how to design
+multiple pages, see the
+<a href="/wear/design/index.html#NotificationPages">Design Principles of Android
+Wear</a>.</p>
+
+
+<p>When creating a notification with multiple pages, start by creating the main notification
+(the first page) the way you'd like the notification to appear on a phone
+or tablet. Then, add pages one at a time with the
+<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addPage(android.app.Notification)">
+<code>addPage()</code></a> method, or add multiple pages in a <code><a href="/reference/java/util/Collection.html">Collection</a></code> with the
+<a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addPages(java.util.Collection<android.app.Notification>)">
+<code>addPages()</code></a> method.</p>
+
+
+<p>For example, here's some code that adds a second page to a notification:</p>
+
+<pre>
+// Create builder for the main notification
+NotificationCompat.Builder notificationBuilder =
+        new NotificationCompat.Builder(this)
+        .setSmallIcon(R.drawable.new_message)
+        .setContentTitle("Page 1")
+        .setContentText("Short message")
+        .setContentIntent(viewPendingIntent);
+
+// Create a big text style for the second page
+BigTextStyle secondPageStyle = new NotificationCompat.BigTextStyle();
+secondPageStyle.setBigContentTitle("Page 2")
+               .bigText("A lot of text...");
+
+// Create second page notification
+Notification secondPageNotification =
+        new NotificationCompat.Builder(this)
+        .setStyle(secondPageStyle)
+        .build();
+
+// Create main notification and add the second page
+Notification twoPageNotification =
+        new WearableNotifications.Builder(notificationBuilder)
+        .addPage(secondPageNotification)
+        .build();
+</pre>
+
+
+
+
+</body>
+</html>
+
+    </div>
+
+      <div class="content-footer layout-content-row"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col col-9" style="padding-top:4px">
+          
+            <div class="g-plusone" data-size="medium"></div>
+          
+        </div>
+        
+        <div class="paging-links layout-content-col col-4">
+          
+        </div>
+        
+      </div>
+
+      
+      
+
+  </div> <!-- end jd-content -->
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is 
+  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+  Creative Commons Attribution 2.5</a>. For details and 
+  restrictions, see the <a href="/license.html">Content 
+  License</a>.
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
+</body>
+</html>
+
+
+
diff --git a/docs/html/wear/notifications/remote-input.html b/docs/html/wear/notifications/remote-input.html
new file mode 100644
index 0000000..6500233
--- /dev/null
+++ b/docs/html/wear/notifications/remote-input.html
@@ -0,0 +1,648 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>Receiving Voice Input from a Notification | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="//www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  " itemscope itemtype="http://schema.org/Article">
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文 (中国)</option>
+                <option value="zh-tw">中文 (台灣)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12" id="doc-col" >
+
+
+  
+    
+      
+        <h1 itemprop="name" >Receiving Voice Input from a Notification</h1>
+      
+    
+  
+
+
+  
+  <div id="jd-content">
+
+
+    <div class="jd-descr" itemprop="articleBody">
+    <img src="/wear/images/13_voicereply.png" height="200" width="169" style="float:right;margin:0 0 20px 60px" />
+
+<img src="/wear/images/03_actions.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
+
+<p>If your notification includes an action to respond with text,
+    such as to reply to an email, it should normally launch an activity
+    on the handheld device. However, when your notification appears on an Android Wear device, you can
+    allow users to dictate a reply with voice input. You can also provide pre-defined text
+    replies for the user to select.</p>
+
+<p>When the user replies with voice or selects one of the available
+responses, the system delivers your app on the handheld the
+message as a string extra in the <code><a href="/reference/android/content/Intent.html">Intent</a></code> you specified
+to be used for the action.</p>
+
+
+<h2 id="RemoteInput">Define the Remote Input</h2>
+
+<p>To create an action that supports voice input, first create an instance of
+  <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">
+<code>RemoteInput</code></a> using the
+  <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> APIs.
+    The
+  <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> constructor takes a string that the system
+    will use as a key for the <code><a href="/reference/android/content/Intent.html">Intent</a></code> extra that caries the reply message
+    to your app on the handheld.</p>
+
+<p>For example, here's a new
+  <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">
+<code>RemoteInput</code></a> object that provides a custom
+    label for the voice input prompt:</p>
+
+<pre class="prettyprint">
+// Key for the string that's delivered in the action's intent
+private static final String EXTRA_VOICE_REPLY = "extra_voice_reply";
+
+String replyLabel = getResources().getString(R.string.reply_label);
+
+RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
+        .setLabel(replyLabel)
+        .build();
+</pre>
+
+
+<h3>Add Pre-defined Text Responses</h3>
+
+<img src="/wear/images/12_voicereply.png" height="200" style="float:right;margin:0 0 20px 40px" />
+
+<p>In addition to allowing voice input, you can
+    provide up to five text responses the user can select for quick replies. Call
+  <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html#setChoices(java.lang.String[])"><code>setChoices()</code></a> and pass it a string array.</p>
+
+<p>For example, you may define some responses in a resource array:</p>
+
+<p class="code-caption">res/values/strings.xml</code>
+<pre class="prettyprint">
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+    &lt;string-array name="reply_choices">
+        &lt;item>Yes&lt;/item>
+        &lt;item>No&lt;/item>
+        &lt;item>Maybe&lt;/item>
+    &lt;/string-array>
+&lt;/resources>
+</pre>
+
+<p>Then, inflate the string array and add it to the
+  <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a>:</p>
+
+<pre>
+String replyLabel = getResources().getString(R.string.reply_label);
+String[] replyChoices = getResources().getStringArray(R.array.reply_choices);
+
+RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
+        .setLabel(replyLabel)
+        .setChoices(replyChoices)
+        .build();
+</pre>
+
+
+
+
+<h2 id="PrimaryAction">Receive Voice Input for the Primary Action</h2>
+
+<p>If "Reply" is your notification's primary action (defined by the <code><a href="/reference/android/support/v4/app/NotificationCompat.Builder.html#setContentIntent(android.app.PendingIntent)">setContentIntent()</a></code>
+method), then you should attach the
+  <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to the main action using
+  <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)">
+<code>addRemoteInputForContentIntent()</code></a>. For example:</p>
+
+<pre>
+// Create intent for reply action
+Intent replyIntent = new Intent(this, ReplyService.class);
+PendingIntent replyPendingIntent =
+        PendingIntent.getService(this, 0, replyIntent, 0);
+
+// Build the notification
+NotificationCompat.Builder replyNotificationBuilder =
+        new NotificationCompat.Builder(this)
+        .setSmallIcon(R.drawable.ic_new_message)
+        .setContentTitle("Message from Travis")
+        .setContentText("I love key lime pie!")
+        .setContentIntent(replyPendingIntent);
+
+// Create the remote input
+RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
+        .setLabel(replyLabel)
+        .build();
+
+// Create wearable notification and add remote input
+Notification replyNotification =
+        new WearableNotifications.Builder(replyNotificationBuilder)
+        .addRemoteInputForContentIntent(replyAction)
+        .build();
+</pre>
+
+
+<p>By using
+  <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addRemoteInputForContentIntent(android.preview.support.wearable.notifications.RemoteInput)">
+<code>addRemoteInputForContentIntent()</code></a> to add the
+  <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> object to the notification's primary action,
+the button that normally appears as an "Open" action becomes the "Reply" action
+and starts the voice input UI when users select it on Android Wear.</p>
+
+
+
+<h2 id="NewAction">Receive Voice Input for a Secondary Action</h2>
+
+<p>If the "Reply" action is not your notification's primary action and you want to enable
+voice input for a secondary action, add the
+  <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to a new action button defined by an
+  <a href="/reference/android/preview/support/wearable/notifications/Action.html">
+<code>Action</code></a> object.</p>
+
+<p>You should instantiate the
+  <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
+<code>Action</code></a> with the
+  <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html"><code>Action.Builder()</code></a>
+constructor, which takes an icon and text label for the action button, plus the
+<code><a href="/reference/android/app/PendingIntent.html">PendingIntent</a></code>
+the system should use to invoke your app when the user selects the action. For example:</p>
+
+<pre>
+// Create the pending intent to fire when the user selects the action
+Intent replyIntent = new Intent(this, ReplyActivity.class);
+PendingIntent pendingReplyIntent =
+        PendingIntent.getActivity(this, 0, replyIntent, 0);
+
+// Create the remote input
+RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
+        .setLabel(replyLabel)
+        .build();
+
+// Create the notification action
+Action replyAction = new Action.Builder(R.drawable.ic_message,
+        "Reply", pendingIntent)
+        .addRemoteInput(remoteInput)
+        .build();
+</pre>
+
+
+<p>After you add the
+  <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html"><code>RemoteInput</code></a> to the
+  <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
+<code>Action</code></a>, add the
+  <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">
+<code>Action</code></a> to the
+  <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html"><code>WearableNotifications.Builder</code></a> using
+  <a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#addAction(Action)"><code>addAction()</code></a>.
+For example:</p>
+
+<pre>
+// Create basic notification builder
+NotificationCompat.Builder replyNotificationBuilder =
+        new NotificationCompat.Builder(this)
+        .setContentTitle("New message");
+
+// Create the notification action and add remote input
+Action replyAction = new Action.Builder(R.drawable.ic_message,
+        "Reply", pendingIntent)
+        .addRemoteInput(remoteInput)
+        .build();
+
+// Create wearable notification and add action
+Notification replyNotification =
+        new WearableNotifications.Builder(replyNotificationBuilder)
+        .addAction(replyAction)
+        .build();
+</pre>
+
+<p>Now, when the user selects "Reply" from an Android wearable,
+    the system prompts for voice input (and provides the list of pre-defined replies, if provided).
+    Once the user completes a response, the system invokes
+    the <code><a href="/reference/android/content/Intent.html">Intent</a></code> attached to the action and adds the
+<code>EXTRA_VOICE_REPLY</code> extra (the string
+    you passed to the
+  <a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html"><code>RemoteInput.Builder</code></a> constructor)
+    with the user's message as the string value.</p>
+
+
+
+
+</body>
+</html>
+
+    </div>
+
+      <div class="content-footer layout-content-row"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col col-9" style="padding-top:4px">
+          
+            <div class="g-plusone" data-size="medium"></div>
+          
+        </div>
+        
+        <div class="paging-links layout-content-col col-4">
+          
+        </div>
+        
+      </div>
+
+      
+      
+
+  </div> <!-- end jd-content -->
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is 
+  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+  Creative Commons Attribution 2.5</a>. For details and 
+  restrictions, see the <a href="/license.html">Content 
+  License</a>.
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
+</body>
+</html>
+
+
+
diff --git a/docs/html/wear/notifications/stacks.html b/docs/html/wear/notifications/stacks.html
new file mode 100644
index 0000000..5d10165
--- /dev/null
+++ b/docs/html/wear/notifications/stacks.html
@@ -0,0 +1,507 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>Stacking Notifications | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="//www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  " itemscope itemtype="http://schema.org/Article">
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文 (中国)</option>
+                <option value="zh-tw">中文 (台灣)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12" id="doc-col" >
+
+
+  
+    
+      
+        <h1 itemprop="name" >Stacking Notifications</h1>
+      
+    
+  
+
+
+  
+  <div id="jd-content">
+
+
+    <div class="jd-descr" itemprop="articleBody">
+    <img src="/wear/images/11_bundles_B.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
+<img src="/wear/images/11_bundles_A.png" height="200" width="169" style="float:right;margin:0 0 20px 40px" />
+
+<p>When your app creates more than one notification about the same type, you should traditionally
+update the existing notification with a summary of all the notifications instead of creating multiple notifications. For instance, instead
+of three notifications for each received email, you should create one with a summary such as "3 new
+messages." To view the contents of each message, the user must then touch the notification to open
+your app.</p>
+
+<p>However, when a user is viewing your notifications on a wearable device, you can create
+a stack that collects all the notifications for immediate access without creating multiple
+cards in the card stream.</p>
+
+<p>For details about designing notification stacks, see the
+<a href="/wear/design/index.html#NotificationStacks">Design Principles of Android
+Wear</a>.</p>
+
+
+<h2 id="AddGroup">Add Each Notification to a Group</h2>
+
+<p>To create a stack, call <a
+href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setGroup(java.lang.String, int)">
+<code>setGroup()</code></a> for each notification you want in the stack, passing the same
+group key. For example:</p>
+
+<pre style="clear:right">
+final static String GROUP_KEY_EMAILS = "group_key_emails";
+
+NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext)
+         .setContentTitle("New mail from " + sender)
+         .setContentText(subject)
+         .setSmallIcon(R.drawable.new_mail);
+
+Notification notif = new WearableNotifications.Builder(builder)
+         .setGroup(GROUP_KEY_EMAILS)
+         .build();
+</pre>
+
+<p>By default, notifications appear in the order in which you added them, with the most recent
+  notification visible at the top.  You can define a specific position in the group
+  by passing an order position as the second parameter for <a
+href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html#setGroup(java.lang.String, int)">
+<code>setGroup()</code></a>.</p>
+
+
+<h2 id="AddSummary">Add a Summary Notification</h2>
+
+<p>It's important that you still provide a summary notification for handheld devices. So in
+addition to adding each unique notification to the same stack group, also add the summary
+notification but set its order position to be <a
+href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html#GROUP_ORDER_SUMMARY"><code>GROUP_ORDER_SUMMARY</code></a>.
+The notification in this position does not appear in the stack on the wearable but
+appears as the only notification on the handheld.</p>
+
+<pre>
+Notification summaryNotification = new WearableNotifications.Builder(builder)
+         .setGroup(GROUP_KEY_EMAILS, WearableNotifications.GROUP_ORDER_SUMMARY)
+         .build();
+</pre>
+
+
+</body>
+</html>
+
+    </div>
+
+      <div class="content-footer layout-content-row"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col col-9" style="padding-top:4px">
+          
+            <div class="g-plusone" data-size="medium"></div>
+          
+        </div>
+        
+        <div class="paging-links layout-content-col col-4">
+          
+        </div>
+        
+      </div>
+
+      
+      
+
+  </div> <!-- end jd-content -->
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is 
+  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+  Creative Commons Attribution 2.5</a>. For details and 
+  restrictions, see the <a href="/license.html">Content 
+  License</a>.
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
+</body>
+</html>
+
+
+
diff --git a/docs/html/wear/preview/signup.html b/docs/html/wear/preview/signup.html
new file mode 100644
index 0000000..ca50179
--- /dev/null
+++ b/docs/html/wear/preview/signup.html
@@ -0,0 +1,609 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>Sign Up for the Developer Preview | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="//www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  " itemscope itemtype="http://schema.org/Article">
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文 (中国)</option>
+                <option value="zh-tw">中文 (台灣)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12" id="doc-col" >
+
+
+  
+    
+      
+        <h1 itemprop="name" >Sign Up for the Developer Preview</h1>
+      
+    
+  
+
+
+  
+  <div id="jd-content">
+
+
+    <div class="jd-descr" itemprop="articleBody">
+    <p>To get started with the Android Wear Developer Preview, you must agree to the
+  following terms and conditions and provide the email address for your Google account.
+After signing up, you’ll have access to:</p>
+<ul>
+  <li>New APIs that allow you to build enhanced notifications for wearables.</li>
+  <li>Sample code using the new APIs.</li>
+  <li>The Android Wear Preview app that delivers your notifications to the Android Wear emulator.</li>
+</ul>
+
+<div class="sdk-terms" style="width:678px" onfocus="this.blur()"><div class="sdk-terms-padding">
+This is the Android Wear Developer Preview License Agreement.
+
+1. Introduction
+
+1.1 The Android Wear Developer Preview Kit (referred to in this License Agreement as the “Developer Preview” and specifically including the Android system files, packaged APIs, Developer Preview library files, and the Developer Preview companion app, if and when they are made available) is licensed to you subject to the terms of this License Agreement. This License Agreement forms a legally binding contract between you and Google in relation to your use of the Developer Preview.
+
+1.2 "Android Wear" means the Android Wear devices and the Android Wear software stack for use on Android Wear devices.
+
+1.3 "Android" means the Android software stack for devices, as made available under the Android Open Source Project, which is located at the following URL: http://source.android.com/, as updated from time to time.
+
+1.4 "Google" means Google Inc., a Delaware corporation with principal place of business at 1600 Amphitheatre Parkway, Mountain View, CA 94043, United States.
+
+2. Accepting this License Agreement
+
+2.1 In order to use the Developer Preview, you must first agree to this License Agreement. You may not use the Developer Preview if you do not accept this License Agreement.
+
+2.2 By clicking to accept, you hereby agree to the terms of this License Agreement.
+
+2.3 You may not use the Developer Preview and may not accept the License Agreement if you are a person barred from receiving the Developer Preview under the laws of the United States or other countries including the country in which you are resident or from which you use the Developer Preview.
+
+2.4 If you are agreeing to be bound by this License Agreement on behalf of your employer or other entity, you represent and warrant that you have full legal authority to bind your employer or such entity to this License Agreement. If you do not have the requisite authority, you may not accept the License Agreement or use the Developer Preview on behalf of your employer or other entity.
+
+3. Developer Preview License from Google
+
+3.1 Subject to the terms of this License Agreement, Google grants you a limited, worldwide, royalty-free, internal-use, non-assignable and non-exclusive license to use the Developer Preview solely to develop applications to run on the Android Wear platform for Android Wear devices.
+
+3.2 You agree that Google or third parties own all legal right, title and interest in and to the Developer Preview, including any Intellectual Property Rights that subsist in the Developer Preview. "Intellectual Property Rights" means any and all rights under patent law, copyright law, trade secret law, trademark law, and any and all other proprietary rights. Google reserves all rights not expressly granted to you.
+
+3.3 You may not use the Developer Preview for any purpose not expressly permitted by this License Agreement. Except to the extent required by applicable third party licenses, you may not: (a) copy (except for backup purposes), modify, adapt, redistribute, decompile, reverse engineer, disassemble, or create derivative works of the Developer Preview or any part of the Developer Preview; or (b) load any part of the Developer Preview onto a mobile handset or wearable computing device or any other hardware device except an Android Wear device, combine any part of the Developer Preview with other software, or distribute any software or device incorporating a part of the Developer Preview.
+
+3.4 You agree that you will not take any actions that may cause or result in the fragmentation of Android Wear, including but not limited to distributing, participating in the creation of, or promoting in any way a software development kit derived from the Developer Preview.
+
+3.5 Use, reproduction and distribution of components of the Developer Preview licensed under an open source software license are governed solely by the terms of that open source software license and not this License Agreement.
+
+3.6 You agree that the form and nature of the Developer Preview that Google provides may change without prior notice to you and that future versions of the Developer Preview may be incompatible with applications developed on previous versions of the Developer Preview. You agree that Google may stop (permanently or temporarily) providing the Developer Preview (or any features within the Developer Preview) to you or to users generally at Google's sole discretion, without prior notice to you.
+
+3.7 Nothing in this License Agreement gives you a right to use any of Google's trade names, trademarks, service marks, logos, domain names, or other distinctive brand features.
+
+3.8 You agree that you will not remove, obscure, or alter any proprietary rights notices (including copyright and trademark notices) that may be affixed to or contained within the Developer Preview.
+
+3.9 Your use of any Android system files, packaged APIs, or other components of the Developer Preview which are part of the Android Software Development Kit is subject to the terms of the Android Software Development Kit License Agreement located at http://developer.android.com/sdk/terms.html. These terms are hereby incorporated by reference into this License Agreement.
+
+4. Use of the Developer Preview by You
+
+4.1 Google agrees that it obtains no right, title or interest from you (or your licensors) under this License Agreement in or to any software applications that you develop using the Developer Preview, including any intellectual property rights that subsist in those applications.
+
+4.2 You agree to use the Developer Preview and write applications only for purposes that are permitted by (a) this License Agreement, (b) the Google Play Developer Program Policies located at https://play.google.com/about/developer-content-policy.html, and hereby incorporated into this License Agreement by reference), and (c) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions (including any laws regarding the export of data or software to and from the United States or other relevant countries).  You agree to use reasonable efforts to comply with the Android Wear Platform Design Guide available on the Android Wear developer website
+
+4.3 You agree that if you use the Developer Preview to develop applications for general public users, you will protect the privacy and legal rights of those users. If the users provide you with user names, passwords, or other login information or personal information, you must make the users aware that the information will be available to your application, and you must provide legally adequate privacy notice and protection for those users. If your application stores personal or sensitive information provided by users, it must do so securely. If the user provides your application with Google Account information, your application may only use that information to access the user's Google Account when, and for the limited purposes for which, the user has given you permission to do so.
+
+4.4 You agree that you will not engage in any activity with the Developer Preview, including the development or distribution of an application, that interferes with, disrupts, damages, or accesses in an unauthorized manner the servers, networks, or other properties or services of any third party including, but not limited to, Google.
+
+4.5 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any data, content, or resources that you create, transmit or display through Android Wear and/or applications for Android Wear, and for the consequences of your actions (including any loss or damage which Google may suffer) by doing so.
+
+4.6 You agree that you are solely responsible for (and that Google has no responsibility to you or to any third party for) any breach of your obligations under this License Agreement, any applicable third party contract or Terms of Service, or any applicable law or regulation, and for the consequences (including any loss or damage which Google or any third party may suffer) of any such breach.
+
+4.7 Unless otherwise specified in writing by Google, Google does not intend use of Android Wear to create obligations under the Health Insurance Portability and Accountability Act, as amended, (“HIPAA”), and makes no representations that Android Wear satisfies HIPAA requirements. If you are (or become) a Covered Entity or Business Associate under HIPAA, you agree not to use Android Wear for any purpose or in any manner involving Protected Health Information unless you have received prior written consent to such use from Google.
+
+4.8 The Developer Preview is in development, and your testing and feedback are an important part of the development process. By using the Developer Preview, you acknowledge that implementation of some features are still under development and that you should not rely on the Developer Preview, Android Wear devices, Android Wear system software, or Android Wear services having the full functionality of a stable release. You agree not to publicly distribute or ship any application using this Developer Preview as this Developer Preview will no longer be supported after the official SDK is released.
+
+5. Your Developer Credentials
+
+5.1 You agree that you are responsible for maintaining the confidentiality of any developer credentials that may be issued to you by Google or which you may choose yourself and that you will be solely responsible for all applications that are developed under your developer credentials.
+
+6. Privacy and Information
+
+6.1 In order to continually innovate and improve the Developer Preview, Google may collect certain usage statistics from the software including but not limited to a unique identifier, associated IP address, version number of the software, and information on which tools and/or services in the Developer Preview are being used and how they are being used. Before any of this information is collected, the Developer Preview will notify you and seek your consent. If you withhold consent, the information will not be collected.
+
+6.2 The data collected is examined in the aggregate to improve the Developer Preview and is maintained in accordance with Google's Privacy Policy lcoated at http://www.google.com/policies/privacy/.
+
+7. Third Party Applications
+
+7.1 If you use the Developer Preview to run applications developed by a third party or that access data, content or resources provided by a third party, you agree that Google is not responsible for those applications, data, content, or resources. You understand that all data, content or resources which you may access through such third party applications are the sole responsibility of the person from which they originated and that Google is not liable for any loss or damage that you may experience as a result of the use or access of any of those third party applications, data, content, or resources.
+
+7.2 You should be aware the data, content, and resources presented to you through such a third party application may be protected by intellectual property rights which are owned by the providers (or by other persons or companies on their behalf). You may not modify, rent, lease, loan, sell, distribute or create derivative works based on these data, content, or resources (either in whole or in part) unless you have been specifically given permission to do so by the relevant owners.
+
+7.3 You acknowledge that your use of such third party applications, data, content, or resources may be subject to separate terms between you and the relevant third party. In that case, this License Agreement does not affect your legal relationship with these third parties.
+
+8. Using Google APIs
+
+8.1 Google APIs
+
+8.1.1 If you use any API to retrieve data from Google, you acknowledge that the data may be protected by intellectual property rights which are owned by Google or those parties that provide the data (or by other persons or companies on their behalf). Your use of any such API may be subject to additional Terms of Service. You may not modify, rent, lease, loan, sell, distribute or create derivative works based on this data (either in whole or in part) unless allowed by the relevant Terms of Service.
+
+8.1.2 If you use any API to retrieve a user's data from Google, you acknowledge and agree that you shall retrieve data only with the user's explicit consent and only when, and for the limited purposes for which, the user has given you permission to do so.
+
+9. Terminating this License Agreement
+
+9.1 This License Agreement will continue to apply until terminated by either you or Google as set out below.
+
+9.2 If you want to terminate this License Agreement, you may do so by ceasing your use of the Developer Preview and any relevant developer credentials.
+
+9.3 Google may at any time, terminate this License Agreement with you if:
+(A) you have breached any provision of this License Agreement; or
+(B) Google is required to do so by law; or
+(C) the partner with whom Google offered certain parts of Developer Preview (such as APIs) to you has terminated its relationship with Google or ceased to offer certain parts of the Developer Preview to you; or
+(D) Google decides to no longer provide the Developer Preview or certain parts of the Developer Preview to users in the country in which you are resident or from which you use the service, or the provision of the Developer Preview or certain Developer Preview services to you by Google is, in Google's sole discretion, no longer commercially viable.
+
+9.4 When this License Agreement comes to an end, all of the legal rights, obligations and liabilities that you and Google have benefited from, been subject to (or which have accrued over time whilst this License Agreement has been in force) or which are expressed to continue indefinitely, shall be unaffected by this cessation, and the provisions of paragraph 14.7 shall continue to apply to such rights, obligations and liabilities indefinitely.
+
+10. DISCLAIMER OF WARRANTIES
+
+10.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT YOUR USE OF THE DEVELOPER PREVIEW IS AT YOUR SOLE RISK AND THAT THE DEVELOPER PREVIEW IS PROVIDED "AS IS" AND "AS AVAILABLE" WITHOUT WARRANTY OF ANY KIND FROM GOOGLE.
+
+10.2 YOUR USE OF THE DEVELOPER PREVIEW AND ANY MATERIAL DOWNLOADED OR OTHERWISE OBTAINED THROUGH THE USE OF THE DEVELOPER PREVIEW IS AT YOUR OWN DISCRETION AND RISK AND YOU ARE SOLELY RESPONSIBLE FOR ANY DAMAGE TO YOUR COMPUTER SYSTEM OR OTHER DEVICE OR LOSS OF DATA THAT RESULTS FROM SUCH USE.
+
+10.3 GOOGLE FURTHER EXPRESSLY DISCLAIMS ALL WARRANTIES AND CONDITIONS OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+
+11. LIMITATION OF LIABILITY
+
+11.1 YOU EXPRESSLY UNDERSTAND AND AGREE THAT GOOGLE, ITS SUBSIDIARIES AND AFFILIATES, AND ITS LICENSORS SHALL NOT BE LIABLE TO YOU UNDER ANY THEORY OF LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL OR EXEMPLARY DAMAGES THAT MAY BE INCURRED BY YOU, INCLUDING ANY LOSS OF DATA, WHETHER OR NOT GOOGLE OR ITS REPRESENTATIVES HAVE BEEN ADVISED OF OR SHOULD HAVE BEEN AWARE OF THE POSSIBILITY OF ANY SUCH LOSSES ARISING.
+
+12. Indemnification
+
+12.1 To the maximum extent permitted by law, you agree to defend, indemnify and hold harmless Google, its affiliates and their respective directors, officers, employees and agents from and against any and all claims, actions, suits or proceedings, as well as any and all losses, liabilities, damages, costs and expenses (including reasonable attorneys’ fees) arising out of or accruing from (a) your use of the Developer Preview, (b) any application you develop on the Developer Preview that infringes any copyright, trademark, trade secret, trade dress, patent or other intellectual property right of any person or defames any person or violates their rights of publicity or privacy, and (c) any non-compliance by you with this License Agreement.
+
+13. Changes to the License Agreement
+
+13.1 Google may make changes to the License Agreement as it distributes new versions of the Developer Preview. When these changes are made, Google will make a new version of the License Agreement available on the website where the Developer Preview is made available.
+
+14. General Legal Terms
+
+14.1 This License Agreement constitutes the whole legal agreement between you and Google and governs your use of the Developer Preview (excluding any services which Google may provide to you under a separate written agreement), and completely replaces any prior agreements between you and Google in relation to the Developer Preview.
+
+14.2 You agree that if Google does not exercise or enforce any legal right or remedy which is contained in this License Agreement (or which Google has the benefit of under any applicable law), this will not be taken to be a formal waiver of Google's rights and that those rights or remedies will still be available to Google.
+
+14.3 If any court of law, having the jurisdiction to decide on this matter, rules that any provision of this License Agreement is invalid, then that provision will be removed from this License Agreement without affecting the rest of this License Agreement. The remaining provisions of this License Agreement will continue to be valid and enforceable.
+
+14.4 You acknowledge and agree that each member of the group of companies of which Google is the parent shall be third party beneficiaries to this License Agreement and that such other companies shall be entitled to directly enforce, and rely upon, any provision of this License Agreement that confers a benefit on (or rights in favor of) them. Other than this, no other person or company shall be third party beneficiaries to this License Agreement.
+
+14.5 EXPORT RESTRICTIONS. THE DEVELOPER PREVIEW IS SUBJECT TO UNITED STATES EXPORT LAWS AND REGULATIONS. YOU MUST COMPLY WITH ALL DOMESTIC AND INTERNATIONAL EXPORT LAWS AND REGULATIONS THAT APPLY TO THE DEVELOPER PREVIEW. THESE LAWS INCLUDE RESTRICTIONS ON DESTINATIONS, END USERS AND END USE.
+
+14.6 The rights granted in this License Agreement may not be assigned or transferred by either you or Google without the prior written approval of the other party. Neither you nor Google shall be permitted to delegate their responsibilities or obligations under this License Agreement without the prior written approval of the other party.
+
+14.7 This License Agreement, and your relationship with Google under this License Agreement, shall be governed by the laws of the State of California without regard to its conflict of laws provisions. You and Google agree to submit to the exclusive jurisdiction of the courts located within the county of Santa Clara, California to resolve any legal matter arising from this License Agreement. Notwithstanding this, you agree that Google shall still be allowed to apply for injunctive remedies (or an equivalent type of urgent legal relief) in any jurisdiction.
+
+
+</div></div>
+
+
+<p class="caution">
+  <strong>Important:</strong> Your email address is used to provide your Google account
+  access to the Android Wear Preview app Beta Preview on Google Play Store. As such, the
+  email address you provide below must be for the account you use to download apps on Google Play Store.
+  We may also use your email address to provide you with updates about the Android Wear
+  platform release.
+</p>
+
+<iframe src="https://docs.google.com/forms/d/1iSJ084kEkV242cZisNMnj6G8qpi9r_zdEyfXA-hB1ao/viewform?embedded=true" width="100%" height="540" frameborder="0" marginheight="0" marginwidth="0" id="signupform">Loading...</iframe>
+
+
+
+
+</body>
+</html>
+
+    </div>
+
+      <div class="content-footer layout-content-row"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col col-9" style="padding-top:4px">
+          
+            <div class="g-plusone" data-size="medium"></div>
+          
+        </div>
+        
+        <div class="paging-links layout-content-col col-4">
+          
+        </div>
+        
+      </div>
+
+      
+      
+
+  </div> <!-- end jd-content -->
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is 
+  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+  Creative Commons Attribution 2.5</a>. For details and 
+  restrictions, see the <a href="/license.html">Content 
+  License</a>.
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
+</body>
+</html>
+
+
+
diff --git a/docs/html/wear/preview/start.html b/docs/html/wear/preview/start.html
new file mode 100644
index 0000000..ce51c66
--- /dev/null
+++ b/docs/html/wear/preview/start.html
@@ -0,0 +1,687 @@
+<!DOCTYPE html>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<html>
+<head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width" />
+
+<link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
+<title>Get Started with the Developer Preview | Android Developers</title>
+
+<!-- STYLESHEETS -->
+<link rel="stylesheet"
+href="//fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" title="roboto">
+<link href="/assets/css/default.css" rel="stylesheet" type="text/css">
+
+
+
+<!-- JAVASCRIPT -->
+<script src="//www.google.com/jsapi" type="text/javascript"></script>
+<script src="/assets/js/android_3p-bundle.js" type="text/javascript"></script>
+<script type="text/javascript">
+  var toRoot = "/";
+  var metaTags = [];
+  var devsite = false;
+</script>
+<script src="/assets/js/docs.js" type="text/javascript"></script>
+
+<script type="text/javascript">
+  var _gaq = _gaq || [];
+  _gaq.push(['_setAccount', 'UA-5831155-1']);
+  _gaq.push(['_trackPageview']);
+
+  (function() {
+    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+  })();
+</script>
+</head>
+
+<body class="gc-documentation 
+  " itemscope itemtype="http://schema.org/Article">
+
+
+  
+<a name="top"></a>
+
+    <!-- Header -->
+    <div id="header">
+        <div class="wrap" id="header-wrap">
+          <div class="col-3 logo-wear">
+          <a href="/wear/index.html">
+            <img src="/wear/images/android-wear.png" height="16" alt="Android Wear" />
+          </a>
+          </div>
+
+
+	<div class="col-8" style="margin:0"><h1 style="margin:1px 0 0 20px;padding:0;line-height:16px;
+  color:#666;font-weight:100;font-size:24px;">Developer Preview</h1></div>
+            
+
+          <!-- New Search -->
+          <div class="menu-container">
+            <div class="moremenu">
+	        <div id="more-btn"></div>
+	    </div>
+  <div class="morehover" id="moremenu">
+    <div class="top"></div>
+    <div class="mid">
+      <div class="header">Links</div>
+      <ul>
+        <li><a href="https://play.google.com/apps/publish/">Google Play Developer Console</a></li>
+        <li><a href="http://android-developers.blogspot.com/">Android Developers Blog</a></li>
+        <li><a href="/about/index.html">About Android</a></li>
+      </ul>
+      <div class="header">Android Sites</div>
+      <ul>
+        <li><a href="http://www.android.com">Android.com</a></li>
+        <li class="active"><a>Android Developers</a></li>
+        <li><a href="http://source.android.com">Android Open Source Project</a></li>
+      </ul>
+      
+      
+      
+        <div class="header">Language</div>
+          <div id="language" class="locales">
+            <select name="language" onChange="changeLangPref(this.value, true)">
+                <option value="en">English</option>
+                <option value="es">Español</option>
+                <option value="ja">日本語</option>
+                <option value="ko">한국어</option>
+                <option value="ru">Русский</option>
+                <option value="zh-cn">中文 (中国)</option>
+                <option value="zh-tw">中文 (台灣)</option>
+            </select>
+          </div>
+        <script type="text/javascript">
+          <!--
+          loadLangPref();
+            //-->
+        </script>
+      
+      
+
+
+      <br class="clearfix" />
+    </div><!-- end mid -->
+    <div class="bottom"></div>
+  </div><!-- end morehover -->
+
+  <div class="search" id="search-container">
+    <div class="search-inner">
+      <div id="search-btn"></div>
+      <div class="left"></div>
+      <form onsubmit="return submit_search()">
+        <input id="search_autocomplete" type="text" value="" autocomplete="off" name="q"
+onfocus="search_focus_changed(this, true)" onblur="search_focus_changed(this, false)"
+onkeydown="return search_changed(event, true, '/')" 
+onkeyup="return search_changed(event, false, '/')" />
+      </form>
+      <div class="right"></div>
+        <a class="close hide">close</a>
+        <div class="left"></div>
+        <div class="right"></div>
+    </div>
+  </div><!--  end search -->
+
+  <div class="search_filtered_wrapper reference">
+    <div class="suggest-card reference no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div>
+
+  <div class="search_filtered_wrapper docs">
+    <div class="suggest-card dummy no-display">&nbsp;</div>
+    <div class="suggest-card develop no-display">
+      <ul class="search_filtered">
+      </ul>
+      <div class="child-card guides no-display">
+      </div>
+      <div class="child-card training no-display">
+      </div>
+      <div class="child-card samples no-display">
+      </div>
+    </div>
+    <div class="suggest-card design no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+    <div class="suggest-card distribute no-display">
+      <ul class="search_filtered">
+      </ul>
+    </div>
+  </div><!-- end search_filtered_wrapper -->
+
+  </div>
+  <!-- end menu_container -->
+
+
+        </div><!-- end header-wrap -->
+    </div>
+    <!-- /Header -->
+
+
+  <div id="searchResults" class="wrap" style="display:none;">
+          <h2 id="searchTitle">Results</h2>
+          <div id="leftSearchControl" class="search-control">Loading...</div>
+  </div>
+
+  
+
+  
+
+  <div class="wrap clearfix" id="body-content">
+    <div class="col-4" id="side-nav" itemscope itemtype="http://schema.org/SiteNavigationElement">
+      <div id="devdoc-nav" class="scroll-pane">
+<a class="totop" href="#top" data-g-event="left-nav-top">to top</a>
+
+<ul id="nav">
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/preview/start.html">Get Started
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/user-interface.html">UI Overview
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/design/index.html">Design Principles
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/creating.html">Creating Notifications for Android Wear
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/remote-input.html">Receiving Voice Input from a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/pages.html">Adding Pages to a Notification
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/notifications/stacks.html">Stacking Notifications
+      </a></div>
+  </li>
+
+  <li class="nav-section">
+    <div class="nav-section-header"><a href="/reference/android/preview/support/package-summary.html">Notification Reference</a></div>
+    <ul class="tree-list-children">
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.v4.app">android.preview.support.v4.app</span></div>
+  <ul>
+<li><a href="/reference/android/preview/support/v4/app/NotificationManagerCompat.html">NotificationManagerCompat</a></li>
+  </ul>
+</li>
+
+<li class="nav-section">
+<div class="nav-section-header-ref"><span class="tree-list-subtitle package" title="android.preview.support.wearable.notifications">android.preview.support.wearable.notifications</span></div>
+<ul>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.html">RemoteInput</a></li>
+<li><a href="/reference/android/preview/support/wearable/notifications/RemoteInput.Builder.html" >RemoteInput.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.html">WearableNotifications</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.html">WearableNotifications.Action</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Action.Builder.html">WearableNotifications.Action.Builder</a></li>
+
+<li><a href="/reference/android/preview/support/wearable/notifications/WearableNotifications.Builder.html">WearableNotifications.Builder</a></li>
+	</ul>
+  </li>
+</ul>
+</li>
+
+
+
+  <li class="nav-section">
+    <div class="nav-section-header empty"><a href="/wear/license.html">License Agreement</a></div>
+  </li>
+
+
+</ul>
+
+        
+
+      </div>
+    </div> <!-- end side-nav -->
+    <script>
+      $(document).ready(function() {
+        scrollIntoView("devdoc-nav");
+        });
+    </script>
+
+
+
+
+<div class="col-12" id="doc-col" >
+
+
+  
+    
+      
+        <h1 itemprop="name" >Get Started with the Developer Preview</h1>
+      
+    
+  
+
+
+  
+  <div id="jd-content">
+
+
+    <div class="jd-descr" itemprop="articleBody">
+    <div class="cols">
+
+  <div class="col-5">
+<p>The Android Wear Developer Preview provides tools and APIs that allow you to
+enhance your app notifications
+to provide an optimized user experience on Android Wear.</p>
+
+<p>With the Android Wear
+Developer Preview, you can:</p>
+
+<ul>
+  <li>Run the Android Wear platform in the Android emulator.</li>
+  <li>Connect your Android device to the emulator and view notifications from the
+device as cards on Android Wear.</li>
+  <li>Try new APIs in the preview support library that enhance your app's notifications
+with features such as voice replies and notification pages.</li>
+</ul>
+
+<p>To get access to the Developer Preview tools,
+click the sign up button on the right, then follow the setup instructions below.</p>
+  </div>
+
+  <div class="col-7">
+<img src="/wear/images/laptop-bridge.png" width="400" height="222" alt="" />
+
+<a href="/wear/preview/signup.html" class="button" style="
+    width: 370px;
+    margin: 10px 0 20px;
+    font-weight: bold;
+    font-size: 16px;
+">Sign Up for the Developer Preview</a>
+
+<p>Signing up provides you access to:</p>
+<ul>
+<li>New notification APIs in the preview support library.</li>
+<li>Sample apps using the new notification APIs.</li>
+<li>The <em>Android Wear Preview</em> app for your mobile device, which connects
+your device to the Android Wear emulator.</li>
+</ul>
+
+  </div>
+</div>
+
+
+<p class="caution"><strong>Caution:</strong>
+The current Android Wear Developer Preview is intended for <b>development and testing purposes only</b>, not for production apps. Google may change this Developer Preview significantly prior to the official release of the Android Wear SDK. You may not publicly distribute or ship any application using this Developer Preview, as this Developer Preview will no longer be supported after the official SDK is released (which will cause applications based only on the Developer Preview to break).</p>
+
+
+
+
+<h2 id="Prereq">Prerequisites</h2>
+
+<p>Before you begin the setup, you must:</p>
+
+<ol>
+  <li><a href="/sdk/index.html"><b>Install the Android SDK</b></a>.
+  <p>The Android SDK includes all the developer tools required to build
+apps for Android (optional IDEs are also available for download).</p></li>
+  <li><a href="/wear/preview/signup.html"><b>Sign up for the Android Wear Developer Preview</b></a>.
+  <p>You must sign up with a Gmail or other Google account in order to download the
+preview support library and receive access to the
+<em>Android Wear Preview</em> beta app on Google Play Store.</p></li>
+</ol>
+
+<p class="note"><strong>Note:</strong>
+If you're already using the ADT plugin for Eclipse, you must update to version 22.6.1 or higher.
+To check for updates, select <strong>Help &gt; Check for updates</strong> in the Eclipse toolbar. </p>
+
+
+
+<h2 id="Install">1. Install the Android Wear system image</h2>
+
+
+<ol>
+  <li>Launch <a href="/tools/help/sdk-manager.html"
+    >Android SDK Manager</a>.
+  <ul>
+    <li>From Eclipse, select <b>Window > Android SDK Manager</b>.</li>
+    <li>From Android Studio, select <b>Tools > Android > SDK Manager</b>.</li>
+  </ul>
+  </li>
+  <li>Below Tools, verify that you have Android SDK Tools revision 22.6 or higher.
+    <p>If your version of Android SDK Tools is lower than 22.6, you must update:</p>
+    <ol>
+      <li>Select <strong>Android SDK Tools</strong>.</li>
+      <li>Click <strong>Install package</strong>.</li>
+      <li>Accept the license and click <strong>Install</strong>.</li>
+      <li>When the installation completes, restart Android SDK Manager.</li>
+    </ol>
+  </li>
+
+  <li>Below Android 4.4.2, select <strong>Android Wear ARM EABI v7a System Image</strong>.</li>
+  <li>Below Extras, ensure that you have the latest version of the
+<a href="/tools/support-library/index.html">Android Support Library</a>.
+    If an update is available, select <strong>Android Support Library</strong>. If you're using Android Studio, also select <strong>Android Support Repository</strong>.</li>
+  <li>Click <strong>Install packages</strong>.</li>
+  <li>Accept the license and click <strong>Install</strong>.</li>
+</ol>
+
+
+
+<h2 id="SetupEmulator">2. Set Up the Android Wear Emulator</h2>
+
+<ol>
+<li>Launch the <a href="/tools/help/avd-manager.html"
+  >Android Virtual Device Manager</a>.
+<ul>
+<li>From Eclipse, select <b>Window > Android Virtual Device Manager</b>.</li>
+<li>From Android Studio, select <b>Tools > Android > AVD Manager</b>.</li>
+</ul>
+</li>
+<li>Click <strong>New</strong>.</li>
+<li>For the AVD Name, enter "AndroidWearSquare" or "AndroidWearRound", depending on whether
+you want to create an emulator with a square or round display.</li>
+<li>For the Device, select <strong>Android Wear Square</strong> or
+	<strong>Android Wear Round</strong>.</li>
+<li>For the Target, select <strong>Android 4.4.2 - API Level 19</strong> (or higher).</li>
+<li>For the CPU/ABI, select <strong>Android Wear ARM (armeabi-v7a)</strong>.</li>
+<li>For the Skin, select <strong>AndroidWearSquare</strong> or
+<strong>AndroidWearRound</strong>.</li>
+<li>Leave all other options set to their defaults and click <strong>OK</strong>.
+  <p>Although real Android Wear devices do not provide a keyboard as an input method,
+    you should keep <strong>Hardware keyboard present</strong> selected so you can
+    provide text input on screens where users will instead provide voice input.</p>
+</li>
+<!--
+<li>Click <strong>Device Definitions</strong>.</li>
+<li>Select <strong>Android WearSquare</strong> then click <strong>Create AVD</strong>.</li>
+<li>Click <strong>OK</strong>.</li>
+-->
+<li>In the list of AVDs, select the one you just created and click
+ <strong>Start</strong>. In the following window, click <strong>Launch</strong>.</li>
+</ol>
+
+<p>The Android Wear emulator now starts. To begin testing your app's notifications,
+you must now pair the emulator to your development device
+that has the <em>Android Wear Preview</em> app installed.</p>
+
+<p class="note"><strong>Tip:</strong> To improve the emulator startup time, edit your AVD
+and enable <strong>Snapshot</strong> under Emulator Options. When you start the emulator,
+select <strong>Save to snapshot</strong> then click <strong>Launch</strong>. Once the emulator
+is running, close it to save a snapshot of the system.
+Start the AVD again, but select <strong>Launch from snapshot</strong> and
+deselect <strong>Save to snapshot</strong>.</p>
+
+<p class="caution"><strong>Caution:</strong> Do not install apps on the Android Wear emulator.
+The system does not support traditional Android apps and the result of running such apps is
+unpredictable.</p>
+
+
+
+<h2 id="SetupApp">3. Set Up the Android Wear Preview App</h2>
+
+<p>The <em>Android Wear Preview</em> app is an app you must have installed on your Android
+device (a phone or tablet) in order to deliver app notifications to the Android Wear emulator.</p>
+
+<p>To receive the Android Wear Preview app, you must <a
+href="/wear/preview/signup.html">sign up for the Developer Preview</a> using the same
+Gmail or Google account you use with Google Play Store.</p>
+</p>
+
+<p class="note"><strong>Note:</strong> The <em>Android Wear Preview</em> app is compatible with
+    Android 4.3 and higher and is not available for the Android emulator.</p>
+
+<p>After you've signed up for the Developer Preview,
+  you'll receive a confirmation email that includes a link to opt-in to the
+  <em>Android Wear Preview</em> app beta program. Once you opt-in, it may take up to 24 hours for the
+  app to become available in Google Play Store.</p>
+
+<p>After you install the <em>Android Wear Preview</em> app, you can set up
+  your device to communicate with the Android Wear emulator:</p>
+
+<ol>
+<li>Open the <em>Android Wear Preview</em> app. You should see a notice that the app is currently
+  not enabled as a notification listener. Tap the message to open the system settings,
+  then select Android Wear Preview to grant it notification access.</li>
+<li>Connect your device to your development machine over USB. Be sure that no other
+ Android devices are connected to the machine.</li>
+<li>Ensure that the Android Wear emulator (created in the previous section) is running.
+The emulator should show the time and an icon that indicates no device is connected.</li>
+<li>Open a command line terminal, navigate to your Android SDK's <code>platform-tools/</code>
+directory, then execute:
+<pre style="margin-top:.5em">adb -d forward tcp:5601 tcp:5601</pre></li>
+<li>Return to the Android Wear Preview app. It should now indicate that it is connected to
+  the emulator. The Android Wear emulator should now show the 'g' orb icon, indicating
+  that is is connected to your device.
+</ol>
+
+<p>Now, notifications from your device also appear in the Android Wear emulator.</p>
+
+
+
+
+<h2 id="AddLibrary">4. Add the Support Library to Your Project</h2>
+
+<p>The Android Wear preview support library includes several APIs that allow you to
+optimize your app's notifications for the Android Wear user experience.</p>
+
+<p>To receive the preview support library, you must <a
+href="/wear/preview/signup.html">sign up for the Developer Preview</a>. The
+confirmation email you receive after you sign up includes a link to download a ZIP file,
+which contains the preview support library and some sample apps.</p>
+
+<p>After you download and unzip the package, add the preview support library
+sto your Android project:</p>
+
+<p><b>If you're using Eclipse:</b></p>
+    <ol>
+      <li>In your Android app project, create a <code>libs/</code> directory in your project root
+    (the same location as the <code>AndroidManifest.xml</code> file).</li>
+      <li>Copy the v4 support library JAR file from your Android SDK directory (e.g.,
+        <code>&lt;sdk&gt;/extras/android/support/v4/android-support-v4.jar</code>) into your
+        project <code>libs/</code> directory.
+      <li>Also save the <code>wearable-preview-support.jar</code> file in the <code>libs/</code> directory.
+      <li>Right click each JAR file and select <strong>Build Path &gt; Add to Build Path</strong>.</li>
+    </ol>
+
+ <p><b>If you're using Android Studio:</b></p>
+    <ol>
+     <li>In your Android app project, create a <code>libs/</code> directory in your project root
+    (the same location as the <code>AndroidManifest.xml</code> file).</li>
+      <li>Save the <code>wearable-preview-support.jar</code> file in the <code>libs/</code> directory.
+      <li>Open the <code>build.gradle</code> file in your app module.</li>
+      <li>Add a dependency rule for both the v4 support library and the Android Wear
+      preview support library:
+<pre>
+dependencies {
+    compile "com.android.support:support-v4:18.0.+"
+    compile files('../libs/wearable-preview-support.jar')
+}
+</pre>
+      </li>
+      <li>Click <strong>Sync Project with Gradle Files</strong> in the toolbar.</li>
+    </ol>
+
+<p>To start optimizing your notifications for Android Wear,
+  read <a href="/wear/notifications/creating.html"
+  >Creating Notifications for Android Wear</a>.</p>
+
+
+
+</body>
+</html>
+
+    </div>
+
+      <div class="content-footer layout-content-row"
+                    itemscope itemtype="http://schema.org/SiteNavigationElement">
+        <div class="layout-content-col col-9" style="padding-top:4px">
+          
+            <div class="g-plusone" data-size="medium"></div>
+          
+        </div>
+        
+        <div class="paging-links layout-content-col col-4">
+          
+        </div>
+        
+      </div>
+
+      
+      
+
+  </div> <!-- end jd-content -->
+
+<div id="footer" class="wrap" >
+        
+
+  <div id="copyright">
+    
+  Except as noted, this content is 
+  licensed under <a href="http://creativecommons.org/licenses/by/2.5/">
+  Creative Commons Attribution 2.5</a>. For details and 
+  restrictions, see the <a href="/license.html">Content 
+  License</a>.
+  </div>
+
+
+  <div id="footerlinks">
+    
+  <p>
+    <a href="/about/index.html">About Android</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/legal.html">Legal</a>&nbsp;&nbsp;|&nbsp;
+    <a href="/support.html">Support</a>
+  </p>
+  </div>
+
+</div> <!-- end footer -->
+</div><!-- end doc-content -->
+
+</div> <!-- end body-content --> 
+
+
+
+
+
+
+<!-- Start of Tag -->
+<script type="text/javascript">
+var axel = Math.random() + "";
+var a = axel * 10000000000000;
+document.write('<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=' + a + '?" width="1" height="1" frameborder="0" style="display:none"></iframe>');
+</script>
+<noscript>
+<iframe src="https://2507573.fls.doubleclick.net/activityi;src=2507573;type=other026;cat=googl348;ord=1?" width="1" height="1" frameborder="0" style="display:none"></iframe>
+</noscript>
+<!-- End of Tag -->
+</body>
+</html>
+
+
+
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 7676143..443e5dd 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1052,7 +1052,7 @@
      * <p>This method will not affect the behavior of a bitmap without an alpha
      * channel, or if {@link #hasAlpha()} returns false.</p>
      *
-     * <p>Calling createBitmap() or createScaledBitmap() with a source
+     * <p>Calling {@link #createBitmap} or {@link #createScaledBitmap} with a source
      * Bitmap whose colors are not pre-multiplied may result in a RuntimeException,
      * since those functions require drawing the source, which is not supported for
      * un-pre-multiplied Bitmaps.</p>
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 6f8292d..9d6d76e 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -89,6 +89,11 @@
     public static final String ACCOUNT_TYPE = "com.android.keychain";
 
     /**
+     * Package name for KeyChain chooser.
+     */
+    private static final String KEYCHAIN_PACKAGE = "com.android.keychain";
+
+    /**
      * Action to bring up the KeyChainActivity
      */
     private static final String ACTION_CHOOSER = "com.android.keychain.CHOOSER";
@@ -272,7 +277,7 @@
             throw new NullPointerException("response == null");
         }
         Intent intent = new Intent(ACTION_CHOOSER);
-        intent.setPackage(CERT_INSTALLER_PACKAGE);
+        intent.setPackage(KEYCHAIN_PACKAGE);
         intent.putExtra(EXTRA_RESPONSE, new AliasResponse(response));
         intent.putExtra(EXTRA_HOST, host);
         intent.putExtra(EXTRA_PORT, port);
diff --git a/libs/hwui/AmbientShadow.cpp b/libs/hwui/AmbientShadow.cpp
index 8327ef7..c0b5402 100644
--- a/libs/hwui/AmbientShadow.cpp
+++ b/libs/hwui/AmbientShadow.cpp
@@ -31,6 +31,7 @@
  * Calculate the shadows as a triangle strips while alpha value as the
  * shadow values.
  *
+ * @param isCasterOpaque Whether the caster is opaque.
  * @param vertices The shadow caster's polygon, which is represented in a Vector3
  *                  array.
  * @param vertexCount The length of caster's polygon in terms of number of
@@ -43,17 +44,18 @@
  * @param shadowVertexBuffer Return an floating point array of (x, y, a)
  *               triangle strips mode.
  */
-void AmbientShadow::createAmbientShadow(const Vector3* vertices, int vertexCount,
-        const Vector3& centroid3d, float heightFactor, float geomFactor,
-        VertexBuffer& shadowVertexBuffer) {
+VertexBufferMode AmbientShadow::createAmbientShadow(bool isCasterOpaque,
+        const Vector3* vertices, int vertexCount, const Vector3& centroid3d,
+        float heightFactor, float geomFactor, VertexBuffer& shadowVertexBuffer) {
     const int rays = SHADOW_RAY_COUNT;
+    VertexBufferMode mode = kVertexBufferMode_OnePolyRingShadow;
     // Validate the inputs.
     if (vertexCount < 3 || heightFactor <= 0 || rays <= 0
         || geomFactor <= 0) {
 #if DEBUG_SHADOW
-        ALOGE("Invalid input for createAmbientShadow(), early return!");
+        ALOGW("Invalid input for createAmbientShadow(), early return!");
 #endif
-        return;
+        return mode; // vertex buffer is empty, so any mode doesn't matter.
     }
 
     Vector<Vector2> dir; // TODO: use C++11 unique_ptr
@@ -75,7 +77,7 @@
         rayDist[i] = rayDistance;
         if (edgeIndex < 0 || edgeIndex >= vertexCount) {
 #if DEBUG_SHADOW
-            ALOGE("Invalid edgeIndex!");
+            ALOGW("Invalid edgeIndex!");
 #endif
             edgeIndex = 0;
         }
@@ -86,7 +88,8 @@
 
     // The output buffer length basically is roughly rays * layers, but since we
     // need triangle strips, so we need to duplicate vertices to accomplish that.
-    AlphaVertex* shadowVertices = shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT);
+    AlphaVertex* shadowVertices =
+            shadowVertexBuffer.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT);
 
     // Calculate the vertex of the shadows.
     //
@@ -95,6 +98,7 @@
     // calculate the normal N, which should be perpendicular to the edge of the
     // polygon (represented by the neighbor intersection points) .
     // Shadow's vertices will be generated as : P + N * scale.
+    const Vector2 centroid2d = Vector2(centroid3d.x, centroid3d.y);
     for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
         Vector2 normal(1.0f, 0.0f);
         calculateNormal(rays, rayIndex, dir.array(), rayDist, normal);
@@ -102,7 +106,7 @@
         // The vertex should be start from rayDist[i] then scale the
         // normalizeNormal!
         Vector2 intersection = dir[rayIndex] * rayDist[rayIndex] +
-                Vector2(centroid3d.x, centroid3d.y);
+                centroid2d;
 
         // outer ring of points, expanded based upon height of each ray intersection
         float expansionDist = rayHeight[rayIndex] * heightFactor *
@@ -114,25 +118,31 @@
 
         // inner ring of points
         float opacity = 1.0 / (1 + rayHeight[rayIndex] * heightFactor);
-        AlphaVertex::set(&shadowVertices[rayIndex + rays],
+        AlphaVertex::set(&shadowVertices[rays + rayIndex],
                 intersection.x,
                 intersection.y,
                 opacity);
     }
-    float centroidAlpha = 1.0 / (1 + centroid3d.z * heightFactor);
-    AlphaVertex::set(&shadowVertices[SHADOW_VERTEX_COUNT - 1],
-            centroid3d.x, centroid3d.y, centroidAlpha);
+
+    // If caster isn't opaque, we need to to fill the umbra by storing the umbra's
+    // centroid in the innermost ring of vertices.
+    if (!isCasterOpaque) {
+        mode = kVertexBufferMode_TwoPolyRingShadow;
+        float centroidAlpha = 1.0 / (1 + centroid3d.z * heightFactor);
+        AlphaVertex centroidXYA;
+        AlphaVertex::set(&centroidXYA, centroid2d.x, centroid2d.y, centroidAlpha);
+        for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
+            shadowVertices[2 * rays + rayIndex] = centroidXYA;
+        }
+    }
 
 #if DEBUG_SHADOW
-    if (currentVertexIndex != SHADOW_VERTEX_COUNT) {
-        ALOGE("number of vertex generated for ambient shadow is wrong! "
-              "current: %d , expected: %d", currentVertexIndex, SHADOW_VERTEX_COUNT);
-    }
     for (int i = 0; i < SHADOW_VERTEX_COUNT; i++) {
         ALOGD("ambient shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
                 shadowVertices[i].y, shadowVertices[i].alpha);
     }
 #endif
+    return mode;
 }
 
 /**
diff --git a/libs/hwui/AmbientShadow.h b/libs/hwui/AmbientShadow.h
index 20d1384..45b8bef 100644
--- a/libs/hwui/AmbientShadow.h
+++ b/libs/hwui/AmbientShadow.h
@@ -19,6 +19,7 @@
 #define ANDROID_HWUI_AMBIENT_SHADOW_H
 
 #include "Debug.h"
+#include "OpenGLRenderer.h"
 #include "Vector.h"
 #include "VertexBuffer.h"
 
@@ -34,9 +35,9 @@
  */
 class AmbientShadow {
 public:
-    static void createAmbientShadow(const Vector3* poly, int polyLength,
-            const Vector3& centroid3d, float heightFactor, float geomFactor,
-            VertexBuffer& shadowVertexBuffer);
+    static VertexBufferMode createAmbientShadow(bool isCasterOpaque, const Vector3* poly,
+            int polyLength, const Vector3& centroid3d, float heightFactor,
+            float geomFactor, VertexBuffer& shadowVertexBuffer);
 
 private:
     static void calculateRayDirections(int rays, Vector2* dir);
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 2cc7a84..eeff4c0 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -38,6 +38,7 @@
 		Program.cpp \
 		ProgramCache.cpp \
 		RenderBufferCache.cpp \
+		RenderProperties.cpp \
 		ResourceCache.cpp \
 		ShadowTessellator.cpp \
 		SkiaShader.cpp \
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 69d3328..477d691 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -315,7 +315,7 @@
     pathCache.clearGarbage();
     patchCache.clearGarbage();
 
-    Vector<DisplayList*> displayLists;
+    Vector<RenderNode*> displayLists;
     Vector<Layer*> layers;
 
     { // scope for the lock
@@ -328,7 +328,7 @@
 
     size_t count = displayLists.size();
     for (size_t i = 0; i < count; i++) {
-        DisplayList* displayList = displayLists.itemAt(i);
+        RenderNode* displayList = displayLists.itemAt(i);
         delete displayList;
     }
 
@@ -345,7 +345,7 @@
     mLayerGarbage.push(layer);
 }
 
-void Caches::deleteDisplayListDeferred(DisplayList* displayList) {
+void Caches::deleteDisplayListDeferred(RenderNode* displayList) {
     Mutex::Autolock _l(mGarbageLock);
     mDisplayListGarbage.push(displayList);
 }
@@ -445,11 +445,11 @@
 
 bool Caches::bindShadowIndicesBuffer() {
     if (!mShadowStripsIndices) {
-        uint16_t* shadowIndices = new uint16_t[SHADOW_INDEX_COUNT];
+        uint16_t* shadowIndices = new uint16_t[MAX_SHADOW_INDEX_COUNT];
         ShadowTessellator::generateShadowIndices(shadowIndices);
         glGenBuffers(1, &mShadowStripsIndices);
         bool force = bindIndicesBufferInternal(mShadowStripsIndices);
-        glBufferData(GL_ELEMENT_ARRAY_BUFFER, SHADOW_INDEX_COUNT * sizeof(uint16_t),
+        glBufferData(GL_ELEMENT_ARRAY_BUFFER, MAX_SHADOW_INDEX_COUNT * sizeof(uint16_t),
             shadowIndices, GL_STATIC_DRAW);
 
         delete[] shadowIndices;
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 6f3d8fb..50c5fef 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -102,7 +102,7 @@
 // Caches
 ///////////////////////////////////////////////////////////////////////////////
 
-class DisplayList;
+class RenderNode;
 
 class ANDROID_API Caches: public Singleton<Caches> {
     Caches();
@@ -169,7 +169,7 @@
     /*
      * Can be used to delete a display list from a non EGL thread.
      */
-    void deleteDisplayListDeferred(DisplayList* layer);
+    void deleteDisplayListDeferred(RenderNode* layer);
 
     /**
      * Binds the VBO used to render simple textured quads.
@@ -420,7 +420,7 @@
 
     mutable Mutex mGarbageLock;
     Vector<Layer*> mLayerGarbage;
-    Vector<DisplayList*> mDisplayListGarbage;
+    Vector<RenderNode*> mDisplayListGarbage;
 
     DebugLevel mDebugLevel;
     bool mInitialized;
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index 7a2e288..7a83967 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -54,7 +54,7 @@
     SkRefCnt_SafeAssign(mColorFilter, colorFilter);
 }
 
-void DeferredLayerUpdater::setDisplayList(DisplayList* displayList,
+void DeferredLayerUpdater::setDisplayList(RenderNode* displayList,
         int left, int top, int right, int bottom) {
     mDisplayList = displayList;
     if (mDirtyRect.isEmpty()) {
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index 65f225c..d124cde 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -72,7 +72,7 @@
         mTransform = matrix ? new SkMatrix(*matrix) : 0;
     }
 
-    ANDROID_API void setDisplayList(DisplayList* displayList,
+    ANDROID_API void setDisplayList(RenderNode* displayList,
                 int left, int top, int right, int bottom);
 
     ANDROID_API void setPaint(const SkPaint* paint);
@@ -101,7 +101,7 @@
     // Layer type specific properties
     // displayList and surfaceTexture are mutually exclusive, only 1 may be set
     // dirtyRect is only valid if displayList is set
-    DisplayList* mDisplayList;
+    RenderNode* mDisplayList;
     Rect mDirtyRect;
     sp<GLConsumer> mSurfaceTexture;
     SkMatrix* mTransform;
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
index b954c1f..f4de8ec 100644
--- a/libs/hwui/DisplayList.cpp
+++ b/libs/hwui/DisplayList.cpp
@@ -29,7 +29,7 @@
 namespace android {
 namespace uirenderer {
 
-void DisplayList::outputLogBuffer(int fd) {
+void RenderNode::outputLogBuffer(int fd) {
     DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
     if (logBuffer.isEmpty()) {
         return;
@@ -48,65 +48,24 @@
     fflush(file);
 }
 
-DisplayList::DisplayList() :
-        mDisplayListData(0), mDestroyed(false), mTransformMatrix(NULL), mTransformCamera(NULL),
-        mTransformMatrix3D(NULL), mStaticMatrix(NULL), mAnimationMatrix(NULL) {
-
-    mLeft = 0;
-    mTop = 0;
-    mRight = 0;
-    mBottom = 0;
-    mClipToBounds = true;
-    mIsolatedZVolume = true;
-    mProjectBackwards = false;
-    mProjectionReceiver = false;
-    mOutline.rewind();
-    mClipToOutline = false;
-    mCastsShadow = false;
-    mUsesGlobalCamera = false;
-    mAlpha = 1;
-    mHasOverlappingRendering = true;
-    mTranslationX = 0;
-    mTranslationY = 0;
-    mTranslationZ = 0;
-    mRotation = 0;
-    mRotationX = 0;
-    mRotationY= 0;
-    mScaleX = 1;
-    mScaleY = 1;
-    mPivotX = 0;
-    mPivotY = 0;
-    mCameraDistance = 0;
-    mMatrixDirty = false;
-    mMatrixFlags = 0;
-    mPrevWidth = -1;
-    mPrevHeight = -1;
-    mWidth = 0;
-    mHeight = 0;
-    mPivotExplicitlySet = false;
-    mCaching = false;
+RenderNode::RenderNode() : mDestroyed(false), mDisplayListData(0) {
 }
 
-DisplayList::~DisplayList() {
+RenderNode::~RenderNode() {
     LOG_ALWAYS_FATAL_IF(mDestroyed, "Double destroyed DisplayList %p", this);
 
     mDestroyed = true;
     delete mDisplayListData;
-    delete mTransformMatrix;
-    delete mTransformCamera;
-    delete mTransformMatrix3D;
-    delete mStaticMatrix;
-    delete mAnimationMatrix;
 }
 
-void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
+void RenderNode::destroyDisplayListDeferred(RenderNode* displayList) {
     if (displayList) {
         DISPLAY_LIST_LOGD("Deferring display list destruction");
         Caches::getInstance().deleteDisplayListDeferred(displayList);
     }
 }
 
-void DisplayList::setData(DisplayListData* data) {
+void RenderNode::setData(DisplayListData* data) {
     delete mDisplayListData;
     mDisplayListData = data;
     if (mDisplayListData) {
@@ -118,7 +77,7 @@
  * This function is a simplified version of replay(), where we simply retrieve and log the
  * display list. This function should remain in sync with the replay() function.
  */
-void DisplayList::output(uint32_t level) {
+void RenderNode::output(uint32_t level) {
     ALOGD("%*sStart display list (%p, %s, render=%d)", (level - 1) * 2, "", this,
             mName.string(), isRenderable());
     ALOGD("%*s%s %d", level * 2, "", "Save",
@@ -133,97 +92,35 @@
     ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, mName.string());
 }
 
-float DisplayList::getPivotX() {
-    updateMatrix();
-    return mPivotX;
-}
-
-float DisplayList::getPivotY() {
-    updateMatrix();
-    return mPivotY;
-}
-
-void DisplayList::updateMatrix() {
-    if (mMatrixDirty) {
-        // NOTE: mTransformMatrix won't be up to date if a DisplayList goes from a complex transform
-        // to a pure translate. This is safe because the matrix isn't read in pure translate cases.
-        if (mMatrixFlags && mMatrixFlags != TRANSLATION) {
-            if (!mTransformMatrix) {
-                // only allocate a matrix if we have a complex transform
-                mTransformMatrix = new Matrix4();
-            }
-            if (!mPivotExplicitlySet) {
-                if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
-                    mPrevWidth = mWidth;
-                    mPrevHeight = mHeight;
-                    mPivotX = mPrevWidth / 2.0f;
-                    mPivotY = mPrevHeight / 2.0f;
-                }
-            }
-
-            if ((mMatrixFlags & ROTATION_3D) == 0) {
-                mTransformMatrix->loadTranslate(
-                        mPivotX + mTranslationX,
-                        mPivotY + mTranslationY,
-                        0);
-                mTransformMatrix->rotate(mRotation, 0, 0, 1);
-                mTransformMatrix->scale(mScaleX, mScaleY, 1);
-                mTransformMatrix->translate(-mPivotX, -mPivotY);
-            } else {
-                if (!mTransformCamera) {
-                    mTransformCamera = new Sk3DView();
-                    mTransformMatrix3D = new SkMatrix();
-                }
-                SkMatrix transformMatrix;
-                transformMatrix.reset();
-                mTransformCamera->save();
-                transformMatrix.preScale(mScaleX, mScaleY, mPivotX, mPivotY);
-                mTransformCamera->rotateX(mRotationX);
-                mTransformCamera->rotateY(mRotationY);
-                mTransformCamera->rotateZ(-mRotation);
-                mTransformCamera->getMatrix(mTransformMatrix3D);
-                mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
-                mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
-                        mPivotY + mTranslationY);
-                transformMatrix.postConcat(*mTransformMatrix3D);
-                mTransformCamera->restore();
-
-                mTransformMatrix->load(transformMatrix);
-            }
-        }
-        mMatrixDirty = false;
+void RenderNode::outputViewProperties(const int level) {
+    properties().updateMatrix();
+    if (properties().mLeft != 0 || properties().mTop != 0) {
+        ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", properties().mLeft, properties().mTop);
     }
-}
-
-void DisplayList::outputViewProperties(const int level) {
-    updateMatrix();
-    if (mLeft != 0 || mTop != 0) {
-        ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", mLeft, mTop);
-    }
-    if (mStaticMatrix) {
+    if (properties().mStaticMatrix) {
         ALOGD("%*sConcatMatrix (static) %p: " SK_MATRIX_STRING,
-                level * 2, "", mStaticMatrix, SK_MATRIX_ARGS(mStaticMatrix));
+                level * 2, "", properties().mStaticMatrix, SK_MATRIX_ARGS(properties().mStaticMatrix));
     }
-    if (mAnimationMatrix) {
+    if (properties().mAnimationMatrix) {
         ALOGD("%*sConcatMatrix (animation) %p: " SK_MATRIX_STRING,
-                level * 2, "", mAnimationMatrix, SK_MATRIX_ARGS(mAnimationMatrix));
+                level * 2, "", properties().mAnimationMatrix, SK_MATRIX_ARGS(properties().mAnimationMatrix));
     }
-    if (mMatrixFlags != 0) {
-        if (mMatrixFlags == TRANSLATION) {
+    if (properties().mMatrixFlags != 0) {
+        if (properties().mMatrixFlags == TRANSLATION) {
             ALOGD("%*sTranslate %.2f, %.2f, %.2f",
-                    level * 2, "", mTranslationX, mTranslationY, mTranslationZ);
+                    level * 2, "", properties().mTranslationX, properties().mTranslationY, properties().mTranslationZ);
         } else {
             ALOGD("%*sConcatMatrix %p: " MATRIX_4_STRING,
-                    level * 2, "", mTransformMatrix, MATRIX_4_ARGS(mTransformMatrix));
+                    level * 2, "", properties().mTransformMatrix, MATRIX_4_ARGS(properties().mTransformMatrix));
         }
     }
 
-    bool clipToBoundsNeeded = mCaching ? false : mClipToBounds;
-    if (mAlpha < 1) {
-        if (mCaching) {
-            ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", mAlpha);
-        } else if (!mHasOverlappingRendering) {
-            ALOGD("%*sScaleAlpha %.2f", level * 2, "", mAlpha);
+    bool clipToBoundsNeeded = properties().mCaching ? false : properties().mClipToBounds;
+    if (properties().mAlpha < 1) {
+        if (properties().mCaching) {
+            ALOGD("%*sSetOverrideLayerAlpha %.2f", level * 2, "", properties().mAlpha);
+        } else if (!properties().mHasOverlappingRendering) {
+            ALOGD("%*sScaleAlpha %.2f", level * 2, "", properties().mAlpha);
         } else {
             int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
             if (clipToBoundsNeeded) {
@@ -231,51 +128,51 @@
                 clipToBoundsNeeded = false; // clipping done by save layer
             }
             ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "",
-                    (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
-                    (int)(mAlpha * 255), flags);
+                    (float) 0, (float) 0, (float) properties().mRight - properties().mLeft, (float) properties().mBottom - properties().mTop,
+                    (int)(properties().mAlpha * 255), flags);
         }
     }
     if (clipToBoundsNeeded) {
         ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f,
-                (float) mRight - mLeft, (float) mBottom - mTop);
+                (float) properties().mRight - properties().mLeft, (float) properties().mBottom - properties().mTop);
     }
 }
 
 /*
  * For property operations, we pass a savecount of 0, since the operations aren't part of the
  * displaylist, and thus don't have to compensate for the record-time/playback-time discrepancy in
- * base saveCount (i.e., how RestoreToCount uses saveCount + mCount)
+ * base saveCount (i.e., how RestoreToCount uses saveCount + properties().mCount)
  */
 #define PROPERTY_SAVECOUNT 0
 
 template <class T>
-void DisplayList::setViewProperties(OpenGLRenderer& renderer, T& handler,
+void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler,
         const int level) {
 #if DEBUG_DISPLAY_LIST
     outputViewProperties(level);
 #endif
-    updateMatrix();
-    if (mLeft != 0 || mTop != 0) {
-        renderer.translate(mLeft, mTop);
+    properties().updateMatrix();
+    if (properties().mLeft != 0 || properties().mTop != 0) {
+        renderer.translate(properties().mLeft, properties().mTop);
     }
-    if (mStaticMatrix) {
-        renderer.concatMatrix(mStaticMatrix);
-    } else if (mAnimationMatrix) {
-        renderer.concatMatrix(mAnimationMatrix);
+    if (properties().mStaticMatrix) {
+        renderer.concatMatrix(properties().mStaticMatrix);
+    } else if (properties().mAnimationMatrix) {
+        renderer.concatMatrix(properties().mAnimationMatrix);
     }
-    if (mMatrixFlags != 0) {
-        if (mMatrixFlags == TRANSLATION) {
-            renderer.translate(mTranslationX, mTranslationY);
+    if (properties().mMatrixFlags != 0) {
+        if (properties().mMatrixFlags == TRANSLATION) {
+            renderer.translate(properties().mTranslationX, properties().mTranslationY);
         } else {
-            renderer.concatMatrix(*mTransformMatrix);
+            renderer.concatMatrix(*properties().mTransformMatrix);
         }
     }
-    bool clipToBoundsNeeded = mCaching ? false : mClipToBounds;
-    if (mAlpha < 1) {
-        if (mCaching) {
-            renderer.setOverrideLayerAlpha(mAlpha);
-        } else if (!mHasOverlappingRendering) {
-            renderer.scaleAlpha(mAlpha);
+    bool clipToBoundsNeeded = properties().mCaching ? false : properties().mClipToBounds;
+    if (properties().mAlpha < 1) {
+        if (properties().mCaching) {
+            renderer.setOverrideLayerAlpha(properties().mAlpha);
+        } else if (!properties().mHasOverlappingRendering) {
+            renderer.scaleAlpha(properties().mAlpha);
         } else {
             // TODO: should be able to store the size of a DL at record time and not
             // have to pass it into this call. In fact, this information might be in the
@@ -287,18 +184,18 @@
             }
 
             SaveLayerOp* op = new (handler.allocator()) SaveLayerOp(
-                    0, 0, mRight - mLeft, mBottom - mTop, mAlpha * 255, saveFlags);
-            handler(op, PROPERTY_SAVECOUNT, mClipToBounds);
+                    0, 0, properties().mRight - properties().mLeft, properties().mBottom - properties().mTop, properties().mAlpha * 255, saveFlags);
+            handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
         }
     }
     if (clipToBoundsNeeded) {
         ClipRectOp* op = new (handler.allocator()) ClipRectOp(0, 0,
-                mRight - mLeft, mBottom - mTop, SkRegion::kIntersect_Op);
-        handler(op, PROPERTY_SAVECOUNT, mClipToBounds);
+                properties().mRight - properties().mLeft, properties().mBottom - properties().mTop, SkRegion::kIntersect_Op);
+        handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
     }
-    if (CC_UNLIKELY(mClipToOutline && !mOutline.isEmpty())) {
-        ClipPathOp* op = new (handler.allocator()) ClipPathOp(&mOutline, SkRegion::kIntersect_Op);
-        handler(op, PROPERTY_SAVECOUNT, mClipToBounds);
+    if (CC_UNLIKELY(properties().mClipToOutline && !properties().mOutline.isEmpty())) {
+        ClipPathOp* op = new (handler.allocator()) ClipPathOp(&properties().mOutline, SkRegion::kIntersect_Op);
+        handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
     }
 }
 
@@ -308,36 +205,36 @@
  * If true3dTransform is set to true, the transform applied to the input matrix will use true 4x4
  * matrix computation instead of the Skia 3x3 matrix + camera hackery.
  */
-void DisplayList::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform) {
-    if (mLeft != 0 || mTop != 0) {
-        matrix.translate(mLeft, mTop);
+void RenderNode::applyViewPropertyTransforms(mat4& matrix, bool true3dTransform) {
+    if (properties().mLeft != 0 || properties().mTop != 0) {
+        matrix.translate(properties().mLeft, properties().mTop);
     }
-    if (mStaticMatrix) {
-        mat4 stat(*mStaticMatrix);
+    if (properties().mStaticMatrix) {
+        mat4 stat(*properties().mStaticMatrix);
         matrix.multiply(stat);
-    } else if (mAnimationMatrix) {
-        mat4 anim(*mAnimationMatrix);
+    } else if (properties().mAnimationMatrix) {
+        mat4 anim(*properties().mAnimationMatrix);
         matrix.multiply(anim);
     }
-    if (mMatrixFlags != 0) {
-        updateMatrix();
-        if (mMatrixFlags == TRANSLATION) {
-            matrix.translate(mTranslationX, mTranslationY,
-                    true3dTransform ? mTranslationZ : 0.0f);
+    if (properties().mMatrixFlags != 0) {
+        properties().updateMatrix();
+        if (properties().mMatrixFlags == TRANSLATION) {
+            matrix.translate(properties().mTranslationX, properties().mTranslationY,
+                    true3dTransform ? properties().mTranslationZ : 0.0f);
         } else {
             if (!true3dTransform) {
-                matrix.multiply(*mTransformMatrix);
+                matrix.multiply(*properties().mTransformMatrix);
             } else {
                 mat4 true3dMat;
                 true3dMat.loadTranslate(
-                        mPivotX + mTranslationX,
-                        mPivotY + mTranslationY,
-                        mTranslationZ);
-                true3dMat.rotate(mRotationX, 1, 0, 0);
-                true3dMat.rotate(mRotationY, 0, 1, 0);
-                true3dMat.rotate(mRotation, 0, 0, 1);
-                true3dMat.scale(mScaleX, mScaleY, 1);
-                true3dMat.translate(-mPivotX, -mPivotY);
+                        properties().mPivotX + properties().mTranslationX,
+                        properties().mPivotY + properties().mTranslationY,
+                        properties().mTranslationZ);
+                true3dMat.rotate(properties().mRotationX, 1, 0, 0);
+                true3dMat.rotate(properties().mRotationY, 0, 1, 0);
+                true3dMat.rotate(properties().mRotation, 0, 0, 1);
+                true3dMat.scale(properties().mScaleX, properties().mScaleY, 1);
+                true3dMat.translate(-properties().mPivotX, -properties().mPivotY);
 
                 matrix.multiply(true3dMat);
             }
@@ -353,7 +250,7 @@
  * Each DisplayList that serves as a 3d root builds its list of composited children,
  * which are flagged to not draw in the standard draw loop.
  */
-void DisplayList::computeOrdering() {
+void RenderNode::computeOrdering() {
     ATRACE_CALL();
     mProjectedNodes.clear();
 
@@ -367,7 +264,7 @@
     }
 }
 
-void DisplayList::computeOrderingImpl(
+void RenderNode::computeOrderingImpl(
         DrawDisplayListOp* opState,
         Vector<DrawDisplayListOp*>* compositedChildrenOfProjectionSurface,
         const mat4* transformFromProjectionSurface) {
@@ -379,7 +276,7 @@
     Matrix4 localTransformFromProjectionSurface(*transformFromProjectionSurface);
     localTransformFromProjectionSurface.multiply(opState->mTransformFromParent);
 
-    if (mProjectBackwards) {
+    if (properties().mProjectBackwards) {
         // composited projectee, flag for out of order draw, save matrix, and store in proj surface
         opState->mSkipInOrderDraw = true;
         opState->mTransformFromCompositingAncestor.load(localTransformFromProjectionSurface);
@@ -394,11 +291,11 @@
         bool haveAppliedPropertiesToProjection = false;
         for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
             DrawDisplayListOp* childOp = mDisplayListData->children[i];
-            DisplayList* child = childOp->mDisplayList;
+            RenderNode* child = childOp->mDisplayList;
 
             Vector<DrawDisplayListOp*>* projectionChildren = NULL;
             const mat4* projectionTransform = NULL;
-            if (isProjectionReceiver && !child->mProjectBackwards) {
+            if (isProjectionReceiver && !child->properties().mProjectBackwards) {
                 // if receiving projections, collect projecting descendent
 
                 // Note that if a direct descendent is projecting backwards, we pass it's
@@ -434,7 +331,7 @@
     const int mLevel;
 };
 
-void DisplayList::defer(DeferStateStruct& deferStruct, const int level) {
+void RenderNode::defer(DeferStateStruct& deferStruct, const int level) {
     DeferOperationHandler handler(deferStruct, level);
     iterate<DeferOperationHandler>(deferStruct.mRenderer, handler, level);
 }
@@ -445,7 +342,7 @@
         : mReplayStruct(replayStruct), mLevel(level) {}
     inline void operator()(DisplayListOp* operation, int saveCount, bool clipToBounds) {
 #if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
-        mReplayStruct.mRenderer.eventMark(operation->name());
+        properties().mReplayStruct.mRenderer.eventMark(operation->name());
 #endif
         operation->replay(mReplayStruct, saveCount, mLevel, clipToBounds);
     }
@@ -456,7 +353,7 @@
     const int mLevel;
 };
 
-void DisplayList::replay(ReplayStateStruct& replayStruct, const int level) {
+void RenderNode::replay(ReplayStateStruct& replayStruct, const int level) {
     ReplayOperationHandler handler(replayStruct, level);
 
     replayStruct.mRenderer.startMark(mName.string());
@@ -467,18 +364,18 @@
             replayStruct.mDrawGlStatus);
 }
 
-void DisplayList::buildZSortedChildList(Vector<ZDrawDisplayListOpPair>& zTranslatedNodes) {
+void RenderNode::buildZSortedChildList(Vector<ZDrawDisplayListOpPair>& zTranslatedNodes) {
     if (mDisplayListData == NULL || mDisplayListData->children.size() == 0) return;
 
     for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
         DrawDisplayListOp* childOp = mDisplayListData->children[i];
-        DisplayList* child = childOp->mDisplayList;
-        float childZ = child->mTranslationZ;
+        RenderNode* child = childOp->mDisplayList;
+        float childZ = child->properties().mTranslationZ;
 
         if (childZ != 0.0f) {
             zTranslatedNodes.add(ZDrawDisplayListOpPair(childZ, childOp));
             childOp->mSkipInOrderDraw = true;
-        } else if (!child->mProjectBackwards) {
+        } else if (!child->properties().mProjectBackwards) {
             // regular, in order drawing DisplayList
             childOp->mSkipInOrderDraw = false;
         }
@@ -491,7 +388,7 @@
 #define SHADOW_DELTA 0.1f
 
 template <class T>
-void DisplayList::iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes,
+void RenderNode::iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTranslatedNodes,
         ChildrenSelectMode mode, OpenGLRenderer& renderer, T& handler) {
     const int size = zTranslatedNodes.size();
     if (size == 0
@@ -503,9 +400,9 @@
 
     int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
     LinearAllocator& alloc = handler.allocator();
-    ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, mWidth, mHeight,
+    ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, properties().mWidth, properties().mHeight,
             SkRegion::kIntersect_Op); // clip to 3d root bounds
-    handler(clipOp, PROPERTY_SAVECOUNT, mClipToBounds);
+    handler(clipOp, PROPERTY_SAVECOUNT, properties().mClipToBounds);
 
     /**
      * Draw shadows and (potential) casters mostly in order, but allow the shadows of casters
@@ -529,13 +426,13 @@
     while (shadowIndex < endIndex || drawIndex < endIndex) {
         if (shadowIndex < endIndex) {
             DrawDisplayListOp* casterOp = zTranslatedNodes[shadowIndex].value;
-            DisplayList* caster = casterOp->mDisplayList;
+            RenderNode* caster = casterOp->mDisplayList;
             const float casterZ = zTranslatedNodes[shadowIndex].key;
             // attempt to render the shadow if the caster about to be drawn is its caster,
             // OR if its caster's Z value is similar to the previous potential caster
             if (shadowIndex == drawIndex || casterZ - lastCasterZ < SHADOW_DELTA) {
 
-                if (caster->mCastsShadow && caster->mAlpha > 0.0f) {
+                if (caster->properties().mAlpha > 0.0f) {
                     mat4 shadowMatrixXY(casterOp->mTransformFromParent);
                     caster->applyViewPropertyTransforms(shadowMatrixXY);
 
@@ -545,8 +442,9 @@
 
                     DisplayListOp* shadowOp  = new (alloc) DrawShadowOp(
                             shadowMatrixXY, shadowMatrixZ,
-                            caster->mAlpha, &(caster->mOutline), caster->mWidth, caster->mHeight);
-                    handler(shadowOp, PROPERTY_SAVECOUNT, mClipToBounds);
+                            caster->properties().mAlpha, &(caster->properties().mOutline),
+                            caster->properties().mWidth, caster->properties().mHeight);
+                    handler(shadowOp, PROPERTY_SAVECOUNT, properties().mClipToBounds);
                 }
 
                 lastCasterZ = casterZ; // must do this even if current caster not casting a shadow
@@ -560,26 +458,26 @@
         int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
 
         DrawDisplayListOp* childOp = zTranslatedNodes[drawIndex].value;
-        DisplayList* child = childOp->mDisplayList;
+        RenderNode* child = childOp->mDisplayList;
 
         renderer.concatMatrix(childOp->mTransformFromParent);
         childOp->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone
-        handler(childOp, renderer.getSaveCount() - 1, mClipToBounds);
+        handler(childOp, renderer.getSaveCount() - 1, properties().mClipToBounds);
         childOp->mSkipInOrderDraw = true;
 
         renderer.restoreToCount(restoreTo);
         drawIndex++;
     }
-    handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, mClipToBounds);
+    handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, properties().mClipToBounds);
 }
 
 template <class T>
-void DisplayList::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level) {
+void RenderNode::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level) {
     int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
     LinearAllocator& alloc = handler.allocator();
-    ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, mWidth, mHeight,
+    ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, properties().mWidth, properties().mHeight,
             SkRegion::kReplace_Op); // clip to projection surface root bounds
-    handler(clipOp, PROPERTY_SAVECOUNT, mClipToBounds);
+    handler(clipOp, PROPERTY_SAVECOUNT, properties().mClipToBounds);
 
     for (size_t i = 0; i < mProjectedNodes.size(); i++) {
         DrawDisplayListOp* childOp = mProjectedNodes[i];
@@ -588,11 +486,11 @@
         int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
         renderer.concatMatrix(childOp->mTransformFromCompositingAncestor);
         childOp->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone
-        handler(childOp, renderer.getSaveCount() - 1, mClipToBounds);
+        handler(childOp, renderer.getSaveCount() - 1, properties().mClipToBounds);
         childOp->mSkipInOrderDraw = true;
         renderer.restoreToCount(restoreTo);
     }
-    handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, mClipToBounds);
+    handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, properties().mClipToBounds);
 }
 
 /**
@@ -605,12 +503,12 @@
  * defer vs replay logic, per operation
  */
 template <class T>
-void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level) {
+void RenderNode::iterate(OpenGLRenderer& renderer, T& handler, const int level) {
     if (CC_UNLIKELY(mDestroyed)) { // temporary debug logging
-        ALOGW("Error: %s is drawing after destruction", getName());
+        ALOGW("Error: %s is drawing after destruction", mName.string());
         CRASH();
     }
-    if (mDisplayListData->isEmpty() || mAlpha <= 0) {
+    if (mDisplayListData->isEmpty() || properties().mAlpha <= 0) {
         DISPLAY_LIST_LOGD("%*sEmpty display list (%p, %s)", level * 2, "", this, mName.string());
         return;
     }
@@ -625,14 +523,14 @@
     LinearAllocator& alloc = handler.allocator();
     int restoreTo = renderer.getSaveCount();
     handler(new (alloc) SaveOp(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag),
-            PROPERTY_SAVECOUNT, mClipToBounds);
+            PROPERTY_SAVECOUNT, properties().mClipToBounds);
 
     DISPLAY_LIST_LOGD("%*sSave %d %d", (level + 1) * 2, "",
             SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
 
     setViewProperties<T>(renderer, handler, level + 1);
 
-    bool quickRejected = mClipToBounds && renderer.quickRejectConservative(0, 0, mWidth, mHeight);
+    bool quickRejected = properties().mClipToBounds && renderer.quickRejectConservative(0, 0, properties().mWidth, properties().mHeight);
     if (!quickRejected) {
         Vector<ZDrawDisplayListOpPair> zTranslatedNodes;
         buildZSortedChildList(zTranslatedNodes);
@@ -651,7 +549,7 @@
 #endif
 
             logBuffer.writeCommand(level, op->name());
-            handler(op, saveCountOffset, mClipToBounds);
+            handler(op, saveCountOffset, properties().mClipToBounds);
 
             if (CC_UNLIKELY(i == projectionReceiveIndex && mProjectedNodes.size() > 0)) {
                 iterateProjectedChildren(renderer, handler, level);
@@ -664,7 +562,7 @@
 
     DISPLAY_LIST_LOGD("%*sRestoreToCount %d", (level + 1) * 2, "", restoreTo);
     handler(new (alloc) RestoreToCountOp(restoreTo),
-            PROPERTY_SAVECOUNT, mClipToBounds);
+            PROPERTY_SAVECOUNT, properties().mClipToBounds);
     renderer.setOverrideLayerAlpha(1.0f);
 }
 
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 189b544a..b80c118 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -40,12 +40,7 @@
 #include "Debug.h"
 #include "Matrix.h"
 #include "DeferredDisplayList.h"
-
-#define TRANSLATION 0x0001
-#define ROTATION    0x0002
-#define ROTATION_3D 0x0004
-#define SCALE       0x0008
-#define PIVOT       0x0010
+#include "RenderProperties.h"
 
 class SkBitmap;
 class SkPaint;
@@ -160,17 +155,17 @@
  * recorded stream of canvas operations is refreshed. The DisplayList (and its properties) stay
  * attached.
  */
-class DisplayList {
+class RenderNode {
 public:
-    ANDROID_API DisplayList();
-    ANDROID_API ~DisplayList();
+    ANDROID_API RenderNode();
+    ANDROID_API ~RenderNode();
 
     // See flags defined in DisplayList.java
     enum ReplayFlag {
         kReplayFlag_ClipChildren = 0x1
     };
 
-    ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
+    ANDROID_API static void destroyDisplayListDeferred(RenderNode* displayList);
     ANDROID_API static void outputLogBuffer(int fd);
 
     ANDROID_API void setData(DisplayListData* newData);
@@ -196,355 +191,20 @@
         }
     }
 
-    const char* getName() const {
-        return mName.string();
-    }
-
-    void setClipToBounds(bool clipToBounds) {
-        mClipToBounds = clipToBounds;
-    }
-
-    void setIsolatedZVolume(bool shouldIsolate) {
-        mIsolatedZVolume = shouldIsolate;
-    }
-
-    void setCastsShadow(bool castsShadow) {
-        mCastsShadow = castsShadow;
-    }
-
-    void setUsesGlobalCamera(bool usesGlobalCamera) {
-        mUsesGlobalCamera = usesGlobalCamera;
-    }
-
-    void setProjectBackwards(bool shouldProject) {
-        mProjectBackwards = shouldProject;
-    }
-
-    void setProjectionReceiver(bool shouldRecieve) {
-        mProjectionReceiver = shouldRecieve;
+    RenderProperties& properties() {
+        return mProperties;
     }
 
     bool isProjectionReceiver() {
-        return mProjectionReceiver;
-    }
-
-    void setOutline(const SkPath* outline) {
-        if (!outline) {
-            mOutline.reset();
-        } else {
-            mOutline = *outline;
-        }
-    }
-
-    void setClipToOutline(bool clipToOutline) {
-        mClipToOutline = clipToOutline;
-    }
-
-    void setStaticMatrix(SkMatrix* matrix) {
-        delete mStaticMatrix;
-        mStaticMatrix = new SkMatrix(*matrix);
-    }
-
-    // Can return NULL
-    SkMatrix* getStaticMatrix() {
-        return mStaticMatrix;
-    }
-
-    void setAnimationMatrix(SkMatrix* matrix) {
-        delete mAnimationMatrix;
-        if (matrix) {
-            mAnimationMatrix = new SkMatrix(*matrix);
-        } else {
-            mAnimationMatrix = NULL;
-        }
-    }
-
-    void setAlpha(float alpha) {
-        alpha = fminf(1.0f, fmaxf(0.0f, alpha));
-        if (alpha != mAlpha) {
-            mAlpha = alpha;
-        }
-    }
-
-    float getAlpha() const {
-        return mAlpha;
-    }
-
-    void setHasOverlappingRendering(bool hasOverlappingRendering) {
-        mHasOverlappingRendering = hasOverlappingRendering;
-    }
-
-    bool hasOverlappingRendering() const {
-        return mHasOverlappingRendering;
-    }
-
-    void setTranslationX(float translationX) {
-        if (translationX != mTranslationX) {
-            mTranslationX = translationX;
-            onTranslationUpdate();
-        }
-    }
-
-    float getTranslationX() const {
-        return mTranslationX;
-    }
-
-    void setTranslationY(float translationY) {
-        if (translationY != mTranslationY) {
-            mTranslationY = translationY;
-            onTranslationUpdate();
-        }
-    }
-
-    float getTranslationY() const {
-        return mTranslationY;
-    }
-
-    void setTranslationZ(float translationZ) {
-        if (translationZ != mTranslationZ) {
-            mTranslationZ = translationZ;
-            onTranslationUpdate();
-        }
-    }
-
-    float getTranslationZ() const {
-        return mTranslationZ;
-    }
-
-    void setRotation(float rotation) {
-        if (rotation != mRotation) {
-            mRotation = rotation;
-            mMatrixDirty = true;
-            if (mRotation == 0.0f) {
-                mMatrixFlags &= ~ROTATION;
-            } else {
-                mMatrixFlags |= ROTATION;
-            }
-        }
-    }
-
-    float getRotation() const {
-        return mRotation;
-    }
-
-    void setRotationX(float rotationX) {
-        if (rotationX != mRotationX) {
-            mRotationX = rotationX;
-            mMatrixDirty = true;
-            if (mRotationX == 0.0f && mRotationY == 0.0f) {
-                mMatrixFlags &= ~ROTATION_3D;
-            } else {
-                mMatrixFlags |= ROTATION_3D;
-            }
-        }
-    }
-
-    float getRotationX() const {
-        return mRotationX;
-    }
-
-    void setRotationY(float rotationY) {
-        if (rotationY != mRotationY) {
-            mRotationY = rotationY;
-            mMatrixDirty = true;
-            if (mRotationX == 0.0f && mRotationY == 0.0f) {
-                mMatrixFlags &= ~ROTATION_3D;
-            } else {
-                mMatrixFlags |= ROTATION_3D;
-            }
-        }
-    }
-
-    float getRotationY() const {
-        return mRotationY;
-    }
-
-    void setScaleX(float scaleX) {
-        if (scaleX != mScaleX) {
-            mScaleX = scaleX;
-            mMatrixDirty = true;
-            if (mScaleX == 1.0f && mScaleY == 1.0f) {
-                mMatrixFlags &= ~SCALE;
-            } else {
-                mMatrixFlags |= SCALE;
-            }
-        }
-    }
-
-    float getScaleX() const {
-        return mScaleX;
-    }
-
-    void setScaleY(float scaleY) {
-        if (scaleY != mScaleY) {
-            mScaleY = scaleY;
-            mMatrixDirty = true;
-            if (mScaleX == 1.0f && mScaleY == 1.0f) {
-                mMatrixFlags &= ~SCALE;
-            } else {
-                mMatrixFlags |= SCALE;
-            }
-        }
-    }
-
-    float getScaleY() const {
-        return mScaleY;
-    }
-
-    void setPivotX(float pivotX) {
-        mPivotX = pivotX;
-        mMatrixDirty = true;
-        if (mPivotX == 0.0f && mPivotY == 0.0f) {
-            mMatrixFlags &= ~PIVOT;
-        } else {
-            mMatrixFlags |= PIVOT;
-        }
-        mPivotExplicitlySet = true;
-    }
-
-    ANDROID_API float getPivotX();
-
-    void setPivotY(float pivotY) {
-        mPivotY = pivotY;
-        mMatrixDirty = true;
-        if (mPivotX == 0.0f && mPivotY == 0.0f) {
-            mMatrixFlags &= ~PIVOT;
-        } else {
-            mMatrixFlags |= PIVOT;
-        }
-        mPivotExplicitlySet = true;
-    }
-
-    ANDROID_API float getPivotY();
-
-    void setCameraDistance(float distance) {
-        if (distance != mCameraDistance) {
-            mCameraDistance = distance;
-            mMatrixDirty = true;
-            if (!mTransformCamera) {
-                mTransformCamera = new Sk3DView();
-                mTransformMatrix3D = new SkMatrix();
-            }
-            mTransformCamera->setCameraLocation(0, 0, distance);
-        }
-    }
-
-    float getCameraDistance() const {
-        return mCameraDistance;
-    }
-
-    void setLeft(int left) {
-        if (left != mLeft) {
-            mLeft = left;
-            mWidth = mRight - mLeft;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    float getLeft() const {
-        return mLeft;
-    }
-
-    void setTop(int top) {
-        if (top != mTop) {
-            mTop = top;
-            mHeight = mBottom - mTop;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    float getTop() const {
-        return mTop;
-    }
-
-    void setRight(int right) {
-        if (right != mRight) {
-            mRight = right;
-            mWidth = mRight - mLeft;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    float getRight() const {
-        return mRight;
-    }
-
-    void setBottom(int bottom) {
-        if (bottom != mBottom) {
-            mBottom = bottom;
-            mHeight = mBottom - mTop;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    float getBottom() const {
-        return mBottom;
-    }
-
-    void setLeftTop(int left, int top) {
-        if (left != mLeft || top != mTop) {
-            mLeft = left;
-            mTop = top;
-            mWidth = mRight - mLeft;
-            mHeight = mBottom - mTop;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    void setLeftTopRightBottom(int left, int top, int right, int bottom) {
-        if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
-            mLeft = left;
-            mTop = top;
-            mRight = right;
-            mBottom = bottom;
-            mWidth = mRight - mLeft;
-            mHeight = mBottom - mTop;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    void offsetLeftRight(float offset) {
-        if (offset != 0) {
-            mLeft += offset;
-            mRight += offset;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    void offsetTopBottom(float offset) {
-        if (offset != 0) {
-            mTop += offset;
-            mBottom += offset;
-            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
-                mMatrixDirty = true;
-            }
-        }
-    }
-
-    void setCaching(bool caching) {
-        mCaching = caching;
+        return properties().isProjectionReceiver();
     }
 
     int getWidth() {
-        return mWidth;
+        return properties().getWidth();
     }
 
     int getHeight() {
-        return mHeight;
+        return properties().getHeight();
     }
 
 private:
@@ -562,15 +222,6 @@
         kPositiveZChildren
     };
 
-    void onTranslationUpdate() {
-        mMatrixDirty = true;
-        if (mTranslationX == 0.0f && mTranslationY == 0.0f && mTranslationZ == 0.0f) {
-            mMatrixFlags &= ~TRANSLATION;
-        } else {
-            mMatrixFlags |= TRANSLATION;
-        }
-    }
-
     void outputViewProperties(const int level);
 
     void applyViewPropertyTransforms(mat4& matrix, bool true3dTransform = false);
@@ -594,8 +245,6 @@
     template <class T>
     inline void iterate(OpenGLRenderer& renderer, T& handler, const int level);
 
-    void updateMatrix();
-
     class TextContainer {
     public:
         size_t length() const {
@@ -610,48 +259,11 @@
         const char* mText;
     };
 
-    DisplayListData* mDisplayListData;
-
     String8 mName;
     bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed
 
-    // Rendering properties
-    bool mClipToBounds;
-    bool mIsolatedZVolume;
-    bool mProjectBackwards;
-    bool mProjectionReceiver;
-    SkPath mOutline;
-    bool mClipToOutline;
-    bool mCastsShadow;
-    bool mUsesGlobalCamera; // TODO: respect value when rendering
-    float mAlpha;
-    bool mHasOverlappingRendering;
-    float mTranslationX, mTranslationY, mTranslationZ;
-    float mRotation, mRotationX, mRotationY;
-    float mScaleX, mScaleY;
-    float mPivotX, mPivotY;
-    float mCameraDistance;
-    int mLeft, mTop, mRight, mBottom;
-    int mWidth, mHeight;
-    int mPrevWidth, mPrevHeight;
-    bool mPivotExplicitlySet;
-    bool mMatrixDirty;
-    bool mMatrixIsIdentity;
-
-    /**
-     * Stores the total transformation of the DisplayList based upon its scalar
-     * translate/rotate/scale properties.
-     *
-     * In the common translation-only case, the matrix isn't allocated and the mTranslation
-     * properties are used directly.
-     */
-    Matrix4* mTransformMatrix;
-    uint32_t mMatrixFlags;
-    Sk3DView* mTransformCamera;
-    SkMatrix* mTransformMatrix3D;
-    SkMatrix* mStaticMatrix;
-    SkMatrix* mAnimationMatrix;
-    bool mCaching;
+    RenderProperties mProperties;
+    DisplayListData* mDisplayListData;
 
     /**
      * Draw time state - these properties are only set and used during rendering
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 6ce8317..549b786 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1488,9 +1488,9 @@
 };
 
 class DrawDisplayListOp : public DrawBoundedOp {
-    friend class DisplayList; // grant DisplayList access to info of child
+    friend class RenderNode; // grant DisplayList access to info of child
 public:
-    DrawDisplayListOp(DisplayList* displayList, int flags, const mat4& transformFromParent)
+    DrawDisplayListOp(RenderNode* displayList, int flags, const mat4& transformFromParent)
             : DrawBoundedOp(0, 0, displayList->getWidth(), displayList->getHeight(), 0),
             mDisplayList(displayList), mFlags(flags), mTransformFromParent(transformFromParent) {}
 
@@ -1522,7 +1522,7 @@
     virtual const char* name() { return "DrawDisplayList"; }
 
 private:
-    DisplayList* mDisplayList;
+    RenderNode* mDisplayList;
     const int mFlags;
 
     ///////////////////////////
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 3b1d567..e69e08e 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -179,7 +179,7 @@
     return StatefulBaseRenderer::clipRegion(region, op);
 }
 
-status_t DisplayListRenderer::drawDisplayList(DisplayList* displayList,
+status_t DisplayListRenderer::drawDisplayList(RenderNode* displayList,
         Rect& dirty, int32_t flags) {
     // dirty is an out parameter and should not be recorded,
     // it matters only when replaying the display list
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 1fb72ce..65498a5 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -156,7 +156,7 @@
 // Canvas draw operations - special
 // ----------------------------------------------------------------------------
     virtual status_t drawLayer(Layer* layer, float x, float y);
-    virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty,
+    virtual status_t drawDisplayList(RenderNode* displayList, Rect& dirty,
             int32_t replayFlags);
 
     // TODO: rename for consistency
@@ -309,7 +309,7 @@
 
     int mRestoreSaveCount;
 
-    friend class DisplayList;
+    friend class RenderNode;
 
 }; // class DisplayListRenderer
 
diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp
index 8992a13..52176d4 100644
--- a/libs/hwui/Layer.cpp
+++ b/libs/hwui/Layer.cpp
@@ -194,7 +194,7 @@
     deferredList = new DeferredDisplayList(dirtyRect);
 
     DeferStateStruct deferredState(*deferredList, *renderer,
-            DisplayList::kReplayFlag_ClipChildren);
+            RenderNode::kReplayFlag_ClipChildren);
 
     renderer->initViewport(width, height);
     renderer->setupFrameState(dirtyRect.left, dirtyRect.top,
@@ -238,7 +238,7 @@
     renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
             !isBlend());
 
-    renderer->drawDisplayList(displayList, dirtyRect, DisplayList::kReplayFlag_ClipChildren);
+    renderer->drawDisplayList(displayList, dirtyRect, RenderNode::kReplayFlag_ClipChildren);
 
     renderer->finish();
     renderer = NULL;
diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h
index f6538f2..d8440ea 100644
--- a/libs/hwui/Layer.h
+++ b/libs/hwui/Layer.h
@@ -43,7 +43,7 @@
 // Forward declarations
 class Caches;
 class OpenGLRenderer;
-class DisplayList;
+class RenderNode;
 class DeferredDisplayList;
 class DeferStateStruct;
 
@@ -84,7 +84,7 @@
         regionRect.translate(layer.left, layer.top);
     }
 
-    void updateDeferred(OpenGLRenderer* renderer, DisplayList* displayList,
+    void updateDeferred(OpenGLRenderer* renderer, RenderNode* displayList,
             int left, int top, int right, int bottom) {
         this->renderer = renderer;
         this->displayList = displayList;
@@ -294,7 +294,7 @@
      */
     bool deferredUpdateScheduled;
     OpenGLRenderer* renderer;
-    DisplayList* displayList;
+    RenderNode* displayList;
     Rect dirtyRect;
     bool debugDrawUpdate;
     bool hasDrawnSinceUpdate;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 879b4c7..cb8155b 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1912,7 +1912,7 @@
 // Drawing
 ///////////////////////////////////////////////////////////////////////////////
 
-status_t OpenGLRenderer::drawDisplayList(DisplayList* displayList, Rect& dirty,
+status_t OpenGLRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty,
         int32_t replayFlags) {
     status_t status;
     // All the usual checks and setup operations (quickReject, setupDraw, etc.)
@@ -2414,9 +2414,12 @@
     if (mode == kVertexBufferMode_Standard) {
         mCaches.unbindIndicesBuffer();
         glDrawArrays(GL_TRIANGLE_STRIP, 0, vertexBuffer.getVertexCount());
-    } else {
+    } else if (mode == kVertexBufferMode_OnePolyRingShadow) {
         mCaches.bindShadowIndicesBuffer();
-        glDrawElements(GL_TRIANGLE_STRIP, SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0);
+        glDrawElements(GL_TRIANGLE_STRIP, ONE_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0);
+    } else if (mode == kVertexBufferMode_TwoPolyRingShadow) {
+        mCaches.bindShadowIndicesBuffer();
+        glDrawElements(GL_TRIANGLE_STRIP, TWO_POLY_RING_SHADOW_INDEX_COUNT, GL_UNSIGNED_SHORT, 0);
     }
 
     if (isAA) {
@@ -3245,14 +3248,15 @@
         }
         centroid3d.z += casterLift;
     }
-
+    bool isCasterOpaque = (casterAlpha == 1.0f);
     // draw caster's shadows
     if (mCaches.propertyAmbientShadowStrength > 0) {
         paint.setARGB(casterAlpha * mCaches.propertyAmbientShadowStrength, 0, 0, 0);
         VertexBuffer ambientShadowVertexBuffer;
-        ShadowTessellator::tessellateAmbientShadow(casterPolygon, casterVertexCount,
-                centroid3d, ambientShadowVertexBuffer);
-        drawVertexBuffer(kVertexBufferMode_Shadow, ambientShadowVertexBuffer, &paint);
+        VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateAmbientShadow(
+                isCasterOpaque, casterPolygon, casterVertexCount, centroid3d,
+                ambientShadowVertexBuffer);
+        drawVertexBuffer(vertexBufferMode, ambientShadowVertexBuffer, &paint);
     }
 
     if (mCaches.propertySpotShadowStrength > 0) {
@@ -3260,10 +3264,10 @@
         VertexBuffer spotShadowVertexBuffer;
         Vector3 lightPosScale(mCaches.propertyLightPosXScale,
                 mCaches.propertyLightPosYScale, mCaches.propertyLightPosZScale);
-        ShadowTessellator::tessellateSpotShadow(casterPolygon, casterVertexCount,
-                lightPosScale, *currentTransform(), getWidth(), getHeight(),
-                spotShadowVertexBuffer);
-        drawVertexBuffer(kVertexBufferMode_Shadow, spotShadowVertexBuffer, &paint);
+        VertexBufferMode vertexBufferMode = ShadowTessellator::tessellateSpotShadow(
+                isCasterOpaque, casterPolygon, casterVertexCount, lightPosScale,
+                *currentTransform(), getWidth(), getHeight(), spotShadowVertexBuffer);
+        drawVertexBuffer(vertexBufferMode, spotShadowVertexBuffer, &paint);
     }
 
     return DrawGlInfo::kStatusDrew;
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 76dd014..059c64f 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -54,7 +54,7 @@
 namespace uirenderer {
 
 class DeferredDisplayState;
-class DisplayList;
+class RenderNode;
 class TextSetupFunctor;
 class VertexBuffer;
 class SkiaShader;
@@ -119,7 +119,8 @@
 
 enum VertexBufferMode {
     kVertexBufferMode_Standard = 0,
-    kVertexBufferMode_Shadow = 1
+    kVertexBufferMode_OnePolyRingShadow = 1,
+    kVertexBufferMode_TwoPolyRingShadow = 2
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -165,7 +166,7 @@
     int saveLayerDeferred(float left, float top, float right, float bottom,
             const SkPaint* paint, int flags);
 
-    virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty, int32_t replayFlags = 1);
+    virtual status_t drawDisplayList(RenderNode* displayList, Rect& dirty, int32_t replayFlags = 1);
     virtual status_t drawLayer(Layer* layer, float x, float y);
     virtual status_t drawBitmap(const SkBitmap* bitmap, float left, float top,
             const SkPaint* paint);
diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp
new file mode 100644
index 0000000..233aace
--- /dev/null
+++ b/libs/hwui/RenderProperties.cpp
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+#include "RenderProperties.h"
+
+#include <SkMatrix.h>
+
+#include "Matrix.h"
+
+namespace android {
+namespace uirenderer {
+
+RenderProperties::RenderProperties()
+        : mClipToBounds(true)
+        , mProjectBackwards(false)
+        , mProjectionReceiver(false)
+        , mClipToOutline(false)
+        , mAlpha(1)
+        , mHasOverlappingRendering(true)
+        , mTranslationX(0), mTranslationY(0), mTranslationZ(0)
+        , mRotation(0), mRotationX(0), mRotationY(0)
+        , mScaleX(1), mScaleY(1)
+        , mPivotX(0), mPivotY(0)
+        , mCameraDistance(0)
+        , mLeft(0), mTop(0), mRight(0), mBottom(0)
+        , mWidth(0), mHeight(0)
+        , mPrevWidth(-1), mPrevHeight(-1)
+        , mPivotExplicitlySet(false)
+        , mMatrixDirty(false)
+        , mMatrixIsIdentity(true)
+        , mTransformMatrix(NULL)
+        , mMatrixFlags(0)
+        , mTransformCamera(NULL)
+        , mTransformMatrix3D(NULL)
+        , mStaticMatrix(NULL)
+        , mAnimationMatrix(NULL)
+        , mCaching(false) {
+    mOutline.rewind();
+}
+
+RenderProperties::~RenderProperties() {
+    delete mTransformMatrix;
+    delete mTransformCamera;
+    delete mTransformMatrix3D;
+    delete mStaticMatrix;
+    delete mAnimationMatrix;
+}
+
+float RenderProperties::getPivotX() {
+    updateMatrix();
+    return mPivotX;
+}
+
+float RenderProperties::getPivotY() {
+    updateMatrix();
+    return mPivotY;
+}
+
+void RenderProperties::updateMatrix() {
+    if (mMatrixDirty) {
+        // NOTE: mTransformMatrix won't be up to date if a DisplayList goes from a complex transform
+        // to a pure translate. This is safe because the matrix isn't read in pure translate cases.
+        if (mMatrixFlags && mMatrixFlags != TRANSLATION) {
+            if (!mTransformMatrix) {
+                // only allocate a matrix if we have a complex transform
+                mTransformMatrix = new Matrix4();
+            }
+            if (!mPivotExplicitlySet) {
+                if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
+                    mPrevWidth = mWidth;
+                    mPrevHeight = mHeight;
+                    mPivotX = mPrevWidth / 2.0f;
+                    mPivotY = mPrevHeight / 2.0f;
+                }
+            }
+
+            if ((mMatrixFlags & ROTATION_3D) == 0) {
+                mTransformMatrix->loadTranslate(
+                        mPivotX + mTranslationX,
+                        mPivotY + mTranslationY,
+                        0);
+                mTransformMatrix->rotate(mRotation, 0, 0, 1);
+                mTransformMatrix->scale(mScaleX, mScaleY, 1);
+                mTransformMatrix->translate(-mPivotX, -mPivotY);
+            } else {
+                if (!mTransformCamera) {
+                    mTransformCamera = new Sk3DView();
+                    mTransformMatrix3D = new SkMatrix();
+                }
+                SkMatrix transformMatrix;
+                transformMatrix.reset();
+                mTransformCamera->save();
+                transformMatrix.preScale(mScaleX, mScaleY, mPivotX, mPivotY);
+                mTransformCamera->rotateX(mRotationX);
+                mTransformCamera->rotateY(mRotationY);
+                mTransformCamera->rotateZ(-mRotation);
+                mTransformCamera->getMatrix(mTransformMatrix3D);
+                mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
+                mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
+                        mPivotY + mTranslationY);
+                transformMatrix.postConcat(*mTransformMatrix3D);
+                mTransformCamera->restore();
+
+                mTransformMatrix->load(transformMatrix);
+            }
+        }
+        mMatrixDirty = false;
+    }
+}
+
+} /* namespace uirenderer */
+} /* namespace android */
diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h
new file mode 100644
index 0000000..6e3b8ae
--- /dev/null
+++ b/libs/hwui/RenderProperties.h
@@ -0,0 +1,439 @@
+/*
+ * 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.
+ */
+#ifndef RENDERNODEPROPERTIES_H_
+#define RENDERNODEPROPERTIES_H_
+
+#include <stddef.h>
+#include <cutils/compiler.h>
+#include <androidfw/ResourceTypes.h>
+
+#include <SkCamera.h>
+#include <SkMatrix.h>
+#include <SkPath.h>
+
+#define TRANSLATION 0x0001
+#define ROTATION    0x0002
+#define ROTATION_3D 0x0004
+#define SCALE       0x0008
+#define PIVOT       0x0010
+
+class SkBitmap;
+class SkPaint;
+class SkRegion;
+
+namespace android {
+namespace uirenderer {
+
+class Matrix4;
+class RenderNode;
+
+/*
+ * Data structure that holds the properties for a RenderNode
+ */
+class RenderProperties {
+public:
+    RenderProperties();
+    virtual ~RenderProperties();
+
+    void setClipToBounds(bool clipToBounds) {
+        mClipToBounds = clipToBounds;
+    }
+
+    void setProjectBackwards(bool shouldProject) {
+        mProjectBackwards = shouldProject;
+    }
+
+    void setProjectionReceiver(bool shouldRecieve) {
+        mProjectionReceiver = shouldRecieve;
+    }
+
+    bool isProjectionReceiver() {
+        return mProjectionReceiver;
+    }
+
+    void setOutline(const SkPath* outline) {
+        if (!outline) {
+            mOutline.reset();
+        } else {
+            mOutline = *outline;
+        }
+    }
+
+    void setClipToOutline(bool clipToOutline) {
+        mClipToOutline = clipToOutline;
+    }
+
+    void setStaticMatrix(SkMatrix* matrix) {
+        delete mStaticMatrix;
+        mStaticMatrix = new SkMatrix(*matrix);
+    }
+
+    // Can return NULL
+    SkMatrix* getStaticMatrix() {
+        return mStaticMatrix;
+    }
+
+    void setAnimationMatrix(SkMatrix* matrix) {
+        delete mAnimationMatrix;
+        if (matrix) {
+            mAnimationMatrix = new SkMatrix(*matrix);
+        } else {
+            mAnimationMatrix = NULL;
+        }
+    }
+
+    void setAlpha(float alpha) {
+        alpha = fminf(1.0f, fmaxf(0.0f, alpha));
+        if (alpha != mAlpha) {
+            mAlpha = alpha;
+        }
+    }
+
+    float getAlpha() const {
+        return mAlpha;
+    }
+
+    void setHasOverlappingRendering(bool hasOverlappingRendering) {
+        mHasOverlappingRendering = hasOverlappingRendering;
+    }
+
+    bool hasOverlappingRendering() const {
+        return mHasOverlappingRendering;
+    }
+
+    void setTranslationX(float translationX) {
+        if (translationX != mTranslationX) {
+            mTranslationX = translationX;
+            onTranslationUpdate();
+        }
+    }
+
+    float getTranslationX() const {
+        return mTranslationX;
+    }
+
+    void setTranslationY(float translationY) {
+        if (translationY != mTranslationY) {
+            mTranslationY = translationY;
+            onTranslationUpdate();
+        }
+    }
+
+    float getTranslationY() const {
+        return mTranslationY;
+    }
+
+    void setTranslationZ(float translationZ) {
+        if (translationZ != mTranslationZ) {
+            mTranslationZ = translationZ;
+            onTranslationUpdate();
+        }
+    }
+
+    float getTranslationZ() const {
+        return mTranslationZ;
+    }
+
+    void setRotation(float rotation) {
+        if (rotation != mRotation) {
+            mRotation = rotation;
+            mMatrixDirty = true;
+            if (mRotation == 0.0f) {
+                mMatrixFlags &= ~ROTATION;
+            } else {
+                mMatrixFlags |= ROTATION;
+            }
+        }
+    }
+
+    float getRotation() const {
+        return mRotation;
+    }
+
+    void setRotationX(float rotationX) {
+        if (rotationX != mRotationX) {
+            mRotationX = rotationX;
+            mMatrixDirty = true;
+            if (mRotationX == 0.0f && mRotationY == 0.0f) {
+                mMatrixFlags &= ~ROTATION_3D;
+            } else {
+                mMatrixFlags |= ROTATION_3D;
+            }
+        }
+    }
+
+    float getRotationX() const {
+        return mRotationX;
+    }
+
+    void setRotationY(float rotationY) {
+        if (rotationY != mRotationY) {
+            mRotationY = rotationY;
+            mMatrixDirty = true;
+            if (mRotationX == 0.0f && mRotationY == 0.0f) {
+                mMatrixFlags &= ~ROTATION_3D;
+            } else {
+                mMatrixFlags |= ROTATION_3D;
+            }
+        }
+    }
+
+    float getRotationY() const {
+        return mRotationY;
+    }
+
+    void setScaleX(float scaleX) {
+        if (scaleX != mScaleX) {
+            mScaleX = scaleX;
+            mMatrixDirty = true;
+            if (mScaleX == 1.0f && mScaleY == 1.0f) {
+                mMatrixFlags &= ~SCALE;
+            } else {
+                mMatrixFlags |= SCALE;
+            }
+        }
+    }
+
+    float getScaleX() const {
+        return mScaleX;
+    }
+
+    void setScaleY(float scaleY) {
+        if (scaleY != mScaleY) {
+            mScaleY = scaleY;
+            mMatrixDirty = true;
+            if (mScaleX == 1.0f && mScaleY == 1.0f) {
+                mMatrixFlags &= ~SCALE;
+            } else {
+                mMatrixFlags |= SCALE;
+            }
+        }
+    }
+
+    float getScaleY() const {
+        return mScaleY;
+    }
+
+    void setPivotX(float pivotX) {
+        mPivotX = pivotX;
+        mMatrixDirty = true;
+        if (mPivotX == 0.0f && mPivotY == 0.0f) {
+            mMatrixFlags &= ~PIVOT;
+        } else {
+            mMatrixFlags |= PIVOT;
+        }
+        mPivotExplicitlySet = true;
+    }
+
+    ANDROID_API float getPivotX();
+
+    void setPivotY(float pivotY) {
+        mPivotY = pivotY;
+        mMatrixDirty = true;
+        if (mPivotX == 0.0f && mPivotY == 0.0f) {
+            mMatrixFlags &= ~PIVOT;
+        } else {
+            mMatrixFlags |= PIVOT;
+        }
+        mPivotExplicitlySet = true;
+    }
+
+    ANDROID_API float getPivotY();
+
+    void setCameraDistance(float distance) {
+        if (distance != mCameraDistance) {
+            mCameraDistance = distance;
+            mMatrixDirty = true;
+            if (!mTransformCamera) {
+                mTransformCamera = new Sk3DView();
+                mTransformMatrix3D = new SkMatrix();
+            }
+            mTransformCamera->setCameraLocation(0, 0, distance);
+        }
+    }
+
+    float getCameraDistance() const {
+        return mCameraDistance;
+    }
+
+    void setLeft(int left) {
+        if (left != mLeft) {
+            mLeft = left;
+            mWidth = mRight - mLeft;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    float getLeft() const {
+        return mLeft;
+    }
+
+    void setTop(int top) {
+        if (top != mTop) {
+            mTop = top;
+            mHeight = mBottom - mTop;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    float getTop() const {
+        return mTop;
+    }
+
+    void setRight(int right) {
+        if (right != mRight) {
+            mRight = right;
+            mWidth = mRight - mLeft;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    float getRight() const {
+        return mRight;
+    }
+
+    void setBottom(int bottom) {
+        if (bottom != mBottom) {
+            mBottom = bottom;
+            mHeight = mBottom - mTop;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    float getBottom() const {
+        return mBottom;
+    }
+
+    void setLeftTop(int left, int top) {
+        if (left != mLeft || top != mTop) {
+            mLeft = left;
+            mTop = top;
+            mWidth = mRight - mLeft;
+            mHeight = mBottom - mTop;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    void setLeftTopRightBottom(int left, int top, int right, int bottom) {
+        if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
+            mLeft = left;
+            mTop = top;
+            mRight = right;
+            mBottom = bottom;
+            mWidth = mRight - mLeft;
+            mHeight = mBottom - mTop;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    void offsetLeftRight(float offset) {
+        if (offset != 0) {
+            mLeft += offset;
+            mRight += offset;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    void offsetTopBottom(float offset) {
+        if (offset != 0) {
+            mTop += offset;
+            mBottom += offset;
+            if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+                mMatrixDirty = true;
+            }
+        }
+    }
+
+    void setCaching(bool caching) {
+        mCaching = caching;
+    }
+
+    int getWidth() {
+        return mWidth;
+    }
+
+    int getHeight() {
+        return mHeight;
+    }
+
+private:
+    void onTranslationUpdate() {
+        mMatrixDirty = true;
+        if (mTranslationX == 0.0f && mTranslationY == 0.0f && mTranslationZ == 0.0f) {
+            mMatrixFlags &= ~TRANSLATION;
+        } else {
+            mMatrixFlags |= TRANSLATION;
+        }
+    }
+
+    void updateMatrix();
+
+    // Rendering properties
+    bool mClipToBounds;
+    bool mProjectBackwards;
+    bool mProjectionReceiver;
+    SkPath mOutline;
+    bool mClipToOutline;
+    float mAlpha;
+    bool mHasOverlappingRendering;
+    float mTranslationX, mTranslationY, mTranslationZ;
+    float mRotation, mRotationX, mRotationY;
+    float mScaleX, mScaleY;
+    float mPivotX, mPivotY;
+    float mCameraDistance;
+    int mLeft, mTop, mRight, mBottom;
+    int mWidth, mHeight;
+    int mPrevWidth, mPrevHeight;
+    bool mPivotExplicitlySet;
+    bool mMatrixDirty;
+    bool mMatrixIsIdentity;
+
+    /**
+     * Stores the total transformation of the DisplayList based upon its scalar
+     * translate/rotate/scale properties.
+     *
+     * In the common translation-only case, the matrix isn't allocated and the mTranslation
+     * properties are used directly.
+     */
+    Matrix4* mTransformMatrix;
+    uint32_t mMatrixFlags;
+    Sk3DView* mTransformCamera;
+    SkMatrix* mTransformMatrix3D;
+    SkMatrix* mStaticMatrix;
+    SkMatrix* mAnimationMatrix;
+    bool mCaching;
+
+    friend class RenderNode;
+};
+
+} /* namespace uirenderer */
+} /* namespace android */
+
+#endif /* RENDERNODEPROPERTIES_H_ */
diff --git a/libs/hwui/Renderer.h b/libs/hwui/Renderer.h
index 4754bad..efcea5f 100644
--- a/libs/hwui/Renderer.h
+++ b/libs/hwui/Renderer.h
@@ -31,7 +31,7 @@
 
 namespace uirenderer {
 
-class DisplayList;
+class RenderNode;
 class Layer;
 class Matrix4;
 class SkiaColorFilter;
@@ -232,7 +232,7 @@
 // Canvas draw operations - special
 // ----------------------------------------------------------------------------
     virtual status_t drawLayer(Layer* layer, float x, float y) = 0;
-    virtual status_t drawDisplayList(DisplayList* displayList, Rect& dirty,
+    virtual status_t drawDisplayList(RenderNode* displayList, Rect& dirty,
             int32_t replayFlags) = 0;
 
     // TODO: rename for consistency
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index f138222..771904a 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -33,9 +33,9 @@
     return a > b ? a : b;
 }
 
-void ShadowTessellator::tessellateAmbientShadow(const Vector3* casterPolygon,
-        int casterVertexCount, const Vector3& centroid3d,
-        VertexBuffer& shadowVertexBuffer) {
+VertexBufferMode ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque,
+        const Vector3* casterPolygon, int casterVertexCount,
+        const Vector3& centroid3d, VertexBuffer& shadowVertexBuffer) {
     ATRACE_CALL();
 
     // A bunch of parameters to tweak the shadow.
@@ -43,12 +43,14 @@
     const float heightFactor = 1.0f / 128;
     const float geomFactor = 64;
 
-    AmbientShadow::createAmbientShadow(casterPolygon, casterVertexCount,
-            centroid3d, heightFactor, geomFactor, shadowVertexBuffer);
+    return AmbientShadow::createAmbientShadow(isCasterOpaque, casterPolygon,
+            casterVertexCount, centroid3d, heightFactor, geomFactor,
+            shadowVertexBuffer);
 
 }
 
-void ShadowTessellator::tessellateSpotShadow(const Vector3* casterPolygon, int casterVertexCount,
+VertexBufferMode ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque,
+        const Vector3* casterPolygon, int casterVertexCount,
         const Vector3& lightPosScale, const mat4& receiverTransform,
         int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer) {
     ATRACE_CALL();
@@ -71,37 +73,40 @@
     const float lightSize = maximal / 4;
     const int lightVertexCount = 8;
 
-    SpotShadow::createSpotShadow(casterPolygon, casterVertexCount, lightCenter,
-            lightSize, lightVertexCount, shadowVertexBuffer);
+    VertexBufferMode mode = SpotShadow::createSpotShadow(isCasterOpaque,
+            casterPolygon, casterVertexCount, lightCenter, lightSize,
+            lightVertexCount, shadowVertexBuffer);
 
+#if DEBUG_SHADOW
+     if(shadowVertexBuffer.getVertexCount() <= 0) {
+        ALOGD("Spot shadow generation failed %d", shadowVertexBuffer.getVertexCount());
+     }
+#endif
+     return mode;
 }
 
 void ShadowTessellator::generateShadowIndices(uint16_t* shadowIndices) {
     int currentIndex = 0;
     const int rays = SHADOW_RAY_COUNT;
     // For the penumbra area.
-    for (int i = 0; i < rays; i++) {
-        shadowIndices[currentIndex++] = i;
-        shadowIndices[currentIndex++] = rays + i;
+    for (int layer = 0; layer < 2; layer ++) {
+        int baseIndex = layer * rays;
+        for (int i = 0; i < rays; i++) {
+            shadowIndices[currentIndex++] = i + baseIndex;
+            shadowIndices[currentIndex++] = rays + i + baseIndex;
+        }
+        // To close the loop, back to the ray 0.
+        shadowIndices[currentIndex++] = 0 + baseIndex;
+         // Note this is the same as the first index of next layer loop.
+        shadowIndices[currentIndex++] = rays + baseIndex;
     }
-    // To close the loop, back to the ray 0.
-    shadowIndices[currentIndex++] = 0;
-    shadowIndices[currentIndex++] = rays;
-
-    uint16_t centroidIndex = 2 * rays;
-    // For the umbra area, using strips to simulate the fans.
-    for (int i = 0; i < rays; i++) {
-        shadowIndices[currentIndex++] = rays + i;
-        shadowIndices[currentIndex++] = centroidIndex;
-    }
-    shadowIndices[currentIndex++] = rays;
 
 #if DEBUG_SHADOW
-    if (currentIndex != SHADOW_INDEX_COUNT) {
-        ALOGE("vertex index count is wrong. current %d, expected %d",
-                currentIndex, SHADOW_INDEX_COUNT);
+    if (currentIndex != MAX_SHADOW_INDEX_COUNT) {
+        ALOGW("vertex index count is wrong. current %d, expected %d",
+                currentIndex, MAX_SHADOW_INDEX_COUNT);
     }
-    for (int i = 0; i < SHADOW_INDEX_COUNT; i++) {
+    for (int i = 0; i < MAX_SHADOW_INDEX_COUNT; i++) {
         ALOGD("vertex index is (%d, %d)", i, shadowIndices[i]);
     }
 #endif
@@ -135,7 +140,7 @@
     if (area != 0) {
         centroid = Vector2(sumx / (3 * area), sumy / (3 * area));
     } else {
-        ALOGE("Area is 0 while computing centroid!");
+        ALOGW("Area is 0 while computing centroid!");
     }
     return centroid;
 }
diff --git a/libs/hwui/ShadowTessellator.h b/libs/hwui/ShadowTessellator.h
index c558460..ab039fa 100644
--- a/libs/hwui/ShadowTessellator.h
+++ b/libs/hwui/ShadowTessellator.h
@@ -20,6 +20,7 @@
 
 #include "Debug.h"
 #include "Matrix.h"
+#include "OpenGLRenderer.h"
 #include "VertexBuffer.h"
 
 namespace android {
@@ -30,15 +31,14 @@
 // Assuming we use 6 rays and only 1 layer, Then we will have 2 hexagons, which
 // are 0 to 5 and 6 to 11. The area between them will be the penumbra area, and
 // the area inside the 2nd hexagon is the umbra.
-// Also, we need to add the centroid "12" to draw the umbra area as triangle fans.
-//
+// Ambient shadow is using only 1 layer for opaque caster, otherwise, spot
+// shadow and ambient shadow are using 2 layers.
 // Triange strip indices for penumbra area: (0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 0, 6)
-// Triange strip indices for numbra area: (6, 12, 7, 12, 8, 12, 9, 12, 10, 12, 11, 12, 6)
 //                 0
 //
 //      5          6         1
 //           11         7
-//                12
+//
 //           10         8
 //      4          9         2
 //
@@ -49,20 +49,27 @@
 #define SHADOW_RAY_COUNT 128
 
 // The total number of all the vertices representing the shadow.
-#define SHADOW_VERTEX_COUNT (2 * SHADOW_RAY_COUNT + 1)
+// For the case we only have 1 layer, then we will just fill only 2/3 of it.
+#define SHADOW_VERTEX_COUNT (3 * SHADOW_RAY_COUNT)
 
 // The total number of indices used for drawing the shadow geometry as triangle strips.
-#define SHADOW_INDEX_COUNT (2 * SHADOW_RAY_COUNT + 1 + 2 * (SHADOW_RAY_COUNT + 1))
+// Depending on the mode we are drawing, we can have 1 layer or 2 layers.
+// Therefore, we only build the longer index buffer.
+#define TWO_POLY_RING_SHADOW_INDEX_COUNT (4 * (SHADOW_RAY_COUNT + 1))
+#define ONE_POLY_RING_SHADOW_INDEX_COUNT (2 * (SHADOW_RAY_COUNT + 1))
+
+#define MAX_SHADOW_INDEX_COUNT TWO_POLY_RING_SHADOW_INDEX_COUNT
 
 #define SHADOW_MIN_CASTER_Z 0.001f
 
 class ShadowTessellator {
 public:
-    static void tessellateAmbientShadow(const Vector3* casterPolygon,
-            int casterVertexCount, const Vector3& centroid3d,
-            VertexBuffer& shadowVertexBuffer);
+    static VertexBufferMode tessellateAmbientShadow(bool isCasterOpaque,
+            const Vector3* casterPolygon, int casterVertexCount,
+            const Vector3& centroid3d, VertexBuffer& shadowVertexBuffer);
 
-    static void tessellateSpotShadow(const Vector3* casterPolygon, int casterVertexCount,
+    static VertexBufferMode tessellateSpotShadow(bool isCasterOpaque,
+            const Vector3* casterPolygon, int casterVertexCount,
             const Vector3& lightPosScale, const mat4& receiverTransform,
             int screenWidth, int screenHeight, VertexBuffer& shadowVertexBuffer);
 
diff --git a/libs/hwui/SpotShadow.cpp b/libs/hwui/SpotShadow.cpp
index 8538b29..f81cd12 100644
--- a/libs/hwui/SpotShadow.cpp
+++ b/libs/hwui/SpotShadow.cpp
@@ -62,7 +62,9 @@
 
 #if DEBUG_SHADOW
     double interpVal = (dx * (p1.y - rayOrigin.y) + dy * rayOrigin.x - dy * p1.x) / divisor;
-    if (interpVal < 0 || interpVal > 1) return -1.0f; // error, doesn't intersect between points
+    if (interpVal < 0 || interpVal > 1) {
+        ALOGW("rayIntersectPoints is hitting outside the segment %f", interpVal);
+    }
 #endif
 
     double distance = (p1.x * (rayOrigin.y - p2.y) + p2.x * (p1.y - rayOrigin.y) +
@@ -161,7 +163,7 @@
 
 /**
  * Calculates the intersection of poly1 with poly2 and put in poly2.
- *
+ * Note that both poly1 and poly2 must be in CW order already!
  *
  * @param poly1 The 1st polygon, as a Vector2 array.
  * @param poly1Length The number of vertices of 1st polygon.
@@ -169,11 +171,16 @@
  * @param poly2Length The number of vertices of 2nd polygon.
  * @return number of vertices in output polygon as poly2.
  */
-int SpotShadow::intersection(Vector2* poly1, int poly1Length,
+int SpotShadow::intersection(const Vector2* poly1, int poly1Length,
         Vector2* poly2, int poly2Length) {
-    makeClockwise(poly1, poly1Length);
-    makeClockwise(poly2, poly2Length);
-
+#if DEBUG_SHADOW
+    if (!isClockwise(poly1, poly1Length)) {
+        ALOGW("Poly1 is not clockwise! Intersection is wrong!");
+    }
+    if (!isClockwise(poly2, poly2Length)) {
+        ALOGW("Poly2 is not clockwise! Intersection is wrong!");
+    }
+#endif
     Vector2 poly[poly1Length * poly2Length + 2];
     int count = 0;
     int pcount = 0;
@@ -411,7 +418,7 @@
  * @param polygon the polygon as a Vector2 array
  * @param len the number of points of the polygon
  */
-bool SpotShadow::isClockwise(Vector2* polygon, int len) {
+bool SpotShadow::isClockwise(const Vector2* polygon, int len) {
     double sum = 0;
     double p1x = polygon[len - 1].x;
     double p1y = polygon[len - 1].y;
@@ -514,13 +521,14 @@
 *                            empty strip if error.
 *
 */
-void SpotShadow::createSpotShadow(const Vector3* poly, int polyLength,
-        const Vector3& lightCenter, float lightSize, int lightVertexCount,
-        VertexBuffer& retStrips) {
+VertexBufferMode SpotShadow::createSpotShadow(bool isCasterOpaque, const Vector3* poly,
+        int polyLength, const Vector3& lightCenter, float lightSize,
+        int lightVertexCount, VertexBuffer& retStrips) {
     Vector3 light[lightVertexCount * 3];
     computeLightPolygon(lightVertexCount, lightCenter, lightSize, light);
-    computeSpotShadow(light, lightVertexCount, lightCenter, poly, polyLength,
-            retStrips);
+    computeSpotShadow(isCasterOpaque, light, lightVertexCount, lightCenter, poly,
+            polyLength, retStrips);
+    return kVertexBufferMode_TwoPolyRingShadow;
 }
 
 /**
@@ -533,9 +541,9 @@
  * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
  *                            empty strip if error.
  */
-void SpotShadow::computeSpotShadow(const Vector3* lightPoly, int lightPolyLength,
-        const Vector3& lightCenter, const Vector3* poly, int polyLength,
-        VertexBuffer& shadowTriangleStrip) {
+void SpotShadow::computeSpotShadow(bool isCasterOpaque, const Vector3* lightPoly,
+        int lightPolyLength, const Vector3& lightCenter, const Vector3* poly,
+        int polyLength, VertexBuffer& shadowTriangleStrip) {
     // Point clouds for all the shadowed vertices
     Vector2 shadowRegion[lightPolyLength * polyLength];
     // Shadow polygon from one point light.
@@ -565,13 +573,13 @@
     for (int j = 0; j < lightPolyLength; j++) {
         int m = 0;
         for (int i = 0; i < polyLength; i++) {
-            float t = lightPoly[j].z - poly[i].z;
-            if (t == 0) {
+            float deltaZ = lightPoly[j].z - poly[i].z;
+            if (deltaZ == 0) {
                 return;
             }
-            t = lightPoly[j].z / t;
-            float x = lightPoly[j].x - t * (lightPoly[j].x - poly[i].x);
-            float y = lightPoly[j].y - t * (lightPoly[j].y - poly[i].y);
+            float ratioZ = lightPoly[j].z / deltaZ;
+            float x = lightPoly[j].x - ratioZ * (lightPoly[j].x - poly[i].x);
+            float y = lightPoly[j].y - ratioZ * (lightPoly[j].y - poly[i].y);
 
             Vector2 newPoint = Vector2(x, y);
             shadowRegion[k] = newPoint;
@@ -606,13 +614,13 @@
     if (umbraLength < 3) {
         // If there is no real umbra, make a fake one.
         for (int i = 0; i < polyLength; i++) {
-            float t = lightCenter.z - poly[i].z;
-            if (t == 0) {
+            float deltaZ = lightCenter.z - poly[i].z;
+            if (deltaZ == 0) {
                 return;
             }
-            t = lightCenter.z / t;
-            float x = lightCenter.x - t * (lightCenter.x - poly[i].x);
-            float y = lightCenter.y - t * (lightCenter.y - poly[i].y);
+            float ratioZ = lightCenter.z / deltaZ;
+            float x = lightCenter.x - ratioZ * (lightCenter.x - poly[i].x);
+            float y = lightCenter.y - ratioZ * (lightCenter.y - poly[i].y);
 
             fakeUmbra[i].x = x;
             fakeUmbra[i].y = y;
@@ -635,8 +643,8 @@
         umbraLength = polyLength;
     }
 
-    generateTriangleStrip(penumbra, penumbraLength, umbra, umbraLength,
-            shadowTriangleStrip);
+    generateTriangleStrip(isCasterOpaque, penumbra, penumbraLength, umbra,
+            umbraLength, poly, polyLength, shadowTriangleStrip);
 }
 
 /**
@@ -684,7 +692,12 @@
                     cos(rayIndex * step),
                     sin(rayIndex * step),
                     *lastVertex, poly[polyIndex]);
-            if (distanceToIntersect < 0) return false; // error case, abort
+            if (distanceToIntersect < 0) {
+#if DEBUG_SHADOW
+                ALOGW("ERROR: convertPolyToRayDist failed");
+#endif
+                return false; // error case, abort
+            }
 
             rayDist[rayIndex] = distanceToIntersect;
 
@@ -696,6 +709,22 @@
    return true;
 }
 
+int SpotShadow::calculateOccludedUmbra(const Vector2* umbra, int umbraLength,
+        const Vector3* poly, int polyLength, Vector2* occludedUmbra) {
+    // Occluded umbra area is computed as the intersection of the projected 2D
+    // poly and umbra.
+    for (int i = 0; i < polyLength; i++) {
+        occludedUmbra[i].x = poly[i].x;
+        occludedUmbra[i].y = poly[i].y;
+    }
+
+    // Both umbra and incoming polygon are guaranteed to be CW, so we can call
+    // intersection() directly.
+    return intersection(umbra, umbraLength,
+            occludedUmbra, polyLength);
+}
+
+#define OCLLUDED_UMBRA_SHRINK_FACTOR 0.95f
 /**
  * Generate a triangle strip given two convex polygons
  *
@@ -706,10 +735,10 @@
  * @param shadowTriangleStrip return an (x,y,alpha) triangle strip representing the shadow. Return
  *                            empty strip if error.
 **/
-void SpotShadow::generateTriangleStrip(const Vector2* penumbra, int penumbraLength,
-        const Vector2* umbra, int umbraLength, VertexBuffer& shadowTriangleStrip) {
+void SpotShadow::generateTriangleStrip(bool isCasterOpaque, const Vector2* penumbra,
+        int penumbraLength, const Vector2* umbra, int umbraLength,
+        const Vector3* poly, int polyLength, VertexBuffer& shadowTriangleStrip) {
     const int rays = SHADOW_RAY_COUNT;
-
     const int size = 2 * rays;
     const float step = M_PI * 2 / rays;
     // Centroid of the umbra.
@@ -721,37 +750,66 @@
     float penumbraDistPerRay[rays];
     // Intersection to the umbra.
     float umbraDistPerRay[rays];
+    // Intersection to the occluded umbra area.
+    float occludedUmbraDistPerRay[rays];
 
     // convert CW polygons to ray distance encoding, aborting on conversion failure
     if (!convertPolyToRayDist(umbra, umbraLength, centroid, umbraDistPerRay)) return;
     if (!convertPolyToRayDist(penumbra, penumbraLength, centroid, penumbraDistPerRay)) return;
 
-    AlphaVertex* shadowVertices = shadowTriangleStrip.alloc<AlphaVertex>(getStripSize(rays));
+    bool hasOccludedUmbraArea = false;
+    if (isCasterOpaque) {
+        Vector2 occludedUmbra[polyLength + umbraLength];
+        int occludedUmbraLength = calculateOccludedUmbra(umbra, umbraLength, poly, polyLength,
+                occludedUmbra);
+        // Make sure the centroid is inside the umbra, otherwise, fall back to the
+        // approach as if there is no occluded umbra area.
+        if (testPointInsidePolygon(centroid, occludedUmbra, occludedUmbraLength)) {
+            hasOccludedUmbraArea = true;
+            // Shrink the occluded umbra area to avoid pixel level artifacts.
+            for (int i = 0; i < occludedUmbraLength; i ++) {
+                occludedUmbra[i] = centroid + (occludedUmbra[i] - centroid) *
+                        OCLLUDED_UMBRA_SHRINK_FACTOR;
+            }
+            if (!convertPolyToRayDist(occludedUmbra, occludedUmbraLength, centroid,
+                    occludedUmbraDistPerRay)) {
+                return;
+            }
+        }
+    }
+
+    AlphaVertex* shadowVertices =
+            shadowTriangleStrip.alloc<AlphaVertex>(SHADOW_VERTEX_COUNT);
 
     // Calculate the vertices (x, y, alpha) in the shadow area.
+    AlphaVertex centroidXYA;
+    AlphaVertex::set(&centroidXYA, centroid.x, centroid.y, 1.0f);
     for (int rayIndex = 0; rayIndex < rays; rayIndex++) {
         float dx = cosf(step * rayIndex);
         float dy = sinf(step * rayIndex);
 
-        // outer ring
-        float currentDist = penumbraDistPerRay[rayIndex];
+        // penumbra ring
+        float penumbraDistance = penumbraDistPerRay[rayIndex];
         AlphaVertex::set(&shadowVertices[rayIndex],
-                dx * currentDist + centroid.x, dy * currentDist + centroid.y, 0.0f);
+                dx * penumbraDistance + centroid.x,
+                dy * penumbraDistance + centroid.y, 0.0f);
 
-        // inner ring
-        float deltaDist = umbraDistPerRay[rayIndex] - penumbraDistPerRay[rayIndex];
-        currentDist += deltaDist;
+        // umbra ring
+        float umbraDistance = umbraDistPerRay[rayIndex];
         AlphaVertex::set(&shadowVertices[rays + rayIndex],
-                dx * currentDist + centroid.x, dy * currentDist + centroid.y, 1.0f);
+                dx * umbraDistance + centroid.x, dy * umbraDistance + centroid.y, 1.0f);
+
+        // occluded umbra ring
+        if (hasOccludedUmbraArea) {
+            float occludedUmbraDistance = occludedUmbraDistPerRay[rayIndex];
+            AlphaVertex::set(&shadowVertices[2 * rays + rayIndex],
+                    dx * occludedUmbraDistance + centroid.x,
+                    dy * occludedUmbraDistance + centroid.y, 1.0f);
+        } else {
+            // Put all vertices of the occluded umbra ring at the centroid.
+            shadowVertices[2 * rays + rayIndex] = centroidXYA;
+        }
     }
-    // The centroid is in the umbra area, so the opacity is considered as 1.0.
-    AlphaVertex::set(&shadowVertices[SHADOW_VERTEX_COUNT - 1], centroid.x, centroid.y, 1.0f);
-#if DEBUG_SHADOW
-    for (int i = 0; i < currentIndex; i++) {
-        ALOGD("spot shadow value: i %d, (x:%f, y:%f, a:%f)", i, shadowVertices[i].x,
-                shadowVertices[i].y, shadowVertices[i].alpha);
-    }
-#endif
 }
 
 /**
@@ -775,17 +833,6 @@
     }
 }
 
-/**
- * Calculate the number of vertex we will create given a number of rays and layers
- *
- * @param rays number of points around the polygons you want
- * @param layers number of layers of triangle strips you need
- * @return number of vertex (multiply by 3 for number of floats)
- */
-int SpotShadow::getStripSize(int rays) {
-    return  (2 + rays + (2 * (rays + 1)));
-}
-
 #if DEBUG_SHADOW
 
 #define TEST_POINT_NUMBER 128
@@ -837,7 +884,7 @@
         bool isCCWOrCoLinear = (delta >= EPSILON);
 
         if (isCCWOrCoLinear) {
-            ALOGE("(Error Type 2): polygon (%s) is not a convex b/c start (x %f, y %f),"
+            ALOGW("(Error Type 2): polygon (%s) is not a convex b/c start (x %f, y %f),"
                     "middle (x %f, y %f) and end (x %f, y %f) , delta is %f !!!",
                     name, start.x, start.y, middle.x, middle.y, end.x, end.y, delta);
             isConvex = false;
@@ -879,14 +926,14 @@
         if (testPointInsidePolygon(testPoint, intersection, intersectionLength)) {
             if (!testPointInsidePolygon(testPoint, poly1, poly1Length)) {
                 dumpPoly = true;
-                ALOGE("(Error Type 1): one point (%f, %f) in the intersection is"
+                ALOGW("(Error Type 1): one point (%f, %f) in the intersection is"
                       " not in the poly1",
                         testPoint.x, testPoint.y);
             }
 
             if (!testPointInsidePolygon(testPoint, poly2, poly2Length)) {
                 dumpPoly = true;
-                ALOGE("(Error Type 1): one point (%f, %f) in the intersection is"
+                ALOGW("(Error Type 1): one point (%f, %f) in the intersection is"
                       " not in the poly2",
                         testPoint.x, testPoint.y);
             }
diff --git a/libs/hwui/SpotShadow.h b/libs/hwui/SpotShadow.h
index 7839dc3..599d37e 100644
--- a/libs/hwui/SpotShadow.h
+++ b/libs/hwui/SpotShadow.h
@@ -26,19 +26,20 @@
 
 class SpotShadow {
 public:
-    static void createSpotShadow(const Vector3* poly, int polyLength,
-            const Vector3& lightCenter, float lightSize, int lightVertexCount,
-            VertexBuffer& retStrips);
+    static VertexBufferMode createSpotShadow(bool isCasterOpaque, const Vector3* poly,
+            int polyLength, const Vector3& lightCenter, float lightSize,
+            int lightVertexCount, VertexBuffer& retStrips);
 
 private:
-    static void computeSpotShadow(const Vector3* lightPoly, int lightPolyLength,
-            const Vector3& lightCenter, const Vector3* poly, int polyLength,
-            VertexBuffer& retstrips);
+    static int calculateOccludedUmbra(const Vector2* umbra, int umbraLength,
+            const Vector3* poly, int polyLength, Vector2* occludedUmbra);
+    static void computeSpotShadow(bool isCasterOpaque, const Vector3* lightPoly,
+            int lightPolyLength, const Vector3& lightCenter, const Vector3* poly,
+            int polyLength, VertexBuffer& retstrips);
 
     static void computeLightPolygon(int points, const Vector3& lightCenter,
             float size, Vector3* ret);
 
-    static int  getStripSize(int rays);
     static void smoothPolygon(int level, int rays, float* rayDist);
     static float rayIntersectPoly(const Vector2* poly, int polyLength,
             const Vector2& point, float dx, float dy);
@@ -46,7 +47,7 @@
     static void xsort(Vector2* points, int pointsLength);
     static int hull(Vector2* points, int pointsLength, Vector2* retPoly);
     static bool ccw(double ax, double ay, double bx, double by, double cx, double cy);
-    static int intersection(Vector2* poly1, int poly1length, Vector2* poly2, int poly2length);
+    static int intersection(const Vector2* poly1, int poly1length, Vector2* poly2, int poly2length);
     static void sort(Vector2* poly, int polyLength, const Vector2& center);
 
     static void swap(Vector2* points, int i, int j);
@@ -55,13 +56,14 @@
 
     static bool testPointInsidePolygon(const Vector2 testPoint, const Vector2* poly, int len);
     static void makeClockwise(Vector2* polygon, int len);
-    static bool isClockwise(Vector2* polygon, int len);
+    static bool isClockwise(const Vector2* polygon, int len);
     static void reverse(Vector2* polygon, int len);
     static inline bool lineIntersection(double x1, double y1, double x2, double y2,
             double x3, double y3, double x4, double y4, Vector2& ret);
 
-    static void generateTriangleStrip(const Vector2* penumbra, int penumbraLength,
-            const Vector2* umbra, int umbraLength, VertexBuffer& retstrips);
+    static void generateTriangleStrip(bool isCasterOpaque, const Vector2* penumbra,
+            int penumbraLength, const Vector2* umbra, int umbraLength,
+            const Vector3* poly, int polyLength, VertexBuffer& retstrips);
 
 #if DEBUG_SHADOW
     // Verification utility function.
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index ce66d8f..8ebffc2 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -373,7 +373,7 @@
     mCanvas->setViewport(width, height);
 }
 
-void CanvasContext::setDisplayListData(DisplayList* displayList, DisplayListData* newData) {
+void CanvasContext::setDisplayListData(RenderNode* displayList, DisplayListData* newData) {
     displayList->setData(newData);
 }
 
@@ -388,7 +388,7 @@
     }
 }
 
-void CanvasContext::drawDisplayList(DisplayList* displayList, Rect* dirty) {
+void CanvasContext::drawDisplayList(RenderNode* displayList, Rect* dirty) {
     LOG_ALWAYS_FATAL_IF(!mCanvas || mEglSurface == EGL_NO_SURFACE,
             "drawDisplayList called on a context with no canvas or surface!");
 
@@ -469,6 +469,7 @@
 void CanvasContext::removeFunctorsTask() {
     if (!mInvokeFunctorsPending) return;
 
+    mInvokeFunctorsPending = false;
     mRenderThread.remove(&mInvokeFunctorsTask);
 }
 
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 649ffb6..e3fdf97 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -31,7 +31,7 @@
 namespace uirenderer {
 
 class DeferredLayerUpdater;
-class DisplayList;
+class RenderNode;
 class DisplayListData;
 class OpenGLRenderer;
 class Rect;
@@ -63,9 +63,9 @@
     bool initialize(EGLNativeWindowType window);
     void updateSurface(EGLNativeWindowType window);
     void setup(int width, int height);
-    void setDisplayListData(DisplayList* displayList, DisplayListData* newData);
+    void setDisplayListData(RenderNode* displayList, DisplayListData* newData);
     void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters);
-    void drawDisplayList(DisplayList* displayList, Rect* dirty);
+    void drawDisplayList(RenderNode* displayList, Rect* dirty);
     void destroyCanvas();
 
     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 200c21f..93360fc 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -117,13 +117,13 @@
     post(task);
 }
 
-CREATE_BRIDGE3(setDisplayListData, CanvasContext* context, DisplayList* displayList,
+CREATE_BRIDGE3(setDisplayListData, CanvasContext* context, RenderNode* displayList,
         DisplayListData* newData) {
     args->context->setDisplayListData(args->displayList, args->newData);
     return NULL;
 }
 
-void RenderProxy::setDisplayListData(DisplayList* displayList, DisplayListData* newData) {
+void RenderProxy::setDisplayListData(RenderNode* displayList, DisplayListData* newData) {
     SETUP_TASK(setDisplayListData);
     args->context = mContext;
     args->displayList = displayList;
@@ -131,7 +131,7 @@
     post(task);
 }
 
-CREATE_BRIDGE4(drawDisplayList, CanvasContext* context, DisplayList* displayList,
+CREATE_BRIDGE4(drawDisplayList, CanvasContext* context, RenderNode* displayList,
         Rect dirty, const Vector<DeferredLayerUpdater*>* layerUpdates) {
     Rect* dirty = &args->dirty;
     if (dirty->bottom == -1 && dirty->left == -1 &&
@@ -143,7 +143,7 @@
     return NULL;
 }
 
-void RenderProxy::drawDisplayList(DisplayList* displayList,
+void RenderProxy::drawDisplayList(RenderNode* displayList,
         int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom) {
     SETUP_TASK(drawDisplayList);
     args->context = mContext;
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 83a8a8f..73e9805 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -32,7 +32,7 @@
 namespace uirenderer {
 
 class DeferredLayerUpdater;
-class DisplayList;
+class RenderNode;
 class DisplayListData;
 class Layer;
 class Rect;
@@ -60,8 +60,8 @@
     ANDROID_API bool initialize(EGLNativeWindowType window);
     ANDROID_API void updateSurface(EGLNativeWindowType window);
     ANDROID_API void setup(int width, int height);
-    ANDROID_API void setDisplayListData(DisplayList* displayList, DisplayListData* newData);
-    ANDROID_API void drawDisplayList(DisplayList* displayList,
+    ANDROID_API void setDisplayListData(RenderNode* displayList, DisplayListData* newData);
+    ANDROID_API void drawDisplayList(RenderNode* displayList,
             int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
     ANDROID_API void destroyCanvas();
 
diff --git a/media/java/android/media/Rating.java b/media/java/android/media/Rating.java
index b94db18..f4fbe2c 100644
--- a/media/java/android/media/Rating.java
+++ b/media/java/android/media/Rating.java
@@ -29,8 +29,13 @@
  * through one of the factory methods.
  */
 public final class Rating implements Parcelable {
-
     private final static String TAG = "Rating";
+    /**
+     * Indicates a rating style is not supported. A Rating will never have this
+     * type, but can be used by other classes to indicate they do not support
+     * Rating.
+     */
+    public final static int RATING_NONE = 0;
 
     /**
      * A rating style with a single degree of rating, "heart" vs "no heart". Can be used to
diff --git a/media/java/android/media/session/IMediaController.aidl b/media/java/android/media/session/IMediaController.aidl
index 8ca0e45..d34e973 100644
--- a/media/java/android/media/session/IMediaController.aidl
+++ b/media/java/android/media/session/IMediaController.aidl
@@ -16,9 +16,12 @@
 package android.media.session;
 
 import android.content.Intent;
+import android.media.Rating;
 import android.media.session.IMediaControllerCallback;
+import android.media.session.MediaMetadata;
+import android.media.session.PlaybackState;
 import android.os.Bundle;
-import android.os.IBinder;
+import android.os.ResultReceiver;
 import android.view.KeyEvent;
 
 /**
@@ -26,9 +29,23 @@
  * @hide
  */
 interface IMediaController {
-    void sendCommand(String command, in Bundle extras);
+    void sendCommand(String command, in Bundle extras, in ResultReceiver cb);
     void sendMediaButton(in KeyEvent mediaButton);
     void registerCallbackListener(in IMediaControllerCallback cb);
     void unregisterCallbackListener(in IMediaControllerCallback cb);
-    int getPlaybackState();
+    boolean isTransportControlEnabled();
+
+    // These commands are for the TransportController
+    void play();
+    void pause();
+    void stop();
+    void next();
+    void previous();
+    void fastForward();
+    void rewind();
+    void seekTo(long pos);
+    void rate(in Rating rating);
+    MediaMetadata getMetadata();
+    PlaybackState getPlaybackState();
+    int getRatingType();
 }
\ No newline at end of file
diff --git a/media/java/android/media/session/IMediaControllerCallback.aidl b/media/java/android/media/session/IMediaControllerCallback.aidl
index 3aa0ee4..3651f1b 100644
--- a/media/java/android/media/session/IMediaControllerCallback.aidl
+++ b/media/java/android/media/session/IMediaControllerCallback.aidl
@@ -15,6 +15,8 @@
 
 package android.media.session;
 
+import android.media.session.MediaMetadata;
+import android.media.session.PlaybackState;
 import android.os.Bundle;
 
 /**
@@ -22,7 +24,9 @@
  */
 oneway interface IMediaControllerCallback {
     void onEvent(String event, in Bundle extras);
-    void onMetadataUpdate(in Bundle metadata);
-    void onPlaybackUpdate(int newState);
     void onRouteChanged(in Bundle route);
+
+    // These callbacks are for the TransportController
+    void onPlaybackStateChanged(in PlaybackState state);
+    void onMetadataChanged(in MediaMetadata metadata);
 }
\ No newline at end of file
diff --git a/media/java/android/media/session/IMediaSession.aidl b/media/java/android/media/session/IMediaSession.aidl
index 19f7092..aed7641 100644
--- a/media/java/android/media/session/IMediaSession.aidl
+++ b/media/java/android/media/session/IMediaSession.aidl
@@ -16,6 +16,8 @@
 package android.media.session;
 
 import android.media.session.IMediaController;
+import android.media.session.MediaMetadata;
+import android.media.session.PlaybackState;
 import android.os.Bundle;
 
 /**
@@ -23,11 +25,17 @@
  * @hide
  */
 interface IMediaSession {
-    void sendEvent(in Bundle data);
-    IMediaController getMediaSessionToken();
-    void setPlaybackState(int state);
-    void setMetadata(in Bundle metadata);
+    void sendEvent(String event, in Bundle data);
+    IMediaController getMediaController();
+    void setTransportPerformerEnabled();
     void setRouteState(in Bundle routeState);
     void setRoute(in Bundle mediaRouteDescriptor);
+    List<String> getSupportedInterfaces();
+    void publish();
     void destroy();
+
+    // These commands are for the TransportPerformer
+    void setMetadata(in MediaMetadata metadata);
+    void setPlaybackState(in PlaybackState state);
+    void setRatingType(int type);
 }
\ No newline at end of file
diff --git a/media/java/android/media/session/IMediaSessionCallback.aidl b/media/java/android/media/session/IMediaSessionCallback.aidl
index eb5f222..7c183e0 100644
--- a/media/java/android/media/session/IMediaSessionCallback.aidl
+++ b/media/java/android/media/session/IMediaSessionCallback.aidl
@@ -15,15 +15,27 @@
 
 package android.media.session;
 
+import android.media.Rating;
 import android.content.Intent;
 import android.os.Bundle;
-import android.os.IBinder;
+import android.os.ResultReceiver;
 
 /**
  * @hide
  */
 oneway interface IMediaSessionCallback {
-    void onCommand(String command, in Bundle extras);
+    void onCommand(String command, in Bundle extras, in ResultReceiver cb);
     void onMediaButton(in Intent mediaRequestIntent);
     void onRequestRouteChange(in Bundle route);
+
+    // These callbacks are for the TransportPerformer
+    void onPlay();
+    void onPause();
+    void onStop();
+    void onNext();
+    void onPrevious();
+    void onFastForward();
+    void onRewind();
+    void onSeekTo(long pos);
+    void onRate(in Rating rating);
 }
\ No newline at end of file
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 09de859..afd8b11 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -16,20 +16,17 @@
 
 package android.media.session;
 
-import android.content.Intent;
-import android.media.session.IMediaController;
-import android.media.session.IMediaControllerCallback;
-import android.media.MediaMetadataRetriever;
-import android.media.RemoteControlClient;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.KeyEvent;
 
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
 /**
@@ -46,58 +43,62 @@
 public final class MediaController {
     private static final String TAG = "MediaController";
 
-    private static final int MESSAGE_EVENT = 1;
+    private static final int MSG_EVENT = 1;
     private static final int MESSAGE_PLAYBACK_STATE = 2;
     private static final int MESSAGE_METADATA = 3;
-    private static final int MESSAGE_ROUTE = 4;
-
-    private static final String KEY_EVENT = "event";
-    private static final String KEY_EXTRAS = "extras";
+    private static final int MSG_ROUTE = 4;
 
     private final IMediaController mSessionBinder;
 
-    private final CallbackStub mCbStub = new CallbackStub();
-    private final ArrayList<Callback> mCbs = new ArrayList<Callback>();
+    private final CallbackStub mCbStub = new CallbackStub(this);
+    private final ArrayList<MessageHandler> mCallbacks = new ArrayList<MessageHandler>();
     private final Object mLock = new Object();
 
     private boolean mCbRegistered = false;
 
-    /**
-     * If you have a {@link MediaSessionToken} from the owner of the session a
-     * controller can be created directly. It is up to the session creator to
-     * handle token distribution if desired.
-     *
-     * @see MediaSession#getSessionToken()
-     * @param token A token from the creator of the session
-     */
-    public MediaController(MediaSessionToken token) {
-        mSessionBinder = token.getBinder();
+    private TransportController mTransportController;
+
+    private MediaController(IMediaController sessionBinder) {
+        mSessionBinder = sessionBinder;
     }
 
     /**
      * @hide
      */
-    public MediaController(IMediaController sessionBinder) {
-        mSessionBinder = sessionBinder;
+    public static MediaController fromBinder(IMediaController sessionBinder) {
+        MediaController controller = new MediaController(sessionBinder);
+        try {
+            controller.mSessionBinder.registerCallbackListener(controller.mCbStub);
+            if (controller.mSessionBinder.isTransportControlEnabled()) {
+                controller.mTransportController = new TransportController(sessionBinder);
+            }
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "MediaController created with expired token", e);
+            controller = null;
+        }
+        return controller;
     }
 
     /**
-     * Sends a generic command to the session. It is up to the session creator
-     * to decide what commands and parameters they will support. As such,
-     * commands should only be sent to sessions that the controller owns.
+     * Get a new MediaController for a MediaSessionToken. If successful the
+     * controller returned will be connected to the session that generated the
+     * token.
      *
-     * @param command The command to send
-     * @param params Any parameters to include with the command
+     * @param token The session token to use
+     * @return A controller for the session or null
      */
-    public void sendCommand(String command, Bundle params) {
-        if (TextUtils.isEmpty(command)) {
-            throw new IllegalArgumentException("command cannot be null or empty");
-        }
-        try {
-            mSessionBinder.sendCommand(command, params);
-        } catch (RemoteException e) {
-            Log.d(TAG, "Dead object in sendCommand.", e);
-        }
+    public static MediaController fromToken(MediaSessionToken token) {
+        return fromBinder(token.getBinder());
+    }
+
+    /**
+     * Get a TransportController if the session supports it. If it is not
+     * supported null will be returned.
+     *
+     * @return A TransportController or null
+     */
+    public TransportController getTransportController() {
+        return mTransportController;
     }
 
     /**
@@ -133,10 +134,10 @@
 
     /**
      * Adds a callback to receive updates from the session. Updates will be
-     * posted on the specified handler.
+     * posted on the specified handler's thread.
      *
      * @param cb Cannot be null.
-     * @param handler The handler to post updates on, if null the callers thread
+     * @param handler The handler to post updates on. If null the callers thread
      *            will be used
      */
     public void addCallback(Callback cb, Handler handler) {
@@ -160,6 +161,26 @@
         }
     }
 
+    /**
+     * Sends a generic command to the session. It is up to the session creator
+     * to decide what commands and parameters they will support. As such,
+     * commands should only be sent to sessions that the controller owns.
+     *
+     * @param command The command to send
+     * @param params Any parameters to include with the command
+     * @param cb The callback to receive the result on
+     */
+    public void sendCommand(String command, Bundle params, ResultReceiver cb) {
+        if (TextUtils.isEmpty(command)) {
+            throw new IllegalArgumentException("command cannot be null or empty");
+        }
+        try {
+            mSessionBinder.sendCommand(command, params, cb);
+        } catch (RemoteException e) {
+            Log.d(TAG, "Dead object in sendCommand.", e);
+        }
+    }
+
     /*
      * @hide
      */
@@ -174,14 +195,13 @@
         if (handler == null) {
             throw new IllegalArgumentException("Handler cannot be null");
         }
-        if (mCbs.contains(cb)) {
+        if (getHandlerForCallbackLocked(cb) != null) {
             Log.w(TAG, "Callback is already added, ignoring");
             return;
         }
-        cb.setHandler(handler);
-        mCbs.add(cb);
+        MessageHandler holder = new MessageHandler(handler.getLooper(), cb);
+        mCallbacks.add(holder);
 
-        // Only register one cb binder, track callbacks internally and notify
         if (!mCbRegistered) {
             try {
                 mSessionBinder.registerCallbackListener(mCbStub);
@@ -192,56 +212,58 @@
         }
     }
 
-    private void removeCallbackLocked(Callback cb) {
+    private boolean removeCallbackLocked(Callback cb) {
         if (cb == null) {
             throw new IllegalArgumentException("Callback cannot be null");
         }
-        mCbs.remove(cb);
-
-        if (mCbs.size() == 0 && mCbRegistered) {
-            try {
-                mSessionBinder.unregisterCallbackListener(mCbStub);
-            } catch (RemoteException e) {
-                Log.d(TAG, "Dead object in unregisterCallback", e);
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mCallbacks.get(i);
+            if (cb == handler.mCallback) {
+                mCallbacks.remove(i);
+                return true;
             }
-            mCbRegistered = false;
+        }
+        return false;
+    }
+
+    private MessageHandler getHandlerForCallbackLocked(Callback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Callback cannot be null");
+        }
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mCallbacks.get(i);
+            if (cb == handler.mCallback) {
+                return handler;
+            }
+        }
+        return null;
+    }
+
+    private void postEvent(String event, Bundle extras) {
+        synchronized (mLock) {
+            for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+                mCallbacks.get(i).post(MSG_EVENT, event, extras);
+            }
         }
     }
 
-    private void pushOnEventLocked(String event, Bundle extras) {
-        for (int i = mCbs.size() - 1; i >= 0; i--) {
-            mCbs.get(i).postEvent(event, extras);
-        }
-    }
-
-    private void pushOnMetadataUpdateLocked(Bundle metadata) {
-        for (int i = mCbs.size() - 1; i >= 0; i--) {
-            mCbs.get(i).postMetadataUpdate(metadata);
-        }
-    }
-
-    private void pushOnPlaybackUpdateLocked(int newState) {
-        for (int i = mCbs.size() - 1; i >= 0; i--) {
-            mCbs.get(i).postPlaybackStateChange(newState);
-        }
-    }
-
-    private void pushOnRouteChangedLocked(Bundle routeDescriptor) {
-        for (int i = mCbs.size() - 1; i >= 0; i--) {
-            mCbs.get(i).postRouteChanged(routeDescriptor);
+    private void postRouteChanged(Bundle routeDescriptor) {
+        synchronized (mLock) {
+            for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+                mCallbacks.get(i).post(MSG_ROUTE, null, routeDescriptor);
+            }
         }
     }
 
     /**
-     * MediaSession callbacks will be posted on the thread that created the
-     * Callback object.
+     * Callback for receiving updates on from the session. A Callback can be
+     * registered using {@link #addCallback}
      */
     public static abstract class Callback {
-        private Handler mHandler;
-
         /**
-         * Override to handle custom events sent by the session owner.
-         * Controllers should only handle these for sessions they own.
+         * Override to handle custom events sent by the session owner without a
+         * specified interface. Controllers should only handle these for
+         * sessions they own.
          *
          * @param event
          */
@@ -249,119 +271,83 @@
         }
 
         /**
-         * Override to handle updates to the playback state. Valid values are in
-         * {@link RemoteControlClient}. TODO put playstate values somewhere more
-         * generic.
-         *
-         * @param state
-         */
-        public void onPlaybackStateChange(int state) {
-        }
-
-        /**
-         * Override to handle metadata changes for this session's media. The
-         * default supported fields are those in {@link MediaMetadataRetriever}.
-         *
-         * @param metadata
-         */
-        public void onMetadataUpdate(Bundle metadata) {
-        }
-
-        /**
          * Override to handle route changes for this session.
          *
          * @param route
          */
         public void onRouteChanged(Bundle route) {
         }
-
-        private void setHandler(Handler handler) {
-            mHandler = new MessageHandler(handler.getLooper(), this);
-        }
-
-        private void postEvent(String event, Bundle extras) {
-            Bundle eventBundle = new Bundle();
-            eventBundle.putString(KEY_EVENT, event);
-            eventBundle.putBundle(KEY_EXTRAS, extras);
-            Message msg = mHandler.obtainMessage(MESSAGE_EVENT, eventBundle);
-            mHandler.sendMessage(msg);
-        }
-
-        private void postPlaybackStateChange(final int state) {
-            Message msg = mHandler.obtainMessage(MESSAGE_PLAYBACK_STATE, state, 0);
-            mHandler.sendMessage(msg);
-        }
-
-        private void postMetadataUpdate(final Bundle metadata) {
-            Message msg = mHandler.obtainMessage(MESSAGE_METADATA, metadata);
-            mHandler.sendMessage(msg);
-        }
-
-        private void postRouteChanged(final Bundle descriptor) {
-            Message msg = mHandler.obtainMessage(MESSAGE_ROUTE, descriptor);
-            mHandler.sendMessage(msg);
-        }
     }
 
-    private final class CallbackStub extends IMediaControllerCallback.Stub {
+    private final static class CallbackStub extends IMediaControllerCallback.Stub {
+        private final WeakReference<MediaController> mController;
+
+        public CallbackStub(MediaController controller) {
+            mController = new WeakReference<MediaController>(controller);
+        }
 
         @Override
-        public void onEvent(String event, Bundle extras) throws RemoteException {
-            synchronized (mLock) {
-                pushOnEventLocked(event, extras);
+        public void onEvent(String event, Bundle extras) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postEvent(event, extras);
             }
         }
 
         @Override
-        public void onMetadataUpdate(Bundle metadata) throws RemoteException {
-            synchronized (mLock) {
-                pushOnMetadataUpdateLocked(metadata);
+        public void onRouteChanged(Bundle mediaRouteDescriptor) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postRouteChanged(mediaRouteDescriptor);
             }
         }
 
         @Override
-        public void onPlaybackUpdate(final int newState) throws RemoteException {
-            synchronized (mLock) {
-                pushOnPlaybackUpdateLocked(newState);
+        public void onPlaybackStateChanged(PlaybackState state) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                TransportController tc = controller.getTransportController();
+                if (tc != null) {
+                    tc.postPlaybackStateChanged(state);
+                }
             }
         }
 
         @Override
-        public void onRouteChanged(Bundle mediaRouteDescriptor) throws RemoteException {
-            synchronized (mLock) {
-                pushOnRouteChangedLocked(mediaRouteDescriptor);
+        public void onMetadataChanged(MediaMetadata metadata) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                TransportController tc = controller.getTransportController();
+                if (tc != null) {
+                    tc.postMetadataChanged(metadata);
+                }
             }
         }
 
     }
 
     private final static class MessageHandler extends Handler {
-        private final MediaController.Callback mCb;
+        private final MediaController.Callback mCallback;
 
         public MessageHandler(Looper looper, MediaController.Callback cb) {
-            super(looper);
-            mCb = cb;
+            super(looper, null, true);
+            mCallback = cb;
         }
 
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-                case MESSAGE_EVENT:
-                    Bundle eventBundle = (Bundle) msg.obj;
-                    String event = eventBundle.getString(KEY_EVENT);
-                    Bundle extras = eventBundle.getBundle(KEY_EXTRAS);
-                    mCb.onEvent(event, extras);
+                case MSG_EVENT:
+                    mCallback.onEvent((String) msg.obj, msg.getData());
                     break;
-                case MESSAGE_PLAYBACK_STATE:
-                    mCb.onPlaybackStateChange(msg.arg1);
-                    break;
-                case MESSAGE_METADATA:
-                    mCb.onMetadataUpdate((Bundle) msg.obj);
-                    break;
-                case MESSAGE_ROUTE:
-                    mCb.onRouteChanged((Bundle) msg.obj);
+                case MSG_ROUTE:
+                    mCallback.onRouteChanged(msg.getData());
             }
         }
+
+        public void post(int what, Object obj, Bundle data) {
+            obtainMessage(what, obj).sendToTarget();
+        }
     }
 
 }
diff --git a/media/java/android/media/session/MediaMetadata.aidl b/media/java/android/media/session/MediaMetadata.aidl
new file mode 100644
index 0000000..4431d9d
--- /dev/null
+++ b/media/java/android/media/session/MediaMetadata.aidl
@@ -0,0 +1,18 @@
+/* Copyright 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.media.session;
+
+parcelable MediaMetadata;
diff --git a/media/java/android/media/session/MediaMetadata.java b/media/java/android/media/session/MediaMetadata.java
new file mode 100644
index 0000000..e2330f7
--- /dev/null
+++ b/media/java/android/media/session/MediaMetadata.java
@@ -0,0 +1,404 @@
+/*
+ * 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.media.session;
+
+import android.graphics.Bitmap;
+import android.media.Rating;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArrayMap;
+import android.util.Log;
+
+/**
+ * Contains metadata about an item, such as the title, artist, etc.
+ */
+public final class MediaMetadata implements Parcelable {
+    private static final String TAG = "MediaMetadata";
+
+    /**
+     * The title of the media.
+     */
+    public static final String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
+
+    /**
+     * The artist of the media.
+     */
+    public static final String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST";
+
+    /**
+     * The duration of the media in ms. A duration of 0 is the default.
+     */
+    public static final String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
+
+    /**
+     * The album title for the media.
+     */
+    public static final String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM";
+
+    /**
+     * The author of the media.
+     */
+    public static final String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR";
+
+    /**
+     * The writer of the media.
+     */
+    public static final String METADATA_KEY_WRITER = "android.media.metadata.WRITER";
+
+    /**
+     * The composer of the media.
+     */
+    public static final String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
+
+    /**
+     * The date the media was created or published as TODO determine format.
+     */
+    public static final String METADATA_KEY_DATE = "android.media.metadata.DATE";
+
+    /**
+     * The year the media was created or published as a numeric String.
+     */
+    public static final String METADATA_KEY_YEAR = "android.media.metadata.YEAR";
+
+    /**
+     * The genre of the media.
+     */
+    public static final String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
+
+    /**
+     * The track number for the media.
+     */
+    public static final String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+
+    /**
+     * The number of tracks in the media's original source.
+     */
+    public static final String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
+
+    /**
+     * The disc number for the media's original source.
+     */
+    public static final String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+
+    /**
+     * The artist for the album of the media's original source.
+     */
+    public static final String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+
+    /**
+     * The artwork for the media as a {@link Bitmap}.
+     */
+    public static final String METADATA_KEY_ART = "android.media.metadata.ART";
+
+    /**
+     * The artwork for the media as a Uri style String.
+     */
+    public static final String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
+
+    /**
+     * The artwork for the album of the media's original source as a
+     * {@link Bitmap}.
+     */
+    public static final String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
+
+    /**
+     * The artwork for the album of the media's original source as a Uri style
+     * String.
+     */
+    public static final String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
+
+    /**
+     * The user's rating for the media.
+     *
+     * @see Rating
+     */
+    public static final String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING";
+
+    /**
+     * The overall rating for the media.
+     *
+     * @see Rating
+     */
+    public static final String METADATA_KEY_RATING = "android.media.metadata.RATING";
+
+    private static final int METADATA_TYPE_INVALID = -1;
+    private static final int METADATA_TYPE_LONG = 0;
+    private static final int METADATA_TYPE_STRING = 1;
+    private static final int METADATA_TYPE_BITMAP = 2;
+    private static final int METADATA_TYPE_RATING = 3;
+    private static final ArrayMap<String, Integer> METADATA_KEYS_TYPE;
+
+    static {
+        METADATA_KEYS_TYPE = new ArrayMap<String, Integer>();
+        METADATA_KEYS_TYPE.put(METADATA_KEY_TITLE, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ARTIST, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DURATION, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_AUTHOR, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_WRITER, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_COMPOSER, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DATE, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_YEAR, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_TRACK_NUMBER, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_NUM_TRACKS, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISC_NUMBER, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ARTIST, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ART, METADATA_TYPE_BITMAP);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ART_URI, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART, METADATA_TYPE_BITMAP);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART_URI, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_USER_RATING, METADATA_TYPE_RATING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_RATING, METADATA_TYPE_RATING);
+    }
+    private final Bundle mBundle;
+
+    private MediaMetadata(Bundle bundle) {
+        mBundle = new Bundle(bundle);
+    }
+
+    private MediaMetadata(Parcel in) {
+        mBundle = in.readBundle();
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if no mapping of
+     * the desired type exists for the given key or a null value is explicitly
+     * associated with the key.
+     *
+     * @param key The key the value is stored under
+     * @return a String value, or null
+     */
+    public String getString(String key) {
+        return mBundle.getString(key);
+    }
+
+    /**
+     * Returns the value associated with the given key, or 0L if no long exists
+     * for the given key.
+     *
+     * @param key The key the value is stored under
+     * @return a long value
+     */
+    public long getLong(String key) {
+        return mBundle.getLong(key);
+    }
+
+    /**
+     * Return a {@link Rating} for the given key or null if no rating exists for
+     * the given key.
+     *
+     * @param key The key the value is stored under
+     * @return A {@link Rating} or null
+     */
+    public Rating getRating(String key) {
+        Rating rating = null;
+        try {
+            rating = mBundle.getParcelable(key);
+        } catch (Exception e) {
+            // ignore, value was not a bitmap
+            Log.d(TAG, "Failed to retrieve a key as Rating.", e);
+        }
+        return rating;
+    }
+
+    /**
+     * Return a {@link Bitmap} for the given key or null if no bitmap exists for
+     * the given key.
+     *
+     * @param key The key the value is stored under
+     * @return A {@link Bitmap} or null
+     */
+    public Bitmap getBitmap(String key) {
+        Bitmap bmp = null;
+        try {
+            bmp = mBundle.getParcelable(key);
+        } catch (Exception e) {
+            // ignore, value was not a bitmap
+            Log.d(TAG, "Failed to retrieve a key as Bitmap.", e);
+        }
+        return bmp;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBundle(mBundle);
+    }
+
+    public static final Parcelable.Creator<MediaMetadata> CREATOR
+            = new Parcelable.Creator<MediaMetadata>() {
+                @Override
+                public MediaMetadata createFromParcel(Parcel in) {
+                    return new MediaMetadata(in);
+                }
+
+                @Override
+                public MediaMetadata[] newArray(int size) {
+                    return new MediaMetadata[size];
+                }
+            };
+
+    /**
+     * Use to build MediaMetadata objects. The system defined metadata keys must
+     * use the appropriate data type.
+     */
+    public static final class Builder {
+        private final Bundle mBundle;
+
+        /**
+         * Create an empty Builder. Any field that should be included in the
+         * {@link MediaMetadata} must be added.
+         */
+        public Builder() {
+            mBundle = new Bundle();
+        }
+
+        /**
+         * Create a Builder using a {@link MediaMetadata} instance to set the
+         * initial values. All fields in the source metadata will be included in
+         * the new metadata. Fields can be overwritten by adding the same key.
+         *
+         * @param source
+         */
+        public Builder(MediaMetadata source) {
+            mBundle = new Bundle(source.mBundle);
+        }
+
+        /**
+         * Put a String value into the metadata. Custom keys may be used, but if
+         * the METADATA_KEYs defined in this class are used they may only be one
+         * of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_TITLE}</li>
+         * <li>{@link #METADATA_KEY_ARTIST}</li>
+         * <li>{@link #METADATA_KEY_ALBUM}</li>
+         * <li>{@link #METADATA_KEY_AUTHOR}</li>
+         * <li>{@link #METADATA_KEY_WRITER}</li>
+         * <li>{@link #METADATA_KEY_COMPOSER}</li>
+         * <li>{@link #METADATA_KEY_DATE}</li>
+         * <li>{@link #METADATA_KEY_YEAR}</li>
+         * <li>{@link #METADATA_KEY_GENRE}</li>
+         * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li>li>
+         * <li>{@link #METADATA_KEY_ART_URI}</li>li>
+         * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The String value to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putString(String key, String value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_STRING) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a String");
+                }
+            }
+            mBundle.putString(key, value);
+            return this;
+        }
+
+        /**
+         * Put a long value into the metadata. Custom keys may be used, but if
+         * the METADATA_KEYs defined in this class are used they may only be one
+         * of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_DURATION}</li>
+         * <li>{@link #METADATA_KEY_TRACK_NUMBER}</li>
+         * <li>{@link #METADATA_KEY_NUM_TRACKS}</li>
+         * <li>{@link #METADATA_KEY_DISC_NUMBER}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The String value to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putLong(String key, long value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_LONG) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a long");
+                }
+            }
+            mBundle.putLong(key, value);
+            return this;
+        }
+
+        /**
+         * Put a {@link Rating} into the metadata. Custom keys may be used, but
+         * if the METADATA_KEYs defined in this class are used they may only be
+         * one of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_RATING}</li>
+         * <li>{@link #METADATA_KEY_USER_RATING}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The String value to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putRating(String key, Rating value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_RATING) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a Rating");
+                }
+            }
+            mBundle.putParcelable(key, value);
+            return this;
+        }
+
+        /**
+         * Put a {@link Bitmap} into the metadata. Custom keys may be used, but
+         * if the METADATA_KEYs defined in this class are used they may only be
+         * one of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_ART}</li>
+         * <li>{@link #METADATA_KEY_ALBUM_ART}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The Bitmap to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putBitmap(String key, Bitmap value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_BITMAP) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a Bitmap");
+                }
+            }
+            mBundle.putParcelable(key, value);
+            return this;
+        }
+
+        /**
+         * Creates a {@link MediaMetadata} instance with the specified fields.
+         *
+         * @return The new MediaMetadata instance
+         */
+        public MediaMetadata build() {
+            return new MediaMetadata(mBundle);
+        }
+    }
+
+}
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 1f1533b..23c3035 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -17,17 +17,21 @@
 package android.media.session;
 
 import android.content.Intent;
+import android.media.Rating;
 import android.media.session.IMediaController;
 import android.media.session.IMediaSession;
 import android.media.session.IMediaSessionCallback;
-import android.media.RemoteControlClient;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.text.TextUtils;
+import android.util.ArrayMap;
 import android.util.Log;
 
+import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
 /**
@@ -58,12 +62,13 @@
 public final class MediaSession {
     private static final String TAG = "MediaSession";
 
-    private static final int MESSAGE_MEDIA_BUTTON = 1;
-    private static final int MESSAGE_COMMAND = 2;
-    private static final int MESSAGE_ROUTE_CHANGE = 3;
+    private static final int MSG_MEDIA_BUTTON = 1;
+    private static final int MSG_COMMAND = 2;
+    private static final int MSG_ROUTE_CHANGE = 3;
 
     private static final String KEY_COMMAND = "command";
     private static final String KEY_EXTRAS = "extras";
+    private static final String KEY_CALLBACK = "callback";
 
     private final Object mLock = new Object();
 
@@ -71,7 +76,14 @@
     private final IMediaSession mBinder;
     private final CallbackStub mCbStub;
 
-    private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
+    private final ArrayList<MessageHandler> mCallbacks = new ArrayList<MessageHandler>();
+    // TODO route interfaces
+    private final ArrayMap<String, RouteInterface.Stub> mInterfaces
+            = new ArrayMap<String, RouteInterface.Stub>();
+
+    private TransportPerformer mPerformer;
+
+    private boolean mPublished = false;;
 
     /**
      * @hide
@@ -81,7 +93,7 @@
         mCbStub = cbStub;
         IMediaController controllerBinder = null;
         try {
-            controllerBinder = mBinder.getMediaSessionToken();
+            controllerBinder = mBinder.getMediaController();
         } catch (RemoteException e) {
             throw new RuntimeException("Dead object in MediaSessionController constructor: ", e);
         }
@@ -102,34 +114,117 @@
             throw new IllegalArgumentException("Callback cannot be null");
         }
         synchronized (mLock) {
-            if (mCallbacks.contains(callback)) {
+            if (getHandlerForCallbackLocked(callback) != null) {
                 Log.w(TAG, "Callback is already added, ignoring");
+                return;
             }
             if (handler == null) {
                 handler = new Handler();
             }
             MessageHandler msgHandler = new MessageHandler(handler.getLooper(), callback);
-            callback.setHandler(msgHandler);
-            mCallbacks.add(callback);
+            mCallbacks.add(msgHandler);
         }
     }
 
     public void removeCallback(Callback callback) {
-        mCallbacks.remove(callback);
+        synchronized (mLock) {
+            removeCallbackLocked(callback);
+        }
     }
 
     /**
-     * Publish the current playback state to the system and any controllers.
-     * Valid values are defined in {@link RemoteControlClient}. TODO move play
-     * states somewhere else.
+     * Start using a TransportPerformer with this media session. This must be
+     * called before calling publish and cannot be called more than once.
+     * Calling this will allow MediaControllers to retrieve a
+     * TransportController.
      *
-     * @param state
+     * @see TransportController
+     * @return The TransportPerformer created for this session
      */
-    public void setPlaybackState(int state) {
+    public TransportPerformer setTransportPerformerEnabled() {
+        if (mPerformer != null) {
+            throw new IllegalStateException("setTransportPerformer can only be called once.");
+        }
+        if (mPublished) {
+            throw new IllegalStateException("setTransportPerformer cannot be called after publish");
+        }
+
+        mPerformer = new TransportPerformer(mBinder);
         try {
-            mBinder.setPlaybackState(state);
+            mBinder.setTransportPerformerEnabled();
         } catch (RemoteException e) {
-            Log.e(TAG, "Dead object in setPlaybackState: ", e);
+            Log.wtf(TAG, "Failure in setTransportPerformerEnabled.", e);
+        }
+        return mPerformer;
+    }
+
+    /**
+     * Retrieves the TransportPerformer used by this session. If called before
+     * {@link #setTransportPerformerEnabled} null will be returned.
+     *
+     * @return The TransportPerformer associated with this session or null
+     */
+    public TransportPerformer getTransportPerformer() {
+        return mPerformer;
+    }
+
+    /**
+     * Call after you have finished setting up the session. This will make it
+     * available to listeners and begin pushing updates to MediaControllers.
+     * This can only be called once.
+     */
+    public void publish() {
+        if (mPublished) {
+            throw new RuntimeException("publish() may only be called once.");
+        }
+        try {
+            mBinder.publish();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Failure in publish.", e);
+        }
+        mPublished = true;
+    }
+
+    /**
+     * Add an interface that can be used by MediaSessions. TODO make this a
+     * route provider api
+     *
+     * @see RouteInterface
+     * @param iface The interface to add
+     * @hide
+     */
+    public void addInterface(RouteInterface.Stub iface) {
+        if (iface == null) {
+            throw new IllegalArgumentException("Stub cannot be null");
+        }
+        String name = iface.getName();
+        if (TextUtils.isEmpty(name)) {
+            throw new IllegalArgumentException("Stub must return a valid name");
+        }
+        if (mInterfaces.containsKey(iface)) {
+            throw new IllegalArgumentException("Interface is already added");
+        }
+        synchronized (mLock) {
+            mInterfaces.put(iface.getName(), iface);
+        }
+    }
+
+    /**
+     * Send a proprietary event to all MediaControllers listening to this
+     * Session. It's up to the Controller/Session owner to determine the meaning
+     * of any events.
+     *
+     * @param event The name of the event to send
+     * @param extras Any extras included with the event
+     */
+    public void sendEvent(String event, Bundle extras) {
+        if (TextUtils.isEmpty(event)) {
+            throw new IllegalArgumentException("event cannot be null or empty");
+        }
+        try {
+            mBinder.sendEvent(event, extras);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error sending event", e);
         }
     }
 
@@ -142,7 +237,7 @@
         try {
             mBinder.destroy();
         } catch (RemoteException e) {
-            Log.e(TAG, "Dead object in onDestroy: ", e);
+            Log.wtf(TAG, "Error releasing session: ", e);
         }
     }
 
@@ -158,15 +253,38 @@
         return mSessionToken;
     }
 
-    private void postCommand(String command, Bundle extras) {
-        Bundle commandBundle = new Bundle();
-        commandBundle.putString(KEY_COMMAND, command);
-        commandBundle.putBundle(KEY_EXTRAS, extras);
+    private MessageHandler getHandlerForCallbackLocked(Callback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Callback cannot be null");
+        }
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mCallbacks.get(i);
+            if (cb == handler.mCallback) {
+                return handler;
+            }
+        }
+        return null;
+    }
+
+    private boolean removeCallbackLocked(Callback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Callback cannot be null");
+        }
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mCallbacks.get(i);
+            if (cb == handler.mCallback) {
+                mCallbacks.remove(i);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void postCommand(String command, Bundle extras, ResultReceiver resultCb) {
+        Command cmd = new Command(command, extras, resultCb);
         synchronized (mLock) {
             for (int i = mCallbacks.size() - 1; i >= 0; i--) {
-                Callback cb = mCallbacks.get(i);
-                Message msg = cb.mHandler.obtainMessage(MESSAGE_COMMAND, commandBundle);
-                cb.mHandler.sendMessage(msg);
+                mCallbacks.get(i).post(MSG_COMMAND, cmd);
             }
         }
     }
@@ -174,9 +292,7 @@
     private void postMediaButton(Intent mediaButtonIntent) {
         synchronized (mLock) {
             for (int i = mCallbacks.size() - 1; i >= 0; i--) {
-                Callback cb = mCallbacks.get(i);
-                Message msg = cb.mHandler.obtainMessage(MESSAGE_MEDIA_BUTTON, mediaButtonIntent);
-                cb.mHandler.sendMessage(msg);
+                mCallbacks.get(i).post(MSG_MEDIA_BUTTON, mediaButtonIntent);
             }
         }
     }
@@ -184,9 +300,7 @@
     private void postRequestRouteChange(Bundle mediaRouteDescriptor) {
         synchronized (mLock) {
             for (int i = mCallbacks.size() - 1; i >= 0; i--) {
-                Callback cb = mCallbacks.get(i);
-                Message msg = cb.mHandler.obtainMessage(MESSAGE_ROUTE_CHANGE, mediaRouteDescriptor);
-                cb.mHandler.sendMessage(msg);
+                mCallbacks.get(i).post(MSG_ROUTE_CHANGE, mediaRouteDescriptor);
             }
         }
     }
@@ -197,7 +311,6 @@
      * MediaSession (TODO).
      */
     public abstract static class Callback {
-        private MessageHandler mHandler;
 
         public Callback() {
         }
@@ -225,7 +338,7 @@
          * @param command
          * @param extras optional
          */
-        public void onCommand(String command, Bundle extras) {
+        public void onCommand(String command, Bundle extras, ResultReceiver cb) {
         }
 
         /**
@@ -237,35 +350,140 @@
          */
         public void onRequestRouteChange(Bundle descriptor) {
         }
-
-        private void setHandler(MessageHandler handler) {
-            mHandler = handler;
-        }
     }
 
     /**
      * @hide
      */
     public static class CallbackStub extends IMediaSessionCallback.Stub {
-        private MediaSession mMediaSession;
+        private WeakReference<MediaSession> mMediaSession;
 
         public void setMediaSession(MediaSession session) {
-            mMediaSession = session;
+            mMediaSession = new WeakReference<MediaSession>(session);
         }
 
         @Override
-        public void onCommand(String command, Bundle extras) throws RemoteException {
-            mMediaSession.postCommand(command, extras);
+        public void onCommand(String command, Bundle extras, ResultReceiver cb)
+                throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.postCommand(command, extras, cb);
+            }
         }
 
         @Override
         public void onMediaButton(Intent mediaButtonIntent) throws RemoteException {
-            mMediaSession.postMediaButton(mediaButtonIntent);
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.postMediaButton(mediaButtonIntent);
+            }
         }
 
         @Override
         public void onRequestRouteChange(Bundle mediaRouteDescriptor) throws RemoteException {
-            mMediaSession.postRequestRouteChange(mediaRouteDescriptor);
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.postRequestRouteChange(mediaRouteDescriptor);
+            }
+        }
+
+        @Override
+        public void onPlay() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onPlay();
+                }
+            }
+        }
+
+        @Override
+        public void onPause() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onPause();
+                }
+            }
+        }
+
+        @Override
+        public void onStop() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onStop();
+                }
+            }
+        }
+
+        @Override
+        public void onNext() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onNext();
+                }
+            }
+        }
+
+        @Override
+        public void onPrevious() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onPrevious();
+                }
+            }
+        }
+
+        @Override
+        public void onFastForward() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onFastForward();
+                }
+            }
+        }
+
+        @Override
+        public void onRewind() throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onRewind();
+                }
+            }
+        }
+
+        @Override
+        public void onSeekTo(long pos) throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onSeekTo(pos);
+                }
+            }
+        }
+
+        @Override
+        public void onRate(Rating rating) throws RemoteException {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                TransportPerformer tp = session.getTransportPerformer();
+                if (tp != null) {
+                    tp.onRate(rating);
+                }
+            }
         }
 
     }
@@ -274,7 +492,7 @@
         private MediaSession.Callback mCallback;
 
         public MessageHandler(Looper looper, MediaSession.Callback callback) {
-            super(looper);
+            super(looper, null, true);
             mCallback = callback;
         }
 
@@ -285,21 +503,35 @@
                     return;
                 }
                 switch (msg.what) {
-                    case MESSAGE_MEDIA_BUTTON:
+                    case MSG_MEDIA_BUTTON:
                         mCallback.onMediaButton((Intent) msg.obj);
                         break;
-                    case MESSAGE_COMMAND:
-                        Bundle commandBundle = (Bundle) msg.obj;
-                        String command = commandBundle.getString(KEY_COMMAND);
-                        Bundle extras = commandBundle.getBundle(KEY_EXTRAS);
-                        mCallback.onCommand(command, extras);
+                    case MSG_COMMAND:
+                        Command cmd = (Command) msg.obj;
+                        mCallback.onCommand(cmd.command, cmd.extras, cmd.stub);
                         break;
-                    case MESSAGE_ROUTE_CHANGE:
+                    case MSG_ROUTE_CHANGE:
                         mCallback.onRequestRouteChange((Bundle) msg.obj);
                         break;
                 }
             }
             msg.recycle();
         }
+
+        public void post(int what, Object obj) {
+            obtainMessage(what, obj).sendToTarget();
+        }
+    }
+
+    private static final class Command {
+        public final String command;
+        public final Bundle extras;
+        public final ResultReceiver stub;
+
+        public Command(String command, Bundle extras, ResultReceiver stub) {
+            this.command = command;
+            this.extras = extras;
+            this.stub = stub;
+        }
     }
 }
diff --git a/media/java/android/media/session/PlaybackState.aidl b/media/java/android/media/session/PlaybackState.aidl
new file mode 100644
index 0000000..0876ebd
--- /dev/null
+++ b/media/java/android/media/session/PlaybackState.aidl
@@ -0,0 +1,18 @@
+/* Copyright 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.media.session;
+
+parcelable PlaybackState;
diff --git a/media/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
new file mode 100644
index 0000000..b3506b3
--- /dev/null
+++ b/media/java/android/media/session/PlaybackState.java
@@ -0,0 +1,351 @@
+/*
+ * 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.media.session;
+
+import android.media.RemoteControlClient;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Playback state for a {@link MediaSession}. This includes a state like
+ * {@link PlaybackState#PLAYSTATE_PLAYING}, the current playback position,
+ * and the current control capabilities.
+ */
+public final class PlaybackState implements Parcelable {
+    /**
+     * Indicates this performer supports the stop command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_STOP = 1 << 0;
+
+    /**
+     * Indicates this performer supports the pause command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_PAUSE = 1 << 1;
+
+    /**
+     * Indicates this performer supports the play command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_PLAY = 1 << 2;
+
+    /**
+     * Indicates this performer supports the rewind command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_REWIND = 1 << 3;
+
+    /**
+     * Indicates this performer supports the previous command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_PREVIOUS_ITEM = 1 << 4;
+
+    /**
+     * Indicates this performer supports the next command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_NEXT_ITEM = 1 << 5;
+
+    /**
+     * Indicates this performer supports the fast forward command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_FASTFORWARD = 1 << 6;
+
+    /**
+     * Indicates this performer supports the set rating command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_RATING = 1 << 7;
+
+    /**
+     * Indicates this performer supports the seek to command.
+     *
+     * @see #setActions
+     */
+    public static final long ACTION_SEEK_TO = 1 << 8;
+
+    /**
+     * This is the default playback state and indicates that no media has been
+     * added yet, or the performer has been reset and has no content to play.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_NONE = 0;
+
+    /**
+     * State indicating this item is currently stopped.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_STOPPED = 1;
+
+    /**
+     * State indicating this item is currently paused.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_PAUSED = 2;
+
+    /**
+     * State indicating this item is currently playing.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_PLAYING = 3;
+
+    /**
+     * State indicating this item is currently fast forwarding.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_FAST_FORWARDING = 4;
+
+    /**
+     * State indicating this item is currently rewinding.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_REWINDING = 5;
+
+    /**
+     * State indicating this item is currently buffering and will begin playing
+     * when enough data has buffered.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_BUFFERING = 6;
+
+    /**
+     * State indicating this item is currently in an error state. The error
+     * message should also be set when entering this state.
+     *
+     * @see #setState
+     */
+    public final static int PLAYSTATE_ERROR = 7;
+
+    private int mState;
+    private long mPosition;
+    private long mBufferPosition;
+    private float mSpeed;
+    private long mCapabilities;
+    private String mErrorMessage;
+
+    /**
+     * Create an empty PlaybackState. At minimum a state and actions should be
+     * set before publishing a PlaybackState.
+     */
+    public PlaybackState() {
+    }
+
+    /**
+     * Create a new PlaybackState from an existing PlaybackState. All fields
+     * will be copied to the new state.
+     *
+     * @param from The PlaybackState to duplicate
+     */
+    public PlaybackState(PlaybackState from) {
+        this.setState(from.getState());
+        this.setPosition(from.getPosition());
+        this.setBufferPosition(from.getBufferPosition());
+        this.setSpeed(from.getSpeed());
+        this.setActions(from.getActions());
+        this.setErrorMessage(from.getErrorMessage());
+    }
+
+    private PlaybackState(Parcel in) {
+        this.setState(in.readInt());
+        this.setPosition(in.readLong());
+        this.setBufferPosition(in.readLong());
+        this.setSpeed(in.readFloat());
+        this.setActions(in.readLong());
+        this.setErrorMessage(in.readString());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(getState());
+        dest.writeLong(getPosition());
+        dest.writeLong(getBufferPosition());
+        dest.writeFloat(getSpeed());
+        dest.writeLong(getActions());
+        dest.writeString(getErrorMessage());
+    }
+
+    /**
+     * Get the current state of playback. One of the following:
+     * <ul>
+     * <li> {@link PlaybackState#PLAYSTATE_NONE}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_STOPPED}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_PLAYING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_PAUSED}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_FAST_FORWARDING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_REWINDING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_BUFFERING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_ERROR}</li>
+     */
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Set the current state of playback. One of the following:
+     * <ul>
+     * <li> {@link PlaybackState#PLAYSTATE_NONE}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_STOPPED}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_PLAYING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_PAUSED}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_FAST_FORWARDING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_REWINDING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_BUFFERING}</li>
+     * <li> {@link PlaybackState#PLAYSTATE_ERROR}</li>
+     */
+    public void setState(int mState) {
+        this.mState = mState;
+    }
+
+    /**
+     * Get the current playback position in ms.
+     */
+    public long getPosition() {
+        return mPosition;
+    }
+
+    /**
+     * Set the current playback position in ms.
+     */
+    public void setPosition(long position) {
+        mPosition = position;
+    }
+
+    /**
+     * Get the current buffer position in ms. This is the farthest playback
+     * point that can be reached from the current position using only buffered
+     * content.
+     */
+    public long getBufferPosition() {
+        return mBufferPosition;
+    }
+
+    /**
+     * Set the current buffer position in ms. This is the farthest playback
+     * point that can be reached from the current position using only buffered
+     * content.
+     */
+    public void setBufferPosition(long bufferPosition) {
+        mBufferPosition = bufferPosition;
+    }
+
+    /**
+     * Get the current playback speed as a multiple of normal playback. This
+     * should be negative when rewinding. A value of 1 means normal playback and
+     * 0 means paused.
+     */
+    public float getSpeed() {
+        return mSpeed;
+    }
+
+    /**
+     * Set the current playback speed as a multiple of normal playback. This
+     * should be negative when rewinding. A value of 1 means normal playback and
+     * 0 means paused.
+     */
+    public void setSpeed(float speed) {
+        mSpeed = speed;
+    }
+
+    /**
+     * Get the current actions available on this session. This should use a
+     * bitmask of the available actions.
+     * <ul>
+     * <li> {@link PlaybackState#ACTION_PREVIOUS_ITEM}</li>
+     * <li> {@link PlaybackState#ACTION_REWIND}</li>
+     * <li> {@link PlaybackState#ACTION_PLAY}</li>
+     * <li> {@link PlaybackState#ACTION_PAUSE}</li>
+     * <li> {@link PlaybackState#ACTION_STOP}</li>
+     * <li> {@link PlaybackState#ACTION_FASTFORWARD}</li>
+     * <li> {@link PlaybackState#ACTION_NEXT_ITEM}</li>
+     * <li> {@link PlaybackState#ACTION_SEEK_TO}</li>
+     * <li> {@link PlaybackState#ACTION_RATING}</li>
+     * </ul>
+     */
+    public long getActions() {
+        return mCapabilities;
+    }
+
+    /**
+     * Set the current capabilities available on this session. This should use a
+     * bitmask of the available capabilities.
+     * <ul>
+     * <li> {@link PlaybackState#ACTION_PREVIOUS_ITEM}</li>
+     * <li> {@link PlaybackState#ACTION_REWIND}</li>
+     * <li> {@link PlaybackState#ACTION_PLAY}</li>
+     * <li> {@link PlaybackState#ACTION_PAUSE}</li>
+     * <li> {@link PlaybackState#ACTION_STOP}</li>
+     * <li> {@link PlaybackState#ACTION_FASTFORWARD}</li>
+     * <li> {@link PlaybackState#ACTION_NEXT_ITEM}</li>
+     * <li> {@link PlaybackState#ACTION_SEEK_TO}</li>
+     * <li> {@link PlaybackState#ACTION_RATING}</li>
+     * </ul>
+     */
+    public void setActions(long capabilities) {
+        mCapabilities = capabilities;
+    }
+
+    /**
+     * Get a user readable error message. This should be set when the state is
+     * {@link PlaybackState#PLAYSTATE_ERROR}.
+     */
+    public String getErrorMessage() {
+        return mErrorMessage;
+    }
+
+    /**
+     * Set a user readable error message. This should be set when the state is
+     * {@link PlaybackState#PLAYSTATE_ERROR}.
+     */
+    public void setErrorMessage(String errorMessage) {
+        mErrorMessage = errorMessage;
+    }
+
+    public static final Parcelable.Creator<PlaybackState> CREATOR
+            = new Parcelable.Creator<PlaybackState>() {
+        @Override
+        public PlaybackState createFromParcel(Parcel in) {
+            return new PlaybackState(in);
+        }
+
+        @Override
+        public PlaybackState[] newArray(int size) {
+            return new PlaybackState[size];
+        }
+    };
+}
diff --git a/media/java/android/media/session/RouteInterface.java b/media/java/android/media/session/RouteInterface.java
new file mode 100644
index 0000000..2391f27
--- /dev/null
+++ b/media/java/android/media/session/RouteInterface.java
@@ -0,0 +1,187 @@
+/*
+ * 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.media.session;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcelable;
+import android.os.ResultReceiver;
+
+/**
+ * Routes can support multiple interfaces for MediaSessions to interact with. To
+ * add a standard interface you should implement that interface's RouteInterface
+ * Stub and register it with the session. The set of supported commands is
+ * dependent on the specific interface's implementation.
+ * <p>
+ * A MediaInterface can be registered by calling TODO. Once added an interface
+ * will be used by Sessions to decide how they communicate with a session and
+ * cannot be removed, so all interfaces that you plan to support should be added
+ * when the route is created.
+ *
+ * @see RouteTransportControls
+ */
+public final class RouteInterface {
+    private static final String TAG = "MediaInterface";
+
+    private static final String KEY_RESULT = "result";
+
+    private final MediaController mController;
+    private final String mIface;
+
+    /**
+     * @hide
+     */
+    RouteInterface(MediaController controller, String iface) {
+        mController = controller;
+        mIface = iface;
+    }
+
+    public void sendCommand(String command, Bundle params, ResultReceiver cb) {
+        // TODO
+    }
+
+    public void addListener(EventListener listener) {
+        addListener(listener, null);
+    }
+
+    public void addListener(EventListener listener, Handler handler) {
+        // TODO See MediaController for add/remove pattern
+    }
+
+    public void removeListener(EventListener listener) {
+        // TODO
+    }
+
+    // TODO decide on list of supported types
+    private static Bundle writeResultToBundle(Object v) {
+        Bundle b = new Bundle();
+        if (v == null) {
+            // Don't send anything if null
+        } else if (v instanceof String) {
+            b.putString(KEY_RESULT, (String) v);
+        } else if (v instanceof Integer) {
+            b.putInt(KEY_RESULT, (Integer) v);
+        } else if (v instanceof Bundle) {
+            // Must be before Parcelable
+            b.putBundle(KEY_RESULT, (Bundle) v);
+        } else if (v instanceof Parcelable) {
+            b.putParcelable(KEY_RESULT, (Parcelable) v);
+        } else if (v instanceof Short) {
+            b.putShort(KEY_RESULT, (Short) v);
+        } else if (v instanceof Long) {
+            b.putLong(KEY_RESULT, (Long) v);
+        } else if (v instanceof Float) {
+            b.putFloat(KEY_RESULT, (Float) v);
+        } else if (v instanceof Double) {
+            b.putDouble(KEY_RESULT, (Double) v);
+        } else if (v instanceof Boolean) {
+            b.putBoolean(KEY_RESULT, (Boolean) v);
+        } else if (v instanceof CharSequence) {
+            // Must be after String
+            b.putCharSequence(KEY_RESULT, (CharSequence) v);
+        } else if (v instanceof boolean[]) {
+            b.putBooleanArray(KEY_RESULT, (boolean[]) v);
+        } else if (v instanceof byte[]) {
+            b.putByteArray(KEY_RESULT, (byte[]) v);
+        } else if (v instanceof String[]) {
+            b.putStringArray(KEY_RESULT, (String[]) v);
+        } else if (v instanceof CharSequence[]) {
+            // Must be after String[] and before Object[]
+            b.putCharSequenceArray(KEY_RESULT, (CharSequence[]) v);
+        } else if (v instanceof IBinder) {
+            b.putBinder(KEY_RESULT, (IBinder) v);
+        } else if (v instanceof Parcelable[]) {
+            b.putParcelableArray(KEY_RESULT, (Parcelable[]) v);
+        } else if (v instanceof int[]) {
+            b.putIntArray(KEY_RESULT, (int[]) v);
+        } else if (v instanceof long[]) {
+            b.putLongArray(KEY_RESULT, (long[]) v);
+        } else if (v instanceof Byte) {
+            b.putByte(KEY_RESULT, (Byte) v);
+        }
+        return b;
+    }
+
+    public abstract static class Stub {
+
+        /**
+         * The name of an interface should be a fully qualified name to prevent
+         * namespace collisions. Example: "com.myproject.MyPlaybackInterface"
+         *
+         * @return The name of this interface
+         */
+        public abstract String getName();
+
+        /**
+         * This is called when a command is received that matches the interface
+         * you registered. Commands can come from any app with a MediaController
+         * reference to the session.
+         *
+         * @see MediaController
+         * @see MediaSession
+         * @param command The command or method to invoke.
+         * @param args Any args that were included with the command. May be
+         *            null.
+         * @param cb The callback provided to send a response on. May be null.
+         */
+        public abstract void onCommand(String command, Bundle args, ResultReceiver cb);
+
+        public final void sendEvent(MediaSession session, String event, Bundle extras) {
+            // TODO
+        }
+    }
+
+    /**
+     * An EventListener can be registered by an app with TODO to handle events
+     * sent by the session on a specific interface.
+     */
+    public static abstract class EventListener {
+        /**
+         * This is called when an event is received from the interface. Events
+         * are sent by the session owner and will be delivered to all
+         * controllers that are listening to the interface.
+         *
+         * @param event The event that occurred.
+         * @param args Any extras that were included with the event. May be
+         *            null.
+         */
+        public abstract void onEvent(String event, Bundle args);
+    }
+
+    private static final class EventHandler extends Handler {
+
+        private final RouteInterface.EventListener mListener;
+
+        public EventHandler(Looper looper, RouteInterface.EventListener cb) {
+            super(looper, null, true);
+            mListener = cb;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            mListener.onEvent((String) msg.obj, msg.getData());
+        }
+
+        public void postEvent(String event, Bundle args) {
+            Message msg = obtainMessage(0, event);
+            msg.setData(args);
+            msg.sendToTarget();
+        }
+    }
+}
diff --git a/media/java/android/media/session/RouteTransportControls.java b/media/java/android/media/session/RouteTransportControls.java
new file mode 100644
index 0000000..665fd10
--- /dev/null
+++ b/media/java/android/media/session/RouteTransportControls.java
@@ -0,0 +1,230 @@
+/*
+ * 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.media.session;
+
+import android.media.RemoteControlClient;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.ResultReceiver;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * A standard media control interface for Routes. Routes can support multiple
+ * interfaces for MediaSessions to interact with. TODO rewrite for routes
+ */
+public final class RouteTransportControls {
+    private static final String TAG = "RouteTransportControls";
+    public static final String NAME = "android.media.session.RouteTransportControls";
+
+    private static final String KEY_VALUE1 = "value1";
+
+    private static final String METHOD_FAST_FORWARD = "fastForward";
+    private static final String METHOD_GET_CURRENT_POSITION = "getCurrentPosition";
+    private static final String METHOD_GET_CAPABILITIES = "getCapabilities";
+
+    private static final String EVENT_PLAYSTATE_CHANGE = "playstateChange";
+    private static final String EVENT_METADATA_CHANGE = "metadataChange";
+
+    private final MediaController mController;
+    private final RouteInterface mIface;
+
+    private RouteTransportControls(RouteInterface iface, MediaController controller) {
+        mIface = iface;
+        mController = controller;
+    }
+
+    public static RouteTransportControls from(MediaController controller) {
+//        MediaInterface iface = controller.getInterface(NAME);
+//        if (iface != null) {
+//            return new RouteTransportControls(iface, controller);
+//        }
+        return null;
+    }
+
+    /**
+     * Send a play command to the route. TODO rename resume() and use messaging
+     * protocol, not KeyEvent
+     */
+    public void play() {
+        // TODO
+    }
+
+    /**
+     * Send a pause command to the session.
+     */
+    public void pause() {
+        // TODO
+    }
+
+    /**
+     * Set the rate at which to fastforward. Valid values are in the range [0,1]
+     * with actual rates depending on the implementation.
+     *
+     * @param rate
+     */
+    public void fastForward(float rate) {
+        if (rate < 0 || rate > 1) {
+            throw new IllegalArgumentException("Rate must be between 0 and 1 inclusive");
+        }
+        Bundle b = new Bundle();
+        b.putFloat(KEY_VALUE1, rate);
+        mIface.sendCommand(METHOD_FAST_FORWARD, b, null);
+    }
+
+    public void getCurrentPosition(ResultReceiver cb) {
+        mIface.sendCommand(METHOD_GET_CURRENT_POSITION, null, cb);
+    }
+
+    public void getCapabilities(ResultReceiver cb) {
+        mIface.sendCommand(METHOD_GET_CAPABILITIES, null, cb);
+    }
+
+    public void addListener(Listener listener) {
+        mIface.addListener(listener.mListener);
+    }
+
+    public void addListener(Listener listener, Handler handler) {
+        mIface.addListener(listener.mListener, handler);
+    }
+
+    public void removeListener(Listener listener) {
+        mIface.removeListener(listener.mListener);
+    }
+
+    public static abstract class Stub extends RouteInterface.Stub {
+        private final MediaSession mSession;
+
+        public Stub(MediaSession session) {
+            mSession = session;
+        }
+
+        @Override
+        public String getName() {
+            return NAME;
+        }
+
+        @Override
+        public void onCommand(String method, Bundle extras, ResultReceiver cb) {
+            if (TextUtils.isEmpty(method)) {
+                return;
+            }
+            Bundle result;
+            if (METHOD_FAST_FORWARD.equals(method)) {
+                fastForward(extras.getFloat(KEY_VALUE1, -1));
+            } else if (METHOD_GET_CURRENT_POSITION.equals(method)) {
+                if (cb != null) {
+                    result = new Bundle();
+                    result.putLong(KEY_VALUE1, getCurrentPosition());
+                    cb.send(0, result);
+                }
+            } else if (METHOD_GET_CAPABILITIES.equals(method)) {
+                if (cb != null) {
+                    result = new Bundle();
+                    result.putLong(KEY_VALUE1, getCapabilities());
+                    cb.send(0, result);
+                }
+            }
+        }
+
+        /**
+         * Override to handle fast forwarding. Valid values are [0,1] inclusive.
+         * The interpretation of the rate is up to the implementation. If no
+         * rate was included with the command a rate of -1 will be used by
+         * default.
+         *
+         * @param rate The rate at which to fast forward as a multiplier
+         */
+        public void fastForward(float rate) {
+            Log.w(TAG, "fastForward is not supported.");
+        }
+
+        /**
+         * Override to handle getting the current position of playback in
+         * millis.
+         *
+         * @return The current position in millis or -1
+         */
+        public long getCurrentPosition() {
+            Log.w(TAG, "getCurrentPosition is not supported");
+            return -1;
+        }
+
+        /**
+         * Override to handle getting the set of capabilities currently
+         * available.
+         *
+         * @return A bit mask of the supported capabilities
+         */
+        public long getCapabilities() {
+            Log.w(TAG, "getCapabilities is not supported");
+            return 0;
+        }
+
+        /**
+         * Publish the current playback state to the system and any controllers.
+         * Valid values are defined in {@link RemoteControlClient}. TODO move
+         * play states somewhere else.
+         *
+         * @param state
+         */
+        public final void updatePlaybackState(int state) {
+            Bundle extras = new Bundle();
+            extras.putInt(KEY_VALUE1, state);
+            sendEvent(mSession, EVENT_PLAYSTATE_CHANGE, extras);
+        }
+    }
+
+    /**
+     * Register this event listener using TODO to receive
+     * TransportControlInterface events from a session.
+     *
+     * @see RouteInterface.EventListener
+     */
+    public static abstract class Listener {
+
+        private RouteInterface.EventListener mListener = new RouteInterface.EventListener() {
+            @Override
+            public final void onEvent(String event, Bundle args) {
+                if (EVENT_PLAYSTATE_CHANGE.equals(event)) {
+                    onPlaybackStateChange(args.getInt(KEY_VALUE1));
+                } else if (EVENT_METADATA_CHANGE.equals(event)) {
+                    onMetadataUpdate(args);
+                }
+            }
+        };
+
+        /**
+         * Override to handle updates to the playback state. Valid values are in
+         * {@link TransportPerformer}. TODO put playstate values somewhere more
+         * generic.
+         *
+         * @param state
+         */
+        public void onPlaybackStateChange(int state) {
+        }
+
+        /**
+         * Override to handle metadata changes for this session's media. The
+         * default supported fields are those in {@link MediaMetadata}.
+         *
+         * @param metadata
+         */
+        public void onMetadataUpdate(Bundle metadata) {
+        }
+    }
+
+}
diff --git a/media/java/android/media/session/TransportController.java b/media/java/android/media/session/TransportController.java
new file mode 100644
index 0000000..15b11f3
--- /dev/null
+++ b/media/java/android/media/session/TransportController.java
@@ -0,0 +1,342 @@
+/*
+ * 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.media.session;
+
+import android.media.Rating;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+/**
+ * Interface for controlling media playback on a session. This allows an app to
+ * request changes in playback, retrieve the current playback state and
+ * metadata, and listen for changes to the playback state and metadata.
+ */
+public final class TransportController {
+    private static final String TAG = "TransportController";
+
+    private final Object mLock = new Object();
+    private final ArrayList<MessageHandler> mListeners = new ArrayList<MessageHandler>();
+    private final IMediaController mBinder;
+
+    /**
+     * @hide
+     */
+    public TransportController(IMediaController binder) {
+        mBinder = binder;
+    }
+
+    /**
+     * Start listening to changes in playback state.
+     */
+    public void addStateListener(TransportStateListener listener) {
+        addStateListener(listener, null);
+    }
+
+    public void addStateListener(TransportStateListener listener, Handler handler) {
+        if (listener == null) {
+            throw new IllegalArgumentException("Listener cannot be null");
+        }
+        synchronized (mLock) {
+            if (getHandlerForListenerLocked(listener) != null) {
+                Log.w(TAG, "Listener is already added, ignoring");
+                return;
+            }
+            if (handler == null) {
+                handler = new Handler();
+            }
+
+            MessageHandler msgHandler = new MessageHandler(handler.getLooper(), listener);
+            mListeners.add(msgHandler);
+        }
+    }
+
+    /**
+     * Stop listening to changes in playback state.
+     */
+    public void removeStateListener(TransportStateListener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("Listener cannot be null");
+        }
+        synchronized (mLock) {
+            removeStateListenerLocked(listener);
+        }
+    }
+
+    /**
+     * Request that the player start its playback at its current position.
+     */
+    public void play() {
+        try {
+            mBinder.play();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling play.", e);
+        }
+    }
+
+    /**
+     * Request that the player pause its playback and stay at its current
+     * position.
+     */
+    public void pause() {
+        try {
+            mBinder.pause();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling pause.", e);
+        }
+    }
+
+    /**
+     * Request that the player stop its playback; it may clear its state in
+     * whatever way is appropriate.
+     */
+    public void stop() {
+        try {
+            mBinder.stop();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling stop.", e);
+        }
+    }
+
+    /**
+     * Move to a new location in the media stream.
+     *
+     * @param pos Position to move to, in milliseconds.
+     */
+    public void seekTo(long pos) {
+        try {
+            mBinder.seekTo(pos);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling seekTo.", e);
+        }
+    }
+
+    /**
+     * Start fast forwarding. If playback is already fast forwarding this may
+     * increase the rate.
+     */
+    public void fastForward() {
+        try {
+            mBinder.fastForward();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling fastForward.", e);
+        }
+    }
+
+    /**
+     * Skip to the next item.
+     */
+    public void next() {
+        try {
+            mBinder.next();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling next.", e);
+        }
+    }
+
+    /**
+     * Start rewinding. If playback is already rewinding this may increase the
+     * rate.
+     */
+    public void rewind() {
+        try {
+            mBinder.rewind();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling rewind.", e);
+        }
+    }
+
+    /**
+     * Skip to the previous item.
+     */
+    public void previous() {
+        try {
+            mBinder.previous();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling previous.", e);
+        }
+    }
+
+    /**
+     * Rate the current content. This will cause the rating to be set for the
+     * current user. The Rating type must match the type returned by
+     * {@link #getRatingType()}.
+     *
+     * @param rating The rating to set for the current content
+     */
+    public void rate(Rating rating) {
+        try {
+            mBinder.rate(rating);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling rate.", e);
+        }
+    }
+
+    /**
+     * Get the rating type supported by the session. One of:
+     * <ul>
+     * <li>{@link Rating#RATING_NONE}</li>
+     * <li>{@link Rating#RATING_HEART}</li>
+     * <li>{@link Rating#RATING_THUMB_UP_DOWN}</li>
+     * <li>{@link Rating#RATING_3_STARS}</li>
+     * <li>{@link Rating#RATING_4_STARS}</li>
+     * <li>{@link Rating#RATING_5_STARS}</li>
+     * <li>{@link Rating#RATING_PERCENTAGE}</li>
+     * </ul>
+     *
+     * @return The supported rating type
+     */
+    public int getRatingType() {
+        try {
+            return mBinder.getRatingType();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getRatingType.", e);
+            return Rating.RATING_NONE;
+        }
+    }
+
+    /**
+     * Get the current playback state for this session.
+     *
+     * @return The current PlaybackState or null
+     */
+    public PlaybackState getPlaybackState() {
+        try {
+            return mBinder.getPlaybackState();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getPlaybackState.", e);
+            return null;
+        }
+    }
+
+    /**
+     * Get the current metadata for this session.
+     *
+     * @return The current MediaMetadata or null.
+     */
+    public MediaMetadata getMetadata() {
+        try {
+            return mBinder.getMetadata();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getMetadata.", e);
+            return null;
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public final void postPlaybackStateChanged(PlaybackState state) {
+        synchronized (mLock) {
+            for (int i = mListeners.size() - 1; i >= 0; i--) {
+                mListeners.get(i).post(MessageHandler.MSG_UPDATE_PLAYBACK_STATE, state);
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public final void postMetadataChanged(MediaMetadata metadata) {
+        synchronized (mLock) {
+            for (int i = mListeners.size() - 1; i >= 0; i--) {
+                mListeners.get(i).post(MessageHandler.MSG_UPDATE_METADATA,
+                        metadata);
+            }
+        }
+    }
+
+    private MessageHandler getHandlerForListenerLocked(TransportStateListener listener) {
+        for (int i = mListeners.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mListeners.get(i);
+            if (listener == handler.mListener) {
+                return handler;
+            }
+        }
+        return null;
+    }
+
+    private boolean removeStateListenerLocked(TransportStateListener listener) {
+        for (int i = mListeners.size() - 1; i >= 0; i--) {
+            if (listener == mListeners.get(i).mListener) {
+                mListeners.remove(i);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Register using {@link #addStateListener} to receive updates when there
+     * are playback changes on the session.
+     */
+    public static abstract class TransportStateListener {
+        private MessageHandler mHandler;
+        /**
+         * Override to handle changes in playback state.
+         *
+         * @param state The new playback state of the session
+         */
+        public void onPlaybackStateChanged(PlaybackState state) {
+        }
+
+        /**
+         * Override to handle changes to the current metadata.
+         *
+         * @see MediaMetadata
+         * @param metadata The current metadata for the session or null
+         */
+        public void onMetadataChanged(MediaMetadata metadata) {
+        }
+
+        private void setHandler(Handler handler) {
+            mHandler = new MessageHandler(handler.getLooper(), this);
+        }
+    }
+
+    private static class MessageHandler extends Handler {
+        private static final int MSG_UPDATE_PLAYBACK_STATE = 1;
+        private static final int MSG_UPDATE_METADATA = 2;
+
+        private TransportStateListener mListener;
+
+        public MessageHandler(Looper looper, TransportStateListener cb) {
+            super(looper, null, true);
+            mListener = cb;
+        }
+
+        public void post(int msg, Object obj) {
+            obtainMessage(msg, obj).sendToTarget();
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_UPDATE_PLAYBACK_STATE:
+                    mListener.onPlaybackStateChanged((PlaybackState) msg.obj);
+                    break;
+                case MSG_UPDATE_METADATA:
+                    mListener.onMetadataChanged((MediaMetadata) msg.obj);
+                    break;
+            }
+        }
+    }
+
+}
diff --git a/media/java/android/media/session/TransportPerformer.java b/media/java/android/media/session/TransportPerformer.java
new file mode 100644
index 0000000..b96db20
--- /dev/null
+++ b/media/java/android/media/session/TransportPerformer.java
@@ -0,0 +1,357 @@
+/*
+ * 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.media.session;
+
+import android.media.AudioManager;
+import android.media.Rating;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * Allows broadcasting of playback changes.
+ */
+public final class TransportPerformer {
+    private static final String TAG = "TransportPerformer";
+    private final Object mLock = new Object();
+    private final ArrayList<MessageHandler> mListeners = new ArrayList<MessageHandler>();
+
+    private IMediaSession mBinder;
+
+    /**
+     * @hide
+     */
+    public TransportPerformer(IMediaSession binder) {
+        mBinder = binder;
+    }
+
+    /**
+     * Add a listener to receive updates on.
+     *
+     * @param listener The callback object
+     */
+    public void addListener(Listener listener) {
+        addListener(listener, null);
+    }
+
+    /**
+     * Add a listener to receive updates on. The updates will be posted to the
+     * specified handler. If no handler is provided they will be posted to the
+     * caller's thread.
+     *
+     * @param listener The listener to receive updates on
+     * @param handler The handler to post the updates on
+     */
+    public void addListener(Listener listener, Handler handler) {
+        if (listener == null) {
+            throw new IllegalArgumentException("Listener cannot be null");
+        }
+        synchronized (mLock) {
+            if (getHandlerForListenerLocked(listener) != null) {
+                Log.w(TAG, "Listener is already added, ignoring");
+            }
+            if (handler == null) {
+                handler = new Handler();
+            }
+            MessageHandler msgHandler = new MessageHandler(handler.getLooper(), listener);
+            mListeners.add(msgHandler);
+        }
+    }
+
+    /**
+     * Stop receiving updates on the specified handler. If an update has already
+     * been posted you may still receive it after this call returns.
+     *
+     * @param listener The listener to stop receiving updates on
+     */
+    public void removeListener(Listener listener) {
+        if (listener == null) {
+            throw new IllegalArgumentException("Listener cannot be null");
+        }
+        synchronized (mLock) {
+            removeListenerLocked(listener);
+        }
+    }
+
+    /**
+     * Update the current playback state.
+     *
+     * @param state The current state of playback
+     */
+    public final void setPlaybackState(PlaybackState state) {
+        try {
+            mBinder.setPlaybackState(state);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
+        }
+    }
+
+    /**
+     * Update the current metadata. New metadata can be created using
+     * {@link MediaMetadata.Builder}.
+     *
+     * @param metadata The new metadata
+     */
+    public final void setMetadata(MediaMetadata metadata) {
+        try {
+            mBinder.setMetadata(metadata);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public final void onPlay() {
+        post(MessageHandler.MESSAGE_PLAY);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onPause() {
+        post(MessageHandler.MESSAGE_PAUSE);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onStop() {
+        post(MessageHandler.MESSAGE_STOP);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onNext() {
+        post(MessageHandler.MESSAGE_NEXT);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onPrevious() {
+        post(MessageHandler.MESSAGE_PREVIOUS);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onFastForward() {
+        post(MessageHandler.MESSAGE_FAST_FORWARD);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onRewind() {
+        post(MessageHandler.MESSAGE_REWIND);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onSeekTo(long pos) {
+        post(MessageHandler.MESSAGE_SEEK_TO, pos);
+    }
+
+    /**
+     * @hide
+     */
+    public final void onRate(Rating rating) {
+        post(MessageHandler.MESSAGE_RATE, rating);
+    }
+
+    private MessageHandler getHandlerForListenerLocked(Listener listener) {
+        for (int i = mListeners.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mListeners.get(i);
+            if (listener == handler.mListener) {
+                return handler;
+            }
+        }
+        return null;
+    }
+
+    private boolean removeListenerLocked(Listener listener) {
+        for (int i = mListeners.size() - 1; i >= 0; i--) {
+            if (listener == mListeners.get(i).mListener) {
+                mListeners.remove(i);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void post(int what, Object obj) {
+        synchronized (mLock) {
+            for (int i = mListeners.size() - 1; i >= 0; i--) {
+                mListeners.get(i).post(what, obj);
+            }
+        }
+    }
+
+    private void post(int what) {
+        post(what, null);
+    }
+
+    /**
+     * Extend Listener to handle transport controls. Listeners can be registered
+     * using {@link #addListener}.
+     */
+    public static abstract class Listener {
+
+        /**
+         * Override to handle requests to begin playback.
+         */
+        public void onPlay() {
+        }
+
+        /**
+         * Override to handle requests to pause playback.
+         */
+        public void onPause() {
+        }
+
+        /**
+         * Override to handle requests to skip to the next media item.
+         */
+        public void onNext() {
+        }
+
+        /**
+         * Override to handle requests to skip to the previous media item.
+         */
+        public void onPrevious() {
+        }
+
+        /**
+         * Override to handle requests to fast forward.
+         */
+        public void onFastForward() {
+        }
+
+        /**
+         * Override to handle requests to rewind.
+         */
+        public void onRewind() {
+        }
+
+        /**
+         * Override to handle requests to stop playback.
+         */
+        public void onStop() {
+        }
+
+        /**
+         * Override to handle requests to seek to a specific position in ms.
+         *
+         * @param pos New position to move to, in milliseconds.
+         */
+        public void onSeekTo(long pos) {
+        }
+
+        /**
+         * Override to handle the item being rated.
+         *
+         * @param rating
+         */
+        public void onRate(Rating rating) {
+        }
+
+        /**
+         * Report that audio focus has changed on the app. This only happens if
+         * you have indicated you have started playing with
+         * {@link #setPlaybackState}. TODO figure out route focus apis/handling.
+         *
+         * @param focusChange The type of focus change, TBD. The default
+         *            implementation will deliver a call to {@link #onPause}
+         *            when focus is lost.
+         */
+        public void onRouteFocusChange(int focusChange) {
+            switch (focusChange) {
+                case AudioManager.AUDIOFOCUS_LOSS:
+                    onPause();
+                    break;
+            }
+        }
+    }
+
+    private class MessageHandler extends Handler {
+        private static final int MESSAGE_PLAY = 1;
+        private static final int MESSAGE_PAUSE = 2;
+        private static final int MESSAGE_STOP = 3;
+        private static final int MESSAGE_NEXT = 4;
+        private static final int MESSAGE_PREVIOUS = 5;
+        private static final int MESSAGE_FAST_FORWARD = 6;
+        private static final int MESSAGE_REWIND = 7;
+        private static final int MESSAGE_SEEK_TO = 8;
+        private static final int MESSAGE_RATE = 9;
+
+        private Listener mListener;
+
+        public MessageHandler(Looper looper, Listener cb) {
+            super(looper);
+            mListener = cb;
+        }
+
+        public void post(int what, Object obj) {
+            obtainMessage(what, obj).sendToTarget();
+        }
+
+        public void post(int what) {
+            post(what, null);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MESSAGE_PLAY:
+                    mListener.onPlay();
+                    break;
+                case MESSAGE_PAUSE:
+                    mListener.onPause();
+                    break;
+                case MESSAGE_STOP:
+                    mListener.onStop();
+                    break;
+                case MESSAGE_NEXT:
+                    mListener.onNext();
+                    break;
+                case MESSAGE_PREVIOUS:
+                    mListener.onPrevious();
+                    break;
+                case MESSAGE_FAST_FORWARD:
+                    mListener.onFastForward();
+                    break;
+                case MESSAGE_REWIND:
+                    mListener.onRewind();
+                    break;
+                case MESSAGE_SEEK_TO:
+                    mListener.onSeekTo((Long) msg.obj);
+                    break;
+                case MESSAGE_RATE:
+                    mListener.onRate((Rating) msg.obj);
+                    break;
+            }
+        }
+    }
+}
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 2ddbb7d..15ae238 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -596,6 +596,11 @@
             MtpConstants.PROPERTY_DURATION,
             MtpConstants.PROPERTY_GENRE,
             MtpConstants.PROPERTY_COMPOSER,
+            MtpConstants.PROPERTY_AUDIO_WAVE_CODEC,
+            MtpConstants.PROPERTY_BITRATE_TYPE,
+            MtpConstants.PROPERTY_AUDIO_BITRATE,
+            MtpConstants.PROPERTY_NUMBER_OF_CHANNELS,
+            MtpConstants.PROPERTY_SAMPLE_RATE,
     };
 
     static final int[] VIDEO_PROPERTIES = {
diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp
index d475eee..fcd425e 100644
--- a/media/jni/android_media_ImageReader.cpp
+++ b/media/jni/android_media_ImageReader.cpp
@@ -86,8 +86,8 @@
     void setCpuConsumer(const sp<CpuConsumer>& consumer) { mConsumer = consumer; }
     CpuConsumer* getCpuConsumer() { return mConsumer.get(); }
 
-    void setBufferQueue(const sp<BufferQueue>& bq) { mBufferQueue = bq; }
-    BufferQueue* getBufferQueue() { return mBufferQueue.get(); }
+    void setProducer(const sp<IGraphicBufferProducer>& producer) { mProducer = producer; }
+    IGraphicBufferProducer* getProducer() { return mProducer.get(); }
 
     void setBufferFormat(int format) { mFormat = format; }
     int getBufferFormat() { return mFormat; }
@@ -104,7 +104,7 @@
 
     List<CpuConsumer::LockedBuffer*> mBuffers;
     sp<CpuConsumer> mConsumer;
-    sp<BufferQueue> mBufferQueue;
+    sp<IGraphicBufferProducer> mProducer;
     jobject mWeakThiz;
     jclass mClazz;
     int mFormat;
@@ -222,7 +222,7 @@
     return ctx->getCpuConsumer();
 }
 
-static BufferQueue* ImageReader_getBufferQueue(JNIEnv* env, jobject thiz)
+static IGraphicBufferProducer* ImageReader_getProducer(JNIEnv* env, jobject thiz)
 {
     ALOGV("%s:", __FUNCTION__);
     JNIImageReaderContext* const ctx = ImageReader_getContext(env, thiz);
@@ -230,7 +230,7 @@
         jniThrowRuntimeException(env, "ImageReaderContext is not initialized");
         return NULL;
     }
-    return ctx->getBufferQueue();
+    return ctx->getProducer();
 }
 
 static void ImageReader_setNativeContext(JNIEnv* env,
@@ -613,8 +613,10 @@
 
     nativeFormat = Image_getPixelFormat(env, format);
 
-    sp<BufferQueue> bq = new BufferQueue();
-    sp<CpuConsumer> consumer = new CpuConsumer(bq, maxImages,
+    sp<IGraphicBufferProducer> gbProducer;
+    sp<IGraphicBufferConsumer> gbConsumer;
+    BufferQueue::createBufferQueue(&gbProducer, &gbConsumer);
+    sp<CpuConsumer> consumer = new CpuConsumer(gbConsumer, maxImages,
                                                /*controlledByApp*/true);
     // TODO: throw dvm exOutOfMemoryError?
     if (consumer == NULL) {
@@ -629,7 +631,7 @@
     }
     sp<JNIImageReaderContext> ctx(new JNIImageReaderContext(env, weakThiz, clazz, maxImages));
     ctx->setCpuConsumer(consumer);
-    ctx->setBufferQueue(bq);
+    ctx->setProducer(gbProducer);
     consumer->setFrameAvailableListener(ctx);
     ImageReader_setNativeContext(env, thiz, ctx);
     ctx->setBufferFormat(nativeFormat);
@@ -794,14 +796,14 @@
 {
     ALOGV("%s: ", __FUNCTION__);
 
-    BufferQueue* bq = ImageReader_getBufferQueue(env, thiz);
-    if (bq == NULL) {
+    IGraphicBufferProducer* gbp = ImageReader_getProducer(env, thiz);
+    if (gbp == NULL) {
         jniThrowRuntimeException(env, "CpuConsumer is uninitialized");
         return NULL;
     }
 
     // Wrap the IGBP in a Java-language Surface.
-    return android_view_Surface_createFromIGraphicBufferProducer(env, bq);
+    return android_view_Surface_createFromIGraphicBufferProducer(env, gbp);
 }
 
 static jobject Image_createSurfacePlane(JNIEnv* env, jobject thiz, int idx)
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index ea75a18..82c6a80 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -1000,6 +1000,22 @@
 
 MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
                                             MtpObjectFormat format) {
+    static const int channelEnum[] = {
+                                        1,  // mono
+                                        2,  // stereo
+                                        3,  // 2.1
+                                        4,  // 3
+                                        5,  // 3.1
+                                        6,  // 4
+                                        7,  // 4.1
+                                        8,  // 5
+                                        9,  // 5.1
+                                    };
+    static const int bitrateEnum[] = {
+                                        1,  // fixed rate
+                                        2,  // variable rate
+                                     };
+
     MtpProperty* result = NULL;
     switch (property) {
         case MTP_PROPERTY_OBJECT_FORMAT:
@@ -1013,6 +1029,7 @@
         case MTP_PROPERTY_STORAGE_ID:
         case MTP_PROPERTY_PARENT_OBJECT:
         case MTP_PROPERTY_DURATION:
+        case MTP_PROPERTY_AUDIO_WAVE_CODEC:
             result = new MtpProperty(property, MTP_TYPE_UINT32);
             break;
         case MTP_PROPERTY_OBJECT_SIZE:
@@ -1041,6 +1058,22 @@
             // We allow renaming files and folders
             result = new MtpProperty(property, MTP_TYPE_STR, true);
             break;
+        case MTP_PROPERTY_BITRATE_TYPE:
+             result = new MtpProperty(property, MTP_TYPE_UINT16);
+            result->setFormEnum(bitrateEnum, sizeof(bitrateEnum)/sizeof(bitrateEnum[0]));
+            break;
+        case MTP_PROPERTY_AUDIO_BITRATE:
+            result = new MtpProperty(property, MTP_TYPE_UINT32);
+            result->setFormRange(1, 1536000, 1);
+            break;
+        case MTP_PROPERTY_NUMBER_OF_CHANNELS:
+            result = new MtpProperty(property, MTP_TYPE_UINT16);
+            result->setFormEnum(channelEnum, sizeof(channelEnum)/sizeof(channelEnum[0]));
+            break;
+        case MTP_PROPERTY_SAMPLE_RATE:
+            result = new MtpProperty(property, MTP_TYPE_UINT32);
+            result->setFormRange(8000, 48000, 1);
+            break;
     }
 
     return result;
diff --git a/media/mca/filterfw/native/core/gl_env.cpp b/media/mca/filterfw/native/core/gl_env.cpp
index 84dad8c..f092af8 100644
--- a/media/mca/filterfw/native/core/gl_env.cpp
+++ b/media/mca/filterfw/native/core/gl_env.cpp
@@ -162,9 +162,11 @@
   }
 
   // Create dummy surface using a GLConsumer
-  sp<BufferQueue> bq = new BufferQueue();
-  surfaceTexture_ = new GLConsumer(bq, 0);
-  window_ = new Surface(static_cast<sp<IGraphicBufferProducer> >(bq));
+  sp<IGraphicBufferProducer> producer;
+  sp<IGraphicBufferConsumer> consumer;
+  BufferQueue::createBufferQueue(&producer, &consumer);
+  surfaceTexture_ = new GLConsumer(consumer, 0);
+  window_ = new Surface(producer);
 
   surfaces_[0] = SurfaceWindowPair(eglCreateWindowSurface(display(), config, window_.get(), NULL), NULL);
   if (CheckEGLError("eglCreateWindowSurface")) return false;
diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
index 1c1ba8b..f1be722 100644
--- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml
+++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml
@@ -44,7 +44,7 @@
     <string name="root_type_shortcut" msgid="3318760609471618093">"Atalhos"</string>
     <string name="root_type_device" msgid="7121342474653483538">"Dispositivos"</string>
     <string name="root_type_apps" msgid="8838065367985945189">"Mais aplicações"</string>
-    <string name="pref_advanced_devices" msgid="903257239609301276">"Apresentar dispositivos avançados"</string>
+    <string name="pref_advanced_devices" msgid="903257239609301276">"Ver dispositivos avançados"</string>
     <string name="pref_file_size" msgid="2826879315743961459">"Apresentar tamanho do ficheiro"</string>
     <string name="pref_device_size" msgid="3542106883278997222">"Apresentar tamanho do dispositivo"</string>
     <string name="empty" msgid="7858882803708117596">"Sem itens"</string>
diff --git a/packages/Keyguard/res/values-am/strings.xml b/packages/Keyguard/res/values-am/strings.xml
index ebe678e..933ef9c 100644
--- a/packages/Keyguard/res/values-am/strings.xml
+++ b/packages/Keyguard/res/values-am/strings.xml
@@ -82,7 +82,7 @@
     <string name="password_keyboard_label_alpha_key" msgid="8001096175167485649">"ABC"</string>
     <string name="password_keyboard_label_alt_key" msgid="1284820942620288678">"ALT"</string>
     <string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Alt"</string>
-    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ተወው"</string>
+    <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ይቅር"</string>
     <string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ሰርዝ"</string>
     <string name="keyboardview_keycode_done" msgid="1992571118466679775">"ተከናውኗል"</string>
     <string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"ሞድ ለውጥ"</string>
diff --git a/packages/PrintSpooler/res/values-am/strings.xml b/packages/PrintSpooler/res/values-am/strings.xml
index 3b94d6d..d86acb86cb 100644
--- a/packages/PrintSpooler/res/values-am/strings.xml
+++ b/packages/PrintSpooler/res/values-am/strings.xml
@@ -58,7 +58,7 @@
     <item quantity="one" msgid="5866624638054847057">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> የህትመት ስራ"</item>
     <item quantity="other" msgid="8746611264734222865">"<xliff:g id="PRINT_JOB_NAME">%1$d</xliff:g> የህትመት ስራዎች"</item>
   </plurals>
-    <string name="cancel" msgid="4373674107267141885">"ሰርዝ"</string>
+    <string name="cancel" msgid="4373674107267141885">"ይቅር"</string>
     <string name="restart" msgid="2472034227037808749">"እንደገና ጀምር"</string>
     <string name="no_connection_to_printer" msgid="2159246915977282728">"ከአታሚ ጋር ምንም ግንኙነት የለም"</string>
     <string name="reason_unknown" msgid="5507940196503246139">"አይታወቅም"</string>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 56c1f4e..1693e01 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -58,12 +58,6 @@
             android:layout_height="@dimen/notification_panel_header_height"
             />
 
-        <com.android.systemui.statusbar.phone.ZenModeView
-            android:id="@+id/zenmode"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            />
-
         <TextView
             android:id="@+id/emergency_calls_only"
             android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Network.EmergencyOnly"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 25c516b..9aa7cfd 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -15,7 +15,7 @@
 ** limitations under the License.
 -->
 
-<com.android.systemui.statusbar.phone.PanelHeaderView
+<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
     android:id="@+id/header"
@@ -106,4 +106,4 @@
             android:contentDescription="@string/accessibility_notifications_button"
             />
     </FrameLayout>
-</com.android.systemui.statusbar.phone.PanelHeaderView>
+</LinearLayout>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 31428b4..98d132a 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Kleur-omkeringmodus"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Verbeterde kontrasmodus"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Kleurregstellingmodus"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ONLANGS"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netwerk word\ndalk gemonitor"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Soek"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Gly op vir <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index e393c90..d7457f0 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"የተቃራኒ ቀለም ሁነታ"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"የተሻሻለ ንፅፅር ሁነታ"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"የቀለም እርማት ሁነታ"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"የቅርብ ጊዜዎች"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"አውታረ መረብ\nክትትል ሊደረግበት ይችላል"</string>
     <string name="description_target_search" msgid="3091587249776033139">"ፍለጋ"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"ለ<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ወደ ላይ አንሸራትት።"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 0060004..596f612 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"وضع انعكاس اللون"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"وضع التباين المحسن"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"وضع تصحيح الألوان"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"الأخيرة"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"قد تكون الشبكة\nخاضعة للرقابة"</string>
     <string name="description_target_search" msgid="3091587249776033139">"بحث"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"تمرير لأعلى لـ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 1488864..335c33a 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим на инвертиране на цветовете"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим на подобрен контраст"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим на коригиране на цветовете"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"СКОРОШНИ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мрежата може\nда се наблюдава"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Търсене"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Плъзнете нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 329e91f..e79e094 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversió de color"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode de contrast millorat"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correcció de color"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"És possible que la xarxa\nestigui controlada"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Cerca"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Fes lliscar el dit cap amunt per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index b326220..60bbe3b 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Režim převrácení barev"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Režim zvýšeného kontrastu"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Režim korekce barev"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"POSLEDNÍ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Síť může být\nmonitorována"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Vyhledávání"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Přejeďte prstem nahoru: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index f0db449..9c920f2 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Farveinverteringstilstand"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Tilstand for forbedret kontrast"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Farvekorrigeringstilstand"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"SENESTE"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netværket kan\nvære overvåget"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Søgning"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Glid op for at <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index fd41752..c8cb0a4 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Farbinversionsmodus"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastverbesserungsmodus"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Farbkorrekturmodus"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"Letzte"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netzwerk wird\neventuell überwacht."</string>
     <string name="description_target_search" msgid="3091587249776033139">"Suche"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Zum <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> nach oben schieben"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 96e2aaa..79025b6 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Λειτουργία αναστροφής χρώματος"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Λειτουργία βελτίωσης αντίθεσης"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Λειτουργία διόρθωσης χρώματος"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ΠΡΟΣΦΑΤΑ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Το δίκτυο μπορεί\nνα παρακολουθείται"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Αναζήτηση"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Κύλιση προς τα επάνω για <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 342061e..338c8ac 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Colour inversion mode"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Enhanced contrast mode"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Colour correction mode"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 342061e..338c8ac 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Colour inversion mode"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Enhanced contrast mode"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Colour correction mode"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTS"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Network may\nbe monitored"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Search"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Slide up for <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index a82e2d7..89fe58b 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversión de color"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste mejorado"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de corrección de color"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECIENTES"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Es posible que la red\nesté supervisada."</string>
     <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 2a977ee..4999f71 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversión de color"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste mejorado"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de corrección de color"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECIENTES"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"La red se\npuede supervisar"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Buscar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Desliza el dedo hacia arriba para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 821c1dd..b734fa8 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Värvide ümberpööramise režiim"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Täiustatud kontrasti režiim"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Värviparandusrežiim"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"HILJUTISED"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Võrku võidakse\njälgida"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Otsing"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Lohistage üles: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 2cb40a0..5780a57 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"حالت وارونگی رنگ"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"حالت کنتراست بهبودیافته"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"حالت تصحیح رنگ"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"موارد اخیر"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ممکن است شبکه\nتحت نظارت باشد"</string>
     <string name="description_target_search" msgid="3091587249776033139">"جستجو"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"لغزاندن به بالا برای <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 41a0bd4..4809741 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Käänteinen väritila"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastinparannustila"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Värinkorjaustila"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"VIIMEISIMMÄT"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Verkkoa saatetaan\nvalvoa"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Haku"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Liu\'uta ylös ja <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 60823b5..36b54ce 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversion des couleurs"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode d\'accentuation du contraste"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correction des couleurs"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RÉCENTS"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Le réseau peut\nêtre surveillé."</string>
     <string name="description_target_search" msgid="3091587249776033139">"Recherche"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Faire glisser le doigt vers le haut : <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 5d6368e..5b81975 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode d\'inversion des couleurs"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode d\'accentuation du contraste"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode de correction des couleurs"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RÉCENTS"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Le réseau peut\nêtre surveillé."</string>
     <string name="description_target_search" msgid="3091587249776033139">"Rechercher"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Faites glisser vers le haut pour <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 3167fe7..9be9550 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"रंग व्युत्क्रम मोड"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"उन्नत कंट्रास्ट मोड"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"रंग सुधार मोड"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"हाल ही का"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"नेटवर्क को\nमॉनीटर किया जा सकता है"</string>
     <string name="description_target_search" msgid="3091587249776033139">"खोजें"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> के लिए ऊपर स्‍लाइड करें."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 529f891..21d6ef5 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Način inverzije boje"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Način pojačanog kontrasta"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Način korekcije boje"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"NEDAVNO"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mreža se\nmožda prati"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Pretraživanje"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Kliznite prema gore za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 7e064dd..8e6ee4f 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Színinvertálás mód"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrasztjavítás mód"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Színjavítás mód"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"LEGUTÓBBIAK"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Lehet, hogy a\nhálózat felügyelt"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Keresés"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"A(z) <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> művelethez csúsztassa felfelé."</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index 1124163..a787983 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Գունաշրջման ռեժիմ"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Ընդլայնված ցայտունության ռեժիմ"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Գույների կարգավորման ռեժիմ"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ՎԵՐՋԻՆՆԵՐԸ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Ցանցը կարող է\nվերահսկվել"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Որոնել"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Սահեցրեք վերև <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-ի համար:"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 167b101..13fc534 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode inversi warna"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode kontras yang disempurnakan"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode koreksi warna"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"TERBARU"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Jaringan bisa\ndiawasi"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Telusuri"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Geser ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 6321870..71a644d 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modalità inversione colori"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modalità di contrasto avanzata"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modalità di correzione del colore"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ELEMENTI RECENTI"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"La rete potrebbe\nessere monitorata"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Ricerca"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Su per <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 24114f7..798e8c3 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"מצב היפוך צבעים"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"מצב ניגודיות מוגברת"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"מצב תיקון צבע"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"אחרונים"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ייתכן שהרשת\nמנוטרת"</string>
     <string name="description_target_search" msgid="3091587249776033139">"חיפוש"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"הסט למעלה כדי להציג <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 0bee9f0..c5070a8 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"色反転モード"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"拡張コントラストモード"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"色補正モード"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"最近"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ネットワークが監視される\n場合があります"</string>
     <string name="description_target_search" msgid="3091587249776033139">"検索します"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"上にスライドして<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>を行います。"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index fe0a047..bbdce19 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"ფერთა ინვერსიის რეჟიმი"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"გაუმჯობესებული კონტრასტის რეჟიმი"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"ფერთა კორექციის რეჟიმი"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ბოლო დროის"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"შესაძლოა ქსელზე\nმონიტორინგი ხორციელდებოდეს"</string>
     <string name="description_target_search" msgid="3091587249776033139">"ძიება"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"გაასრიალეთ ზემოთ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-თვის."</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 470309a..61ca77d 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"របៀប​​បញ្ច្រាស​ពណ៌"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"របៀប​កម្រិត​ពណ៌​ប្រ​សើ​រ​ឡើង"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"របៀប​កែ​ពណ៌"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ថ្មីៗ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"បណ្ដាញ​អាច​\nត្រូវ​បាន​ត្រួតពិនិត្យ"</string>
     <string name="description_target_search" msgid="3091587249776033139">"ស្វែងរក"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"រុញ​ឡើង​លើ​ដើម្បី <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ។"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index f72549d..8108daa 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"색상 반전 모드"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"향상된 대비 모드"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"색상 보정 모드"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"최근"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"네트워크가\n모니터링될 수 있음"</string>
     <string name="description_target_search" msgid="3091587249776033139">"검색"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>하려면 위로 슬라이드"</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 59cf520..c2e5990 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"ໂໝດສະລັບສີ"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"ໂໝດຄວາມຕ່າງແສງ"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"ໂໝດການແກ້ໄຂສີ"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ບໍ່​ດົນ​ມາ​ນີ້"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"ເຄືອຄ່າຍອາດ\nຖືກຕິດຕາມ"</string>
     <string name="description_target_search" msgid="3091587249776033139">"ຊອກຫາ"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"ເລື່ອນຂຶ້ນເພື່ອ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 29ca84a9..1d8b051 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Spalvų inversijos režimas"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Patobulinto kontrasto režimas"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Spalvų taisymo režimas"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"PASTARIEJI"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Tinklas gali\nbūti stebimas"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Paieška"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Slyskite aukštyn link <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 4230b2e..603fa1a 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Krāsu inversijas režīms"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Uzlabota kontrasta režīms"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Krāsu korekcijas režīms"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"JAUNĀKIE"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Tīkls var\ntikt uzraudzīts"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Meklēt"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Velciet uz augšu, lai veiktu šādu darbību: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index d6c68bc..110cfd2 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Өнгө урвуулах горим"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Сайжруулсан ялгаралтай горим"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Өнгө залруулах горим"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"СҮҮЛИЙН"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Сүлжээ хянагдаж\nбайж болзошгүй"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Хайх"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>-г гулсуулах."</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 114d03e..62c90ab 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mod penyongsangan warna"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mod kontras dipertingkat"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mod pembetulan warna"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"TERBAHARU"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Rangkaian mungkin\nboleh dipantau"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Carian"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Luncurkan ke atas untuk <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 12deaef..0e914ea 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modus for fargeinvertering"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Forbedret kontrastmodus"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modus for fargekorrigering"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"NYLIGE"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Nettverket kan\nvære overvåket"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Søk"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Dra opp for å <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 59c64b5..6e09131 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modus voor kleurinversie"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modus voor verbeterd contrast"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modus voor kleurcorrectie"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTEN"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Netwerk kan\nworden gecontroleerd"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Zoeken"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Veeg omhoog voor <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index b2628e1..c21230c 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Tryb odwrócenia kolorów"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Tryb zwiększonego kontrastu"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Tryb korekcji kolorów"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"OSTATNIE"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Sieć może być\nmonitorowana"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Szukaj"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Przesuń w górę: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index fc25ea8..771daf2 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversão de cor"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste melhorado"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de correção de cor"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTES"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"A rede pode ser\nmonitorizada"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Deslize para cima para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index e077fc6..b643bae 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Modo de inversão de cores"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Modo de contraste aprimorado"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Modo de correção de cor"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTES"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"A rede pode estar\nsob monitoração"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Pesquisar"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Para <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>, deslize para cima."</string>
diff --git a/packages/SystemUI/res/values-rm/strings.xml b/packages/SystemUI/res/values-rm/strings.xml
index adf54bc..33cb355 100644
--- a/packages/SystemUI/res/values-rm/strings.xml
+++ b/packages/SystemUI/res/values-rm/strings.xml
@@ -378,6 +378,8 @@
     <skip />
     <!-- no translation found for quick_settings_color_space_label (853443689745584770) -->
     <skip />
+    <!-- no translation found for recents_empty_message (2269156590813544104) -->
+    <skip />
     <!-- no translation found for ssl_ca_cert_warning (9005954106902053641) -->
     <skip />
     <!-- no translation found for description_target_search (3091587249776033139) -->
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 9cfb329..87f9c0c 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mod de inversare a culorilor"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mod contrast îmbunătățit"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mod de corectare a culorilor"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"RECENTE"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Rețeaua poate\nfi monitorizată"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Căutaţi"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Glisaţi în sus pentru <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 7a89d27..e79a0dd 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -208,6 +208,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Инверсия цвета"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Контрастность"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Коррекция цвета"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"НЕДАВНИЕ СООБЩЕНИЯ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Действия в сети\nмогут отслеживаться"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Поиск"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Проведите вверх, чтобы <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 13c60946..d39c8bd 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Režim prevrátenia farieb"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Režim zvýšeného kontrastu"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Režim korekcie farieb"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"NEDÁVNE"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Sieť môže byť\nmonitorovaná"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Vyhľadávanie"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Prejdite prstom nahor: <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index a5b3244..c49b6c2 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Način inverzije barv"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Način izboljšanega kontrasta"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Način popravljanja barv"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"NEDAVNI"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Omrežje je\nlahko spremljano"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Iskanje"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Povlecite navzgor za <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 0bdccee..89bc3c5 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим инверзије боје"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим унапређеног контраста"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим корекције боје"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"НАЈНОВИЈЕ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мрежа се можда\nнадгледа"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Претрага"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Превуците нагоре за <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index efe7fcb..1b47be5 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Färginverteringsläge"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Kontrastförbättringsläge"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Färgkorrigeringsläge"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"NYA"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Nätverket kan\nvara övervakat"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Sök"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Dra uppåt för <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 9336ade..3702196 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -202,6 +202,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Hali ya ugeuzaji kinyume wa rangi"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Hali ya utofautishaji ulioboreshwa"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Hali ya kusahihisha rangi"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"YA HIVI KARIBUNI"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Huenda mtandao\nunafuatiliwa"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Tafuta"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Sogeza juu kwa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> ."</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 033e56d..0d9be4c 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"โหมดการกลับสี"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"โหมดคอนทราสต์ที่ปรับปรุงแล้ว"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"โหมดการแก้ไขสี"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ล่าสุด"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"เครือข่ายอาจ\nถูกตรวจสอบ"</string>
     <string name="description_target_search" msgid="3091587249776033139">"ค้นหา"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"เลื่อนขึ้นเพื่อ <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 3704c48..d7502cb 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Mode ng pag-invert ng kulay"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Mode na dinagdagan ang contrast"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Mode ng pagtatama ng kulay"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"MGA KAMAKAILAN"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Maaaring\nsinusubaybayan ang network"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Maghanap"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Mag-slide pataas para sa <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 56e5c88..f56293b 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Renk ters çevirme modu"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Geliştirilmiş kontrast modu"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Renk düzeltme modu"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"SON İLETİLER"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Ağ izleniyor\nolabilir"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Ara"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g> için yukarı kaydırın."</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 3a474a4..df94b26 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Режим інверсії кольорів"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Режим посиленого контрасту"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Режим коригування кольору"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"ОСТАННІ"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Мережа може\nвідстежуватися"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Пошук"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Проведіть пальцем угору, щоб <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 700c20d..471cbd3 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Chế độ đảo ngược màu sắc"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Chế độ tương phản tăng cường"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Chế độ hiệu chỉnh màu sắc"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"GẦN ĐÂY"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Mạng có thể\nđược giám sát"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Tìm kiếm"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Trượt lên để <xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 5909fbf..e53c1fb 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"颜色反转模式"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"增强对比度模式"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"颜色校正模式"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"最近"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"网络可能会\n受到监控"</string>
     <string name="description_target_search" msgid="3091587249776033139">"搜索"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"向上滑动以<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index d229347..d4defa4 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"色彩反轉模式"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"增強對比模式"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校準模式"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"近期"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"網絡可能會\n受到監控"</string>
     <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index bf2d7ce..55399c2 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -206,6 +206,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"彩色反轉模式"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"增強對比模式"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"色彩校正模式"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"近期"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"網路可能\n受到監控"</string>
     <string name="description_target_search" msgid="3091587249776033139">"搜尋"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"向上滑動即可<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index d676b5c..92e3382 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -204,6 +204,7 @@
     <string name="quick_settings_inversion_label" msgid="1666358784283020762">"Imodi yokuguqulwa kombala"</string>
     <string name="quick_settings_contrast_label" msgid="3319507551689108692">"Imodi ethuthukisiwe yokugqama"</string>
     <string name="quick_settings_color_space_label" msgid="853443689745584770">"Imodi yokulungisa umbala"</string>
+    <string name="recents_empty_message" msgid="2269156590813544104">"OKWAKAMUVA"</string>
     <string name="ssl_ca_cert_warning" msgid="9005954106902053641">"Kungenzeka inethiwekhi\niqashiwe"</string>
     <string name="description_target_search" msgid="3091587249776033139">"Sesha"</string>
     <string name="description_direction_up" msgid="7169032478259485180">"Shelelisela ngenhla ku-<xliff:g id="TARGET_DESCRIPTION">%s</xliff:g>."</string>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
index c714d8b..9d2d6ee 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentTasksLoader.java
@@ -367,8 +367,9 @@
     public TaskDescription loadFirstTask() {
         final ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
 
-        final List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasksForUser(
-                1, ActivityManager.RECENT_IGNORE_UNAVAILABLE, UserHandle.CURRENT.getIdentifier());
+        final List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasksForUser(1,
+                ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED,
+                UserHandle.CURRENT.getIdentifier());
         TaskDescription item = null;
         if (recentTasks.size() > 0) {
             ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(0);
@@ -439,7 +440,8 @@
                 mContext.getSystemService(Context.ACTIVITY_SERVICE);
 
                 final List<ActivityManager.RecentTaskInfo> recentTasks =
-                        am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
+                        am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE
+                        | ActivityManager.RECENT_INCLUDE_RELATED);
                 int numTasks = recentTasks.size();
                 ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN)
                         .addCategory(Intent.CATEGORY_HOME).resolveActivityInfo(pm, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Recents.java b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
index 07c0c78..56acf04 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Recents.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Recents.java
@@ -107,8 +107,10 @@
     final static int MSG_UPDATE_TASK_THUMBNAIL = 1;
     final static int MSG_PRELOAD_TASKS = 2;
     final static int MSG_CANCEL_PRELOAD_TASKS = 3;
+    final static int MSG_CLOSE_RECENTS = 4;
+    final static int MSG_TOGGLE_RECENTS = 5;
 
-    final static String sToggleRecentsAction = "com.android.systemui.recents.TOGGLE_RECENTS";
+    final static String sToggleRecentsAction = "com.android.systemui.recents.SHOW_RECENTS";
     final static String sRecentsPackage = "com.android.systemui";
     final static String sRecentsActivity = "com.android.systemui.recents.RecentsActivity";
     final static String sRecentsService = "com.android.systemui.recents.RecentsService";
@@ -357,7 +359,8 @@
     Bitmap loadFirstTaskThumbnail() {
         ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
         List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1,
-                ActivityManager.RECENT_IGNORE_UNAVAILABLE, UserHandle.CURRENT.getIdentifier());
+                ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED,
+                UserHandle.CURRENT.getIdentifier());
         for (ActivityManager.RecentTaskInfo t : tasks) {
             // Skip tasks in the home stack
             if (am.isInHomeStack(t.persistentId)) {
@@ -374,7 +377,8 @@
     boolean hasFirstTask() {
         ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
         List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1,
-                ActivityManager.RECENT_IGNORE_UNAVAILABLE, UserHandle.CURRENT.getIdentifier());
+                ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_RELATED,
+                UserHandle.CURRENT.getIdentifier());
         for (ActivityManager.RecentTaskInfo t : tasks) {
             // Skip tasks in the home stack
             if (am.isInHomeStack(t.persistentId)) {
@@ -419,6 +423,33 @@
 
     /** Starts the recents activity */
     void startAlternateRecentsActivity() {
+        // If Recents is the front most activity, then we should just communicate with it directly
+        // to launch the first task or dismiss itself
+        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
+        if (!tasks.isEmpty()) {
+            ComponentName topActivity = tasks.get(0).topActivity;
+            Log.d(TAG, "[RecentsComponent|topActivity] " + topActivity);
+
+            // Check if the front most activity is recents
+            if (topActivity.getPackageName().equals(sRecentsPackage) &&
+                    topActivity.getClassName().equals(sRecentsActivity)) {
+                // Notify Recents to toggle itself
+                try {
+                    Bundle data = new Bundle();
+                    Message msg = Message.obtain(null, MSG_TOGGLE_RECENTS, 0, 0);
+                    msg.setData(data);
+                    mService.send(msg);
+                } catch (RemoteException re) {
+                    re.printStackTrace();
+                }
+                return;
+            }
+        }
+
+        // XXX: If window transitions are currently happening, then we should eat up the event here
+
+        // Otherwise, Recents is not the front-most activity and we should animate into it
         Rect taskRect = mFirstTaskRect;
         if (taskRect != null && taskRect.width() > 0 && taskRect.height() > 0 && hasFirstTask()) {
             // Loading from thumbnail
@@ -511,6 +542,17 @@
     public void closeRecents() {
         if (mUseAlternateRecents) {
             Log.d(TAG, "[RecentsComponent|closeRecents]");
+            if (mServiceIsBound) {
+                // Try and update the recents configuration
+                try {
+                    Bundle data = new Bundle();
+                    Message msg = Message.obtain(null, MSG_CLOSE_RECENTS, 0, 0);
+                    msg.setData(data);
+                    mService.send(msg);
+                } catch (RemoteException re) {
+                    re.printStackTrace();
+                }
+            }
         } else {
             Intent intent = new Intent(RecentsActivity.CLOSE_RECENTS_INTENT);
             intent.setPackage("com.android.systemui");
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
index 09a7a5e..f75ea92 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsActivity.java
@@ -164,7 +164,8 @@
             final List<ActivityManager.RecentTaskInfo> recentTasks =
                     am.getRecentTasks(2,
                             ActivityManager.RECENT_WITH_EXCLUDED |
-                            ActivityManager.RECENT_IGNORE_UNAVAILABLE);
+                            ActivityManager.RECENT_IGNORE_UNAVAILABLE |
+                            ActivityManager.RECENT_INCLUDE_RELATED);
             if (recentTasks.size() > 1 &&
                     mRecentsPanel.simulateClick(recentTasks.get(1).persistentId)) {
                 // recents panel will take care of calling show(false) through simulateClick
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Console.java b/packages/SystemUI/src/com/android/systemui/recents/Console.java
index b3d9ccf..db95193 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Console.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Console.java
@@ -17,6 +17,7 @@
 package com.android.systemui.recents;
 
 
+import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.util.Log;
 import android.view.MotionEvent;
@@ -36,20 +37,20 @@
 
     /** Logs a key */
     public static void log(String key) {
-        Console.log(true, key, "", AnsiReset);
+        log(true, key, "", AnsiReset);
     }
 
     /** Logs a conditioned key */
     public static void log(boolean condition, String key) {
         if (condition) {
-            Console.log(condition, key, "", AnsiReset);
+            log(condition, key, "", AnsiReset);
         }
     }
 
     /** Logs a key in a specific color */
     public static void log(boolean condition, String key, Object data) {
         if (condition) {
-            Console.log(condition, key, data, AnsiReset);
+            log(condition, key, data, AnsiReset);
         }
     }
 
@@ -74,6 +75,50 @@
         }
     }
 
+    /** Logs a stack trace */
+    public static void logStackTrace() {
+        logStackTrace("", 99);
+    }
+
+    /** Logs a stack trace to a certain depth */
+    public static void logStackTrace(int depth) {
+        logStackTrace("", depth);
+    }
+
+    /** Logs a stack trace to a certain depth with a key */
+    public static void logStackTrace(String key, int depth) {
+        int offset = 0;
+        StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+        String tinyStackTrace = "";
+        // Skip over the known stack trace classes
+        for (int i = 0; i < callStack.length; i++) {
+            StackTraceElement el = callStack[i];
+            String className = el.getClassName();
+            if (className.indexOf("dalvik.system.VMStack") == -1 &&
+                className.indexOf("java.lang.Thread") == -1 &&
+                className.indexOf("recents.Console") == -1) {
+                break;
+            } else {
+                offset++;
+            }
+        }
+        // Build the pretty stack trace
+        int start = Math.min(offset + depth, callStack.length);
+        int end = offset;
+        String indent = "";
+        for (int i = start - 1; i >= end; i--) {
+            StackTraceElement el = callStack[i];
+            tinyStackTrace += indent + " -> " + el.getClassName() +
+                    "[" + el.getLineNumber() + "]." + el.getMethodName();
+            if (i > end) {
+                tinyStackTrace += "\n";
+                indent += "  ";
+            }
+        }
+        log(true, key, tinyStackTrace, AnsiRed);
+    }
+
+
     /** Returns the stringified MotionEvent action */
     public static String motionEventActionToString(int action) {
         switch (action) {
@@ -93,4 +138,25 @@
                 return "" + action;
         }
     }
+
+    public static String trimMemoryLevelToString(int level) {
+        switch (level) {
+            case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
+                return "UI Hidden";
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
+                return "Running Moderate";
+            case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
+                return "Background";
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
+                return "Running Low";
+            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
+                return "Moderate";
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
+                return "Critical";
+            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
+                return "Complete";
+            default:
+                return "" + level;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index aeae4ab..ede4ea8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -28,11 +28,14 @@
         public static class App {
             public static final boolean EnableTaskFiltering = false;
             public static final boolean EnableTaskStackClipping = false;
-            public static final boolean EnableBackgroundTaskLoading = true;
-            public static final boolean ForceDisableBackgroundCache = false;
+            public static final boolean EnableToggleNewRecentsActivity = false;
+            // This disables the bitmap and icon caches to
+            public static final boolean DisableBackgroundCache = false;
+
             public static final boolean TaskDataLoader = false;
             public static final boolean SystemUIHandshake = false;
             public static final boolean TimeSystemCalls = false;
+            public static final boolean Memory = false;
         }
 
         public static class UI {
@@ -41,7 +44,7 @@
             public static final boolean TouchEvents = false;
             public static final boolean MeasureAndLayout = false;
             public static final boolean Clipping = false;
-            public static final boolean HwLayers = true;
+            public static final boolean HwLayers = false;
         }
 
         public static class TaskStack {
@@ -55,13 +58,16 @@
 
     public static class Values {
         public static class Window {
+            // The dark background dim is set behind the empty recents view
             public static final float DarkBackgroundDim = 0.5f;
+            // The background dim is set behind the card stack
             public static final float BackgroundDim = 0.35f;
         }
 
         public static class RecentsTaskLoader {
             // XXX: This should be calculated on the first load
             public static final int PreloadFirstTasksCount = 5;
+            // For debugging, this allows us to multiply the number of cards for each task
             public static final int TaskEntryMultiplier = 1;
         }
 
@@ -69,10 +75,10 @@
             public static class Animation {
                 public static final int TaskRemovedReshuffleDuration = 200;
                 public static final int SnapScrollBackDuration = 650;
-                public static final int SwipeDismissDuration = 350;
-                public static final int SwipeSnapBackDuration = 350;
             }
 
+            public static final int TaskStackOverscrollRange = 150;
+
             // The padding will be applied to the smallest dimension, and then applied to all sides
             public static final float StackPaddingPct = 0.15f;
             // The overlap height relative to the task height
@@ -88,12 +94,13 @@
         public static class TaskView {
             public static class Animation {
                 public static final int TaskDataUpdatedFadeDuration = 250;
-                public static final int TaskIconCircularClipInDuration = 225;
-                public static final int TaskIconCircularClipOutDuration = 85;
+                public static final int TaskIconOnEnterDuration = 175;
+                public static final int TaskIconOnLeavingDuration = 75;
             }
 
             public static final boolean AnimateFrontTaskIconOnEnterRecents = true;
             public static final boolean AnimateFrontTaskIconOnLeavingRecents = true;
+            public static final boolean AnimateFrontTaskIconOnEnterUseClip = false;
             public static final boolean AnimateFrontTaskIconOnLeavingUseClip = false;
             public static final boolean DrawColoredTaskBars = false;
             public static final boolean UseRoundedCorners = true;
@@ -103,9 +110,4 @@
             public static final float TaskIconSizeDps = 60;
         }
     }
-
-    // UNMIGRATED CONSTANTS:
-
-    /** Determines whether to layout the stack vertically in landscape mode */
-    public static final boolean LANDSCAPE_LAYOUT_VERTICAL_STACK = true;
 }
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index d050847..8408684 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -17,26 +17,48 @@
 package com.android.systemui.recents;
 
 import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
+import com.android.systemui.R;
 import com.android.systemui.recents.model.SpaceNode;
 import com.android.systemui.recents.model.TaskStack;
 import com.android.systemui.recents.views.RecentsView;
-import com.android.systemui.R;
 
 import java.util.ArrayList;
 
 
 /* Activity */
-public class RecentsActivity extends Activity {
+public class RecentsActivity extends Activity implements RecentsView.RecentsViewCallbacks {
     FrameLayout mContainerView;
     RecentsView mRecentsView;
     View mEmptyView;
+
     boolean mVisible;
+    boolean mTaskLaunched;
+
+    BroadcastReceiver mServiceBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+                    "[RecentsActivity|serviceBroadcast]", action, Console.AnsiRed);
+            if (action.equals(RecentsService.ACTION_FINISH_RECENTS_ACTIVITY)) {
+                if (Constants.DebugFlags.App.EnableToggleNewRecentsActivity) {
+                    finish();
+                }
+            } else if (action.equals(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY)) {
+                // Dismiss recents and launch the first task if possible
+                dismissRecentsIfVisible();
+            }
+        }
+    };
 
     /** Updates the set of recent tasks */
     void updateRecentsTasks() {
@@ -44,7 +66,6 @@
         SpaceNode root = loader.reload(this, Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount);
         ArrayList<TaskStack> stacks = root.getStacks();
         if (!stacks.isEmpty()) {
-            // XXX: We just replace the root every time for now, we will change this in the future
             mRecentsView.setBSP(root);
         }
 
@@ -63,14 +84,12 @@
     }
 
     /** Dismisses recents if we are already visible and the intent is to toggle the recents view */
-    boolean dismissRecentsIfVisible(Intent intent) {
-        if ("com.android.systemui.recents.TOGGLE_RECENTS".equals(intent.getAction())) {
-            if (mVisible) {
-                if (!mRecentsView.launchFirstTask()) {
-                    finish();
-                }
-                return true;
+    boolean dismissRecentsIfVisible() {
+        if (mVisible) {
+            if (!mRecentsView.launchFirstTask()) {
+                finish();
             }
+            return true;
         }
         return false;
     }
@@ -87,9 +106,6 @@
         RecentsTaskLoader.initialize(this);
         RecentsConfiguration.reinitialize(this);
 
-        // Dismiss recents if it is visible and we are toggling
-        if (dismissRecentsIfVisible(getIntent())) return;
-
         // Set the background dim
         WindowManager.LayoutParams wlp = getWindow().getAttributes();
         wlp.dimAmount = Constants.Values.Window.BackgroundDim;
@@ -98,6 +114,7 @@
 
         // Create the view hierarchy
         mRecentsView = new RecentsView(this);
+        mRecentsView.setCallbacks(this);
         mRecentsView.setLayoutParams(new FrameLayout.LayoutParams(
                 FrameLayout.LayoutParams.MATCH_PARENT,
                 FrameLayout.LayoutParams.MATCH_PARENT));
@@ -118,13 +135,14 @@
     @Override
     protected void onNewIntent(Intent intent) {
         super.onNewIntent(intent);
+
+        // Reset the task launched flag if we encounter an onNewIntent() before onStop()
+        mTaskLaunched = false;
+
         Console.logDivider(Constants.DebugFlags.App.SystemUIHandshake);
         Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onNewIntent]",
                 intent.getAction() + " visible: " + mVisible, Console.AnsiRed);
 
-        // Dismiss recents if it is visible and we are toggling
-        if (dismissRecentsIfVisible(intent)) return;
-
         // Initialize the loader and the configuration
         RecentsTaskLoader.initialize(this);
         RecentsConfiguration.reinitialize(this);
@@ -146,6 +164,12 @@
         Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onResume]", "",
                 Console.AnsiRed);
         super.onResume();
+
+        // Register the broadcast receiver to handle messages from our service
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
+        filter.addAction(RecentsService.ACTION_FINISH_RECENTS_ACTIVITY);
+        registerReceiver(mServiceBroadcastReceiver, filter);
     }
 
     @Override
@@ -154,9 +178,8 @@
                 Console.AnsiRed);
         super.onPause();
 
-        // Stop the loader when we leave Recents
-        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
-        loader.stopLoader();
+        // Unregister any broadcast receivers we have registered
+        unregisterReceiver(mServiceBroadcastReceiver);
     }
 
     @Override
@@ -164,7 +187,29 @@
         Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onStop]", "",
                 Console.AnsiRed);
         super.onStop();
+
+        // Finish the current recents activity after we have launched a task
+        if (mTaskLaunched && Constants.DebugFlags.App.EnableToggleNewRecentsActivity) {
+            finish();
+        }
+
         mVisible = false;
+        mTaskLaunched = false;
+    }
+
+    @Override
+    protected void onDestroy() {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsActivity|onDestroy]", "",
+                Console.AnsiRed);
+        super.onDestroy();
+    }
+
+    @Override
+    public void onTrimMemory(int level) {
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        if (loader != null) {
+            loader.onTrimMemory(level);
+        }
     }
 
     @Override
@@ -173,4 +218,9 @@
             super.onBackPressed();
         }
     }
+
+    @Override
+    public void onTaskLaunching() {
+        mTaskLaunched = true;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index f3881ae..ed981ed 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -30,7 +30,6 @@
 
     DisplayMetrics mDisplayMetrics;
 
-    public boolean layoutVerticalStack;
     public Rect systemInsets = new Rect();
 
     /** Private constructor */
@@ -56,7 +55,6 @@
 
         boolean isPortrait = context.getResources().getConfiguration().orientation ==
                 Configuration.ORIENTATION_PORTRAIT;
-        layoutVerticalStack = isPortrait || Constants.LANDSCAPE_LAYOUT_VERTICAL_STACK;
     }
 
     public void updateSystemInsets(Rect insets) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
index 522ab0f..485b136 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
@@ -30,46 +30,75 @@
 import com.android.systemui.recents.views.TaskStackView;
 import com.android.systemui.recents.views.TaskViewTransform;
 
+import java.lang.ref.WeakReference;
+
+
+/** The message handler to process Recents SysUI messages */
+class SystemUIMessageHandler extends Handler {
+    WeakReference<Context> mContext;
+
+    SystemUIMessageHandler(Context context) {
+        // Keep a weak ref to the context instead of a strong ref
+        mContext = new WeakReference<Context>(context);
+    }
+
+    @Override
+    public void handleMessage(Message msg) {
+        Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+                "[RecentsService|handleMessage]", msg);
+
+        Context context = mContext.get();
+        if (context == null) return;
+
+        if (msg.what == RecentsService.MSG_UPDATE_RECENTS_FOR_CONFIGURATION) {
+            RecentsTaskLoader.initialize(context);
+            RecentsConfiguration.reinitialize(context);
+
+            try {
+                Bundle data = msg.getData();
+                Rect windowRect = (Rect) data.getParcelable("windowRect");
+                Rect systemInsets = (Rect) data.getParcelable("systemInsets");
+
+                // Create a dummy task stack & compute the rect for the thumbnail to animate to
+                TaskStack stack = new TaskStack(context);
+                TaskStackView tsv = new TaskStackView(context, stack);
+                // Since the nav bar height is already accounted for in the windowRect, don't pass
+                // in a bottom inset
+                tsv.computeRects(windowRect.width(), windowRect.height() - systemInsets.top, 0);
+                tsv.boundScroll();
+                TaskViewTransform transform = tsv.getStackTransform(0);
+                Rect taskRect = new Rect(transform.rect);
+
+                data.putParcelable("taskRect", taskRect);
+                Message reply = Message.obtain(null,
+                        RecentsService.MSG_UPDATE_RECENTS_FOR_CONFIGURATION, 0, 0);
+                reply.setData(data);
+                msg.replyTo.send(reply);
+            } catch (RemoteException re) {
+                re.printStackTrace();
+            }
+        } else if (msg.what == RecentsService.MSG_CLOSE_RECENTS) {
+            // Do nothing
+        } else if (msg.what == RecentsService.MSG_TOGGLE_RECENTS) {
+            // Send a broadcast to toggle recents
+            Intent intent = new Intent(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
+            intent.setPackage(context.getPackageName());
+            context.sendBroadcast(intent);
+        }
+    }
+}
 
 /* Service */
 public class RecentsService extends Service {
+    final static String ACTION_FINISH_RECENTS_ACTIVITY = "action_finish_recents_activity";
+    final static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
+
     // XXX: This should be getting the message from recents definition
     final static int MSG_UPDATE_RECENTS_FOR_CONFIGURATION = 0;
+    final static int MSG_CLOSE_RECENTS = 4;
+    final static int MSG_TOGGLE_RECENTS = 5;
 
-    class MessageHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsService|handleMessage]", msg);
-            if (msg.what == MSG_UPDATE_RECENTS_FOR_CONFIGURATION) {
-                Context context = RecentsService.this;
-                RecentsTaskLoader.initialize(context);
-                RecentsConfiguration.reinitialize(context);
-
-                try {
-                    Bundle data = msg.getData();
-                    Rect windowRect = (Rect) data.getParcelable("windowRect");
-                    Rect systemInsets = (Rect) data.getParcelable("systemInsets");
-                    RecentsConfiguration.getInstance().updateSystemInsets(systemInsets);
-
-                    // Create a dummy task stack & compute the rect for the thumbnail to animate to
-                    TaskStack stack = new TaskStack(context);
-                    TaskStackView tsv = new TaskStackView(context, stack);
-                    tsv.computeRects(windowRect.width(), windowRect.height() - systemInsets.top);
-                    tsv.boundScroll();
-                    TaskViewTransform transform = tsv.getStackTransform(0);
-
-                    data.putParcelable("taskRect", transform.rect);
-                    Message reply = Message.obtain(null, MSG_UPDATE_RECENTS_FOR_CONFIGURATION, 0, 0);
-                    reply.setData(data);
-                    msg.replyTo.send(reply);
-                } catch (RemoteException re) {
-                    re.printStackTrace();
-                }
-            }
-        }
-    }
-
-    Messenger mMessenger = new Messenger(new MessageHandler());
+    Messenger mSystemUIMessenger = new Messenger(new SystemUIMessageHandler(this));
 
     @Override
     public void onCreate() {
@@ -80,7 +109,7 @@
     @Override
     public IBinder onBind(Intent intent) {
         Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsService|onBind]");
-        return mMessenger.getBinder();
+        return mSystemUIMessenger.getBinder();
     }
 
     @Override
@@ -100,4 +129,12 @@
         Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsService|onDestroy]");
         super.onDestroy();
     }
+
+    @Override
+    public void onTrimMemory(int level) {
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        if (loader != null) {
+            loader.onTrimMemory(level);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
index c303ca7..5f9162d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
@@ -17,6 +17,7 @@
 package com.android.systemui.recents;
 
 import android.app.ActivityManager;
+import android.content.ComponentCallbacks2;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
@@ -82,7 +83,9 @@
     TaskResourceLoadQueue mLoadQueue;
     DrawableLruCache mIconCache;
     BitmapLruCache mThumbnailCache;
+
     boolean mCancelled;
+    boolean mWaitingOnLoadQueue;
 
     /** Constructor, creates a new loading thread that loads task resources in the background */
     public TaskResourceLoader(TaskResourceLoadQueue loadQueue, DrawableLruCache iconCache,
@@ -114,6 +117,11 @@
         Console.log(Constants.DebugFlags.App.TaskDataLoader, "[TaskResourceLoader|stop]");
         // Mark as cancelled for the thread to pick up
         mCancelled = true;
+        // If we are waiting for the load queue for more tasks, then we can just reset the
+        // Context now, since nothing is using it
+        if (mWaitingOnLoadQueue) {
+            mContext = null;
+        }
     }
 
     @Override
@@ -122,6 +130,8 @@
             Console.log(Constants.DebugFlags.App.TaskDataLoader,
                     "[TaskResourceLoader|run|" + Thread.currentThread().getId() + "]");
             if (mCancelled) {
+                Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                        "[TaskResourceLoader|cancel|" + Thread.currentThread().getId() + "]");
                 // We have to unset the context here, since the background thread may be using it
                 // when we call stop()
                 mContext = null;
@@ -140,50 +150,54 @@
                 final Task t = mLoadQueue.nextTask();
                 if (t != null) {
                     try {
-                        Drawable cachedIcon = mIconCache.get(t);
-                        Bitmap cachedThumbnail = mThumbnailCache.get(t);
+                        Drawable loadIcon = mIconCache.get(t.key);
+                        Bitmap loadThumbnail = mThumbnailCache.get(t.key);
                         Console.log(Constants.DebugFlags.App.TaskDataLoader,
                                 "  [TaskResourceLoader|load]",
-                                t + " icon: " + cachedIcon + " thumbnail: " + cachedThumbnail);
+                                t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail);
                         // Load the icon
-                        if (cachedIcon == null) {
+                        if (loadIcon == null) {
                             PackageManager pm = mContext.getPackageManager();
-                            ActivityInfo info = pm.getActivityInfo(t.intent.getComponent(),
+                            ActivityInfo info = pm.getActivityInfo(t.key.intent.getComponent(),
                                     PackageManager.GET_META_DATA);
                             Drawable icon = info.loadIcon(pm);
                             if (!mCancelled) {
-                                Console.log(Constants.DebugFlags.App.TaskDataLoader,
-                                        "    [TaskResourceLoader|loadIcon]",
-                                        icon);
-                                t.icon = icon;
-                                mIconCache.put(t, icon);
+                                if (icon != null) {
+                                    Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                            "    [TaskResourceLoader|loadIcon]",
+                                            icon);
+                                    loadIcon = icon;
+                                    mIconCache.put(t.key, icon);
+                                }
                             }
                         }
                         // Load the thumbnail
-                        if (cachedThumbnail == null) {
+                        if (loadThumbnail == null) {
                             ActivityManager am = (ActivityManager)
                                     mContext.getSystemService(Context.ACTIVITY_SERVICE);
-                            Bitmap thumbnail = am.getTaskTopThumbnail(t.id);
+                            Bitmap thumbnail = am.getTaskTopThumbnail(t.key.id);
                             if (!mCancelled) {
                                 if (thumbnail != null) {
                                     Console.log(Constants.DebugFlags.App.TaskDataLoader,
                                             "    [TaskResourceLoader|loadThumbnail]",
                                             thumbnail);
-                                    t.thumbnail = thumbnail;
-                                    mThumbnailCache.put(t, thumbnail);
+                                    loadThumbnail = thumbnail;
+                                    mThumbnailCache.put(t.key, thumbnail);
                                 } else {
                                     Console.logError(mContext,
                                             "Failed to load task top thumbnail for: " +
-                                                    t.intent.getComponent().getPackageName());
+                                                    t.key.intent.getComponent().getPackageName());
                                 }
                             }
                         }
                         if (!mCancelled) {
                             // Notify that the task data has changed
+                            final Drawable newIcon = loadIcon;
+                            final Bitmap newThumbnail = loadThumbnail;
                             mMainThreadHandler.post(new Runnable() {
                                 @Override
                                 public void run() {
-                                    t.notifyTaskDataChanged();
+                                    t.notifyTaskDataLoaded(newThumbnail, newIcon);
                                 }
                             });
                         }
@@ -198,7 +212,9 @@
                         try {
                             Console.log(Constants.DebugFlags.App.TaskDataLoader,
                                     "[TaskResourceLoader|waitOnLoadQueue]");
+                            mWaitingOnLoadQueue = true;
                             mLoadQueue.wait();
+                            mWaitingOnLoadQueue = false;
                         } catch (InterruptedException ie) {
                             ie.printStackTrace();
                         }
@@ -209,14 +225,17 @@
     }
 }
 
-/** The drawable cache */
-class DrawableLruCache extends LruCache<Task, Drawable> {
+/**
+ * The drawable cache.  By using the Task's key, we can prevent holding onto a reference to the Task
+ * resource data, while keeping the cache data in memory where necessary.
+ */
+class DrawableLruCache extends LruCache<Task.TaskKey, Drawable> {
     public DrawableLruCache(int cacheSize) {
         super(cacheSize);
     }
 
     @Override
-    protected int sizeOf(Task t, Drawable d) {
+    protected int sizeOf(Task.TaskKey t, Drawable d) {
         // The cache size will be measured in kilobytes rather than number of items
         // NOTE: this isn't actually correct, as the icon may be smaller
         int maxBytes = (d.getIntrinsicWidth() * d.getIntrinsicHeight() * 4);
@@ -224,16 +243,19 @@
     }
 }
 
-/** The bitmap cache */
-class BitmapLruCache extends LruCache<Task, Bitmap> {
+/**
+ * The bitmap cache.  By using the Task's key, we can prevent holding onto a reference to the Task
+ * resource data, while keeping the cache data in memory where necessary.
+ */
+class BitmapLruCache extends LruCache<Task.TaskKey, Bitmap> {
     public BitmapLruCache(int cacheSize) {
         super(cacheSize);
     }
 
     @Override
-    protected int sizeOf(Task t, Bitmap bitmap) {
+    protected int sizeOf(Task.TaskKey t, Bitmap bitmap) {
         // The cache size will be measured in kilobytes rather than number of items
-        return bitmap.getByteCount() / 1024;
+        return bitmap.getAllocationByteCount() / 1024;
     }
 }
 
@@ -247,17 +269,30 @@
     TaskResourceLoadQueue mLoadQueue;
     TaskResourceLoader mLoader;
 
+    int mMaxThumbnailCacheSize;
+    int mMaxIconCacheSize;
+
     BitmapDrawable mDefaultIcon;
     Bitmap mDefaultThumbnail;
 
     /** Private Constructor */
     private RecentsTaskLoader(Context context) {
+        // Calculate the cache sizes, we just use a reasonable number here similar to those
+        // suggested in the Android docs, 1/8th for the thumbnail cache and 1/32 of the max memory
+        // for icons.
         int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
-        int iconCacheSize = Constants.DebugFlags.App.ForceDisableBackgroundCache ? 1 : maxMemory / 16;
-        int thumbnailCacheSize = Constants.DebugFlags.App.ForceDisableBackgroundCache ? 1 : maxMemory / 8;
-        Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+        mMaxThumbnailCacheSize = maxMemory / 8;
+        mMaxIconCacheSize = mMaxThumbnailCacheSize / 4;
+        int iconCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 :
+                mMaxIconCacheSize;
+        int thumbnailCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 :
+                mMaxThumbnailCacheSize;
+
+        Console.log(Constants.DebugFlags.App.TaskDataLoader,
                 "[RecentsTaskLoader|init]", "thumbnailCache: " + thumbnailCacheSize +
                 " iconCache: " + iconCacheSize);
+
+        // Initialize the cache and loaders
         mLoadQueue = new TaskResourceLoadQueue();
         mIconCache = new DrawableLruCache(iconCacheSize);
         mThumbnailCache = new BitmapLruCache(thumbnailCacheSize);
@@ -293,7 +328,7 @@
 
     /** Reload the set of recent tasks */
     SpaceNode reload(Context context, int preloadCount) {
-        Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsTaskLoader|reload]");
+        Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]");
         TaskStack stack = new TaskStack(context);
         SpaceNode root = new SpaceNode(context);
         root.setStack(stack);
@@ -310,7 +345,7 @@
             Console.log(Constants.DebugFlags.App.TimeSystemCalls,
                     "[RecentsTaskLoader|getRecentTasks]",
                     "" + (System.currentTimeMillis() - t1) + "ms");
-            Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+            Console.log(Constants.DebugFlags.App.TaskDataLoader,
                     "[RecentsTaskLoader|tasks]", "" + tasks.size());
 
             // Remove home/recents tasks
@@ -335,49 +370,61 @@
             int taskCount = tasks.size();
             for (int i = 0; i < taskCount; i++) {
                 ActivityManager.RecentTaskInfo t = tasks.get(i);
-
-                // Load the label, icon and thumbnail
                 ActivityInfo info = pm.getActivityInfo(t.baseIntent.getComponent(),
                         PackageManager.GET_META_DATA);
                 String title = info.loadLabel(pm).toString();
-                Drawable icon = null;
-                Bitmap thumbnail = null;
-                Task task;
-                if (i >= (taskCount - preloadCount) || !Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
-                    Console.log(Constants.DebugFlags.App.SystemUIHandshake,
+                boolean isForemostTask = (i == (taskCount - 1));
+
+                // Preload the specified number of apps
+                if (i >= (taskCount - preloadCount)) {
+                    Console.log(Constants.DebugFlags.App.TaskDataLoader,
                             "[RecentsTaskLoader|preloadTask]",
                             "i: " + i + " task: " + t.baseIntent.getComponent().getPackageName());
-                    icon = info.loadIcon(pm);
-                    thumbnail = am.getTaskTopThumbnail(t.id);
-                    for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
-                        Console.log(Constants.DebugFlags.App.SystemUIHandshake,
-                                "  [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
-                        task = new Task(t.persistentId, t.baseIntent, title, icon, thumbnail);
-                        if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
-                            if (thumbnail != null) mThumbnailCache.put(task, thumbnail);
-                            if (icon != null) {
-                                mIconCache.put(task, icon);
-                            }
-                        }
-                        stack.addTask(task);
-                    }
-                } else {
-                    for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
-                        Console.log(Constants.DebugFlags.App.SystemUIHandshake,
-                                "  [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
-                        task = new Task(t.persistentId, t.baseIntent, title, null, null);
-                        stack.addTask(task);
-                    }
-                }
 
-                /*
-                if (stacks.containsKey(t.stackId)) {
-                    builder = stacks.get(t.stackId);
+                    Task task = new Task(t.persistentId, t.baseIntent, title);
+
+                    // Load the icon (if possible and not the foremost task, from the cache)
+                    if (!isForemostTask) {
+                        task.icon = mIconCache.get(task.key);
+                    }
+                    if (task.icon == null) {
+                        task.icon = info.loadIcon(pm);
+                        if (task.icon != null) {
+                            mIconCache.put(task.key, task.icon);
+                        } else {
+                            task.icon = mDefaultIcon;
+                        }
+                    }
+
+                    // Load the thumbnail (if possible and not the foremost task, from the cache)
+                    if (!isForemostTask) {
+                        task.thumbnail = mThumbnailCache.get(task.key);
+                    }
+                    if (task.thumbnail == null) {
+                        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                "[RecentsTaskLoader|loadingTaskThumbnail]");
+                        task.thumbnail = am.getTaskTopThumbnail(t.id);
+                        if (task.thumbnail != null) {
+                            mThumbnailCache.put(task.key, task.thumbnail);
+                        } else {
+                            task.thumbnail = mDefaultThumbnail;
+                        }
+                    }
+
+                    // Create as many tasks a we want to multiply by
+                    for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
+                        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                "  [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
+                        stack.addTask(task);
+                    }
                 } else {
-                    builder = new TaskStackBuilder();
-                    stacks.put(t.stackId, builder);
+                    // Create as many tasks a we want to multiply by
+                    for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
+                        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                                "  [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
+                        stack.addTask(new Task(t.persistentId, t.baseIntent, title));
+                    }
                 }
-                */
             }
             Console.log(Constants.DebugFlags.App.TimeSystemCalls,
                     "[RecentsTaskLoader|getAllTaskTopThumbnail]",
@@ -388,9 +435,9 @@
             t1 = System.currentTimeMillis();
             List<ActivityManager.StackInfo> stackInfos = ams.getAllStackInfos();
             Console.log(Constants.DebugFlags.App.TimeSystemCalls, "[RecentsTaskLoader|getAllStackInfos]", "" + (System.currentTimeMillis() - t1) + "ms");
-            Console.log(Constants.DebugFlags.App.SystemUIHandshake, "[RecentsTaskLoader|stacks]", "" + tasks.size());
+            Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|stacks]", "" + tasks.size());
             for (ActivityManager.StackInfo s : stackInfos) {
-                Console.log(Constants.DebugFlags.App.SystemUIHandshake, "  [RecentsTaskLoader|stack]", s.toString());
+                Console.log(Constants.DebugFlags.App.TaskDataLoader, "  [RecentsTaskLoader|stack]", s.toString());
                 if (stacks.containsKey(s.stackId)) {
                     stacks.get(s.stackId).setRect(s.bounds);
                 }
@@ -399,65 +446,94 @@
         } catch (Exception e) {
             e.printStackTrace();
         }
+
+        // Start the task loader
         mLoader.start(context);
+
         return root;
     }
 
-    /** Acquires the task resource data from the pool.
-     * XXX: Move this into Task? */
+    /** Acquires the task resource data from the pool. */
     public void loadTaskData(Task t) {
-        if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
-            t.icon = mIconCache.get(t);
-            t.thumbnail = mThumbnailCache.get(t);
+        Drawable icon = mIconCache.get(t.key);
+        Bitmap thumbnail = mThumbnailCache.get(t.key);
 
-            Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|loadTask]",
-                    t + " icon: " + t.icon + " thumbnail: " + t.thumbnail);
+        Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|loadTask]",
+                t + " icon: " + icon + " thumbnail: " + thumbnail +
+                        " thumbnailCacheSize: " + mThumbnailCache.size());
 
-            boolean requiresLoad = false;
-            if (t.icon == null) {
-                t.icon = mDefaultIcon;
-                requiresLoad = true;
-            }
-            if (t.thumbnail == null) {
-                t.thumbnail = mDefaultThumbnail;
-                requiresLoad = true;
-            }
-            if (requiresLoad) {
-                mLoadQueue.addTask(t);
-            }
+        boolean requiresLoad = false;
+        if (icon == null) {
+            icon = mDefaultIcon;
+            requiresLoad = true;
         }
+        if (thumbnail == null) {
+            thumbnail = mDefaultThumbnail;
+            requiresLoad = true;
+        }
+        if (requiresLoad) {
+            mLoadQueue.addTask(t);
+        }
+        t.notifyTaskDataLoaded(thumbnail, icon);
     }
 
-    /** Releases the task resource data back into the pool.
-     * XXX: Move this into Task? */
+    /** Releases the task resource data back into the pool. */
     public void unloadTaskData(Task t) {
-        if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
-            Console.log(Constants.DebugFlags.App.TaskDataLoader,
-                    "[RecentsTaskLoader|unloadTask]", t);
-            mLoadQueue.removeTask(t);
-            t.icon = mDefaultIcon;
-            t.thumbnail = mDefaultThumbnail;
-        }
+        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                "[RecentsTaskLoader|unloadTask]", t +
+                " thumbnailCacheSize: " + mThumbnailCache.size());
+
+        mLoadQueue.removeTask(t);
+        t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultIcon);
     }
 
-    /** Completely removes the resource data from the pool.
-     * XXX: Move this into Task? */
+    /** Completely removes the resource data from the pool. */
     public void deleteTaskData(Task t) {
-        if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
-            Console.log(Constants.DebugFlags.App.TaskDataLoader,
-                    "[RecentsTaskLoader|deleteTask]", t);
-            mLoadQueue.removeTask(t);
-            mThumbnailCache.remove(t);
-            mIconCache.remove(t);
-        }
-        t.icon = mDefaultIcon;
-        t.thumbnail = mDefaultThumbnail;
+        Console.log(Constants.DebugFlags.App.TaskDataLoader,
+                "[RecentsTaskLoader|deleteTask]", t);
+
+        mLoadQueue.removeTask(t);
+        mThumbnailCache.remove(t.key);
+        mIconCache.remove(t.key);
+        t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultIcon);
     }
 
-    /** Stops the task loader */
+    /** Stops the task loader and clears all pending tasks */
     void stopLoader() {
         Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|stopLoader]");
         mLoader.stop();
         mLoadQueue.clearTasks();
     }
+
+    void onTrimMemory(int level) {
+        Console.log(Constants.DebugFlags.App.Memory, "[RecentsTaskLoader|onTrimMemory]",
+                Console.trimMemoryLevelToString(level));
+
+        switch (level) {
+            case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
+                // Stop the loader immediately when the UI is no longer visible
+                stopLoader();
+                break;
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
+            case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
+                // We are leaving recents, so trim the data a bit
+                mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 2);
+                mIconCache.trimToSize(mMaxIconCacheSize / 2);
+                break;
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
+            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
+                // We are going to be low on memory
+                mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 4);
+                mIconCache.trimToSize(mMaxIconCacheSize / 4);
+                break;
+            case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
+            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
+                // We are low on memory, so release everything
+                mThumbnailCache.evictAll();
+                mIconCache.evictAll();
+                break;
+            default:
+                break;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java b/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java
index 5893abc..1dd1be6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java
@@ -17,6 +17,7 @@
 package com.android.systemui.recents.model;
 
 import android.content.Context;
+import android.graphics.Rect;
 
 import java.util.ArrayList;
 
@@ -26,6 +27,14 @@
  * stacks should be placed.
  */
 public class SpaceNode {
+    /* BSP node callbacks */
+    public interface SpaceNodeCallbacks {
+        /** Notifies when a node is added */
+        public void onSpaceNodeAdded(SpaceNode node);
+        /** Notifies when a node is measured */
+        public void onSpaceNodeMeasured(SpaceNode node, Rect rect);
+    }
+
     Context mContext;
 
     SpaceNode mStartNode;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNodeCallbacks.java b/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNodeCallbacks.java
deleted file mode 100644
index 31b02e7..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNodeCallbacks.java
+++ /dev/null
@@ -1,28 +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 com.android.systemui.recents.model;
-
-import android.graphics.Rect;
-
-
-/* BSP node callbacks */
-public interface SpaceNodeCallbacks {
-    /** Notifies when a node is added */
-    public void onSpaceNodeAdded(SpaceNode node);
-    /** Notifies when a node is measured */
-    public void onSpaceNodeMeasured(SpaceNode node, Rect rect);
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 9b03c5d..0c3c528 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -26,17 +26,53 @@
  * A task represents the top most task in the system's task stack.
  */
 public class Task {
-    public final int id;
-    public final Intent intent;
+    /* Task callbacks */
+    public interface TaskCallbacks {
+        /* Notifies when a task has been bound */
+        public void onTaskDataLoaded();
+        /* Notifies when a task has been unbound */
+        public void onTaskDataUnloaded();
+    }
+
+    /* The Task Key represents the unique primary key for the task */
+    public static class TaskKey {
+        public final int id;
+        public final Intent intent;
+
+        public TaskKey(int id, Intent intent) {
+            this.id = id;
+            this.intent = intent;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            return hashCode() == o.hashCode();
+        }
+
+        @Override
+        public int hashCode() {
+            return id;
+        }
+
+        @Override
+        public String toString() {
+            return "Task.Key: " + id + ", " + intent.getComponent().getPackageName();
+        }
+    }
+
+    public TaskKey key;
     public String title;
     public Drawable icon;
     public Bitmap thumbnail;
 
     TaskCallbacks mCb;
 
+    public Task(int id, Intent intent, String activityTitle) {
+        this(id, intent, activityTitle, null, null);
+    }
+
     public Task(int id, Intent intent, String activityTitle, Drawable icon, Bitmap thumbnail) {
-        this.id = id;
-        this.intent = intent;
+        this.key = new TaskKey(id, intent);
         this.title = activityTitle;
         this.icon = icon;
         this.thumbnail = thumbnail;
@@ -47,10 +83,21 @@
         mCb = cb;
     }
 
-    /** Notifies the callback listeners that this task's data has changed */
-    public void notifyTaskDataChanged() {
+    /** Notifies the callback listeners that this task has been loaded */
+    public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable icon) {
+        this.icon = icon;
+        this.thumbnail = thumbnail;
         if (mCb != null) {
-            mCb.onTaskDataChanged(this);
+            mCb.onTaskDataLoaded();
+        }
+    }
+
+    /** Notifies the callback listeners that this task has been unloaded */
+    public void notifyTaskDataUnloaded(Bitmap defaultThumbnail, Drawable defaultIcon) {
+        icon = defaultIcon;
+        thumbnail = defaultThumbnail;
+        if (mCb != null) {
+            mCb.onTaskDataUnloaded();
         }
     }
 
@@ -65,12 +112,11 @@
         // Otherwise, check that the id and intent match (the other fields can be asynchronously
         // loaded and is unsuitable to testing the identity of this Task)
         Task t = (Task) o;
-        return (id == t.id) &&
-                (intent.equals(t.intent));
+        return key.equals(t.key);
     }
 
     @Override
     public String toString() {
-        return "Task: " + intent.getComponent().getPackageName() + " [" + super.toString() + "]";
+        return "Task: " + key.intent.getComponent().getPackageName() + " [" + super.toString() + "]";
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskCallbacks.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskCallbacks.java
deleted file mode 100644
index 169f56c..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskCallbacks.java
+++ /dev/null
@@ -1,23 +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 com.android.systemui.recents.model;
-
-/* Task callbacks */
-public interface TaskCallbacks {
-    /* Notifies when a task's data has been updated */
-    public void onTaskDataChanged(Task task);
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index a5aa387..f2f89ae3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -119,6 +119,18 @@
  * The task stack contains a list of multiple tasks.
  */
 public class TaskStack {
+    /* Task stack callbacks */
+    public interface TaskStackCallbacks {
+        /* Notifies when a task has been added to the stack */
+        public void onStackTaskAdded(TaskStack stack, Task t);
+        /* Notifies when a task has been removed from the stack */
+        public void onStackTaskRemoved(TaskStack stack, Task t);
+        /** Notifies when the stack was filtered */
+        public void onStackFiltered(TaskStack stack);
+        /** Notifies when the stack was un-filtered */
+        public void onStackUnfiltered(TaskStack stack);
+    }
+
     Context mContext;
 
     FilteredTaskList mTaskList = new FilteredTaskList();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStackCallbacks.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStackCallbacks.java
deleted file mode 100644
index 4bec655..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStackCallbacks.java
+++ /dev/null
@@ -1,29 +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 com.android.systemui.recents.model;
-
-/* Task stack callbacks */
-public interface TaskStackCallbacks {
-    /* Notifies when a task has been added to the stack */
-    public void onStackTaskAdded(TaskStack stack, Task t);
-    /* Notifies when a task has been removed from the stack */
-    public void onStackTaskRemoved(TaskStack stack, Task t);
-    /** Notifies when the stack was filtered */
-    public void onStackFiltered(TaskStack stack);
-    /** Notifies when the stack was un-filtered */
-    public void onStackUnfiltered(TaskStack stack);
-}
\ No newline at end of file
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 c92041c..9133f7d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -39,21 +39,33 @@
  * This view is the the top level layout that contains TaskStacks (which are laid out according
  * to their SpaceNode bounds.
  */
-public class RecentsView extends FrameLayout implements TaskStackViewCallbacks {
+public class RecentsView extends FrameLayout implements TaskStackView.TaskStackViewCallbacks {
+
+    /** The RecentsView callbacks */
+    public interface RecentsViewCallbacks {
+        public void onTaskLaunching();
+    }
+
     // The space partitioning root of this container
     SpaceNode mBSP;
+    // Recents view callbacks
+    RecentsViewCallbacks mCb;
 
     public RecentsView(Context context) {
         super(context);
         setWillNotDraw(false);
     }
 
+    /** Sets the callbacks */
+    public void setCallbacks(RecentsViewCallbacks cb) {
+        mCb = cb;
+    }
+
     /** Set/get the bsp root node */
     public void setBSP(SpaceNode n) {
         mBSP = n;
 
-        // XXX: We shouldn't be recereating new stacks every time, but for now, that is OK
-        // Add all the stacks for this partition
+        // Create and add all the stacks for this partition of space.
         removeAllViews();
         ArrayList<TaskStack> stacks = mBSP.getStacks();
         for (TaskStack stack : stacks) {
@@ -65,14 +77,19 @@
 
     /** Launches the first task from the first stack if possible */
     public boolean launchFirstTask() {
+        // Get the first stack view
         int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
             TaskStackView stackView = (TaskStackView) getChildAt(i);
             TaskStack stack = stackView.mStack;
             ArrayList<Task> tasks = stack.getTasks();
+
+            // Get the first task in the stack
             if (!tasks.isEmpty()) {
                 Task task = tasks.get(tasks.size() - 1);
                 TaskView tv = null;
+
+                // Try and use the first child task view as the source of the launch animation
                 if (stackView.getChildCount() > 0) {
                     TaskView stv = (TaskView) stackView.getChildAt(stackView.getChildCount() - 1);
                     if (stv.getTask() == task) {
@@ -91,7 +108,8 @@
         int width = MeasureSpec.getSize(widthMeasureSpec);
         int height = MeasureSpec.getSize(heightMeasureSpec);
         int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|measure]", "width: " + width + " height: " + height, Console.AnsiGreen);
+        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|measure]",
+                "width: " + width + " height: " + height, Console.AnsiGreen);
 
         // We measure our stack views sans the status bar.  It will handle the nav bar itself.
         RecentsConfiguration config = RecentsConfiguration.getInstance();
@@ -112,7 +130,8 @@
 
     @Override
     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|layout]", new Rect(left, top, right, bottom) + " changed: " + changed, Console.AnsiGreen);
+        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|layout]",
+                new Rect(left, top, right, bottom) + " changed: " + changed, Console.AnsiGreen);
         // We offset our stack views by the status bar height.  It will handle the nav bar itself.
         RecentsConfiguration config = RecentsConfiguration.getInstance();
         top += config.systemInsets.top;
@@ -132,13 +151,15 @@
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
-        Console.log(Constants.DebugFlags.UI.Draw, "[RecentsView|dispatchDraw]", "", Console.AnsiPurple);
+        Console.log(Constants.DebugFlags.UI.Draw, "[RecentsView|dispatchDraw]", "",
+                Console.AnsiPurple);
         super.dispatchDraw(canvas);
     }
 
     @Override
     protected boolean fitSystemWindows(Rect insets) {
-        Console.log(Constants.DebugFlags.UI.MeasureAndLayout, "[RecentsView|fitSystemWindows]", "insets: " + insets, Console.AnsiGreen);
+        Console.log(Constants.DebugFlags.UI.MeasureAndLayout,
+                "[RecentsView|fitSystemWindows]", "insets: " + insets, Console.AnsiGreen);
 
         // Update the configuration with the latest system insets and trigger a relayout
         RecentsConfiguration config = RecentsConfiguration.getInstance();
@@ -165,11 +186,16 @@
         return false;
     }
 
-    /**** View.OnClickListener Implementation ****/
+    /**** TaskStackView.TaskStackCallbacks Implementation ****/
 
     @Override
     public void onTaskLaunched(final TaskStackView stackView, final TaskView tv,
                                final TaskStack stack, final Task task) {
+        // Notify any callbacks of the launching of a new task
+        if (mCb != null) {
+            mCb.onTaskLaunching();
+        }
+
         final Runnable launchRunnable = new Runnable() {
             @Override
             public void run() {
@@ -206,7 +232,7 @@
                 }
 
                 // Launch the activity with the desired animation
-                Intent i = new Intent(task.intent);
+                Intent i = new Intent(task.key.intent);
                 i.setFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
                         | Intent.FLAG_ACTIVITY_TASK_ON_HOME
                         | Intent.FLAG_ACTIVITY_NEW_TASK);
@@ -220,7 +246,7 @@
 
         // Launch the app right away if there is no task view, otherwise, animate the icon out first
         if (tv == null || !Constants.Values.TaskView.AnimateFrontTaskIconOnLeavingRecents) {
-            launchRunnable.run();
+            post(launchRunnable);
         } else {
             tv.animateOnLeavingRecents(launchRunnable);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
index fe661bc..21ef9ff 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
@@ -28,6 +28,8 @@
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.animation.LinearInterpolator;
+import com.android.systemui.recents.Console;
+import com.android.systemui.recents.Constants;
 
 /**
  * This class facilitates swipe to dismiss. It defines an interface to be implemented by the
@@ -176,6 +178,9 @@
     }
 
     public boolean onInterceptTouchEvent(MotionEvent ev) {
+        Console.log(Constants.DebugFlags.UI.TouchEvents,
+                "[SwipeHelper|interceptTouchEvent]",
+                Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
         final int action = ev.getAction();
 
         switch (action) {
@@ -200,7 +205,7 @@
                     if (Math.abs(delta) > mPagingTouchSlop) {
                         mCallback.onBeginDrag(mCurrView);
                         mDragging = true;
-                        mInitialTouchPos = getPos(ev) - getTranslation(mCurrView);
+                        mInitialTouchPos = pos - getTranslation(mCurrView);
                     }
                 }
                 break;
@@ -286,6 +291,10 @@
     }
 
     public boolean onTouchEvent(MotionEvent ev) {
+        Console.log(Constants.DebugFlags.UI.TouchEvents,
+                "[SwipeHelper|touchEvent]",
+                Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
+
         if (!mDragging) {
             if (!onInterceptTouchEvent(ev)) {
                 return mCanCurrViewBeDimissed;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 9dd6c0b..62cf394 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -33,7 +33,6 @@
 import android.view.ViewParent;
 import android.widget.FrameLayout;
 import android.widget.OverScroller;
-import android.widget.Toast;
 import com.android.systemui.recents.Console;
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.RecentsConfiguration;
@@ -41,18 +40,20 @@
 import com.android.systemui.recents.Utilities;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
-import com.android.systemui.recents.model.TaskStackCallbacks;
 
 import java.util.ArrayList;
 
-/** The TaskView callbacks */
-interface TaskStackViewCallbacks {
-    public void onTaskLaunched(TaskStackView stackView, TaskView tv, TaskStack stack, Task t);
-}
 
 /* The visual representation of a task stack view */
-public class TaskStackView extends FrameLayout implements TaskStackCallbacks, TaskViewCallbacks,
-        ViewPoolConsumer<TaskView, Task>, View.OnClickListener {
+public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCallbacks,
+        TaskView.TaskViewCallbacks, ViewPool.ViewPoolConsumer<TaskView, Task>,
+        View.OnClickListener {
+
+    /** The TaskView callbacks */
+    interface TaskStackViewCallbacks {
+        public void onTaskLaunched(TaskStackView stackView, TaskView tv, TaskStack stack, Task t);
+    }
+
     TaskStack mStack;
     TaskStackViewTouchHandler mTouchHandler;
     TaskStackViewCallbacks mCb;
@@ -242,10 +243,10 @@
         int newScroll = Math.max(mMinScroll, Math.min(mMaxScroll, curScroll));
         if (newScroll != curScroll) {
             // Enable hw layers on the stack
-            addHwLayersRefCount();
+            addHwLayersRefCount("animateBoundScroll");
 
             // Abort any current animations
-            mScroller.abortAnimation();
+            abortScroller();
             if (mScrollAnimator != null) {
                 mScrollAnimator.cancel();
                 mScrollAnimator.removeAllListeners();
@@ -264,7 +265,7 @@
                 @Override
                 public void onAnimationEnd(Animator animation) {
                     // Disable hw layers on the stack
-                    decHwLayersRefCount();
+                    decHwLayersRefCount("animateBoundScroll");
                 }
             });
             mScrollAnimator.start();
@@ -279,6 +280,15 @@
         }
     }
 
+    void abortScroller() {
+        if (!mScroller.isFinished()) {
+            // Abort the scroller
+            mScroller.abortAnimation();
+            // And disable hw layers on the stack
+            decHwLayersRefCount("flingScroll");
+        }
+    }
+
     /** Bounds the current scroll if necessary */
     public boolean boundScroll() {
         int curScroll = getStackScroll();
@@ -318,10 +328,10 @@
     }
 
     /** Enables the hw layers and increments the hw layer requirement ref count */
-    void addHwLayersRefCount() {
+    void addHwLayersRefCount(String reason) {
         Console.log(Constants.DebugFlags.UI.HwLayers,
                 "[TaskStackView|addHwLayersRefCount] refCount: " +
-                        mHwLayersRefCount + "->" + (mHwLayersRefCount + 1));
+                        mHwLayersRefCount + "->" + (mHwLayersRefCount + 1) + " " + reason);
         if (mHwLayersRefCount == 0) {
             // Enable hw layers on each of the children
             int childCount = getChildCount();
@@ -335,10 +345,10 @@
 
     /** Decrements the hw layer requirement ref count and disables the hw layers when we don't
         need them anymore. */
-    void decHwLayersRefCount() {
+    void decHwLayersRefCount(String reason) {
         Console.log(Constants.DebugFlags.UI.HwLayers,
                 "[TaskStackView|decHwLayersRefCount] refCount: " +
-                        mHwLayersRefCount + "->" + (mHwLayersRefCount - 1));
+                        mHwLayersRefCount + "->" + (mHwLayersRefCount - 1) + " " + reason);
         mHwLayersRefCount--;
         if (mHwLayersRefCount == 0) {
             // Disable hw layers on each of the children
@@ -348,7 +358,8 @@
                 tv.disableHwLayers();
             }
         } else if (mHwLayersRefCount < 0) {
-            throw new RuntimeException("Invalid hw layers ref count");
+            new Throwable("Invalid hw layers ref count").printStackTrace();
+            Console.logError(getContext(), "Invalid HW layers ref count");
         }
     }
 
@@ -360,7 +371,7 @@
 
             // If we just finished scrolling, then disable the hw layers
             if (mScroller.isFinished()) {
-                decHwLayersRefCount();
+                decHwLayersRefCount("finishedFlingScroll");
             }
         }
     }
@@ -417,16 +428,15 @@
     }
 
     /** Computes the stack and task rects */
-    public void computeRects(int width, int height) {
+    public void computeRects(int width, int height, int insetBottom) {
         // Note: We let the stack view be the full height because we want the cards to go under the
         //       navigation bar if possible.  However, the stack rects which we use to calculate
         //       max scroll, etc. need to take the nav bar into account
 
         // Compute the stack rects
-        RecentsConfiguration config = RecentsConfiguration.getInstance();
         mRect.set(0, 0, width, height);
         mStackRect.set(mRect);
-        mStackRect.bottom -= config.systemInsets.bottom;
+        mStackRect.bottom -= insetBottom;
 
         int smallestDimension = Math.min(width, height);
         int padding = (int) (Constants.Values.TaskStackView.StackPaddingPct * smallestDimension / 2f);
@@ -435,19 +445,12 @@
         mStackRectSansPeek.top += Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height();
 
         // Compute the task rect
-        if (RecentsConfiguration.getInstance().layoutVerticalStack) {
-            int minHeight = (int) (mStackRect.height() -
-                    (Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height()));
-            int size = Math.min(minHeight, Math.min(mStackRect.width(), mStackRect.height()));
-            int centerX = mStackRect.centerX();
-            mTaskRect.set(centerX - size / 2, mStackRectSansPeek.top,
-                    centerX + size / 2, mStackRectSansPeek.top + size);
-        } else {
-            int size = Math.min(mStackRect.width(), mStackRect.height());
-            int centerY = mStackRect.centerY();
-            mTaskRect.set(mStackRectSansPeek.top, centerY - size / 2,
-                    mStackRectSansPeek.top + size, centerY + size / 2);
-        }
+        int minHeight = (int) (mStackRect.height() -
+                (Constants.Values.TaskStackView.StackPeekHeightPct * mStackRect.height()));
+        int size = Math.min(minHeight, Math.min(mStackRect.width(), mStackRect.height()));
+        int centerX = mStackRect.centerX();
+        mTaskRect.set(centerX - size / 2, mStackRectSansPeek.top,
+                centerX + size / 2, mStackRectSansPeek.top + size);
 
         // Update the scroll bounds
         updateMinMaxScroll(false);
@@ -462,7 +465,8 @@
                 " awaitingFirstLayout: " + mAwaitingFirstLayout, Console.AnsiGreen);
 
         // Compute our stack/task rects
-        computeRects(width, height);
+        RecentsConfiguration config = RecentsConfiguration.getInstance();
+        computeRects(width, height, config.systemInsets.bottom);
 
         // Debug logging
         if (Constants.DebugFlags.UI.MeasureAndLayout) {
@@ -589,7 +593,6 @@
         // Report that this tasks's data is no longer being used
         RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
         loader.unloadTaskData(task);
-        tv.unbindFromTask();
 
         // Detach the view from the hierarchy
         detachViewFromParent(tv);
@@ -606,11 +609,10 @@
         // Setup and attach the view to the window
         Task task = prepareData;
         // We try and rebind the task (this MUST be done before the task filled)
-        tv.bindToTask(task, this);
+        tv.onTaskBound(task);
         // Request that this tasks's data be filled
         RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
         loader.loadTaskData(task);
-        tv.syncToTask();
 
         // Find the index where this task should be placed in the children
         int insertIndex = -1;
@@ -628,7 +630,10 @@
                 "" + insertIndex);
         if (isNewView) {
             addView(tv, insertIndex);
+
+            // Set the callbacks and listeners for this new view
             tv.setOnClickListener(this);
+            tv.setCallbacks(this);
         } else {
             attachViewToParent(tv, insertIndex, tv.getLayoutParams());
         }
@@ -658,7 +663,7 @@
                 mStack.filterTasks(tv.getTask());
             }
         } else {
-            Toast.makeText(getContext(), "Task Filtering TBD", Toast.LENGTH_SHORT).show();
+            Console.logError(getContext(), "Task Filtering TBD");
         }
     }
 
@@ -678,14 +683,13 @@
 }
 
 /* Handles touch events */
-class TaskStackViewTouchHandler {
+class TaskStackViewTouchHandler implements SwipeHelper.Callback {
     static int INACTIVE_POINTER_ID = -1;
 
     TaskStackView mSv;
     VelocityTracker mVelocityTracker;
 
     boolean mIsScrolling;
-    boolean mIsSwiping;
 
     int mInitialMotionX, mInitialMotionY;
     int mLastMotionX, mLastMotionY;
@@ -697,21 +701,24 @@
     int mMaximumVelocity;
     // The scroll touch slop is used to calculate when we start scrolling
     int mScrollTouchSlop;
-    // The swipe touch slop is used to calculate when we start swiping left/right, this takes
-    // precendence over the scroll touch slop in case the user makes a gesture that starts scrolling
-    // but is intended to be a swipe
-    int mSwipeTouchSlop;
-    // After a certain amount of scrolling, we should start ignoring checks for swiping
-    int mMaxScrollMotionToRejectSwipe;
+    // The page touch slop is used to calculate when we start swiping
+    float mPagingTouchSlop;
+
+    SwipeHelper mSwipeHelper;
+    boolean mInterceptedBySwipeHelper;
 
     public TaskStackViewTouchHandler(Context context, TaskStackView sv) {
         ViewConfiguration configuration = ViewConfiguration.get(context);
         mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
         mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
         mScrollTouchSlop = configuration.getScaledTouchSlop();
-        mSwipeTouchSlop = 2 * mScrollTouchSlop;
-        mMaxScrollMotionToRejectSwipe = 4 * mScrollTouchSlop;
+        mPagingTouchSlop = configuration.getScaledPagingTouchSlop();
         mSv = sv;
+
+
+        float densityScale = context.getResources().getDisplayMetrics().density;
+        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, mPagingTouchSlop);
+        mSwipeHelper.setMinAlpha(1f);
     }
 
     /** Velocity tracker helpers */
@@ -754,11 +761,18 @@
                 "[TaskStackViewTouchHandler|interceptTouchEvent]",
                 Console.motionEventActionToString(ev.getAction()), Console.AnsiBlue);
 
+        // Return early if we have no children
         boolean hasChildren = (mSv.getChildCount() > 0);
         if (!hasChildren) {
             return false;
         }
 
+        // Pass through to swipe helper if we are swiping
+        mInterceptedBySwipeHelper = mSwipeHelper.onInterceptTouchEvent(ev);
+        if (mInterceptedBySwipeHelper) {
+            return true;
+        }
+
         boolean wasScrolling = !mSv.mScroller.isFinished() ||
                 (mSv.mScrollAnimator != null && mSv.mScrollAnimator.isRunning());
         int action = ev.getAction();
@@ -770,14 +784,13 @@
                 mActivePointerId = ev.getPointerId(0);
                 mActiveTaskView = findViewAtPoint(mLastMotionX, mLastMotionY);
                 // Stop the current scroll if it is still flinging
-                mSv.mScroller.abortAnimation();
+                mSv.abortScroller();
                 mSv.abortBoundScrollAnimation();
                 // Initialize the velocity tracker
                 initOrResetVelocityTracker();
                 mVelocityTracker.addMovement(ev);
                 // Check if the scroller is finished yet
                 mIsScrolling = !mSv.mScroller.isFinished();
-                mIsSwiping = false;
                 break;
             }
             case MotionEvent.ACTION_MOVE: {
@@ -786,25 +799,7 @@
                 int activePointerIndex = ev.findPointerIndex(mActivePointerId);
                 int y = (int) ev.getY(activePointerIndex);
                 int x = (int) ev.getX(activePointerIndex);
-                if (mActiveTaskView != null &&
-                        mTotalScrollMotion < mMaxScrollMotionToRejectSwipe &&
-                        Math.abs(x - mInitialMotionX) > Math.abs(y - mInitialMotionY) &&
-                        Math.abs(x - mInitialMotionX) > mSwipeTouchSlop) {
-                    // Start swiping and stop scrolling
-                    mIsScrolling = false;
-                    mIsSwiping = true;
-                    System.out.println("SWIPING: " + mActiveTaskView);
-                    // Initialize the velocity tracker if necessary
-                    initOrResetVelocityTracker();
-                    mVelocityTracker.addMovement(ev);
-                    // Disallow parents from intercepting touch events
-                    final ViewParent parent = mSv.getParent();
-                    if (parent != null) {
-                        parent.requestDisallowInterceptTouchEvent(true);
-                    }
-                    // Enable HW layers
-                    mSv.addHwLayersRefCount();
-                } else if (Math.abs(y - mInitialMotionY) > mScrollTouchSlop) {
+                if (Math.abs(y - mInitialMotionY) > mScrollTouchSlop) {
                     // Save the touch move info
                     mIsScrolling = true;
                     // Initialize the velocity tracker if necessary
@@ -816,7 +811,7 @@
                         parent.requestDisallowInterceptTouchEvent(true);
                     }
                     // Enable HW layers
-                    mSv.addHwLayersRefCount();
+                    mSv.addHwLayersRefCount("stackScroll");
                 }
 
                 mLastMotionX = x;
@@ -827,9 +822,12 @@
             case MotionEvent.ACTION_UP: {
                 // Animate the scroll back if we've cancelled
                 mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
+                // Disable HW layers
+                if (mIsScrolling) {
+                    mSv.decHwLayersRefCount("stackScroll");
+                }
                 // Reset the drag state and the velocity tracker
                 mIsScrolling = false;
-                mIsSwiping = false;
                 mActivePointerId = INACTIVE_POINTER_ID;
                 mActiveTaskView = null;
                 mTotalScrollMotion = 0;
@@ -838,7 +836,7 @@
             }
         }
 
-        return wasScrolling || mIsScrolling || mIsSwiping;
+        return wasScrolling || mIsScrolling;
     }
 
     /** Handles touch events once we have intercepted them */
@@ -853,6 +851,11 @@
             return false;
         }
 
+        // Pass through to swipe helper if we are swiping
+        if (mInterceptedBySwipeHelper && mSwipeHelper.onTouchEvent(ev)) {
+            return true;
+        }
+
         // Update the velocity tracker
         initVelocityTrackerIfNotExists();
         mVelocityTracker.addMovement(ev);
@@ -866,12 +869,11 @@
                 mActivePointerId = ev.getPointerId(0);
                 mActiveTaskView = findViewAtPoint(mLastMotionX, mLastMotionY);
                 // Stop the current scroll if it is still flinging
-                mSv.mScroller.abortAnimation();
+                mSv.abortScroller();
                 mSv.abortBoundScrollAnimation();
                 // Initialize the velocity tracker
                 initOrResetVelocityTracker();
                 mVelocityTracker.addMovement(ev);
-                // XXX: Set mIsScrolling or mIsSwiping?
                 // Disallow parents from intercepting touch events
                 final ViewParent parent = mSv.getParent();
                 if (parent != null) {
@@ -886,28 +888,7 @@
                 int x = (int) ev.getX(activePointerIndex);
                 int y = (int) ev.getY(activePointerIndex);
                 int deltaY = mLastMotionY - y;
-                int deltaX = x - mLastMotionX;
-                if (!mIsSwiping) {
-                    if (mActiveTaskView != null &&
-                            mTotalScrollMotion < mMaxScrollMotionToRejectSwipe &&
-                            Math.abs(x - mInitialMotionX) > Math.abs(y - mInitialMotionY) &&
-                            Math.abs(x - mInitialMotionX) > mSwipeTouchSlop) {
-                        mIsScrolling = false;
-                        mIsSwiping = true;
-                        System.out.println("SWIPING: " + mActiveTaskView);
-                        // Initialize the velocity tracker if necessary
-                        initOrResetVelocityTracker();
-                        mVelocityTracker.addMovement(ev);
-                        // Disallow parents from intercepting touch events
-                        final ViewParent parent = mSv.getParent();
-                        if (parent != null) {
-                            parent.requestDisallowInterceptTouchEvent(true);
-                        }
-                        // Enable HW layers
-                        mSv.addHwLayersRefCount();
-                    }
-                }
-                if (!mIsSwiping && !mIsScrolling) {
+                if (!mIsScrolling) {
                     if (Math.abs(y - mInitialMotionY) > mScrollTouchSlop) {
                         mIsScrolling = true;
                         // Initialize the velocity tracker
@@ -919,7 +900,7 @@
                             parent.requestDisallowInterceptTouchEvent(true);
                         }
                         // Enable HW layers
-                        mSv.addHwLayersRefCount();
+                        mSv.addHwLayersRefCount("stackScroll");
                     }
                 }
                 if (mIsScrolling) {
@@ -927,8 +908,6 @@
                     if (mSv.isScrollOutOfBounds()) {
                         mVelocityTracker.clear();
                     }
-                } else if (mIsSwiping) {
-                    mActiveTaskView.setTranslationX(mActiveTaskView.getTranslationX() + deltaX);
                 }
                 mLastMotionX = x;
                 mLastMotionY = y;
@@ -936,140 +915,133 @@
                 break;
             }
             case MotionEvent.ACTION_UP: {
-                if (mIsScrolling || mIsSwiping) {
-                    final TaskView activeTv = mActiveTaskView;
-                    final VelocityTracker velocityTracker = mVelocityTracker;
-                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+                final VelocityTracker velocityTracker = mVelocityTracker;
+                velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+                int velocity = (int) velocityTracker.getYVelocity(mActivePointerId);
 
-                    if (mIsSwiping) {
-                        int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);
-                        if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
-                            // Fling to dismiss
-                            int newScrollX = (int) (Math.signum(initialVelocity) *
-                                    activeTv.getMeasuredWidth());
-                            int duration = Math.min(Constants.Values.TaskStackView.Animation.SwipeDismissDuration,
-                                    (int) (Math.abs(newScrollX - activeTv.getScrollX()) *
-                                            1000f / Math.abs(initialVelocity)));
-                            activeTv.animate()
-                                    .translationX(newScrollX)
-                                    .alpha(0f)
-                                    .setDuration(duration)
-                                    .setListener(new AnimatorListenerAdapter() {
-                                        @Override
-                                        public void onAnimationEnd(Animator animation) {
-                                            Task task = activeTv.getTask();
-                                            Activity activity = (Activity) mSv.getContext();
+                if (mIsScrolling && (Math.abs(velocity) > mMinimumVelocity)) {
+                    // Enable HW layers on the stack
+                    mSv.addHwLayersRefCount("flingScroll");
+                    int overscrollRange = (int) (Math.min(1f,
+                            Math.abs((float) velocity / mMaximumVelocity)) *
+                            Constants.Values.TaskStackView.TaskStackOverscrollRange);
 
-                                            // We have to disable the listener to ensure that we
-                                            // don't hit this again
-                                            activeTv.animate().setListener(null);
+                    Console.log(Constants.DebugFlags.UI.TouchEvents,
+                            "[TaskStackViewTouchHandler|fling]",
+                            "scroll: " + mSv.getStackScroll() + " velocity: " + velocity +
+                                    " maxVelocity: " + mMaximumVelocity +
+                                    " overscrollRange: " + overscrollRange,
+                            Console.AnsiGreen);
 
-                                            // Remove the task from the view
-                                            mSv.mStack.removeTask(task);
-
-                                            // Remove any stored data from the loader
-                                            RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
-                                            loader.deleteTaskData(task);
-
-                                            // Remove the task from activity manager
-                                            final ActivityManager am = (ActivityManager)
-                                                activity.getSystemService(Context.ACTIVITY_SERVICE);
-                                            if (am != null) {
-                                                am.removeTask(activeTv.getTask().id,
-                                                        ActivityManager.REMOVE_TASK_KILL_PROCESS);
-                                            }
-
-                                            // If there are no remaining tasks, then just close the activity
-                                            if (mSv.mStack.getTaskCount() == 0) {
-                                                activity.finish();
-                                            }
-
-                                            // Disable HW layers
-                                            mSv.decHwLayersRefCount();
-                                        }
-                                    })
-                                    .start();
-                            // Enable HW layers
-                            mSv.addHwLayersRefCount();
-                        } else {
-                            // Animate it back into place
-                            // XXX: Make this animation a function of the velocity OR distance
-                            int duration = Constants.Values.TaskStackView.Animation.SwipeSnapBackDuration;
-                            activeTv.animate()
-                                    .translationX(0)
-                                    .setDuration(duration)
-                                    .setListener(new AnimatorListenerAdapter() {
-                                        @Override
-                                        public void onAnimationEnd(Animator animation) {
-                                            // Disable HW layers
-                                            mSv.decHwLayersRefCount();
-                                        }
-                                    })
-                                    .start();
-                            // Enable HW layers
-                            mSv.addHwLayersRefCount();
-                        }
-                    } else {
-                        int velocity = (int) velocityTracker.getYVelocity(mActivePointerId);
-                        if ((Math.abs(velocity) > mMinimumVelocity)) {
-                            Console.log(Constants.DebugFlags.UI.TouchEvents,
-                                "[TaskStackViewTouchHandler|fling]",
-                                "scroll: " + mSv.getStackScroll() + " velocity: " + velocity,
-                                    Console.AnsiGreen);
-                            // Enable HW layers on the stack
-                            mSv.addHwLayersRefCount();
-                            // Fling scroll
-                            mSv.mScroller.fling(0, mSv.getStackScroll(),
-                                    0, -velocity,
-                                    0, 0,
-                                    mSv.mMinScroll, mSv.mMaxScroll,
-                                    0, 0);
-                            // Invalidate to kick off computeScroll
-                            mSv.invalidate();
-                        } else if (mSv.isScrollOutOfBounds()) {
-                            // Animate the scroll back into bounds
-                            // XXX: Make this animation a function of the velocity OR distance
-                            mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
-                        }
-                    }
+                    // Fling scroll
+                    mSv.mScroller.fling(0, mSv.getStackScroll(),
+                            0, -velocity,
+                            0, 0,
+                            mSv.mMinScroll, mSv.mMaxScroll,
+                            0, overscrollRange);
+                    // Invalidate to kick off computeScroll
+                    mSv.invalidate();
+                } else if (mSv.isScrollOutOfBounds()) {
+                    // Animate the scroll back into bounds
+                    // XXX: Make this animation a function of the velocity OR distance
+                    mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
                 }
 
+                if (mIsScrolling) {
+                    // Disable HW layers
+                    mSv.decHwLayersRefCount("stackScroll");
+                }
                 mActivePointerId = INACTIVE_POINTER_ID;
                 mIsScrolling = false;
-                mIsSwiping = false;
                 mTotalScrollMotion = 0;
                 recycleVelocityTracker();
-                // Disable HW layers
-                mSv.decHwLayersRefCount();
                 break;
             }
             case MotionEvent.ACTION_CANCEL: {
-                if (mIsScrolling || mIsSwiping) {
-                    if (mIsSwiping) {
-                        // Animate it back into place
-                        // XXX: Make this animation a function of the velocity OR distance
-                        int duration = Constants.Values.TaskStackView.Animation.SwipeSnapBackDuration;
-                        mActiveTaskView.animate()
-                                .translationX(0)
-                                .setDuration(duration)
-                                .start();
-                    } else {
-                        // Animate the scroll back into bounds
-                        // XXX: Make this animation a function of the velocity OR distance
-                        mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
-                    }
+                if (mIsScrolling) {
+                    // Disable HW layers
+                    mSv.decHwLayersRefCount("stackScroll");
                 }
-
+                if (mSv.isScrollOutOfBounds()) {
+                    // Animate the scroll back into bounds
+                    // XXX: Make this animation a function of the velocity OR distance
+                    mSv.animateBoundScroll(Constants.Values.TaskStackView.Animation.SnapScrollBackDuration);
+                }
                 mActivePointerId = INACTIVE_POINTER_ID;
                 mIsScrolling = false;
-                mIsSwiping = false;
                 mTotalScrollMotion = 0;
                 recycleVelocityTracker();
-                // Disable HW layers
-                mSv.decHwLayersRefCount();
                 break;
             }
         }
         return true;
     }
+
+    /**** SwipeHelper Implementation ****/
+
+    @Override
+    public View getChildAtPosition(MotionEvent ev) {
+        return findViewAtPoint((int) ev.getX(), (int) ev.getY());
+    }
+
+    @Override
+    public boolean canChildBeDismissed(View v) {
+        return true;
+    }
+
+    @Override
+    public void onBeginDrag(View v) {
+        // Enable HW layers
+        mSv.addHwLayersRefCount("swipeBegin");
+        // Disallow parents from intercepting touch events
+        final ViewParent parent = mSv.getParent();
+        if (parent != null) {
+            parent.requestDisallowInterceptTouchEvent(true);
+        }
+    }
+
+    @Override
+    public void onChildDismissed(View v) {
+        TaskView tv = (TaskView) v;
+        Task task = tv.getTask();
+        Activity activity = (Activity) mSv.getContext();
+
+        // We have to disable the listener to ensure that we
+        // don't hit this again
+        tv.animate().setListener(null);
+
+        // Remove the task from the view
+        mSv.mStack.removeTask(task);
+
+        // Remove any stored data from the loader
+        RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
+        loader.deleteTaskData(task);
+
+        // Remove the task from activity manager
+        final ActivityManager am = (ActivityManager)
+                activity.getSystemService(Context.ACTIVITY_SERVICE);
+        if (am != null) {
+            am.removeTask(tv.getTask().key.id,
+                    ActivityManager.REMOVE_TASK_KILL_PROCESS);
+        }
+
+        // If there are no remaining tasks, then just close the activity
+        if (mSv.mStack.getTaskCount() == 0) {
+            activity.finish();
+        }
+
+        // Disable HW layers
+        mSv.decHwLayersRefCount("swipeComplete");
+    }
+
+    @Override
+    public void onSnapBackCompleted(View v) {
+        // Do Nothing
+    }
+
+    @Override
+    public void onDragCancelled(View v) {
+        // Disable HW layers
+        mSv.decHwLayersRefCount("swipeCancelled");
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index b1d0d13..9d4f92d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -39,13 +39,7 @@
 import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.RecentsConfiguration;
 import com.android.systemui.recents.model.Task;
-import com.android.systemui.recents.model.TaskCallbacks;
 
-/** The TaskView callbacks */
-interface TaskViewCallbacks {
-    public void onTaskIconClicked(TaskView tv);
-    // public void onTaskViewReboundToTask(TaskView tv, Task t);
-}
 
 /** The task thumbnail view */
 class TaskThumbnailView extends ImageView {
@@ -66,7 +60,7 @@
             // Update the bar color
             if (Constants.Values.TaskView.DrawColoredTaskBars) {
                 int[] colors = {0xFFCC0C39, 0xFFE6781E, 0xFFC8CF02, 0xFF1693A7};
-                mBarColor = colors[mTask.intent.getComponent().getPackageName().length() % colors.length];
+                mBarColor = colors[mTask.key.intent.getComponent().getPackageName().length() % colors.length];
             }
 
             setImageBitmap(t.thumbnail);
@@ -213,7 +207,13 @@
 }
 
 /* A task view */
-public class TaskView extends FrameLayout implements View.OnClickListener, TaskCallbacks {
+public class TaskView extends FrameLayout implements View.OnClickListener, Task.TaskCallbacks {
+    /** The TaskView callbacks */
+    interface TaskViewCallbacks {
+        public void onTaskIconClicked(TaskView tv);
+        // public void onTaskViewReboundToTask(TaskView tv, Task t);
+    }
+
     Task mTask;
     TaskThumbnailView mThumbnailView;
     TaskIconView mIconView;
@@ -247,26 +247,11 @@
         ((LayoutParams) mIconView.getLayoutParams()).rightMargin = offset;
     }
 
-    /** Set the task and callback */
-    void bindToTask(Task t, TaskViewCallbacks cb) {
-        mTask = t;
-        mTask.setCallbacks(this);
+    /** Set callback */
+    void setCallbacks(TaskViewCallbacks cb) {
         mCb = cb;
     }
 
-    /** Actually synchronizes the model data into the views */
-    void syncToTask() {
-        mThumbnailView.rebindToTask(mTask, false);
-        mIconView.rebindToTask(mTask, false);
-    }
-
-    /** Unset the task and callback */
-    void unbindFromTask() {
-        mTask.setCallbacks(null);
-        mThumbnailView.unbindFromTask();
-        mIconView.unbindFromTask();
-    }
-
     /** Gets the task */
     Task getTask() {
         return mTask;
@@ -305,17 +290,36 @@
 
     /** Animates this task view as it enters recents */
     public void animateOnEnterRecents() {
-        mIconView.setCircularClipRadius(0f);
-        mIconView.animateCircularClip(true, 1f,
-            Constants.Values.TaskView.Animation.TaskIconCircularClipInDuration,
-            300, new AccelerateInterpolator(), null);
+        if (Constants.Values.TaskView.AnimateFrontTaskIconOnEnterUseClip) {
+            mIconView.setCircularClipRadius(0f);
+            mIconView.animateCircularClip(true, 1f,
+                Constants.Values.TaskView.Animation.TaskIconOnEnterDuration,
+                300, new AccelerateInterpolator(), null);
+        } else {
+            RecentsConfiguration config = RecentsConfiguration.getInstance();
+            int translate = config.pxFromDp(10);
+            mIconView.setScaleX(1.25f);
+            mIconView.setScaleY(1.25f);
+            mIconView.setAlpha(0f);
+            mIconView.setTranslationX(translate / 2);
+            mIconView.setTranslationY(-translate);
+            mIconView.animate()
+                    .alpha(1f)
+                    .scaleX(1f)
+                    .scaleY(1f)
+                    .translationX(0)
+                    .translationY(0)
+                    .setStartDelay(235)
+                    .setDuration(Constants.Values.TaskView.Animation.TaskIconOnEnterDuration)
+                    .start();
+        }
     }
 
     /** Animates this task view as it exits recents */
     public void animateOnLeavingRecents(final Runnable r) {
         if (Constants.Values.TaskView.AnimateFrontTaskIconOnLeavingUseClip) {
             mIconView.animateCircularClip(false, 0f,
-                Constants.Values.TaskView.Animation.TaskIconCircularClipOutDuration, 0,
+                Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration, 0,
                 new DecelerateInterpolator(),
                 new AnimatorListenerAdapter() {
                     @Override
@@ -326,7 +330,7 @@
         } else {
             mIconView.animate()
                 .alpha(0f)
-                .setDuration(Constants.Values.TaskView.Animation.TaskIconCircularClipOutDuration)
+                .setDuration(Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration)
                 .setInterpolator(new DecelerateInterpolator())
                 .setListener(
                     new AnimatorListenerAdapter() {
@@ -357,26 +361,35 @@
 
     /** Enable the hw layers on this task view */
     void enableHwLayers() {
-        Console.log(Constants.DebugFlags.UI.HwLayers, "[TaskView|enableHwLayers]");
         mThumbnailView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
     }
 
     /** Disable the hw layers on this task view */
     void disableHwLayers() {
-        Console.log(Constants.DebugFlags.UI.HwLayers, "[TaskView|disableHwLayers]");
         mThumbnailView.setLayerType(View.LAYER_TYPE_NONE, null);
     }
 
-    @Override
-    public void onTaskDataChanged(Task task) {
-        Console.log(Constants.DebugFlags.App.EnableBackgroundTaskLoading,
-                "[TaskView|onTaskDataChanged]", task);
+    /**** TaskCallbacks Implementation ****/
 
-        // Only update this task view if the changed task is the same as the task for this view
-        if (mTask == task) {
-            mThumbnailView.rebindToTask(mTask, true);
-            mIconView.rebindToTask(mTask, true);
-        }
+    /** Binds this task view to the task */
+    public void onTaskBound(Task t) {
+        mTask = t;
+        mTask.setCallbacks(this);
+    }
+
+    @Override
+    public void onTaskDataLoaded() {
+        // Bind each of the views to the new task data
+        mThumbnailView.rebindToTask(mTask, false);
+        mIconView.rebindToTask(mTask, false);
+    }
+
+    @Override
+    public void onTaskDataUnloaded() {
+        // Unbind each of the views from the task data and remove the task callback
+        mTask.setCallbacks(null);
+        mThumbnailView.unbindFromTask();
+        mIconView.unbindFromTask();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
index f7d7095..af0094e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
@@ -24,6 +24,15 @@
 
 /* A view pool to manage more views than we can visibly handle */
 public class ViewPool<V, T> {
+
+    /* An interface to the consumer of a view pool */
+    public interface ViewPoolConsumer<V, T> {
+        public V createView(Context context);
+        public void prepareViewToEnterPool(V v);
+        public void prepareViewToLeavePool(V v, T prepareData, boolean isNewView);
+        public boolean hasPreferredData(V v, T preferredData);
+    }
+
     Context mContext;
     ViewPoolConsumer<V, T> mViewCreator;
     LinkedList<V> mPool = new LinkedList<V>();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPoolConsumer.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewPoolConsumer.java
deleted file mode 100644
index 50f45bf..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPoolConsumer.java
+++ /dev/null
@@ -1,28 +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 com.android.systemui.recents.views;
-
-import android.content.Context;
-
-
-/* An interface to the consumer of a view pool */
-public interface ViewPoolConsumer<V, T> {
-    public V createView(Context context);
-    public void prepareViewToEnterPool(V v);
-    public void prepareViewToLeavePool(V v, T prepareData, boolean isNewView);
-    public boolean hasPreferredData(V v, T preferredData);
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index a89921f..bd36128 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -28,6 +28,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.database.ContentObserver;
@@ -46,6 +47,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.service.dreams.DreamService;
 import android.service.dreams.IDreamManager;
@@ -55,6 +57,7 @@
 import android.text.TextUtils;
 import android.text.style.TextAppearanceSpan;
 import android.util.Log;
+import android.util.SparseArray;
 import android.util.SparseBooleanArray;
 import android.view.ContextThemeWrapper;
 import android.view.Display;
@@ -140,6 +143,7 @@
     protected PopupMenu mNotificationBlamePopup;
 
     protected int mCurrentUserId = 0;
+    final protected SparseArray<UserInfo> mRelatedUsers = new SparseArray<UserInfo>();
 
     protected int mLayoutDirection = -1; // invalid
     private Locale mLocale;
@@ -156,6 +160,8 @@
     private Context mLightThemeContext;
     private ImageUtils mImageUtils = new ImageUtils();
 
+    private UserManager mUserManager;
+
     // UI-specific methods
 
     /**
@@ -248,12 +254,26 @@
             String action = intent.getAction();
             if (Intent.ACTION_USER_SWITCHED.equals(action)) {
                 mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                updateRelatedUserCache();
                 if (true) Log.v(TAG, "userId " + mCurrentUserId + " is in the house");
                 userSwitched(mCurrentUserId);
+            } else if (Intent.ACTION_USER_ADDED.equals(action)) {
+                updateRelatedUserCache();
             }
         }
     };
 
+    private void updateRelatedUserCache() {
+        synchronized (mRelatedUsers) {
+            mRelatedUsers.clear();
+            if (mUserManager != null) {
+                for (UserInfo related : mUserManager.getRelatedUsers(mCurrentUserId)) {
+                    mRelatedUsers.put(related.id, related);
+                }
+            }
+        }
+    }
+
     public void start() {
         mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
         mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
@@ -287,6 +307,8 @@
         mLocale = mContext.getResources().getConfiguration().locale;
         mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
 
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+
         // Connect in to the status bar manager service
         StatusBarIconList iconList = new StatusBarIconList();
         ArrayList<IBinder> notificationKeys = new ArrayList<IBinder>();
@@ -348,22 +370,28 @@
 
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_SWITCHED);
+        filter.addAction(Intent.ACTION_USER_ADDED);
         mContext.registerReceiver(mBroadcastReceiver, filter);
+
+        updateRelatedUserCache();
     }
 
     public void userSwitched(int newUserId) {
         // should be overridden
     }
 
-    public boolean notificationIsForCurrentUser(StatusBarNotification n) {
+    public boolean notificationIsForCurrentOrRelatedUser(StatusBarNotification n) {
         final int thisUserId = mCurrentUserId;
         final int notificationUserId = n.getUserId();
         if (DEBUG && MULTIUSER_DEBUG) {
             Log.v(TAG, String.format("%s: current userid: %d, notification userid: %d",
                     n, thisUserId, notificationUserId));
         }
-        return notificationUserId == UserHandle.USER_ALL
-                || thisUserId == notificationUserId;
+        synchronized (mRelatedUsers) {
+            return notificationUserId == UserHandle.USER_ALL
+                    || thisUserId == notificationUserId
+                    || mRelatedUsers.get(notificationUserId) != null;
+        }
     }
 
     @Override
@@ -389,13 +417,14 @@
             final String _pkg = n.getPackageName();
             final String _tag = n.getTag();
             final int _id = n.getId();
+            final int _userId = n.getUserId();
             vetoButton.setOnClickListener(new View.OnClickListener() {
                     public void onClick(View v) {
                         // Accessibility feedback
                         v.announceForAccessibility(
                                 mContext.getString(R.string.accessibility_notification_dismissed));
                         try {
-                            mBarService.onNotificationClear(_pkg, _tag, _id);
+                            mBarService.onNotificationClear(_pkg, _tag, _id, _userId);
 
                         } catch (RemoteException ex) {
                             // system process is dead if we're here.
@@ -907,7 +936,7 @@
         PendingIntent contentIntent = sbn.getNotification().contentIntent;
         if (contentIntent != null) {
             final View.OnClickListener listener = makeClicker(contentIntent,
-                    sbn.getPackageName(), sbn.getTag(), sbn.getId(), isHeadsUp);
+                    sbn.getPackageName(), sbn.getTag(), sbn.getId(), isHeadsUp, sbn.getUserId());
             content.setOnClickListener(listener);
         } else {
             content.setOnClickListener(null);
@@ -1017,7 +1046,7 @@
             TextView debug = (TextView) row.findViewById(R.id.debug_info);
             if (debug != null) {
                 debug.setVisibility(View.VISIBLE);
-                debug.setText("U " + entry.notification.getUserId());
+                debug.setText("CU " + mCurrentUserId +" NU " + entry.notification.getUserId());
             }
         }
         entry.row = row;
@@ -1030,9 +1059,9 @@
         return true;
     }
 
-    public NotificationClicker makeClicker(PendingIntent intent, String pkg, String tag, int id,
-            boolean forHun) {
-        return new NotificationClicker(intent, pkg, tag, id, forHun);
+    public NotificationClicker makeClicker(PendingIntent intent, String pkg, String tag,
+            int id, boolean forHun, int userId) {
+        return new NotificationClicker(intent, pkg, tag, id, forHun, userId);
     }
 
     protected class NotificationClicker implements View.OnClickListener {
@@ -1041,14 +1070,16 @@
         private String mTag;
         private int mId;
         private boolean mIsHeadsUp;
+        private int mUserId;
 
         public NotificationClicker(PendingIntent intent, String pkg, String tag, int id,
-                boolean forHun) {
+                boolean forHun, int userId) {
             mIntent = intent;
             mPkg = pkg;
             mTag = tag;
             mId = id;
             mIsHeadsUp = forHun;
+            mUserId = userId;
         }
 
         public void onClick(View v) {
@@ -1084,7 +1115,7 @@
                 if (mIsHeadsUp) {
                     mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
                 }
-                mBarService.onNotificationClick(mPkg, mTag, mId);
+                mBarService.onNotificationClick(mPkg, mTag, mId, mUserId);
             } catch (RemoteException ex) {
                 // system process is dead if we're here.
             }
@@ -1122,7 +1153,8 @@
     void handleNotificationError(IBinder key, StatusBarNotification n, String message) {
         removeNotification(key);
         try {
-            mBarService.onNotificationError(n.getPackageName(), n.getTag(), n.getId(), n.getUid(), n.getInitialPid(), message);
+            mBarService.onNotificationError(n.getPackageName(), n.getTag(), n.getId(), n.getUid(),
+                    n.getInitialPid(), message, n.getUserId());
         } catch (RemoteException ex) {
             // The end is nigh.
         }
@@ -1391,7 +1423,7 @@
         updateNotificationVetoButton(oldEntry.row, notification);
 
         // Is this for you?
-        boolean isForCurrentUser = notificationIsForCurrentUser(notification);
+        boolean isForCurrentUser = notificationIsForCurrentOrRelatedUser(notification);
         if (DEBUG) Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
 
         // Restart the ticker if it's still running
@@ -1443,7 +1475,7 @@
         if (contentIntent != null) {
             final View.OnClickListener listener = makeClicker(contentIntent,
                     notification.getPackageName(), notification.getTag(), notification.getId(),
-                    isHeadsUp);
+                    isHeadsUp, notification.getUserId());
             entry.content.setOnClickListener(listener);
         } else {
             entry.content.setOnClickListener(null);
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 237b7f7..6be6d4d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -20,7 +20,6 @@
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
-import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.EventLog;
 import android.view.MotionEvent;
@@ -57,17 +56,6 @@
         mHandleBar = resources.getDrawable(R.drawable.status_bar_close);
         mHandleBarHeight = resources.getDimensionPixelSize(R.dimen.close_handle_height);
         mHandleView = findViewById(R.id.handle);
-        PanelHeaderView header = (PanelHeaderView) findViewById(R.id.header);
-        ZenModeView zenModeView = (ZenModeView) findViewById(R.id.zenmode);
-        zenModeView.setAdapter(new ZenModeViewAdapter(mContext) {
-            @Override
-            public void configure() {
-                if (mStatusBar != null) {
-                    mStatusBar.startSettingsActivity(Settings.ACTION_ZEN_MODE_SETTINGS);
-                }
-            }
-        });
-        header.setZenModeView(zenModeView);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelHeaderView.java
deleted file mode 100644
index a28324d..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelHeaderView.java
+++ /dev/null
@@ -1,70 +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 com.android.systemui.statusbar.phone;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.widget.LinearLayout;
-
-public class PanelHeaderView extends LinearLayout {
-    private static final String TAG = "PanelHeaderView";
-    private static final boolean DEBUG = false;
-
-    private ZenModeView mZenModeView;
-
-    public PanelHeaderView(Context context) {
-        super(context);
-    }
-
-    public PanelHeaderView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public void setZenModeView(ZenModeView zmv) {
-        mZenModeView = zmv;
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent ev) {
-        final boolean rt = super.dispatchTouchEvent(ev);
-        if (DEBUG) logTouchEvent("dispatchTouchEvent", rt, ev);
-        if (mZenModeView != null) {
-            mZenModeView.dispatchExternalTouchEvent(ev);
-        }
-        return rt;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        final boolean rt = super.onInterceptTouchEvent(ev);
-        if (DEBUG) logTouchEvent("onInterceptTouchEvent", rt, ev);
-        return rt;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        boolean rt = super.onTouchEvent(event);
-        if (DEBUG) logTouchEvent("onTouchEvent", rt, event);
-        return true;
-    }
-
-    private void logTouchEvent(String method, boolean rt, MotionEvent ev) {
-        Log.d(TAG, method + " " + (rt ? "TRUE" : "FALSE") + " " + ev);
-    }
-}
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 6718de1..9540bd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1056,7 +1056,10 @@
         for (int i=0; i<N; i++) {
             Entry ent = mNotificationData.get(N-i-1);
             if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
-            if (!notificationIsForCurrentUser(ent.notification)) continue;
+
+            // TODO How do we want to badge notifcations from related users.
+            if (!notificationIsForCurrentOrRelatedUser(ent.notification)) continue;
+
             final int vis = ent.notification.getNotification().visibility;
             if (vis != Notification.VISIBILITY_SECRET) {
                 // when isLockscreenPublicMode() we show the public form of VISIBILITY_PRIVATE notifications
@@ -1114,7 +1117,7 @@
             Entry ent = mNotificationData.get(N-i-1);
             if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE)
                     || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
-            if (!notificationIsForCurrentUser(ent.notification)) continue;
+            if (!notificationIsForCurrentOrRelatedUser(ent.notification)) continue;
             if (isLockscreenPublicMode()
                     && ent.notification.getNotification().visibility
                             == Notification.VISIBILITY_SECRET
@@ -2121,7 +2124,7 @@
         if (!isDeviceProvisioned()) return;
 
         // not for you
-        if (!notificationIsForCurrentUser(n)) return;
+        if (!notificationIsForCurrentOrRelatedUser(n)) return;
 
         // Show the ticker if one is requested. Also don't do this
         // until status bar window is attached to the window manager,
@@ -2429,7 +2432,7 @@
                                 }
                                 try {
                                     mPile.setViewRemoval(true);
-                                    mBarService.onClearAllNotifications();
+                                    mBarService.onClearAllNotifications(mCurrentUserId);
                                 } catch (Exception ex) { }
                             }
                         };
@@ -2607,7 +2610,8 @@
                 mBarService.onNotificationClear(
                         mInterruptingNotificationEntry.notification.getPackageName(),
                         mInterruptingNotificationEntry.notification.getTag(),
-                        mInterruptingNotificationEntry.notification.getId());
+                        mInterruptingNotificationEntry.notification.getId(),
+                        mInterruptingNotificationEntry.notification.getUserId());
             } catch (android.os.RemoteException ex) {
                 // oh well
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
index c1c8946..8170b5a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettings.java
@@ -52,13 +52,16 @@
 import android.provider.ContactsContract.Profile;
 import android.provider.Settings;
 import android.security.KeyChain;
+import android.text.TextUtils.TruncateAt;
 import android.util.Log;
 import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.Window;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
+import android.widget.Button;
 import android.widget.ImageView;
 import android.widget.TextView;
 
@@ -586,6 +589,31 @@
         });
         parent.addView(airplaneTile);
 
+        // Zen Mode
+        final QuickSettingsBasicTile zenModeTile = new QuickSettingsBasicTile(mContext);
+        zenModeTile.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showZenModeDialog();
+            }
+        });
+        mModel.addZenModeTile(zenModeTile, new QuickSettingsModel.RefreshCallback() {
+            @Override
+            public void refreshView(QuickSettingsTileView unused, State state) {
+                zenModeTile.setImageResource(state.iconId);
+                // TODO cut new assets
+                zenModeTile.getImageView().setAlpha(state.enabled ? 1 : .2f);
+                zenModeTile.getImageView().setScaleX(1.5f);
+                zenModeTile.getImageView().setScaleY(1.5f);
+                // for landscape version
+                zenModeTile.getTextView().setMaxLines(2);
+                zenModeTile.getTextView().setEllipsize(TruncateAt.END);
+                // TODO content description
+                zenModeTile.setText(state.label);
+            }
+        });
+        parent.addView(zenModeTile);
+
         // Bluetooth
         if (mModel.deviceSupportsBluetooth()
                 || DEBUG_GONE_TILES) {
@@ -864,6 +892,31 @@
         dialog.show();
     }
 
+    private void showZenModeDialog() {
+        final Dialog d = new Dialog(mContext);
+        d.requestWindowFeature(Window.FEATURE_NO_TITLE);
+        d.setCancelable(true);
+        d.setCanceledOnTouchOutside(true);
+        final ZenModeView v = new ZenModeView(mContext);
+        v.setAdapter(new ZenModeViewAdapter(mContext) {
+            @Override
+            public void configure() {
+                if (mStatusBarService != null) {
+                    mStatusBarService.startSettingsActivity(Settings.ACTION_ZEN_MODE_SETTINGS);
+                }
+                d.dismiss();
+            }
+            @Override
+            public void close() {
+                d.dismiss();
+            }
+        });
+        d.setContentView(v);
+        d.create();
+        d.getWindow().setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
+        d.show();
+    }
+
     private void applyBluetoothStatus() {
         mModel.onBluetoothStateChange(mBluetoothState);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
index 174cad8..c3c281c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickSettingsModel.java
@@ -38,6 +38,7 @@
 import android.text.TextUtils;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.WindowManager;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodSubtype;
@@ -112,6 +113,9 @@
     public static class RotationLockState extends State {
         boolean visible = false;
     }
+    public static class ZenModeState extends State {
+        int zenMode = Settings.Global.ZEN_MODE_OFF;
+    }
 
     /** The callback to update a given tile. */
     interface RefreshCallback {
@@ -294,6 +298,25 @@
         }
     }
 
+    /** ContentObserver to watch display color space adjustment */
+    private class ZenModeObserver extends ContentObserver {
+        public ZenModeObserver(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            onZenModeChanged();
+        }
+
+        public void startObserving() {
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.unregisterContentObserver(this);
+            cr.registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false, this);
+        }
+    }
+
     /** Callback for changes to remote display routes. */
     private class RemoteDisplayRouteCallback extends MediaRouter.SimpleCallback {
         @Override
@@ -327,6 +350,7 @@
     private final DisplayInversionObserver mInversionObserver;
     private final DisplayContrastObserver mContrastObserver;
     private final DisplayColorSpaceObserver mColorSpaceObserver;
+    private final ZenModeObserver mZenModeObserver;
 
     private final MediaRouter mMediaRouter;
     private final RemoteDisplayRouteCallback mRemoteDisplayRouteCallback;
@@ -349,6 +373,10 @@
     private RefreshCallback mAirplaneModeCallback;
     private State mAirplaneModeState = new State();
 
+    private QuickSettingsTileView mZenModeTile;
+    private RefreshCallback mZenModeCallback;
+    private ZenModeState mZenModeState = new ZenModeState();
+
     private QuickSettingsTileView mWifiTile;
     private RefreshCallback mWifiCallback;
     private WifiState mWifiState = new WifiState();
@@ -445,6 +473,8 @@
         mContrastObserver.startObserving();
         mColorSpaceObserver = new DisplayColorSpaceObserver(mHandler);
         mColorSpaceObserver.startObserving();
+        mZenModeObserver = new ZenModeObserver(mHandler);
+        mZenModeObserver.startObserving();
 
         mMediaRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
         rebindMediaRouterAsCurrentUser();
@@ -567,6 +597,30 @@
         mAirplaneModeCallback.refreshView(mAirplaneModeTile, mAirplaneModeState);
     }
 
+    // Zen Mode
+    void addZenModeTile(QuickSettingsTileView view, RefreshCallback cb) {
+        mZenModeTile = view;
+        mZenModeCallback = cb;
+        onZenModeChanged();
+    }
+    private void onZenModeChanged() {
+        final int mode = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
+        mZenModeState.enabled = mode != Settings.Global.ZEN_MODE_OFF;
+        mZenModeState.zenMode = mode;
+        if (mode == Settings.Global.ZEN_MODE_FULL) {
+            mZenModeState.iconId = R.drawable.stat_sys_zen_full;
+            mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_FULL);
+        } else if (mode == Settings.Global.ZEN_MODE_LIMITED) {
+            mZenModeState.iconId = R.drawable.stat_sys_zen_limited;
+            mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_LIMITED);
+        } else {
+            mZenModeState.iconId = R.drawable.stat_sys_zen_limited;
+            mZenModeState.label = ZenModeView.modeToLabel(ZenModeView.Adapter.MODE_LIMITED);
+        }
+        mZenModeCallback.refreshView(mZenModeTile, mZenModeState);
+    }
+
     // Wifi
     void addWifiTile(QuickSettingsTileView view, RefreshCallback cb) {
         mWifiTile = view;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
index fa7f96a..d1c7a41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeView.java
@@ -19,22 +19,16 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.content.Context;
-import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Path;
-import android.graphics.Rect;
 import android.graphics.Typeface;
 import android.graphics.drawable.ShapeDrawable;
 import android.graphics.drawable.shapes.PathShape;
-import android.os.AsyncTask;
-import android.os.Vibrator;
 import android.text.Spannable;
 import android.text.SpannableStringBuilder;
 import android.text.TextPaint;
 import android.text.method.LinkMovementMethod;
-import android.text.style.RelativeSizeSpan;
 import android.text.style.URLSpan;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -62,7 +56,7 @@
     private static final Typeface CONDENSED =
             Typeface.create("sans-serif-condensed", Typeface.NORMAL);
     private static final int GRAY = 0xff999999; //TextAppearance.StatusBar.Expanded.Network
-    private static final int BACKGROUND = 0xff1d3741; //0x3333b5e5;
+    private static final int BACKGROUND = 0xff282828;
     private static final long DURATION = new ValueAnimator().getDuration();
     private static final long BOUNCE_DURATION = DURATION / 3;
     private static final float BOUNCE_SCALE = 0.8f;
@@ -73,23 +67,14 @@
 
     private final Context mContext;
     private final Paint mPathPaint;
-    private final TextView mHintText;
-    private final ModeSpinner mModeSpinner;
-    private final ImageView mCloseButton;
     private final ImageView mSettingsButton;
-    private final Rect mLayoutRect = new Rect();
+    private final ModeSpinner mModeSpinner;
+    private final TextView mActionButton;
+    private final View mDivider;
     private final UntilPager mUntilPager;
     private final AlarmWarning mAlarmWarning;
-    private final int mPopDuration;
 
-    private float mDownY;
-    private int mDownBottom;
-    private boolean mPeekable = true;
-    private boolean mClosing;
-    private int mBottom;
-    private int mWidthSpec;
     private Adapter mAdapter;
-    private boolean mPopped;
 
     public ZenModeView(Context context) {
         this(context, null);
@@ -100,34 +85,22 @@
         if (DEBUG) log("new %s()", getClass().getSimpleName());
         mContext = context;
 
-        mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        mPathPaint.setStyle(Paint.Style.STROKE);
-        mPathPaint.setColor(GRAY);
-        mPathPaint.setStrokeWidth(5);
-
         final int iconSize = mContext.getResources()
                 .getDimensionPixelSize(com.android.internal.R.dimen.notification_large_icon_width);
         final int topRowSize = iconSize * 2 / 3;
+        final int p = topRowSize / 7;
 
-        mCloseButton = new ImageView(mContext);
-        mCloseButton.setAlpha(0f);
-        mCloseButton.setImageDrawable(sd(closePath(topRowSize), topRowSize, mPathPaint));
-        addView(mCloseButton, new LayoutParams(topRowSize, topRowSize));
-        mCloseButton.setOnClickListener(new View.OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                bounce(v, null);
-                close();
-            }
-        });
+        mPathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        mPathPaint.setStyle(Paint.Style.STROKE);
+        mPathPaint.setColor(GRAY);
+        mPathPaint.setStrokeWidth(p / 2);
 
         mSettingsButton = new ImageView(mContext);
-        mSettingsButton.setAlpha(0f);
-        final int p = topRowSize / 7;
         mSettingsButton.setPadding(p, p, p, p);
         mSettingsButton.setImageResource(R.drawable.ic_notify_settings_normal);
         LayoutParams lp = new LayoutParams(topRowSize, topRowSize);
-        lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
+        lp.topMargin = p;
+        lp.leftMargin = p;
         addView(mSettingsButton, lp);
         mSettingsButton.setOnClickListener(new View.OnClickListener() {
             @Override
@@ -140,65 +113,65 @@
         });
 
         mModeSpinner = new ModeSpinner(mContext);
-        mModeSpinner.setAlpha(0);
-        mModeSpinner.setEnabled(false);
         mModeSpinner.setId(android.R.id.title);
         lp = new LayoutParams(LayoutParams.WRAP_CONTENT, topRowSize);
-        lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
+        lp.topMargin = p;
+        lp.addRule(CENTER_HORIZONTAL);
         addView(mModeSpinner, lp);
 
-        mUntilPager = new UntilPager(mContext, mPathPaint, iconSize);
-        mUntilPager.setId(android.R.id.tabhost);
-        mUntilPager.setAlpha(0);
-        lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+        mActionButton = new TextView(mContext);
+        mActionButton.setTextColor(GRAY);
+        mActionButton.setTypeface(CONDENSED);
+        mActionButton.setTextSize(TypedValue.COMPLEX_UNIT_PX, mActionButton.getTextSize() * 1.2f);
+        mActionButton.setAllCaps(true);
+        mActionButton.setGravity(Gravity.CENTER);
+        mActionButton.setPadding(p, 0, p * 2, 0);
+        lp = new LayoutParams(LayoutParams.WRAP_CONTENT, topRowSize);
+        lp.topMargin = p;
+        lp.addRule(ALIGN_PARENT_RIGHT);
+        lp.addRule(ALIGN_BASELINE, mModeSpinner.getId());
+        addView(mActionButton, lp);
+        mActionButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                bounce(v, null);
+                beginOrEnd();
+            }
+        });
+
+        mDivider = new View(mContext);
+        mDivider.setId(android.R.id.empty);
+        mDivider.setBackgroundColor(GRAY);
+        lp = new LayoutParams(LayoutParams.MATCH_PARENT, 2);
         lp.addRule(BELOW, mModeSpinner.getId());
+        lp.topMargin = p;
+        lp.bottomMargin = p;
+        addView(mDivider, lp);
+
+        mUntilPager = new UntilPager(mContext, mPathPaint, iconSize * 3 / 4);
+        mUntilPager.setId(android.R.id.tabhost);
+        lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+        lp.addRule(BELOW, mDivider.getId());
         addView(mUntilPager, lp);
 
         mAlarmWarning = new AlarmWarning(mContext);
-        mAlarmWarning.setAlpha(0);
         lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
         lp.addRule(CENTER_HORIZONTAL);
         lp.addRule(BELOW, mUntilPager.getId());
+        lp.bottomMargin = p;
         addView(mAlarmWarning, lp);
-
-        mHintText = new TextView(mContext);
-        mHintText.setTypeface(CONDENSED);
-        mHintText.setText("Swipe down for Limited Interruptions");
-        mHintText.setGravity(Gravity.CENTER);
-        mHintText.setTextColor(GRAY);
-        addView(mHintText, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
-
-        mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms);
     }
 
-    private boolean isApplicable() {
-        return mAdapter != null && mAdapter.isApplicable();
-    }
-
-    private void close() {
-        mClosing = true;
-        final int startBottom = mBottom;
-        final int max = mPeekable ? getExpandedBottom() : startBottom;
-        mHintText.animate().alpha(1).setUpdateListener(new AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                final float f = animation.getAnimatedFraction();
-                final int hintBottom = mHintText.getBottom();
-                final boolean isDone = f == 1;
-                setPeeked(hintBottom + (int)((1-f) * (startBottom - hintBottom)), max, isDone);
-                if (isDone) {
-                    mPeekable = true;
-                    mPopped = false;
-                    mClosing = false;
-                    mModeSpinner.updateState();
-                    if (mAdapter != null) {
-                        mAdapter.cancel();
-                    }
-                }
-            }
-        }).start();
-        mUntilPager.animate().alpha(0).start();
-        mAlarmWarning.animate().alpha(0).start();
+    private void beginOrEnd() {
+        if (mAdapter == null) return;
+        if (mAdapter.getMode() == mAdapter.getCommittedMode()) {
+            // end
+            mAdapter.setCommittedMode(Adapter.MODE_OFF);
+        } else {
+            // begin
+            mAdapter.setCommittedMode(mAdapter.getMode());
+        }
+        mAdapter.close();
     }
 
     public void setAdapter(Adapter adapter) {
@@ -218,180 +191,41 @@
     }
 
     private void updateState(boolean animate) {
-        final boolean applicable = isApplicable();
-        setVisibility(applicable ? VISIBLE : GONE);
-        if (!applicable) {
-            return;
-        }
-        if (mAdapter != null && mAdapter.getMode() == Adapter.MODE_OFF && !mPeekable) {
-            close();
-        } else {
-            mModeSpinner.updateState();
-            mUntilPager.updateState();
-            mAlarmWarning.updateState(animate);
-            final float settingsAlpha = getSettingsButtonAlpha();
-            if (settingsAlpha != mSettingsButton.getAlpha()) {
-                if (animate) {
-                    mSettingsButton.animate().alpha(settingsAlpha).start();
-                } else {
-                    mSettingsButton.setAlpha(settingsAlpha);
-                }
-            }
-            if (mPeekable && mAdapter != null && mAdapter.getMode() != Adapter.MODE_OFF) {
-                if (DEBUG) log("panic expand!");
-                mPeekable = false;
-                mModeSpinner.setEnabled(true);
-                mBottom = getExpandedBottom();
-                setExpanded(1);
+        mModeSpinner.updateState();
+        mUntilPager.updateState();
+        mAlarmWarning.updateState(animate);
+        final float settingsAlpha = isFull() ? 0 : SETTINGS_ALPHA;
+        if (settingsAlpha != mSettingsButton.getAlpha()) {
+            if (animate) {
+                mSettingsButton.animate().alpha(settingsAlpha).start();
+            } else {
+                mSettingsButton.setAlpha(settingsAlpha);
             }
         }
+        final boolean committed = mAdapter != null
+                && mAdapter.getMode() == mAdapter.getCommittedMode();
+        mActionButton.setText(committed ? "End" : "Begin");
     }
 
-    private float getSettingsButtonAlpha() {
-        final boolean full = mAdapter != null && mAdapter.getMode() == Adapter.MODE_FULL;
-        final boolean collapsed = mHintText.getAlpha() == 1;
-        return full || collapsed ? 0 : SETTINGS_ALPHA;
-    }
-
-    private static Path closePath(int size) {
-        final int pad = size / 4;
-        final Path p = new Path();
-        p.moveTo(pad, pad);
-        p.lineTo(size - pad, size - pad);
-        p.moveTo(size - pad, pad);
-        p.lineTo(pad, size - pad);
-        return p;
+    private boolean isFull() {
+        return mAdapter != null && mAdapter.getMode() == Adapter.MODE_FULL;
     }
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         if (DEBUG) log("onMeasure %s %s",
                 MeasureSpec.toString(widthMeasureSpec), MeasureSpec.toString(heightMeasureSpec));
-        final boolean widthExact = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY;
-
-        if (!widthExact || (widthMeasureSpec != mWidthSpec)) {
-            if (DEBUG) log("  super.onMeasure");
-            final int hms = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-            super.onMeasure(widthMeasureSpec, hms);
-            mBottom = mPeekable ? mHintText.getMeasuredHeight() : getExpandedBottom();
-            mWidthSpec = widthMeasureSpec;
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        if (!isFull()) {
+            final LayoutParams lp = (LayoutParams) mModeSpinner.getLayoutParams();
+            final int mh = vh(mModeSpinner) + vh(mDivider) + vh(mUntilPager) + lp.topMargin;
+            setMeasuredDimension(getMeasuredWidth(), mh);
         }
-        if (DEBUG) log("mBottom (OM) = " + mBottom);
-        setMeasuredDimension(getMeasuredWidth(), mBottom);
-        if (DEBUG) log("  mw=%s mh=%s",
-                toString(getMeasuredWidthAndState()), toString(getMeasuredHeightAndState()));
     }
 
-    private static String toString(int sizeAndState) {
-        final int size = sizeAndState & MEASURED_SIZE_MASK;
-        final boolean tooSmall = (sizeAndState & MEASURED_STATE_TOO_SMALL) != 0;
-        return size + (tooSmall ? "TOO SMALL" : "");
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        mLayoutRect.set(left, top, right, bottom);
-        if (DEBUG) log("onLayout %s %s %dx%d", changed,
-                mLayoutRect.toShortString(), mLayoutRect.width(), mLayoutRect.height());
-        super.onLayout(changed, left, top, right, bottom);
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent ev) {
-        final boolean rt = super.dispatchTouchEvent(ev);
-        if (DEBUG) logTouchEvent("dispatchTouchEvent", rt, ev);
-        return rt;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        final boolean rt = super.onInterceptTouchEvent(ev);
-        if (DEBUG) logTouchEvent("onInterceptTouchEvent", rt, ev);
-        if (isApplicable()
-                && ev.getAction() == MotionEvent.ACTION_DOWN
-                && ev.getY() > mCloseButton.getBottom()
-                && mPeekable) {
-            return true;
-        }
-        return rt;
-    }
-
-    private static void logTouchEvent(String method, boolean rt, MotionEvent event) {
-        final String action = MotionEvent.actionToString(event.getAction());
-        Log.d(TAG, method + " " + (rt ? "TRUE" : "FALSE") + " " + action);
-    }
-
-    private int getExpandedBottom() {
-        int b = mModeSpinner.getMeasuredHeight() + mUntilPager.getMeasuredHeight();
-        if (mAlarmWarning.getAlpha() == 1) b += mAlarmWarning.getMeasuredHeight();
-        return b;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        boolean rt = super.onTouchEvent(event);
-        if (DEBUG) logTouchEvent("onTouchEvent", rt, event);
-        if (!isApplicable() || !mPeekable) {
-            return rt;
-        }
-        if (event.getAction() == MotionEvent.ACTION_DOWN) {
-            mDownY = event.getY();
-            if (DEBUG) log("  mDownY=" + mDownY);
-            mDownBottom = mBottom;
-            return true;
-        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
-            final float dy = event.getY() - mDownY;
-            if (!mPopped) {
-                mPopped = true;
-                AsyncTask.execute(mPopVibration);
-            }
-            setPeeked(mDownBottom + (int)dy, getExpandedBottom(), false);
-        } else if (event.getAction() == MotionEvent.ACTION_UP
-                || event.getAction() == MotionEvent.ACTION_CANCEL) {
-            final float dy = event.getY() - mDownY;
-            setPeeked(mDownBottom + (int)dy, getExpandedBottom(), true);
-            if (mPeekable) {
-                close();
-            }
-        }
-        return rt;
-    }
-
-    private void setPeeked(int peeked, int max, boolean isDone) {
-        if (DEBUG) log("setPeeked=" + peeked);
-        final int min = mHintText.getBottom();
-        peeked = Math.max(min, Math.min(peeked, max));
-        if (!isDone && mBottom == peeked) {
-            return;
-        }
-        if (peeked == max && isDone) {
-            mPeekable = false;
-            mModeSpinner.setEnabled(true);
-            if (mAdapter != null) {
-                mAdapter.setMode(Adapter.MODE_LIMITED);
-            }
-        }
-        if (peeked == min) {
-            mPeekable = true;
-            mModeSpinner.setEnabled(false);
-        }
-        if (DEBUG) log("  mBottom=" + peeked);
-        mBottom = peeked;
-        final float f = (peeked - min) / (float)(max - min);
-        setExpanded(f);
-        requestLayout();
-    }
-
-    private void setExpanded(float f) {
-        if (DEBUG) log("setExpanded " + f);
-        final int a = (int)(Color.alpha(BACKGROUND) * f);
-        setBackgroundColor(Color.argb(a,
-                Color.red(BACKGROUND), Color.green(BACKGROUND), Color.blue(BACKGROUND)));
-        mHintText.setAlpha(1 - f);
-        mCloseButton.setAlpha(f);
-        mModeSpinner.setAlpha(f);
-        mUntilPager.setAlpha(f);
-        mSettingsButton.setAlpha(f * getSettingsButtonAlpha());
+    private int vh(View v) {
+        LayoutParams lp = (LayoutParams) v.getLayoutParams();
+        return v.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;
     }
 
     private static void log(String msg, Object... args) {
@@ -406,12 +240,6 @@
         return sd;
     }
 
-    public void dispatchExternalTouchEvent(MotionEvent ev) {
-        if (isApplicable()) {
-            onTouchEvent(ev);
-        }
-    }
-
     private static void bounce(final View v, final Runnable midBounce) {
         v.animate().scaleX(BOUNCE_SCALE).scaleY(BOUNCE_SCALE).setDuration(DURATION / 3)
             .setListener(new AnimatorListenerAdapter() {
@@ -429,13 +257,18 @@
             }).start();
     }
 
-    private final Runnable mPopVibration = new Runnable() {
-        @Override
-        public void run() {
-            Vibrator v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
-            v.vibrate(mPopDuration);
-        }
-    };
+    public static String modeToString(int mode) {
+        if (mode == Adapter.MODE_OFF) return "MODE_OFF";
+        if (mode == Adapter.MODE_LIMITED) return "MODE_LIMITED";
+        if (mode == Adapter.MODE_FULL) return "MODE_FULL";
+        throw new IllegalArgumentException("Invalid mode: " + mode);
+    }
+
+    public static String modeToLabel(int mode) {
+        if (mode == Adapter.MODE_LIMITED) return "Limited interruptions";
+        if (mode == Adapter.MODE_FULL) return "Zero interruptions";
+        throw new UnsupportedOperationException("Unsupported mode: " + mode);
+    }
 
     private final class UntilPager extends RelativeLayout {
         private final ImageView mPrev;
@@ -448,6 +281,7 @@
         public UntilPager(Context context, Paint pathPaint, int iconSize) {
             super(context);
             mText1 = new TextView(mContext);
+            mText1.setTextSize(TypedValue.COMPLEX_UNIT_PX, mText1.getTextSize() * 1.2f);
             mText1.setTypeface(CONDENSED);
             mText1.setTextColor(GRAY);
             mText1.setGravity(Gravity.CENTER);
@@ -456,6 +290,7 @@
             mText = mText1;
 
             mText2 = new TextView(mContext);
+            mText2.setTextSize(TypedValue.COMPLEX_UNIT_PX, mText1.getTextSize());
             mText2.setTypeface(CONDENSED);
             mText2.setTextColor(GRAY);
             mText2.setAlpha(0);
@@ -478,7 +313,7 @@
             });
 
             lp = new LayoutParams(iconSize, iconSize);
-            lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
+            lp.addRule(ALIGN_PARENT_RIGHT);
             final View v2 = new View(mContext);
             v2.setBackgroundColor(BACKGROUND);
             addView(v2, lp);
@@ -532,9 +367,7 @@
         }
 
         private void setText(final TextView textView, final ExitCondition ec) {
-            SpannableStringBuilder ss = new SpannableStringBuilder(ec.line1 + "\n" + ec.line2);
-            ss.setSpan(new RelativeSizeSpan(1.5f), (ec.line1 + "\n").length(), ss.length(),
-                    Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+            SpannableStringBuilder ss = new SpannableStringBuilder(ec.summary);
             if (ec.action != null) {
                 ss.setSpan(new CustomLinkSpan() {
                     @Override
@@ -542,7 +375,7 @@
                         // TODO wire up links
                         Toast.makeText(mContext, ec.action, Toast.LENGTH_SHORT).show();
                     }
-                }, (ec.line1 + "\n").length(), ss.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
+                }, 0, ss.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
                 textView.setMovementMethod(LinkMovementMethod.getInstance());
             } else {
                 textView.setMovementMethod(null);
@@ -558,7 +391,7 @@
         }
 
         private Path prevPath(int size) {
-            final int hp = size / 3;
+            final int hp = size * 3 / 8;
             final int vp = size / 4;
             final Path p = new Path();
             p.moveTo(size - hp, vp);
@@ -568,7 +401,7 @@
         }
 
         private Path nextPath(int size) {
-            final int hp = size / 3;
+            final int hp = size * 3 / 8;
             final int vp = size / 4;
             Path p = new Path();
             p.moveTo(hp, vp);
@@ -603,12 +436,14 @@
         public static final int MODE_LIMITED = 1;
         public static final int MODE_FULL = 2;
 
-        boolean isApplicable();
         void configure();
+        void close();
         int getMode();
         void setMode(int mode);
+        int getCommittedMode();
+        void setCommittedMode(int mode);
         void select(ExitCondition ec);
-        void cancel();
+        void init();
         void setCallbacks(Callbacks callbacks);
         ExitCondition getExitCondition(int d);
         int getExitConditionCount();
@@ -637,38 +472,38 @@
                 }
 
                 @Override
-                public View getDropDownView(int position, View convertView, ViewGroup parent) {
+                public View getDropDownView(final int position, View convertView, ViewGroup parent) {
                     if (DEBUG) log("getDropDownView %s cv=%s parent=%s",
                             position, convertView, parent);
                     final TextView tv = convertView != null ? (TextView) convertView
                             : new TextView(context);
                     final int mode = getItem(position);
-                    tv.setText(modeToString(mode));
+                    tv.setText(modeToLabel(mode));
+                    final boolean inDropdown = parent instanceof ListView;
                     if (convertView == null) {
                         if (DEBUG) log(" setting up view");
                         tv.setTextColor(GRAY);
                         tv.setTypeface(CONDENSED);
                         tv.setAllCaps(true);
-                        tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.5f);
+                        tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize() * 1.2f);
                         final int p = (int) tv.getTextSize() / 2;
-                        if (parent instanceof ListView) {
-                            tv.setPadding(p, p, p, p);
+                        if (inDropdown) {
+                            tv.setPadding(p, p, 0, p);
                         } else {
                             tv.setGravity(Gravity.CENTER_HORIZONTAL);
-                            tv.setPadding(p, 0, p, 0);
+                            tv.setPadding(p, 0, 0, 0);
                         }
                     }
                     tv.setOnTouchListener(new OnTouchListener(){
                         @Override
                         public boolean onTouch(View v, MotionEvent event) {
-                            if (DEBUG) log("onTouch %s %s", tv.getText(),
-                                    MotionEvent.actionToString(event.getAction()));
-                            if (mAdapter != null) {
+                            if (DEBUG) log("onTouch %s %s inDropdown=%s", tv.getText(),
+                                    MotionEvent.actionToString(event.getAction()), inDropdown);
+                            if (inDropdown && mAdapter != null) {
                                 mAdapter.setMode(mode);
                             }
                             return false;
                         }
-
                     });
                     return tv;
                 }
@@ -688,16 +523,10 @@
                 if (getAdapter().getItem(i).equals(mode)) {
                     if (DEBUG) log("  setting selection = " + i);
                     setSelection(i, true);
-                    return;
+                    onDetachedFromWindow();
                 }
             }
         }
-
-        private String modeToString(int mode) {
-            if (mode == Adapter.MODE_LIMITED) return "Limited interruptions";
-            if (mode == Adapter.MODE_FULL) return "Zero interruptions";
-            throw new UnsupportedOperationException("Unsupported mode: " + mode);
-        }
     }
 
     private final class AlarmWarning extends LinearLayout {
@@ -724,29 +553,12 @@
         }
 
         public void updateState(boolean animate) {
-            final boolean visible = mAdapter != null && mAdapter.getMode() == Adapter.MODE_FULL;
-            final float alpha = visible ? 1 : 0;
+            final float alpha = isFull() ? 1 : 0;
             if (alpha == getAlpha()) {
                 return;
             }
             if (animate) {
-                final boolean in = alpha == 1;
-                animate().alpha(alpha).setUpdateListener(new AnimatorUpdateListener() {
-                    @Override
-                    public void onAnimationUpdate(ValueAnimator animation) {
-                        if (mPeekable || mClosing) {
-                            return;
-                        }
-                        float f = animation.getAnimatedFraction();
-                        if (!in) {
-                            f = 1 - f;
-                        }
-                        ZenModeView.this.mBottom = mUntilPager.getBottom()
-                                + (int)(mAlarmWarning.getMeasuredHeight() * f);
-                        if (DEBUG) log("mBottom (AW) = " + mBottom);
-                        requestLayout();
-                    }
-                }).start();
+                animate().alpha(alpha).start();
             } else {
                 setAlpha(alpha);
                 requestLayout();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java
index 39c4faa..d2067a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ZenModeViewAdapter.java
@@ -35,23 +35,19 @@
     private final Handler mHandler = new Handler();
     private final SettingsObserver mObserver;
     private final List<ExitCondition> mExits = Arrays.asList(
-            newExit("Until you delete this", "Until", "You delete this"));
+            newExit("Until you turn this off", "Until", "You turn this off"));
 
     private Callbacks mCallbacks;
     private int mExitIndex;
-    private boolean mDeviceProvisioned;
     private int mMode;
+    private int mCommittedMode;
 
     public ZenModeViewAdapter(Context context) {
         mContext = context;
         mResolver = mContext.getContentResolver();
         mObserver = new SettingsObserver(mHandler);
         mObserver.init();
-    }
-
-    @Override
-    public boolean isApplicable() {
-        return mDeviceProvisioned;
+        init();
     }
 
     @Override
@@ -61,6 +57,18 @@
 
     @Override
     public void setMode(int mode) {
+        if (mode == mMode) return;
+        mMode = mode;
+        dispatchChanged();
+    }
+
+    @Override
+    public int getCommittedMode() {
+        return mCommittedMode;
+    }
+
+    @Override
+    public void setCommittedMode(int mode) {
         final int v = mode == MODE_LIMITED ? Settings.Global.ZEN_MODE_LIMITED
                     : mode == MODE_FULL ? Settings.Global.ZEN_MODE_FULL
                     : Settings.Global.ZEN_MODE_OFF;
@@ -74,12 +82,21 @@
     }
 
     @Override
-    public void cancel() {
+    public void init() {
         if (mExitIndex != 0) {
             mExitIndex = 0;
-            mHandler.post(mChange);
+            dispatchChanged();
         }
-        setMode(MODE_OFF);
+        final int mode = mCommittedMode == MODE_FULL ? MODE_FULL : MODE_LIMITED;
+        if (mode != mMode) {
+            mMode = mode;
+            dispatchChanged();
+        }
+    }
+
+    private void dispatchChanged() {
+        mHandler.removeCallbacks(mChanged);
+        mHandler.post(mChanged);
     }
 
     @Override
@@ -111,7 +128,7 @@
             return;
         }
         mExitIndex = i;
-        mHandler.post(mChange);
+        dispatchChanged();
     }
 
     private static ExitCondition newExit(String summary, String line1, String line2) {
@@ -122,7 +139,7 @@
         return rt;
     }
 
-    private final Runnable mChange = new Runnable() {
+    private final Runnable mChanged = new Runnable() {
         public void run() {
             if (mCallbacks == null) {
                 return;
@@ -145,24 +162,19 @@
             mResolver.registerContentObserver(
                     Settings.Global.getUriFor(Settings.Global.ZEN_MODE),
                     false, this);
-            mResolver.registerContentObserver(
-                    Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
-                    false, this);
         }
 
         @Override
         public void onChange(boolean selfChange) {
             loadSettings();
-            mChange.run();  // already on handler
+            mChanged.run();  // already on handler
         }
 
         private void loadSettings() {
-            mDeviceProvisioned = Settings.Global.getInt(mResolver,
-                    Settings.Global.DEVICE_PROVISIONED, 0) != 0;
-            mMode = getMode();
+            mCommittedMode = getModeFromSetting();
         }
 
-        private int getMode() {
+        private int getModeFromSetting() {
             final int v = Settings.Global.getInt(mResolver,
                     Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
             if (v == Settings.Global.ZEN_MODE_LIMITED) return MODE_LIMITED;
diff --git a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
index b9b87b1..e45b98c 100644
--- a/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
+++ b/packages/WallpaperCropper/src/com/android/wallpapercropper/WallpaperCropActivity.java
@@ -340,6 +340,13 @@
                 getWindowManager());
         // Get the crop
         RectF cropRect = mCropView.getCrop();
+
+        // Due to rounding errors in the cropview renderer the edges can be slightly offset
+        // therefore we ensure that the boundaries are sanely defined
+        cropRect.left = Math.max(0, cropRect.left);
+        cropRect.right = Math.min(mCropView.getWidth(), cropRect.right);
+        cropRect.top = Math.max(0, cropRect.top);
+        cropRect.bottom = Math.min(mCropView.getHeight(), cropRect.bottom);
         int cropRotation = mCropView.getImageRotation();
         float cropScale = mCropView.getWidth() / (float) cropRect.width();
 
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 15a68ef..1cca164 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3417,18 +3417,22 @@
                         && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
                     if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win);
                     mTopFullscreenOpaqueWindowState = win;
-                    if (showWhenLocked && !mHideWindowBehindKeyguard) {
-                        if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mHideLockScreen to true by win " + win);
-                        mHideLockScreen = true;
-                        mForceStatusBarFromKeyguard = false;
-                    }
-                    if ((fl & FLAG_DISMISS_KEYGUARD) != 0
-                            && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
-                        if (DEBUG_LAYOUT) Slog.v(TAG, "Setting mDismissKeyguard true by win " + win);
-                        mDismissKeyguard = mWinDismissingKeyguard == win ?
-                                DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
-                        mWinDismissingKeyguard = win;
-                        mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
+                    if (!mHideWindowBehindKeyguard) {
+                        if (showWhenLocked) {
+                            if (DEBUG_LAYOUT) Slog.v(TAG,
+                                    "Setting mHideLockScreen to true by win " + win);
+                            mHideLockScreen = true;
+                            mForceStatusBarFromKeyguard = false;
+                        }
+                        if ((fl & FLAG_DISMISS_KEYGUARD) != 0
+                                && mDismissKeyguard == DISMISS_KEYGUARD_NONE) {
+                            if (DEBUG_LAYOUT) Slog.v(TAG,
+                                    "Setting mDismissKeyguard true by win " + win);
+                            mDismissKeyguard = mWinDismissingKeyguard == win ?
+                                    DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
+                            mWinDismissingKeyguard = win;
+                            mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
+                        }
                     }
                     if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
                         mAllowLockscreenWhenOn = true;
diff --git a/services/Android.mk b/services/Android.mk
index 5260540..165f456 100644
--- a/services/Android.mk
+++ b/services/Android.mk
@@ -8,6 +8,10 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under,java)
 
+# EventLogTags files.
+LOCAL_SRC_FILES += \
+        core/java/com/android/server/EventLogTags.logtags
+
 # Uncomment to enable output of certain warnings (deprecated, unchecked)
 # LOCAL_JAVACFLAGS := -Xlint
 
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index 399e7d1..0f78c9b 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -52,12 +52,12 @@
 # NotificationManagerService.java
 # ---------------------------
 # when a NotificationManager.notify is called
-2750 notification_enqueue (pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3)
+2750 notification_enqueue (uid|1|5),(pid|1|5),(pkg|3),(id|1|5),(tag|3),(userid|1|5),(notification|3)
 # when someone tries to cancel a notification, the notification manager sometimes
 # calls this with flags too
-2751 notification_cancel (pkg|3),(id|1|5),(tag|3),(userid|1|5),(required_flags|1),(forbidden_flags|1)
+2751 notification_cancel (uid|1|5),(pid|1|5),(pkg|3),(id|1|5),(tag|3),(userid|1|5),(required_flags|1),(forbidden_flags|1),(reason|1|5),(listener|3)
 # when someone tries to cancel all of the notifications for a particular package
-2752 notification_cancel_all (pkg|3),(userid|1|5),(required_flags|1),(forbidden_flags|1)
+2752 notification_cancel_all (uid|1|5),(pid|1|5),(pkg|3),(userid|1|5),(required_flags|1),(forbidden_flags|1),(reason|1|5),(listener|3)
 
 
 # ---------------------------
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index 6827b3f..af8a6e7 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -1225,7 +1225,8 @@
         mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
                 mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
         if (bindCurrentInputMethodService(mCurIntent, this, Context.BIND_AUTO_CREATE
-                | Context.BIND_NOT_VISIBLE | Context.BIND_SHOWING_UI)) {
+                | Context.BIND_NOT_VISIBLE | Context.BIND_NOT_FOREGROUND
+                | Context.BIND_SHOWING_UI)) {
             mLastBindTime = SystemClock.uptimeMillis();
             mHaveConnection = true;
             mCurId = info.getId();
@@ -1783,7 +1784,8 @@
             mInputShown = true;
             if (mHaveConnection && !mVisibleBound) {
                 bindCurrentInputMethodService(
-                        mCurIntent, mVisibleConnection, Context.BIND_AUTO_CREATE);
+                        mCurIntent, mVisibleConnection, Context.BIND_AUTO_CREATE
+                                | Context.BIND_TREAT_LIKE_ACTIVITY);
                 mVisibleBound = true;
             }
             res = true;
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 3dcb488..e6163bd 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -457,6 +457,9 @@
      * @param userId the new active user's UserId
      */
     private void switchUser(int userId) {
+        if (mCurrentUserId == userId) {
+            return;
+        }
         mBlacklist.switchUser(userId);
         mLocationHandler.removeMessages(MSG_LOCATION_CHANGED);
         synchronized (mLock) {
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index c9f9a25..1ed943c 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -142,25 +142,40 @@
         class DefaultState extends State {
             @Override
             public boolean processMessage(Message msg) {
+                ClientInfo cInfo = null;
                 switch (msg.what) {
                     case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
                         if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
                             AsyncChannel c = (AsyncChannel) msg.obj;
                             if (DBG) Slog.d(TAG, "New client listening to asynchronous messages");
                             c.sendMessage(AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED);
-                            ClientInfo cInfo = new ClientInfo(c, msg.replyTo);
+                            cInfo = new ClientInfo(c, msg.replyTo);
                             mClients.put(msg.replyTo, cInfo);
                         } else {
                             Slog.e(TAG, "Client connection failure, error=" + msg.arg1);
                         }
                         break;
                     case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                        if (msg.arg1 == AsyncChannel.STATUS_SEND_UNSUCCESSFUL) {
-                            Slog.e(TAG, "Send failed, client connection lost");
-                        } else {
-                            if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
+                        switch (msg.arg1) {
+                            case AsyncChannel.STATUS_SEND_UNSUCCESSFUL:
+                                Slog.e(TAG, "Send failed, client connection lost");
+                                break;
+                            case AsyncChannel.STATUS_REMOTE_DISCONNECTION:
+                                if (DBG) Slog.d(TAG, "Client disconnected");
+                                break;
+                            default:
+                                if (DBG) Slog.d(TAG, "Client connection lost with reason: " + msg.arg1);
+                                break;
                         }
-                        mClients.remove(msg.replyTo);
+                        cInfo = mClients.get(msg.replyTo);
+                        if (cInfo != null) {
+                            cInfo.expungeAllRequests();
+                            mClients.remove(msg.replyTo);
+                        }
+                        //Last client
+                        if (mClients.size() == 0) {
+                            stopMDnsDaemon();
+                        }
                         break;
                     case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION:
                         AsyncChannel ac = new AsyncChannel();
@@ -238,13 +253,15 @@
                 return false;
             }
 
-            private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
+            private void storeRequestMap(int clientId, int globalId, ClientInfo clientInfo, int what) {
                 clientInfo.mClientIds.put(clientId, globalId);
+                clientInfo.mClientRequests.put(clientId, what);
                 mIdToClientInfoMap.put(globalId, clientInfo);
             }
 
             private void removeRequestMap(int clientId, int globalId, ClientInfo clientInfo) {
                 clientInfo.mClientIds.remove(clientId);
+                clientInfo.mClientRequests.remove(clientId);
                 mIdToClientInfoMap.remove(globalId);
             }
 
@@ -264,10 +281,6 @@
                         result = NOT_HANDLED;
                         break;
                     case AsyncChannel.CMD_CHANNEL_DISCONNECTED:
-                        //Last client
-                        if (mClients.size() == 1) {
-                            stopMDnsDaemon();
-                        }
                         result = NOT_HANDLED;
                         break;
                     case NsdManager.DISABLE:
@@ -291,7 +304,7 @@
                                 Slog.d(TAG, "Discover " + msg.arg2 + " " + id +
                                         servInfo.getServiceType());
                             }
-                            storeRequestMap(msg.arg2, id, clientInfo);
+                            storeRequestMap(msg.arg2, id, clientInfo, msg.what);
                             replyToMessage(msg, NsdManager.DISCOVER_SERVICES_STARTED, servInfo);
                         } else {
                             stopServiceDiscovery(id);
@@ -330,7 +343,7 @@
                         id = getUniqueId();
                         if (registerService(id, (NsdServiceInfo) msg.obj)) {
                             if (DBG) Slog.d(TAG, "Register " + msg.arg2 + " " + id);
-                            storeRequestMap(msg.arg2, id, clientInfo);
+                            storeRequestMap(msg.arg2, id, clientInfo, msg.what);
                             // Return success after mDns reports success
                         } else {
                             unregisterService(id);
@@ -371,7 +384,7 @@
                         id = getUniqueId();
                         if (resolveService(id, servInfo)) {
                             clientInfo.mResolvedService = new NsdServiceInfo();
-                            storeRequestMap(msg.arg2, id, clientInfo);
+                            storeRequestMap(msg.arg2, id, clientInfo, msg.what);
                         } else {
                             replyToMessage(msg, NsdManager.RESOLVE_SERVICE_FAILED,
                                     NsdManager.FAILURE_INTERNAL_ERROR);
@@ -477,7 +490,7 @@
 
                         int id2 = getUniqueId();
                         if (getAddrInfo(id2, cooked[3])) {
-                            storeRequestMap(clientId, id2, clientInfo);
+                            storeRequestMap(clientId, id2, clientInfo, NsdManager.RESOLVE_SERVICE);
                         } else {
                             clientInfo.mChannel.sendMessage(NsdManager.RESOLVE_SERVICE_FAILED,
                                     NsdManager.FAILURE_INTERNAL_ERROR, clientId);
@@ -821,6 +834,9 @@
         /* A map from client id to unique id sent to mDns */
         private SparseArray<Integer> mClientIds = new SparseArray<Integer>();
 
+        /* A map from client id to the type of the request we had received */
+        private SparseArray<Integer> mClientRequests = new SparseArray<Integer>();
+
         private ClientInfo(AsyncChannel c, Messenger m) {
             mChannel = c;
             mMessenger = m;
@@ -834,10 +850,41 @@
             sb.append("mMessenger ").append(mMessenger).append("\n");
             sb.append("mResolvedService ").append(mResolvedService).append("\n");
             for(int i = 0; i< mClientIds.size(); i++) {
-                sb.append("clientId ").append(mClientIds.keyAt(i));
-                sb.append(" mDnsId ").append(mClientIds.valueAt(i)).append("\n");
+                int clientID = mClientIds.keyAt(i);
+                sb.append("clientId ").append(clientID).
+                    append(" mDnsId ").append(mClientIds.valueAt(i)).
+                    append(" type ").append(mClientRequests.get(clientID)).append("\n");
             }
             return sb.toString();
         }
+
+        // Remove any pending requests from the global map when we get rid of a client,
+        // and send cancellations to the daemon.
+        private void expungeAllRequests() {
+            int globalId, clientId, i;
+            for (i = 0; i < mClientIds.size(); i++) {
+                clientId = mClientIds.keyAt(i);
+                globalId = mClientIds.valueAt(i);
+                mIdToClientInfoMap.remove(globalId);
+                if (DBG) Slog.d(TAG, "Terminating client-ID " + clientId +
+                        " global-ID " + globalId + " type " + mClientRequests.get(clientId));
+                switch (mClientRequests.get(clientId)) {
+                    case NsdManager.DISCOVER_SERVICES:
+                        stopServiceDiscovery(globalId);
+                        break;
+                    case NsdManager.RESOLVE_SERVICE:
+                        stopResolveService(globalId);
+                        break;
+                    case NsdManager.REGISTER_SERVICE:
+                        unregisterService(globalId);
+                        break;
+                    default:
+                        break;
+                }
+            }
+            mClientIds.clear();
+            mClientRequests.clear();
+        }
+
     }
 }
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index ad693d0..94f699f 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -173,7 +173,9 @@
         mDeskModeKeepsScreenOn = (context.getResources().getInteger(
                 com.android.internal.R.integer.config_deskDockKeepsScreenOn) == 1);
         mTelevision = context.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_TELEVISION);
+                PackageManager.FEATURE_TELEVISION) ||
+            context.getPackageManager().hasSystemFeature(
+                    PackageManager.FEATURE_LEANBACK);
 
         mNightMode = Settings.Secure.getInt(context.getContentResolver(),
                 Settings.Secure.UI_NIGHT_MODE, UiModeManager.MODE_NIGHT_AUTO);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index a845127..1345cfd 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -667,8 +667,7 @@
             // what they are, so we can report this elsewhere for
             // others to know why certain services are running.
             try {
-                clientIntent = (PendingIntent)service.getParcelableExtra(
-                        Intent.EXTRA_CLIENT_INTENT);
+                clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT);
             } catch (RuntimeException e) {
             }
             if (clientIntent != null) {
@@ -682,6 +681,11 @@
             }
         }
 
+        if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
+            mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
+                    "BIND_TREAT_LIKE_ACTIVITY");
+        }
+
         final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
 
         ServiceLookupResult res =
@@ -755,8 +759,12 @@
             }
 
             if (s.app != null) {
+                if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
+                    s.app.treatLikeActivity = true;
+                }
                 // This could have made the service more important.
-                mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities, b.client);
+                mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
+                        || s.app.treatLikeActivity, b.client);
                 mAm.updateOomAdjLocked(s.app);
             }
 
@@ -858,6 +866,12 @@
 
                 if (r.binding.service.app != null) {
                     // This could have made the service less important.
+                    if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
+                        r.binding.service.app.treatLikeActivity = true;
+                        mAm.updateLruProcessLocked(r.binding.service.app,
+                                r.binding.service.app.hasClientActivities
+                                || r.binding.service.app.treatLikeActivity, null);
+                    }
                     mAm.updateOomAdjLocked(r.binding.service.app);
                 }
             }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 128f636..5eaa3a1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2314,11 +2314,12 @@
 
     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
             ProcessRecord client) {
-        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities;
+        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
+                || app.treatLikeActivity;
         final boolean hasService = false; // not impl yet. app.services.size() > 0;
         if (!activityChange && hasActivity) {
-            // The process has activties, so we are only going to allow activity-based
-            // adjustments move it.  It should be kept in the front of the list with other
+            // The process has activities, so we are only allowing activity-based adjustments
+            // to move it.  It should be kept in the front of the list with other
             // processes that have activities, and we don't want those to change their
             // order except due to activity operations.
             return;
@@ -3319,20 +3320,35 @@
             return;
         }
         // Remove any existing entries that are the same kind of task.
+        final Intent intent = task.intent;
+        final boolean document = intent != null && intent.isDocument();
         for (int i=0; i<N; i++) {
             TaskRecord tr = mRecentTasks.get(i);
-            if (task.userId == tr.userId
-                    && ((task.affinity != null && task.affinity.equals(tr.affinity))
-                    || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
-                tr.disposeThumbnail();
-                mRecentTasks.remove(i);
-                i--;
-                N--;
-                if (task.intent == null) {
-                    // If the new recent task we are adding is not fully
-                    // specified, then replace it with the existing recent task.
-                    task = tr;
+            if (task != tr) {
+                if (task.userId != tr.userId) {
+                    continue;
                 }
+                final Intent trIntent = tr.intent;
+                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
+                    (intent == null || !intent.filterEquals(trIntent))) {
+                    continue;
+                }
+                if (document || trIntent != null && trIntent.isDocument()) {
+                    // Document tasks do not match other tasks.
+                    continue;
+                }
+            }
+
+            // Either task and tr are the same or, their affinities match or their intents match
+            // and neither of them is a document.
+            tr.disposeThumbnail();
+            mRecentTasks.remove(i);
+            i--;
+            N--;
+            if (task.intent == null) {
+                // If the new recent task we are adding is not fully
+                // specified, then replace it with the existing recent task.
+                task = tr;
             }
         }
         if (N >= MAX_RECENT_TASKS) {
@@ -6841,10 +6857,19 @@
             ArrayList<ActivityManager.RecentTaskInfo> res
                     = new ArrayList<ActivityManager.RecentTaskInfo>(
                             maxNum < N ? maxNum : N);
+
+            final Set<Integer> includedUsers;
+            if ((flags & ActivityManager.RECENT_INCLUDE_RELATED) != 0) {
+                includedUsers = getRelatedUsersLocked(userId);
+            } else {
+                includedUsers = new HashSet<Integer>();
+            }
+            includedUsers.add(Integer.valueOf(userId));
             for (int i=0; i<N && maxNum > 0; i++) {
                 TaskRecord tr = mRecentTasks.get(i);
-                // Only add calling user's recent tasks
-                if (tr.userId != userId) continue;
+                // Only add calling user or related users recent tasks
+                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
+
                 // Return the entry if desired by the caller.  We always return
                 // the first entry, because callers always expect this to be the
                 // foreground app.  We may filter others if the caller has
@@ -6868,6 +6893,7 @@
                     rti.origActivity = tr.origActivity;
                     rti.description = tr.lastDescription;
                     rti.stackId = tr.stack.mStackId;
+                    rti.userId = tr.userId;
 
                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
                         // Check whether this activity is currently available.
@@ -6887,7 +6913,7 @@
                             // Will never happen.
                         }
                     }
-                    
+
                     res.add(rti);
                     maxNum--;
                 }
@@ -7047,11 +7073,11 @@
      * TODO: Add mController hook
      */
     @Override
-    public void moveTaskToFront(int task, int flags, Bundle options) {
+    public void moveTaskToFront(int taskId, int flags, Bundle options) {
         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
                 "moveTaskToFront()");
 
-        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving task=" + task);
+        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
         synchronized(this) {
             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
                     Binder.getCallingUid(), "Task to front")) {
@@ -7060,6 +7086,14 @@
             }
             final long origId = Binder.clearCallingIdentity();
             try {
+                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+                if (task == null) {
+                    return;
+                }
+                if (mStackSupervisor.isLockTaskModeViolation(task)) {
+                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
+                    return;
+                }
                 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
             } finally {
                 Binder.restoreCallingIdentity(origId);
@@ -7269,6 +7303,85 @@
         }
     }
 
+    private boolean isLockTaskAuthorized(ComponentName name) {
+//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
+//                "startLockTaskMode()");
+//        DevicePolicyManager dpm = (DevicePolicyManager)
+//                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+//        return dpm != null && dpm.isLockTaskPermitted(name);
+        return true;
+    }
+
+    private void startLockTaskMode(TaskRecord task) {
+        if (!isLockTaskAuthorized(task.intent.getComponent())) {
+            return;
+        }
+        long ident = Binder.clearCallingIdentity();
+        try {
+            synchronized (this) {
+                // Since we lost lock on task, make sure it is still there.
+                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
+                if (task != null) {
+                    mStackSupervisor.setLockTaskModeLocked(task);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public void startLockTaskMode(int taskId) {
+        long ident = Binder.clearCallingIdentity();
+        try {
+            final TaskRecord task;
+            synchronized (this) {
+                task = mStackSupervisor.anyTaskForIdLocked(taskId);
+            }
+            if (task != null) {
+                startLockTaskMode(task);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public void startLockTaskMode(IBinder token) {
+        long ident = Binder.clearCallingIdentity();
+        try {
+            final TaskRecord task;
+            synchronized (this) {
+                final ActivityRecord r = ActivityRecord.forToken(token);
+                if (r == null) {
+                    return;
+                }
+                task = r.task;
+            }
+            if (task != null) {
+                startLockTaskMode(task);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override
+    public void stopLockTaskMode() {
+//        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
+//                "stopLockTaskMode()");
+        synchronized (this) {
+            mStackSupervisor.setLockTaskModeLocked(null);
+        }
+    }
+
+    @Override
+    public boolean isInLockTaskMode() {
+        synchronized (this) {
+            return mStackSupervisor.isInLockTaskMode();
+        }
+    }
+
     // =========================================================
     // THUMBNAILS
     // =========================================================
@@ -12459,6 +12572,7 @@
         updateProcessForegroundLocked(app, false, false);
         app.foregroundActivities = false;
         app.hasShownUi = false;
+        app.treatLikeActivity = false;
         app.hasAboveClient = false;
 
         mServices.killServicesLocked(app, allowRestart);
@@ -14750,6 +14864,9 @@
                             app.adjTarget = s.name;
                         }
                     }
+                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
+                        app.treatLikeActivity = true;
+                    }
                     final ActivityRecord a = cr.activity;
                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
@@ -14882,10 +14999,17 @@
             }
         }
 
-        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) {
-            // This is a cached process, but with client activities.  Mark it so.
-            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
-            app.adjType = "cch-client-act";
+        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
+            if (app.hasClientActivities) {
+                // This is a cached process, but with client activities.  Mark it so.
+                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
+                app.adjType = "cch-client-act";
+            } else if (app.treatLikeActivity) {
+                // This is a cached process, but somebody wants us to treat it like it has
+                // an activity, okay!
+                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
+                app.adjType = "cch-as-act";
+            }
         }
 
         if (adj == ProcessList.SERVICE_ADJ) {
@@ -16160,6 +16284,15 @@
         mRelatedUserIds = relatedUserIds;
     }
 
+    private Set getRelatedUsersLocked(int userId) {
+        Set userIds = new HashSet<Integer>();
+        final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(userId);
+        for (UserInfo user : relatedUsers) {
+            userIds.add(Integer.valueOf(user.id));
+        }
+        return userIds;
+    }
+
     @Override
     public boolean switchUser(final int userId) {
         return startUser(userId, /* foregound */ true);
@@ -16186,6 +16319,8 @@
                     return true;
                 }
 
+                mStackSupervisor.setLockTaskModeLocked(null);
+
                 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
                 if (userInfo == null) {
                     Slog.w(TAG, "No user info for user #" + userId);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 087ad83c..25292a0 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -36,8 +36,6 @@
 import static com.android.server.am.ActivityStackSupervisor.DEBUG_STATES;
 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
 
-import android.os.Trace;
-import android.util.Log;
 import com.android.internal.os.BatteryStatsImpl;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityManagerService.ItemMatcher;
@@ -494,6 +492,9 @@
             cls = new ComponentName(info.packageName, info.targetActivity);
         }
         final int userId = UserHandle.getUserId(info.applicationInfo.uid);
+        boolean isDocument = intent != null & intent.isDocument();
+        // If documentData is non-null then it must match the existing task data.
+        Uri documentData = isDocument ? intent.getData() : null;
 
         if (DEBUG_TASKS) Slog.d(TAG, "Looking for task of " + target + " in " + this);
         for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
@@ -510,23 +511,39 @@
                 continue;
             }
 
+            final Intent taskIntent = task.intent;
+            final Intent affinityIntent = task.affinityIntent;
+            final boolean taskIsDocument;
+            final Uri taskDocumentData;
+            if (taskIntent != null && taskIntent.isDocument()) {
+                taskIsDocument = true;
+                taskDocumentData = taskIntent.getData();
+            } else if (affinityIntent != null && affinityIntent.isDocument()) {
+                taskIsDocument = true;
+                taskDocumentData = affinityIntent.getData();
+            } else {
+                taskIsDocument = false;
+                taskDocumentData = null;
+            }
+
             if (DEBUG_TASKS) Slog.d(TAG, "Comparing existing cls="
-                    + r.task.intent.getComponent().flattenToShortString()
+                    + taskIntent.getComponent().flattenToShortString()
                     + "/aff=" + r.task.affinity + " to new cls="
                     + intent.getComponent().flattenToShortString() + "/aff=" + info.taskAffinity);
-            if (task.affinity != null) {
-                if (task.affinity.equals(info.taskAffinity)) {
+            if (!isDocument && !taskIsDocument && task.affinity != null) {
+                if (task.affinity.equals(target.taskAffinity)) {
                     if (DEBUG_TASKS) Slog.d(TAG, "Found matching affinity!");
                     return r;
                 }
-            } else if (task.intent != null && task.intent.getComponent().equals(cls)) {
+            } else if (taskIntent != null && taskIntent.getComponent().equals(cls) &&
+                    Objects.equals(documentData, taskDocumentData)) {
                 if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!");
                 //dump();
                 if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: "
                         + r.intent);
                 return r;
-            } else if (task.affinityIntent != null
-                    && task.affinityIntent.getComponent().equals(cls)) {
+            } else if (affinityIntent != null && affinityIntent.getComponent().equals(cls) &&
+                    Objects.equals(documentData, taskDocumentData)) {
                 if (DEBUG_TASKS) Slog.d(TAG, "Found matching class!");
                 //dump();
                 if (DEBUG_TASKS) Slog.d(TAG, "For Intent " + intent + " bringing to top: "
@@ -1859,7 +1876,7 @@
                 // If the caller has requested that the target task be
                 // reset, then do so.
                 if ((r.intent.getFlags()
-                        &Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
+                        & Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) != 0) {
                     resetTaskIfNeededLocked(r, r);
                     doShow = topRunningNonDelayedActivityLocked(null) == r;
                 }
@@ -2008,14 +2025,7 @@
                             + " out to new task " + target.task);
                 }
 
-                if (clearWhenTaskReset) {
-                    // This is the start of a new sub-task.
-                    if (target.thumbHolder == null) {
-                        target.thumbHolder = new ThumbnailHolder();
-                    }
-                } else {
-                    target.thumbHolder = newThumbHolder;
-                }
+                target.thumbHolder = newThumbHolder;
 
                 final int targetTaskId = targetTask.taskId;
                 mWindowManager.setAppGroupId(target.appToken, targetTaskId);
@@ -2478,14 +2488,15 @@
         }
 
         r.makeFinishing();
+        final TaskRecord task = r.task;
         EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
                 r.userId, System.identityHashCode(r),
-                r.task.taskId, r.shortComponentName, reason);
-        final ArrayList<ActivityRecord> activities = r.task.mActivities;
+                task.taskId, r.shortComponentName, reason);
+        final ArrayList<ActivityRecord> activities = task.mActivities;
         final int index = activities.indexOf(r);
         if (index < (activities.size() - 1)) {
-            r.task.setFrontOfTask();
-            if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
+            task.setFrontOfTask();
+            if ((r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
                 // If the caller asked that this activity (and all above it)
                 // be cleared when the task is reset, don't lose that information,
                 // but propagate it up to the next activity.
@@ -2524,6 +2535,9 @@
                 startPausingLocked(false, false);
             }
 
+            if (endTask) {
+                mStackSupervisor.endLockTaskModeIfTaskEnding(task);
+            }
         } else if (r.state != ActivityState.PAUSING) {
             // If the activity is PAUSING, we will complete the finish once
             // it is done pausing; else we can just directly finish it here.
@@ -3088,23 +3102,6 @@
         }
     }
 
-    final boolean findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
-        final TaskRecord task = taskForIdLocked(taskId);
-        if (task != null) {
-            if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
-                mStackSupervisor.mUserLeaving = true;
-            }
-            if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
-                // Caller wants the home activity moved with it.  To accomplish this,
-                // we'll just indicate that this task returns to the home task.
-                task.mOnTopOfHome = true;
-            }
-            moveTaskToFrontLocked(task, null, options);
-            return true;
-        }
-        return false;
-    }
-
     final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason, Bundle options) {
         if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr);
 
@@ -3162,7 +3159,15 @@
      * @return Returns true if the move completed, false if not.
      */
     final boolean moveTaskToBackLocked(int taskId, ActivityRecord reason) {
-        Slog.i(TAG, "moveTaskToBack: " + taskId);
+        final TaskRecord tr = taskForIdLocked(taskId);
+        if (tr == null) {
+            Slog.i(TAG, "moveTaskToBack: bad taskId=" + taskId);
+            return false;
+        }
+
+        Slog.i(TAG, "moveTaskToBack: " + tr);
+
+        mStackSupervisor.endLockTaskModeIfTaskEnding(tr);
 
         // If we have a watcher, preflight the move before committing to it.  First check
         // for *other* available tasks, but if none are available, then try again allowing the
@@ -3190,11 +3195,6 @@
         if (DEBUG_TRANSITION) Slog.v(TAG,
                 "Prepare to back transition: task=" + taskId);
 
-        final TaskRecord tr = taskForIdLocked(taskId);
-        if (tr == null) {
-            return false;
-        }
-
         mTaskHistory.remove(tr);
         mTaskHistory.add(0, tr);
 
@@ -3678,6 +3678,7 @@
     }
 
     void removeTask(TaskRecord task) {
+        mStackSupervisor.endLockTaskModeIfTaskEnding(task);
         mWindowManager.removeTask(task.taskId);
         final ActivityRecord r = mResumedActivity;
         if (r != null && r.task == task) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 9636de7..3555993 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.Manifest.permission.START_ANY_ACTIVITY;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -231,6 +232,10 @@
 
     InputManagerInternal mInputManagerInternal;
 
+    /** If non-null then the task specified remains in front and no other tasks may be started
+     * until the task exits or #stopLockTaskMode() is called. */
+    private TaskRecord mLockTaskModeTask;
+
     public ActivityStackSupervisor(ActivityManagerService service) {
         mService = service;
         PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
@@ -1198,6 +1203,19 @@
                 resultRecord.removeResultsLocked(
                     sourceRecord, resultWho, requestCode);
             }
+            if (sourceRecord.launchedFromUid == callingUid) {
+                // The new activity is being launched from the same uid as the previous
+                // activity in the flow, and asking to forward its result back to the
+                // previous.  In this case the activity is serving as a trampoline between
+                // the two, so we also want to update its launchedFromPackage to be the
+                // same as the previous activity.  Note that this is safe, since we know
+                // these two packages come from the same uid; the caller could just as
+                // well have supplied that same package name itself.  This specifially
+                // deals with the case of an intent picker/chooser being launched in the app
+                // flow to redirect to an activity picked by the user, where we want the final
+                // activity to consider it to have been launched by the previous app activity.
+                callingPackage = sourceRecord.launchedFromPackage;
+            }
         }
 
         if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
@@ -1426,14 +1444,20 @@
             }
         }
 
+        final boolean newDocument = intent.isDocument();
         if (sourceRecord == null) {
             // This activity is not being started from another...  in this
             // case we -always- start a new task.
-            if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
+            if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
                 Slog.w(TAG, "startActivity called from non-Activity context; forcing " +
                         "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
                 launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
             }
+        } else if (newDocument) {
+            if (r.launchMode != ActivityInfo.LAUNCH_MULTIPLE) {
+                Slog.w(TAG, "FLAG_ACTIVITY_NEW_DOCUMENT and launchMode != \"standard\"");
+                r.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+            }
         } else if (sourceRecord.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
             // The original activity who is starting us is running as a single
             // instance...  this new activity it is starting must go on its
@@ -1456,7 +1480,7 @@
                 // so we don't want to blindly throw it in to that task.  Instead we will take
                 // the NEW_TASK flow and try to find a task for it. But save the task information
                 // so it can be used when creating the new task.
-                if ((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
+                if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
                     Slog.w(TAG, "startActivity called from finishing " + sourceRecord
                             + "; forcing " + "Intent.FLAG_ACTIVITY_NEW_TASK for: " + intent);
                     launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -1472,7 +1496,7 @@
             sourceStack = null;
         }
 
-        if (r.resultTo != null && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+        if (r.resultTo != null && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
             // For whatever reason this activity is being launched into a new
             // task...  yet the caller has requested a result back.  Well, that
             // is pretty messed up, so instead immediately send back a cancel
@@ -1489,8 +1513,8 @@
         boolean movedHome = false;
         TaskRecord reuseTask = null;
         ActivityStack targetStack;
-        if (((launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
-                (launchFlags&Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
+        if (((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0 &&
+                (launchFlags & Intent.FLAG_ACTIVITY_MULTIPLE_TASK) == 0)
                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK
                 || r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE) {
             // If bring to front is requested, and no result is requested, and
@@ -1505,6 +1529,10 @@
                         ? findTaskLocked(r)
                         : findActivityLocked(intent, r.info);
                 if (intentActivity != null) {
+                    if (isLockTaskModeViolation(intentActivity.task)) {
+                        Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
+                        return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+                    }
                     if (r.task == null) {
                         r.task = intentActivity.task;
                     }
@@ -1675,7 +1703,7 @@
             if (top != null && r.resultTo == null) {
                 if (top.realActivity.equals(r.realActivity) && top.userId == r.userId) {
                     if (top.app != null && top.app.thread != null) {
-                        if ((launchFlags&Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
+                        if ((launchFlags & Intent.FLAG_ACTIVITY_SINGLE_TOP) != 0
                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP
                             || r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK) {
                             ActivityStack.logStartActivity(EventLogTags.AM_NEW_INTENT, top,
@@ -1715,6 +1743,10 @@
         // Should this be considered a new task?
         if (r.resultTo == null && !addingToTask
                 && (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
+            if (isLockTaskModeViolation(reuseTask)) {
+                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
+                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+            }
             targetStack = adjustStackFocus(r);
             targetStack.moveToFront();
             if (reuseTask == null) {
@@ -1739,6 +1771,10 @@
             }
         } else if (sourceRecord != null) {
             TaskRecord sourceTask = sourceRecord.task;
+            if (isLockTaskModeViolation(sourceTask)) {
+                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
+                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+            }
             targetStack = sourceTask.stack;
             targetStack.moveToFront();
             if (!addingToTask &&
@@ -1782,6 +1818,10 @@
             // An existing activity is starting this new activity, so we want
             // to keep the new one in the same task as the one that is starting
             // it.
+            if (isLockTaskModeViolation(sourceTask)) {
+                Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
+                return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
+            }
             r.setTask(sourceTask, sourceRecord.thumbHolder, false);
             if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
                     + " in existing task " + r.task + " from source " + sourceRecord);
@@ -2098,17 +2138,18 @@
         }
     }
 
-    void findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
-        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
-            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
-                if (stacks.get(stackNdx).findTaskToMoveToFrontLocked(taskId, flags, options)) {
-                    if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
-                            + stacks.get(stackNdx));
-                    return;
-                }
-            }
+    void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
+        if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
+            mUserLeaving = true;
         }
+        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
+            // Caller wants the home activity moved with it.  To accomplish this,
+            // we'll just indicate that this task returns to the home task.
+            task.mOnTopOfHome = true;
+        }
+        task.stack.moveTaskToFrontLocked(task, null, options);
+        if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
+                + task.stack);
     }
 
     ActivityStack getStack(int stackId) {
@@ -2288,6 +2329,7 @@
             }
         }
         checkReadyForSleepLocked();
+        setLockTaskModeLocked(null);
     }
 
     boolean shutdownLocked(int timeout) {
@@ -2469,7 +2511,10 @@
             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                 final ActivityStack stack = stacks.get(stackNdx);
                 stack.switchUserLocked(userId);
-                mWindowManager.moveTaskToTop(stack.topTask().taskId);
+                TaskRecord task = stack.topTask();
+                if (task != null) {
+                    mWindowManager.moveTaskToTop(task.taskId);
+                }
             }
         }
 
@@ -2480,7 +2525,10 @@
         final boolean homeInFront = stack.isHomeStack();
         if (stack.isOnHomeDisplay()) {
             moveHomeStack(homeInFront);
-            mWindowManager.moveTaskToTop(stack.topTask().taskId);
+            TaskRecord task = stack.topTask();
+            if (task != null) {
+                mWindowManager.moveTaskToTop(task.taskId);
+            }
         } else {
             // Stack was moved to another display while user was swapped out.
             resumeHomeActivity(null);
@@ -2866,6 +2914,35 @@
         return list;
     }
 
+    void setLockTaskModeLocked(TaskRecord task) {
+        if (task == null) {
+            // Take out of lock task mode.
+            mLockTaskModeTask = null;
+            return;
+        }
+        if (isLockTaskModeViolation(task)) {
+            Slog.e(TAG, "setLockTaskMode: Attempt to start a second Lock Task Mode task.");
+            return;
+        }
+        mLockTaskModeTask = task;
+        findTaskToMoveToFrontLocked(task, 0, null);
+        resumeTopActivitiesLocked();
+    }
+
+    boolean isLockTaskModeViolation(TaskRecord task) {
+        return mLockTaskModeTask != null && mLockTaskModeTask != task;
+    }
+
+    void endLockTaskModeIfTaskEnding(TaskRecord task) {
+        if (mLockTaskModeTask != null && mLockTaskModeTask == task) {
+            mLockTaskModeTask = null;
+        }
+    }
+
+    boolean isInLockTaskMode() {
+        return mLockTaskModeTask != null;
+    }
+
     private final class ActivityStackSupervisorHandler extends Handler {
 
         public ActivityStackSupervisorHandler(Looper looper) {
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 10574ed..d04a6b2 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -95,6 +95,7 @@
     boolean hasShownUi;         // Has UI been shown in this process since it was started?
     boolean pendingUiClean;     // Want to clean up resources from showing UI?
     boolean hasAboveClient;     // Bound using BIND_ABOVE_CLIENT, so want to be lower
+    boolean treatLikeActivity;  // Bound using BIND_TREAT_LIKE_ACTIVITY
     boolean bad;                // True if disabled in the bad process list
     boolean killedByAm;         // True when proc has been killed by activity manager, not for RAM
     boolean procStateChanged;   // Keep track of whether we changed 'setAdj'.
@@ -251,10 +252,11 @@
                 pw.print(" lastStateTime=");
                 TimeUtils.formatDuration(lastStateTime, now, pw);
                 pw.println();
-        if (hasShownUi || pendingUiClean || hasAboveClient) {
+        if (hasShownUi || pendingUiClean || hasAboveClient || treatLikeActivity) {
             pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
                     pw.print(" pendingUiClean="); pw.print(pendingUiClean);
-                    pw.print(" hasAboveClient="); pw.println(hasAboveClient);
+                    pw.print(" hasAboveClient="); pw.print(hasAboveClient);
+                    pw.print(" treatLikeActivity="); pw.println(treatLikeActivity);
         }
         if (setIsForeground || foregroundServices || forcingToForeground != null) {
             pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 89acec9..1ff925c 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -21,14 +21,22 @@
 import android.media.session.IMediaControllerCallback;
 import android.media.session.IMediaSession;
 import android.media.session.IMediaSessionCallback;
-import android.media.RemoteControlClient;
+import android.media.session.MediaMetadata;
+import android.media.session.PlaybackState;
+import android.media.Rating;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
 import android.os.RemoteException;
+import android.os.ResultReceiver;
 import android.util.Log;
+import android.util.Slog;
 import android.view.KeyEvent;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * This is the system implementation of a Session. Apps will interact with the
@@ -37,6 +45,8 @@
 public class MediaSessionRecord implements IBinder.DeathRecipient {
     private static final String TAG = "MediaSessionImpl";
 
+    private final MessageHandler mHandler;
+
     private final int mPid;
     private final String mPackageName;
     private final String mTag;
@@ -45,13 +55,25 @@
     private final SessionCb mSessionCb;
     private final MediaSessionService mService;
 
-    private final ArrayList<IMediaControllerCallback> mSessionCallbacks =
+    private final Object mControllerLock = new Object();
+    private final ArrayList<IMediaControllerCallback> mControllerCallbacks =
             new ArrayList<IMediaControllerCallback>();
+    private final ArrayList<String> mInterfaces = new ArrayList<String>();
 
-    private int mPlaybackState = RemoteControlClient.PLAYSTATE_NONE;
+    private boolean mTransportPerformerEnabled = false;
+    private Bundle mRoute;
+
+    // TransportPerformer fields
+
+    private MediaMetadata mMetadata;
+    private PlaybackState mPlaybackState;
+    private int mRatingType;
+    // End TransportPerformer fields
+
+    private boolean mIsPublished = false;
 
     public MediaSessionRecord(int pid, String packageName, IMediaSessionCallback cb, String tag,
-            MediaSessionService service) {
+            MediaSessionService service, Handler handler) {
         mPid = pid;
         mPackageName = packageName;
         mTag = tag;
@@ -59,6 +81,7 @@
         mSession = new SessionStub();
         mSessionCb = new SessionCb(cb);
         mService = service;
+        mHandler = new MessageHandler(handler.getLooper());
     }
 
     public IMediaSession getSessionBinder() {
@@ -69,61 +92,132 @@
         return mController;
     }
 
-    public void setPlaybackStateInternal(int state) {
-        mPlaybackState = state;
-        for (int i = mSessionCallbacks.size() - 1; i >= 0; i--) {
-            IMediaControllerCallback cb = mSessionCallbacks.get(i);
-            try {
-                cb.onPlaybackUpdate(state);
-            } catch (RemoteException e) {
-                Log.d(TAG, "SessionCallback object dead in setPlaybackState.", e);
-                mSessionCallbacks.remove(i);
-            }
-        }
-    }
-
     @Override
     public void binderDied() {
         mService.sessionDied(this);
     }
 
+    public boolean isPublished() {
+        return mIsPublished;
+    }
+
     private void onDestroy() {
         mService.destroySession(this);
     }
 
+    private void pushPlaybackStateUpdate() {
+        synchronized (mControllerLock) {
+            for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
+                IMediaControllerCallback cb = mControllerCallbacks.get(i);
+                try {
+                    cb.onPlaybackStateChanged(mPlaybackState);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Removing dead callback in pushPlaybackStateUpdate.", e);
+                    mControllerCallbacks.remove(i);
+                }
+            }
+        }
+    }
+
+    private void pushMetadataUpdate() {
+        synchronized (mControllerLock) {
+            for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
+                IMediaControllerCallback cb = mControllerCallbacks.get(i);
+                try {
+                    cb.onMetadataChanged(mMetadata);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Removing dead callback in pushMetadataUpdate.", e);
+                    mControllerCallbacks.remove(i);
+                }
+            }
+        }
+    }
+
+    private void pushRouteUpdate() {
+        synchronized (mControllerLock) {
+            for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
+                IMediaControllerCallback cb = mControllerCallbacks.get(i);
+                try {
+                    cb.onRouteChanged(mRoute);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Removing dead callback in pushRouteUpdate.", e);
+                    mControllerCallbacks.remove(i);
+                }
+            }
+        }
+    }
+
+    private void pushEvent(String event, Bundle data) {
+        synchronized (mControllerLock) {
+            for (int i = mControllerCallbacks.size() - 1; i >= 0; i--) {
+                IMediaControllerCallback cb = mControllerCallbacks.get(i);
+                try {
+                    cb.onEvent(event, data);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Removing dead callback in pushRouteUpdate.", e);
+                    mControllerCallbacks.remove(i);
+                }
+            }
+        }
+    }
+
     private final class SessionStub extends IMediaSession.Stub {
 
         @Override
-        public void setPlaybackState(int state) throws RemoteException {
-            setPlaybackStateInternal(state);
-        }
-
-        @Override
-        public void destroy() throws RemoteException {
+        public void destroy() {
             onDestroy();
         }
 
         @Override
-        public void sendEvent(Bundle data) throws RemoteException {
+        public void sendEvent(String event, Bundle data) {
+            mHandler.post(MessageHandler.MSG_SEND_EVENT, event, data);
         }
 
         @Override
-        public IMediaController getMediaSessionToken() throws RemoteException {
+        public IMediaController getMediaController() {
             return mController;
         }
 
         @Override
-        public void setMetadata(Bundle metadata) throws RemoteException {
+        public void setRouteState(Bundle routeState) {
         }
 
         @Override
-        public void setRouteState(Bundle routeState) throws RemoteException {
+        public void setRoute(Bundle mediaRouteDescriptor) {
+            mRoute = mediaRouteDescriptor;
+            mHandler.post(MessageHandler.MSG_UPDATE_ROUTE);
         }
 
         @Override
-        public void setRoute(Bundle medaiRouteDescriptor) throws RemoteException {
+        public void publish() {
+            mIsPublished = true; // TODO push update to service
+        }
+        @Override
+        public void setTransportPerformerEnabled() {
+            mTransportPerformerEnabled = true;
         }
 
+        @Override
+        public List<String> getSupportedInterfaces() {
+            return mInterfaces;
+        }
+
+        @Override
+        public void setMetadata(MediaMetadata metadata) {
+            mMetadata = metadata;
+            mHandler.post(MessageHandler.MSG_UPDATE_METADATA);
+        }
+
+        @Override
+        public void setPlaybackState(PlaybackState state) {
+            mPlaybackState = state;
+            mHandler.post(MessageHandler.MSG_UPDATE_PLAYBACK_STATE);
+        }
+
+        @Override
+        public void setRatingType(int type) {
+            mRatingType = type;
+        }
     }
 
     class SessionCb {
@@ -139,32 +233,96 @@
             try {
                 mCb.onMediaButton(mediaButtonIntent);
             } catch (RemoteException e) {
-                Log.d(TAG, "Controller object dead in sendMediaRequest.", e);
-                onDestroy();
+                Slog.e(TAG, "Remote failure in sendMediaRequest.", e);
             }
         }
 
-        public void sendCommand(String command, Bundle extras) {
+        public void sendCommand(String command, Bundle extras, ResultReceiver cb) {
             try {
-                mCb.onCommand(command, extras);
+                mCb.onCommand(command, extras, cb);
             } catch (RemoteException e) {
-                Log.d(TAG, "Controller object dead in sendCommand.", e);
-                onDestroy();
+                Slog.e(TAG, "Remote failure in sendCommand.", e);
             }
         }
 
-        public void registerCallbackListener(IMediaSessionCallback cb) {
-
+        public void play() {
+            try {
+                mCb.onPlay();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in play.", e);
+            }
         }
 
+        public void pause() {
+            try {
+                mCb.onPause();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in pause.", e);
+            }
+        }
+
+        public void stop() {
+            try {
+                mCb.onStop();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in stop.", e);
+            }
+        }
+
+        public void next() {
+            try {
+                mCb.onNext();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in next.", e);
+            }
+        }
+
+        public void previous() {
+            try {
+                mCb.onPrevious();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in previous.", e);
+            }
+        }
+
+        public void fastForward() {
+            try {
+                mCb.onFastForward();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in fastForward.", e);
+            }
+        }
+
+        public void rewind() {
+            try {
+                mCb.onRewind();
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in rewind.", e);
+            }
+        }
+
+        public void seekTo(long pos) {
+            try {
+                mCb.onSeekTo(pos);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in seekTo.", e);
+            }
+        }
+
+        public void rate(Rating rating) {
+            try {
+                mCb.onRate(rating);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Remote failure in rate.", e);
+            }
+        }
     }
 
     class ControllerStub extends IMediaController.Stub {
-        /*
-         */
         @Override
-        public void sendCommand(String command, Bundle extras) throws RemoteException {
-            mSessionCb.sendCommand(command, extras);
+        public void sendCommand(String command, Bundle extras, ResultReceiver cb)
+                throws RemoteException {
+            mSessionCb.sendCommand(command, extras, cb);
         }
 
         @Override
@@ -172,29 +330,130 @@
             mSessionCb.sendMediaButton(mediaButtonIntent);
         }
 
-        /*
-         */
         @Override
-        public void registerCallbackListener(IMediaControllerCallback cb) throws RemoteException {
-            if (!mSessionCallbacks.contains(cb)) {
-                mSessionCallbacks.add(cb);
+        public void registerCallbackListener(IMediaControllerCallback cb) {
+            synchronized (mControllerLock) {
+                if (!mControllerCallbacks.contains(cb)) {
+                    mControllerCallbacks.add(cb);
+                }
             }
         }
 
-        /*
-         */
         @Override
         public void unregisterCallbackListener(IMediaControllerCallback cb)
                 throws RemoteException {
-            mSessionCallbacks.remove(cb);
+            synchronized (mControllerLock) {
+                mControllerCallbacks.remove(cb);
+            }
         }
 
-        /*
-         */
         @Override
-        public int getPlaybackState() throws RemoteException {
+        public void play() throws RemoteException {
+            mSessionCb.play();
+        }
+
+        @Override
+        public void pause() throws RemoteException {
+            mSessionCb.pause();
+        }
+
+        @Override
+        public void stop() throws RemoteException {
+            mSessionCb.stop();
+        }
+
+        @Override
+        public void next() throws RemoteException {
+            mSessionCb.next();
+        }
+
+        @Override
+        public void previous() throws RemoteException {
+            mSessionCb.previous();
+        }
+
+        @Override
+        public void fastForward() throws RemoteException {
+            mSessionCb.fastForward();
+        }
+
+        @Override
+        public void rewind() throws RemoteException {
+            mSessionCb.rewind();
+        }
+
+        @Override
+        public void seekTo(long pos) throws RemoteException {
+            mSessionCb.seekTo(pos);
+        }
+
+        @Override
+        public void rate(Rating rating) throws RemoteException {
+            mSessionCb.rate(rating);
+        }
+
+
+        @Override
+        public MediaMetadata getMetadata() {
+            return mMetadata;
+        }
+
+        @Override
+        public PlaybackState getPlaybackState() {
             return mPlaybackState;
         }
+
+        @Override
+        public int getRatingType() {
+            return mRatingType;
+        }
+
+        @Override
+        public boolean isTransportControlEnabled() throws RemoteException {
+            return mTransportPerformerEnabled;
+        }
+    }
+
+    private class MessageHandler extends Handler {
+        private static final int MSG_UPDATE_METADATA = 1;
+        private static final int MSG_UPDATE_PLAYBACK_STATE = 2;
+        private static final int MSG_UPDATE_ROUTE = 3;
+        private static final int MSG_SEND_EVENT = 4;
+
+        public MessageHandler(Looper looper) {
+            super(looper);
+        }
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_UPDATE_METADATA:
+                    pushMetadataUpdate();
+                    break;
+                case MSG_UPDATE_PLAYBACK_STATE:
+                    pushPlaybackStateUpdate();
+                    break;
+                case MSG_UPDATE_ROUTE:
+                    pushRouteUpdate();
+                    break;
+                case MSG_SEND_EVENT:
+                    pushEvent((String) msg.obj, msg.getData());
+                    break;
+            }
+        }
+
+        public void post(int what) {
+            post(what, null);
+        }
+
+        public void post(int what, Object obj) {
+            obtainMessage(what, obj).sendToTarget();
+        }
+
+        public void post(int what, Object obj, Bundle data) {
+            Message msg = obtainMessage(what, obj);
+            msg.setData(data);
+            msg.sendToTarget();
+        }
     }
 
 }
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index a7ff926..8fe6055 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -21,6 +21,7 @@
 import android.media.session.IMediaSessionCallback;
 import android.media.session.IMediaSessionManager;
 import android.os.Binder;
+import android.os.Handler;
 import android.os.RemoteException;
 import android.text.TextUtils;
 import android.util.Log;
@@ -41,6 +42,8 @@
     private final ArrayList<MediaSessionRecord> mSessions
             = new ArrayList<MediaSessionRecord>();
     private final Object mLock = new Object();
+    // TODO do we want a separate thread for handling mediasession messages?
+    private final Handler mHandler = new Handler();
 
     public MediaSessionService(Context context) {
         super(context);
@@ -91,7 +94,8 @@
 
     private MediaSessionRecord createSessionLocked(int pid, String packageName,
             IMediaSessionCallback cb, String tag) {
-        final MediaSessionRecord session = new MediaSessionRecord(pid, packageName, cb, tag, this);
+        final MediaSessionRecord session = new MediaSessionRecord(pid, packageName, cb, tag, this,
+                mHandler);
         try {
             cb.asBinder().linkToDeath(session, 0);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java
index 243bd74..4c8dcc3 100644
--- a/services/core/java/com/android/server/notification/NotificationDelegate.java
+++ b/services/core/java/com/android/server/notification/NotificationDelegate.java
@@ -20,11 +20,14 @@
 
 public interface NotificationDelegate {
     void onSetDisabled(int status);
-    void onClearAll();
-    void onNotificationClick(String pkg, String tag, int id);
-    void onNotificationClear(String pkg, String tag, int id);
-    void onNotificationError(String pkg, String tag, int id,
-            int uid, int initialPid, String message);
+    void onClearAll(int callingUid, int callingPid, int userId);
+    void onNotificationClick(int callingUid, int callingPid,
+            String pkg, String tag, int id, int userId);
+    void onNotificationClear(int callingUid, int callingPid,
+            String pkg, String tag, int id, int userId);
+    void onNotificationError(int callingUid, int callingPid,
+            String pkg, String tag, int id,
+            int uid, int initialPid, String message, int userId);
     void onPanelRevealed();
     boolean allowDisable(int what, IBinder token, String pkg);
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ce13a7a..e2226aa 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -43,6 +43,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
@@ -56,6 +57,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.service.notification.INotificationListener;
@@ -67,6 +69,7 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.Xml;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -217,6 +220,23 @@
             ));
     private static final String EXTRA_INTERCEPT = "android.intercept";
 
+    // Users related to the current user.
+    final protected SparseArray<UserInfo> mRelatedUsers = new SparseArray<UserInfo>();
+
+    private static final int MY_UID = Process.myUid();
+    private static final int MY_PID = Process.myPid();
+    private static final int REASON_DELEGATE_CLICK = 1;
+    private static final int REASON_DELEGATE_CANCEL = 2;
+    private static final int REASON_DELEGATE_CANCEL_ALL = 3;
+    private static final int REASON_DELEGATE_ERROR = 4;
+    private static final int REASON_PACKAGE_CHANGED = 5;
+    private static final int REASON_USER_STOPPED = 6;
+    private static final int REASON_PACKAGE_BANNED = 7;
+    private static final int REASON_NOMAN_CANCEL = 8;
+    private static final int REASON_NOMAN_CANCEL_ALL = 9;
+    private static final int REASON_LISTENER_CANCEL = 10;
+    private static final int REASON_LISTENER_CANCEL_ALL = 11;
+
     private class NotificationListenerInfo implements IBinder.DeathRecipient {
         INotificationListener listener;
         ComponentName component;
@@ -910,28 +930,23 @@
         }
 
         @Override
-        public void onClearAll() {
-            // XXX to be totally correct, the caller should tell us which user
-            // this is for.
-            cancelAll(ActivityManager.getCurrentUser());
+        public void onClearAll(int callingUid, int callingPid, int userId) {
+            cancelAll(callingUid, callingPid, userId, REASON_DELEGATE_CANCEL_ALL, null);
         }
 
         @Override
-        public void onNotificationClick(String pkg, String tag, int id) {
-            // XXX to be totally correct, the caller should tell us which user
-            // this is for.
-            cancelNotification(pkg, tag, id, Notification.FLAG_AUTO_CANCEL,
-                    Notification.FLAG_FOREGROUND_SERVICE, false,
-                    ActivityManager.getCurrentUser());
+        public void onNotificationClick(int callingUid, int callingPid,
+                String pkg, String tag, int id, int userId) {
+            cancelNotification(callingUid, callingPid, pkg, tag, id, Notification.FLAG_AUTO_CANCEL,
+                    Notification.FLAG_FOREGROUND_SERVICE, false, userId, REASON_DELEGATE_CLICK, null);
         }
 
         @Override
-        public void onNotificationClear(String pkg, String tag, int id) {
-            // XXX to be totally correct, the caller should tell us which user
-            // this is for.
-            cancelNotification(pkg, tag, id, 0,
-                Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
-                true, ActivityManager.getCurrentUser());
+        public void onNotificationClear(int callingUid, int callingPid,
+                String pkg, String tag, int id, int userId) {
+            cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
+                    Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
+                    true, userId, REASON_DELEGATE_CANCEL, null);
         }
 
         @Override
@@ -968,13 +983,12 @@
         }
 
         @Override
-        public void onNotificationError(String pkg, String tag, int id,
-                int uid, int initialPid, String message) {
+        public void onNotificationError(int callingUid, int callingPid, String pkg, String tag, int id,
+                int uid, int initialPid, String message, int userId) {
             Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id
                     + "; will crashApplication(uid=" + uid + ", pid=" + initialPid + ")");
-            // XXX to be totally correct, the caller should tell us which user
-            // this is for.
-            cancelNotification(pkg, tag, id, 0, 0, false, UserHandle.getUserId(uid));
+            cancelNotification(callingUid, callingPid, pkg, tag, id, 0, 0, false, userId,
+                    REASON_DELEGATE_ERROR, null);
             long ident = Binder.clearCallingIdentity();
             try {
                 ActivityManagerNative.getDefault().crashApplication(uid, initialPid, pkg,
@@ -1051,8 +1065,8 @@
                 if (pkgList != null && (pkgList.length > 0)) {
                     for (String pkgName : pkgList) {
                         if (cancelNotifications) {
-                            cancelAllNotificationsInt(pkgName, 0, 0, !queryRestart,
-                                    UserHandle.USER_ALL);
+                            cancelAllNotificationsInt(MY_UID, MY_PID, pkgName, 0, 0, !queryRestart,
+                                    UserHandle.USER_ALL, REASON_PACKAGE_CHANGED, null);
                         }
                         if (mEnabledListenerPackageNames.contains(pkgName)) {
                             anyListenersInvolved = true;
@@ -1082,7 +1096,8 @@
             } else if (action.equals(Intent.ACTION_USER_STOPPED)) {
                 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                 if (userHandle >= 0) {
-                    cancelAllNotificationsInt(null, 0, 0, true, userHandle);
+                    cancelAllNotificationsInt(MY_UID, MY_PID, null, 0, 0, true, userHandle,
+                            REASON_USER_STOPPED, null);
                 }
             } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                 // turn off LED when user passes through lock screen
@@ -1090,6 +1105,9 @@
             } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                 // reload per-user settings
                 mSettingsObserver.update(null);
+                updateRelatedUserCache(context);
+            } else if (action.equals(Intent.ACTION_USER_ADDED)) {
+                updateRelatedUserCache(context);
             }
         }
     };
@@ -1223,6 +1241,7 @@
         filter.addAction(Intent.ACTION_USER_PRESENT);
         filter.addAction(Intent.ACTION_USER_STOPPED);
         filter.addAction(Intent.ACTION_USER_SWITCHED);
+        filter.addAction(Intent.ACTION_USER_ADDED);
         getContext().registerReceiver(mIntentReceiver, filter);
         IntentFilter pkgFilter = new IntentFilter();
         pkgFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
@@ -1304,7 +1323,8 @@
 
         // Now, cancel any outstanding notifications that are part of a just-disabled app
         if (ENABLE_BLOCKED_NOTIFICATIONS && !enabled) {
-            cancelAllNotificationsInt(pkg, 0, 0, true, UserHandle.getUserId(uid));
+            cancelAllNotificationsInt(MY_UID, MY_PID, pkg, 0, 0, true, UserHandle.getUserId(uid),
+                    REASON_PACKAGE_BANNED, null);
         }
     }
 
@@ -1420,9 +1440,10 @@
             userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                     Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg);
             // Don't allow client applications to cancel foreground service notis.
-            cancelNotification(pkg, tag, id, 0,
+            cancelNotification(Binder.getCallingUid(), Binder.getCallingPid(), pkg, tag, id, 0,
                     Binder.getCallingUid() == Process.SYSTEM_UID
-                    ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false, userId);
+                    ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false, userId, REASON_NOMAN_CANCEL,
+                    null);
         }
 
         @Override
@@ -1434,7 +1455,9 @@
 
             // Calling from user space, don't allow the canceling of actively
             // running foreground services.
-            cancelAllNotificationsInt(pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId);
+            cancelAllNotificationsInt(Binder.getCallingUid(), Binder.getCallingPid(),
+                    pkg, 0, Notification.FLAG_FOREGROUND_SERVICE, true, userId,
+                    REASON_NOMAN_CANCEL_ALL, null);
         }
 
         @Override
@@ -1543,9 +1566,12 @@
         @Override
         public void cancelAllNotificationsFromListener(INotificationListener token) {
             NotificationListenerInfo info = checkListenerToken(token);
+            final int callingUid = Binder.getCallingUid();
+            final int callingPid = Binder.getCallingPid();
             long identity = Binder.clearCallingIdentity();
             try {
-                cancelAll(info.userid);
+                cancelAll(callingUid, callingPid, info.userid,
+                        REASON_LISTENER_CANCEL_ALL, info);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -1562,12 +1588,14 @@
         public void cancelNotificationFromListener(INotificationListener token, String pkg,
                 String tag, int id) {
             NotificationListenerInfo info = checkListenerToken(token);
+            final int callingUid = Binder.getCallingUid();
+            final int callingPid = Binder.getCallingPid();
             long identity = Binder.clearCallingIdentity();
             try {
-                cancelNotification(pkg, tag, id, 0,
+                cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
                         Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
                         true,
-                        info.userid);
+                        info.userid, REASON_LISTENER_CANCEL, info);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -1735,8 +1763,8 @@
         //     behalf of the download manager without affecting other apps.
         if (!pkg.equals("com.android.providers.downloads")
                 || Log.isLoggable("DownloadManager", Log.VERBOSE)) {
-            EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, tag, userId,
-                    notification.toString());
+            EventLogTags.writeNotificationEnqueue(callingUid, callingPid,
+                    pkg, id, tag, userId, notification.toString());
         }
 
         if (pkg == null || notification == null) {
@@ -2287,9 +2315,10 @@
      * Cancels a notification ONLY if it has all of the {@code mustHaveFlags}
      * and none of the {@code mustNotHaveFlags}.
      */
-    void cancelNotification(final String pkg, final String tag, final int id,
+    void cancelNotification(final int callingUid, final int callingPid,
+            final String pkg, final String tag, final int id,
             final int mustHaveFlags, final int mustNotHaveFlags, final boolean sendDelete,
-            final int userId) {
+            final int userId, final int reason, final NotificationListenerInfo listener) {
         // In enqueueNotificationInternal notifications are added by scheduling the
         // work on the worker handler. Hence, we also schedule the cancel on this
         // handler to avoid a scenario where an add notification call followed by a
@@ -2297,8 +2326,9 @@
         mHandler.post(new Runnable() {
             @Override
             public void run() {
-                EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, tag, userId,
-                        mustHaveFlags, mustNotHaveFlags);
+                EventLogTags.writeNotificationCancel(callingUid, callingPid, pkg, id, tag, userId,
+                        mustHaveFlags, mustNotHaveFlags, reason,
+                        listener == null ? null : listener.component.toShortString());
 
                 synchronized (mNotificationList) {
                     int index = indexOfNotificationLocked(pkg, tag, id, userId);
@@ -2337,13 +2367,27 @@
     }
 
     /**
+     * Determine whether the userId applies to the notification in question, either because
+     * they match exactly, or one of them is USER_ALL (which is treated as a wildcard) or
+     * because it matches a related user.
+     */
+    private boolean notificationMatchesUserIdOrRelated(NotificationRecord r, int userId) {
+        synchronized (mRelatedUsers) {
+            return notificationMatchesUserId(r, userId)
+                    || mRelatedUsers.get(r.getUserId()) != null;
+        }
+    }
+
+    /**
      * Cancels all notifications from a given package that have all of the
      * {@code mustHaveFlags}.
      */
-    boolean cancelAllNotificationsInt(String pkg, int mustHaveFlags,
-            int mustNotHaveFlags, boolean doit, int userId) {
-        EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL_ALL, pkg, userId,
-                mustHaveFlags, mustNotHaveFlags);
+    boolean cancelAllNotificationsInt(int callingUid, int callingPid, String pkg, int mustHaveFlags,
+            int mustNotHaveFlags, boolean doit, int userId, int reason,
+            NotificationListenerInfo listener) {
+        EventLogTags.writeNotificationCancelAll(callingUid, callingPid,
+                pkg, userId, mustHaveFlags, mustNotHaveFlags, reason,
+                listener == null ? null : listener.component.toShortString());
 
         synchronized (mNotificationList) {
             final int N = mNotificationList.size();
@@ -2418,13 +2462,17 @@
         }
     }
 
-    void cancelAll(int userId) {
+    void cancelAll(int callingUid, int callingPid, int userId, int reason,
+            NotificationListenerInfo listener) {
+        EventLogTags.writeNotificationCancelAll(callingUid, callingPid,
+                null, userId, 0, 0, reason,
+                listener == null ? null : listener.component.toShortString());
         synchronized (mNotificationList) {
             final int N = mNotificationList.size();
             for (int i=N-1; i>=0; i--) {
                 NotificationRecord r = mNotificationList.get(i);
 
-                if (!notificationMatchesUserId(r, userId)) {
+                if (!notificationMatchesUserIdOrRelated(r, userId)) {
                     continue;
                 }
 
@@ -2582,6 +2630,20 @@
         }
     }
 
+    private void updateRelatedUserCache(Context context) {
+        UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+        int currentUserId = ActivityManager.getCurrentUser();
+        if (userManager != null) {
+            List<UserInfo> relatedUsers = userManager.getRelatedUsers(currentUserId);
+            synchronized (mRelatedUsers) {
+                mRelatedUsers.clear();
+                for (UserInfo related : relatedUsers) {
+                    mRelatedUsers.put(related.id, related);
+                }
+            }
+        }
+    }
+
     private boolean isCall(String pkg, Notification n) {
         return CALL_PACKAGES.contains(pkg);
     }
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index fc98c4e..7f55464 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -234,9 +234,7 @@
     }
 
     void systemReady() {
-        final Context context = ActivityThread.systemMain().getSystemContext();
-        mUserPackageMonitor.register(context,
-                null, UserHandle.ALL, false);
+        mUserPackageMonitor.register(mContext, null, UserHandle.ALL, false);
         userForeground(UserHandle.USER_OWNER);
     }
 
@@ -457,7 +455,7 @@
 
     /**
      * Enforces that only the system UID or root's UID or apps that have the
-     * {@link android.Manifest.permission.MANAGE_USERS MANAGE_USERS}
+     * {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}
      * permission can make certain calls to the UserManager.
      *
      * @param message used as message if SecurityException is thrown
@@ -1046,7 +1044,7 @@
     /**
      * Removes a user and all data directories created for that user. This method should be called
      * after the user's processes have been terminated.
-     * @param id the user's id
+     * @param userHandle the user's id
      */
     public boolean removeUser(int userHandle) {
         checkManageUsersPermission("Only the system can remove users");
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index df06bae..81af636 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -165,11 +165,11 @@
             int newFlags, String newTag, String newPackageName, int newOwnerUid,
             int newOwnerPid, WorkSource newWorkSource, String newHistoryTag) {
 
-        final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
-        final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
-        boolean unimportantForLogging = (flags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
-                && ownerUid == Process.SYSTEM_UID;
         if (workSource != null && newWorkSource != null) {
+            final int monitorType = getBatteryStatsWakeLockMonitorType(flags);
+            final int newMonitorType = getBatteryStatsWakeLockMonitorType(newFlags);
+            boolean unimportantForLogging = (newFlags&PowerManager.UNIMPORTANT_FOR_LOGGING) != 0
+                    && newOwnerUid == Process.SYSTEM_UID;
             if (DEBUG) {
                 Slog.d(TAG, "onWakeLockChanging: flags=" + newFlags + ", tag=\"" + newTag
                         + "\", packageName=" + newPackageName
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index e0a46b9..fab972f 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1816,7 +1816,12 @@
 
     private boolean isScreenOnInternal() {
         synchronized (mLock) {
-            return isScreenOnLocked();
+            // XXX This is a temporary hack to let certain parts of the system pretend the
+            // screen is still on even when dozing and we would normally want to report
+            // screen off.  Will be removed when the window manager is modified to use
+            // the true blanking state of the display.
+            return isScreenOnLocked()
+                    || mWakefulness == WAKEFULNESS_DOZING;
         }
     }
 
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 8219eb5..4ce02c1 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -535,11 +535,13 @@
     }
 
     @Override
-    public void onNotificationClick(String pkg, String tag, int id) {
+    public void onNotificationClick(String pkg, String tag, int id, int userId) {
         enforceStatusBarService();
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
         long identity = Binder.clearCallingIdentity();
         try {
-            mNotificationDelegate.onNotificationClick(pkg, tag, id);
+            mNotificationDelegate.onNotificationClick(callingUid, callingPid, pkg, tag, id, userId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -547,34 +549,41 @@
 
     @Override
     public void onNotificationError(String pkg, String tag, int id,
-            int uid, int initialPid, String message) {
+            int uid, int initialPid, String message, int userId) {
         enforceStatusBarService();
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
         long identity = Binder.clearCallingIdentity();
         try {
             // WARNING: this will call back into us to do the remove.  Don't hold any locks.
-            mNotificationDelegate.onNotificationError(pkg, tag, id, uid, initialPid, message);
+            mNotificationDelegate.onNotificationError(callingUid, callingPid,
+                    pkg, tag, id, uid, initialPid, message, userId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     @Override
-    public void onNotificationClear(String pkg, String tag, int id) {
+    public void onNotificationClear(String pkg, String tag, int id, int userId) {
         enforceStatusBarService();
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
         long identity = Binder.clearCallingIdentity();
         try {
-            mNotificationDelegate.onNotificationClear(pkg, tag, id);
+            mNotificationDelegate.onNotificationClear(callingUid, callingPid, pkg, tag, id, userId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
     }
 
     @Override
-    public void onClearAllNotifications() {
+    public void onClearAllNotifications(int userId) {
         enforceStatusBarService();
+        final int callingUid = Binder.getCallingUid();
+        final int callingPid = Binder.getCallingPid();
         long identity = Binder.clearCallingIdentity();
         try {
-            mNotificationDelegate.onClearAll();
+            mNotificationDelegate.onClearAll(callingUid, callingPid, userId);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 0b19b5c..93f6d22 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -669,15 +669,10 @@
 
             int flags = SurfaceControl.HIDDEN;
             final WindowManager.LayoutParams attrs = mWin.mAttrs;
-            final boolean isVideoPlane =
-                    (attrs.privateFlags & WindowManager.LayoutParams.PRIVATE_FLAG_VIDEO_PLANE) != 0;
 
             if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
                 flags |= SurfaceControl.SECURE;
             }
-            if (isVideoPlane) {
-                flags |= SurfaceControl.FX_SURFACE_VIDEO_PLANE;
-            }
             if (DEBUG_VISIBILITY) Slog.v(
                 TAG, "Creating surface in session "
                 + mSession.mSurfaceSession + " window " + this
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 91d77fb..b4c099d 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -51,6 +51,7 @@
 import com.android.internal.R;
 import com.android.internal.os.BinderInternal;
 import com.android.internal.os.SamplingProfilerIntegration;
+import com.android.server.accessibility.AccessibilityManagerService;
 import com.android.server.accounts.AccountManagerService;
 import com.android.server.am.ActivityManagerService;
 import com.android.server.am.BatteryStatsService;
@@ -482,8 +483,8 @@
 
                 try {
                     Slog.i(TAG, "Accessibility Manager");
-                    ServiceManager.addService(Context.ACCESSIBILITY_SERVICE, (IBinder)
-                            getClass().getClassLoader().loadClass("com.android.server.accessibility.AccessibilityManagerService").getConstructor(Context.class).newInstance(context));
+                    ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
+                            new AccessibilityManagerService(context));
                 } catch (Throwable e) {
                     reportWtf("starting Accessibility Manager", e);
                 }
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index b925856..efbfb33 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -90,6 +90,7 @@
     private static final int MSG_SYSTEM_READY = 3;
     private static final int MSG_BOOT_COMPLETED = 4;
     private static final int MSG_USER_SWITCHED = 5;
+    private static final int MSG_START_ACCESSORY_MODE = 6;
 
     private static final int AUDIO_MODE_NONE = 0;
     private static final int AUDIO_MODE_SOURCE = 1;
@@ -152,7 +153,7 @@
                 mHandler.updateState(state);
             } else if ("START".equals(accessory)) {
                 if (DEBUG) Slog.d(TAG, "got accessory start");
-                startAccessoryMode();
+                 mHandler.sendEmptyMessage(MSG_START_ACCESSORY_MODE);
             }
         }
     };
@@ -170,7 +171,7 @@
 
         if (nativeIsStartRequested()) {
             if (DEBUG) Slog.d(TAG, "accessory attached at boot");
-            startAccessoryMode();
+             mHandler.sendEmptyMessage(MSG_START_ACCESSORY_MODE);
         }
 
         boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false);
@@ -232,6 +233,8 @@
             functions = UsbManager.USB_FUNCTION_AUDIO_SOURCE;
         }
 
+        if (DEBUG) Slog.d(TAG, "startAccessoryMode: " + functions);
+
         if (functions != null) {
             mAccessoryModeRequestTime = SystemClock.elapsedRealtime();
             setCurrentFunctions(functions, false);
@@ -306,6 +309,7 @@
         // current USB state
         private boolean mConnected;
         private boolean mConfigured;
+        private boolean mAccessoryStartPending;
         private String mCurrentFunctions;
         private String mDefaultFunctions;
         private UsbAccessory mCurrentAccessory;
@@ -612,6 +616,11 @@
                 case MSG_UPDATE_STATE:
                     mConnected = (msg.arg1 == 1);
                     mConfigured = (msg.arg2 == 1);
+
+                    if (!mConnected) {
+                        mAccessoryStartPending = false;
+                    }
+
                     updateUsbNotification();
                     updateAdbNotification();
                     if (containsFunction(mCurrentFunctions,
@@ -625,6 +634,10 @@
                         updateUsbState();
                         updateAudioSourceFunction();
                     }
+                    if (mConnected && mConfigured && mAccessoryStartPending) {
+                        startAccessoryMode();
+                        mAccessoryStartPending = false;
+                    }
                     break;
                 case MSG_ENABLE_ADB:
                     setAdbEnabled(msg.arg1 == 1);
@@ -661,6 +674,16 @@
                     mCurrentUser = msg.arg1;
                     break;
                 }
+                case MSG_START_ACCESSORY_MODE:
+                    if (mConnected && mConfigured) {
+                        startAccessoryMode();
+                    } else {
+                        // we sometimes receive the kernel "accessory start" uevent
+                        // before the "configured" uevent. In this case we need to defer
+                        // handling this event until after we received the configured event
+                        mAccessoryStartPending = true;
+                    }
+                    break;
             }
         }
 
diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
index ff4857b..37b5c51 100644
--- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java
@@ -27,6 +27,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.hardware.usb.UsbAccessory;
 import android.hardware.usb.UsbDevice;
@@ -73,6 +74,7 @@
 
     private final UserHandle mUser;
     private final AtomicFile mSettingsFile;
+    private final boolean mDisablePermissionDialogs;
 
     private final Context mContext;
     private final Context mUserContext;
@@ -510,6 +512,9 @@
                 Environment.getUserSystemDirectory(user.getIdentifier()),
                 "usb_device_manager.xml"));
 
+        mDisablePermissionDialogs = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_disableUsbPermissionDialogs);
+
         synchronized (mLock) {
             if (UserHandle.OWNER.equals(user)) {
                 upgradeSingleUserLocked();
@@ -815,6 +820,14 @@
                     (rInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                 defaultRI = rInfo;
             }
+
+            if (mDisablePermissionDialogs) {
+                // bypass dialog and launch the only matching activity
+                rInfo = matches.get(0);
+                if (rInfo.activityInfo != null) {
+                    defaultPackage = rInfo.activityInfo.packageName;
+                }
+            }
         }
 
         if (defaultRI == null && defaultPackage != null) {
@@ -970,7 +983,7 @@
     public boolean hasPermission(UsbDevice device) {
         synchronized (mLock) {
             int uid = Binder.getCallingUid();
-            if (uid == Process.SYSTEM_UID) {
+            if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
                 return true;
             }
             SparseBooleanArray uidList = mDevicePermissionMap.get(device.getDeviceName());
@@ -984,7 +997,7 @@
     public boolean hasPermission(UsbAccessory accessory) {
         synchronized (mLock) {
             int uid = Binder.getCallingUid();
-            if (uid == Process.SYSTEM_UID) {
+            if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
                 return true;
             }
             SparseBooleanArray uidList = mAccessoryPermissionMap.get(accessory);
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index ff5c935..118cba4 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -335,6 +335,27 @@
     }
 
     @Override
+    public Drawable getActivityBanner(ComponentName activityName)
+            throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getActivityBanner(Intent intent) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getApplicationBanner(ApplicationInfo info) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Drawable getApplicationBanner(String packageName) throws NameNotFoundException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public Drawable getApplicationIcon(ApplicationInfo info) {
         throw new UnsupportedOperationException();
     }
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
index 208c387..5ba3ad9 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
@@ -8,7 +8,7 @@
 
 import android.app.Activity;
 import android.util.AttributeSet;
-import android.view.DisplayList;
+import android.view.RenderNode;
 import android.view.View;
 import android.widget.LinearLayout;
 
@@ -46,7 +46,7 @@
         }
 
         private void setProject(boolean value) {
-            DisplayList displayList = getDisplayList();
+            RenderNode displayList = getDisplayList();
             if (displayList != null) {
                 displayList.setProjectBackwards(value);
             }
diff --git a/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java b/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java
index 7ff81e4..3114ca9 100644
--- a/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java
+++ b/tests/OneMedia/src/com/android/onemedia/OnePlayerActivity.java
@@ -1,7 +1,24 @@
+/*
+ * 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 com.android.onemedia;
 
 
 import android.app.Activity;
+import android.media.session.MediaMetadata;
+import android.media.session.PlaybackState;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.Menu;
@@ -79,10 +96,10 @@
             switch (v.getId()) {
                 case R.id.play_button:
                     Log.d(TAG, "Play button pressed, in state " + mPlaybackState);
-                    if (mPlaybackState == Renderer.STATE_PAUSED
-                            || mPlaybackState == Renderer.STATE_ENDED) {
+                    if (mPlaybackState == PlaybackState.PLAYSTATE_PAUSED
+                            || mPlaybackState == PlaybackState.PLAYSTATE_STOPPED) {
                         mPlayer.play();
-                    } else if (mPlaybackState == Renderer.STATE_PLAYING) {
+                    } else if (mPlaybackState == PlaybackState.PLAYSTATE_PLAYING) {
                         mPlayer.pause();
                     }
                     break;
@@ -97,48 +114,55 @@
 
     private PlayerController.Listener mListener = new PlayerController.Listener() {
         @Override
-        public void onSessionStateChange(int state) {
-            mPlaybackState = state;
+        public void onPlaybackStateChange(PlaybackState state) {
+            mPlaybackState = state.getState();
             boolean enablePlay = false;
+            StringBuilder statusBuilder = new StringBuilder();
             switch (mPlaybackState) {
-                case Renderer.STATE_PLAYING:
-                    mStatusView.setText("playing");
+                case PlaybackState.PLAYSTATE_PLAYING:
+                    statusBuilder.append("playing");
                     mPlayButton.setText("Pause");
                     enablePlay = true;
                     break;
-                case Renderer.STATE_PAUSED:
-                    mStatusView.setText("paused");
+                case PlaybackState.PLAYSTATE_PAUSED:
+                    statusBuilder.append("paused");
                     mPlayButton.setText("Play");
                     enablePlay = true;
                     break;
-                case Renderer.STATE_ENDED:
-                    mStatusView.setText("ended");
+                case PlaybackState.PLAYSTATE_STOPPED:
+                    statusBuilder.append("ended");
                     mPlayButton.setText("Play");
                     enablePlay = true;
                     break;
-                case Renderer.STATE_ERROR:
-                    mStatusView.setText("error");
+                case PlaybackState.PLAYSTATE_ERROR:
+                    statusBuilder.append("error: ").append(state.getErrorMessage());
                     break;
-                case Renderer.STATE_PREPARING:
-                    mStatusView.setText("preparing");
+                case PlaybackState.PLAYSTATE_BUFFERING:
+                    statusBuilder.append("buffering");
                     break;
-                case Renderer.STATE_READY:
-                    mStatusView.setText("ready");
+                case PlaybackState.PLAYSTATE_NONE:
+                    statusBuilder.append("none");
                     break;
-                case Renderer.STATE_STOPPED:
-                    mStatusView.setText("stopped");
-                    break;
+                default:
+                    statusBuilder.append(mPlaybackState);
             }
+            statusBuilder.append(" -- At position: ").append(state.getPosition());
+            mStatusView.setText(statusBuilder.toString());
             mPlayButton.setEnabled(enablePlay);
         }
 
         @Override
-        public void onPlayerStateChange(int state) {
+        public void onConnectionStateChange(int state) {
             if (state == PlayerController.STATE_DISCONNECTED) {
                 setControlsEnabled(false);
             } else if (state == PlayerController.STATE_CONNECTED) {
                 setControlsEnabled(true);
             }
         }
+
+        @Override
+        public void onMetadataChange(MediaMetadata metadata) {
+            Log.d(TAG, "Metadata update! Title: " + metadata);
+        }
     };
 }
diff --git a/tests/OneMedia/src/com/android/onemedia/OnePlayerService.java b/tests/OneMedia/src/com/android/onemedia/OnePlayerService.java
index 01610cd..573f7ff 100644
--- a/tests/OneMedia/src/com/android/onemedia/OnePlayerService.java
+++ b/tests/OneMedia/src/com/android/onemedia/OnePlayerService.java
@@ -1,3 +1,18 @@
+/*
+ * 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 com.android.onemedia;
 
 import android.content.Context;
@@ -5,9 +20,6 @@
 
 import java.util.ArrayList;
 
-/**
- * TODO: Insert description here. (generated by epastern)
- */
 public class OnePlayerService extends PlayerService {
     private static final String TAG = "OnePlayerService";
 
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerController.java b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
index 3f15db5..e831ec6 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerController.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerController.java
@@ -1,8 +1,27 @@
 
+/*
+ * 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 com.android.onemedia;
 
 import android.media.session.MediaController;
+import android.media.session.MediaMetadata;
 import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
+import android.media.session.TransportController;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -11,22 +30,23 @@
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.util.Log;
-import android.view.KeyEvent;
 
 import com.android.onemedia.playback.RequestUtils;
 
 public class PlayerController {
-    private static final String TAG = "PlayerSession";
+    private static final String TAG = "PlayerController";
 
     public static final int STATE_DISCONNECTED = 0;
     public static final int STATE_CONNECTED = 1;
 
     protected MediaController mController;
     protected IPlayerService mBinder;
+    protected TransportController mTransportControls;
 
     private final Intent mServiceIntent;
     private Context mContext;
     private Listener mListener;
+    private TransportListener mTransportListener = new TransportListener();
     private SessionCallback mControllerCb;
     private MediaSessionManager mManager;
     private Handler mHandler = new Handler();
@@ -52,7 +72,7 @@
         Log.d(TAG, "Listener set to " + listener + " session is " + mController);
         if (mListener != null) {
             mHandler = new Handler();
-            mListener.onPlayerStateChange(
+            mListener.onConnectionStateChange(
                     mController == null ? STATE_DISCONNECTED : STATE_CONNECTED);
         }
     }
@@ -70,11 +90,15 @@
     }
 
     public void play() {
-        mController.sendMediaButton(KeyEvent.KEYCODE_MEDIA_PLAY);
+        if (mTransportControls != null) {
+            mTransportControls.play();
+        }
     }
 
     public void pause() {
-        mController.sendMediaButton(KeyEvent.KEYCODE_MEDIA_PAUSE);
+        if (mTransportControls != null) {
+            mTransportControls.pause();
+        }
     }
 
     public void setContent(String source) {
@@ -113,10 +137,11 @@
             }
             mBinder = null;
             mController = null;
+            mTransportControls = null;
             Log.d(TAG, "Disconnected from PlayerService");
 
             if (mListener != null) {
-                mListener.onPlayerStateChange(STATE_DISCONNECTED);
+                mListener.onConnectionStateChange(STATE_DISCONNECTED);
             }
         }
 
@@ -125,33 +150,60 @@
             mBinder = IPlayerService.Stub.asInterface(service);
             Log.d(TAG, "service is " + service + " binder is " + mBinder);
             try {
-                mController = new MediaController(mBinder.getSessionToken());
+                mController = MediaController.fromToken(mBinder.getSessionToken());
             } catch (RemoteException e) {
                 Log.e(TAG, "Error getting session", e);
                 return;
             }
             mController.addCallback(mControllerCb, mHandler);
+            mTransportControls = mController.getTransportController();
+            if (mTransportControls != null) {
+                mTransportControls.addStateListener(mTransportListener);
+            }
             Log.d(TAG, "Ready to use PlayerService");
 
             if (mListener != null) {
-                mListener.onPlayerStateChange(STATE_CONNECTED);
+                mListener.onConnectionStateChange(STATE_CONNECTED);
+                if (mTransportControls != null) {
+                    mListener.onPlaybackStateChange(mTransportControls.getPlaybackState());
+                }
             }
         }
     };
 
     private class SessionCallback extends MediaController.Callback {
         @Override
-        public void onPlaybackStateChange(int state) {
-            if (mListener != null) {
-                mListener.onSessionStateChange(state);
+        public void onRouteChanged(Bundle route) {
+            // TODO
+        }
+    }
+
+    private class TransportListener extends TransportController.TransportStateListener {
+        @Override
+        public void onPlaybackStateChanged(PlaybackState state) {
+            if (state == null) {
+                return;
             }
+            Log.d(TAG, "Received playback state change to state " + state.getState());
+            if (mListener != null) {
+                mListener.onPlaybackStateChange(state);
+            }
+        }
+
+        @Override
+        public void onMetadataChanged(MediaMetadata metadata) {
+            if (metadata == null) {
+                return;
+            }
+            Log.d(TAG, "Received metadata change, title is "
+                    + metadata.getString(MediaMetadata.METADATA_KEY_TITLE));
         }
     }
 
     public interface Listener {
-        public void onSessionStateChange(int state);
-
-        public void onPlayerStateChange(int state);
+        public void onPlaybackStateChange(PlaybackState state);
+        public void onMetadataChange(MediaMetadata metadata);
+        public void onConnectionStateChange(int state);
     }
 
 }
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerService.java b/tests/OneMedia/src/com/android/onemedia/PlayerService.java
index 0b2ba8f..0ad6dd1 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerService.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerService.java
@@ -1,11 +1,28 @@
+/*
+ * 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 com.android.onemedia;
 
 import android.app.Service;
 import android.content.Intent;
 import android.media.session.MediaSessionToken;
+import android.media.session.PlaybackState;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.util.Log;
 
 import com.android.onemedia.playback.IRequestCallback;
 import com.android.onemedia.playback.RequestUtils;
@@ -18,14 +35,19 @@
     private PlayerBinder mBinder;
     private PlayerSession mSession;
     private Intent mIntent;
+    private boolean mStarted = false;
 
     private ArrayList<IPlayerCallback> mCbs = new ArrayList<IPlayerCallback>();
 
     @Override
     public void onCreate() {
+        Log.d(TAG, "onCreate");
         mIntent = onCreateServiceIntent();
-        mSession = onCreatePlayerController();
-        mSession.createSession();
+        if (mSession == null) {
+            mSession = onCreatePlayerController();
+            mSession.createSession();
+            mSession.setListener(mPlayerListener);
+        }
     }
 
     @Override
@@ -38,12 +60,31 @@
 
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
+        Log.d(TAG, "onStartCommand");
         return START_STICKY;
     }
 
     @Override
     public void onDestroy() {
+        Log.d(TAG, "onDestroy");
         mSession.onDestroy();
+        mSession = null;
+    }
+
+    public void onPlaybackStarted() {
+        if (!mStarted) {
+            Log.d(TAG, "Starting self");
+            startService(onCreateServiceIntent());
+            mStarted = true;
+        }
+    }
+
+    public void onPlaybackEnded() {
+        if (mStarted) {
+            Log.d(TAG, "Stopping self");
+            stopSelf();
+            mStarted = false;
+        }
     }
 
     protected Intent onCreateServiceIntent() {
@@ -58,6 +99,21 @@
         return null;
     }
 
+    private final PlayerSession.Listener mPlayerListener = new PlayerSession.Listener() {
+        @Override
+        public void onPlayStateChanged(PlaybackState state) {
+            switch (state.getState()) {
+                case PlaybackState.PLAYSTATE_PLAYING:
+                    onPlaybackStarted();
+                    break;
+                case PlaybackState.PLAYSTATE_STOPPED:
+                case PlaybackState.PLAYSTATE_ERROR:
+                    onPlaybackEnded();
+                    break;
+            }
+        }
+    };
+
     public class PlayerBinder extends IPlayerService.Stub {
         @Override
         public void sendRequest(String action, Bundle params, IRequestCallback cb) {
@@ -94,7 +150,6 @@
 
         @Override
         public MediaSessionToken getSessionToken() throws RemoteException {
-            // TODO(epastern): Auto-generated method stub
             return mSession.getSessionToken();
         }
     }
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
index e5fb0d0..a2d7897e 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
@@ -1,3 +1,18 @@
+/*
+ * 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 com.android.onemedia;
 
 import android.content.Context;
@@ -5,6 +20,8 @@
 import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
 import android.media.session.MediaSessionToken;
+import android.media.session.PlaybackState;
+import android.media.session.TransportPerformer;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -14,14 +31,18 @@
 import com.android.onemedia.playback.RendererFactory;
 
 public class PlayerSession {
-    private static final String TAG = "PlayerController";
+    private static final String TAG = "PlayerSession";
 
     protected MediaSession mSession;
     protected Context mContext;
     protected RendererFactory mRendererFactory;
     protected LocalRenderer mRenderer;
-    protected ControllerCb mCallback;
-    protected RenderListener mRenderListener;
+    protected MediaSession.Callback mCallback;
+    protected Renderer.Listener mRenderListener;
+    protected TransportPerformer mPerformer;
+
+    protected PlaybackState mPlaybackState;
+    protected Listener mListener;
 
     public PlayerSession(Context context) {
         mContext = context;
@@ -29,6 +50,9 @@
         mRenderer = new LocalRenderer(context, null);
         mCallback = new ControllerCb();
         mRenderListener = new RenderListener();
+        mPlaybackState = new PlaybackState();
+        mPlaybackState.setActions(PlaybackState.ACTION_PAUSE
+                | PlaybackState.ACTION_PLAY);
 
         mRenderer.registerListener(mRenderListener);
     }
@@ -42,6 +66,10 @@
         Log.d(TAG, "Creating session for package " + mContext.getBasePackageName());
         mSession = man.createSession("OneMedia");
         mSession.addCallback(mCallback);
+        mPerformer = mSession.setTransportPerformerEnabled();
+        mPerformer.addListener(new TransportListener());
+        mPerformer.setPlaybackState(mPlaybackState);
+        mSession.publish();
     }
 
     public void onDestroy() {
@@ -54,6 +82,10 @@
         }
     }
 
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
     public MediaSessionToken getSessionToken() {
         return mSession.getSessionToken();
     }
@@ -66,16 +98,58 @@
         mRenderer.setNextContent(request);
     }
 
-    protected class RenderListener implements Renderer.Listener {
+    public interface Listener {
+        public void onPlayStateChanged(PlaybackState state);
+    }
+
+    private class RenderListener implements Renderer.Listener {
 
         @Override
         public void onError(int type, int extra, Bundle extras, Throwable error) {
-            mSession.setPlaybackState(Renderer.STATE_ERROR);
+            Log.d(TAG, "Sending onError with type " + type + " and extra " + extra);
+            mPlaybackState.setState(PlaybackState.PLAYSTATE_ERROR);
+            if (error != null) {
+                mPlaybackState.setErrorMessage(error.getLocalizedMessage());
+            }
+            mPerformer.setPlaybackState(mPlaybackState);
+            if (mListener != null) {
+                mListener.onPlayStateChanged(mPlaybackState);
+            }
         }
 
         @Override
         public void onStateChanged(int newState) {
-            mSession.setPlaybackState(newState);
+            if (newState != Renderer.STATE_ERROR) {
+                mPlaybackState.setErrorMessage(null);
+            }
+            switch (newState) {
+                case Renderer.STATE_ENDED:
+                case Renderer.STATE_STOPPED:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_STOPPED);
+                    break;
+                case Renderer.STATE_INIT:
+                case Renderer.STATE_PREPARING:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_BUFFERING);
+                    break;
+                case Renderer.STATE_ERROR:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_ERROR);
+                    break;
+                case Renderer.STATE_PAUSED:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_PAUSED);
+                    break;
+                case Renderer.STATE_PLAYING:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_PLAYING);
+                    break;
+                default:
+                    mPlaybackState.setState(PlaybackState.PLAYSTATE_ERROR);
+                    mPlaybackState.setErrorMessage("unkown state");
+                    break;
+            }
+            mPlaybackState.setPosition(mRenderer.getSeekPosition());
+            mPerformer.setPlaybackState(mPlaybackState);
+            if (mListener != null) {
+                mListener.onPlayStateChanged(mPlaybackState);
+            }
         }
 
         @Override
@@ -84,7 +158,13 @@
 
         @Override
         public void onFocusLost() {
-            mSession.setPlaybackState(Renderer.STATE_PAUSED);
+            Log.d(TAG, "Focus lost, changing state to " + Renderer.STATE_PAUSED);
+            mPlaybackState.setState(PlaybackState.PLAYSTATE_PAUSED);
+            mPlaybackState.setPosition(mRenderer.getSeekPosition());
+            mPerformer.setPlaybackState(mPlaybackState);
+            if (mListener != null) {
+                mListener.onPlayStateChanged(mPlaybackState);
+            }
         }
 
         @Override
@@ -93,7 +173,7 @@
 
     }
 
-    protected class ControllerCb extends MediaSession.Callback {
+    private class ControllerCb extends MediaSession.Callback {
 
         @Override
         public void onMediaButton(Intent mediaRequestIntent) {
@@ -114,4 +194,16 @@
         }
     }
 
+    private class TransportListener extends TransportPerformer.Listener {
+        @Override
+        public void onPlay() {
+            mRenderer.onPlay();
+        }
+
+        @Override
+        public void onPause() {
+            mRenderer.onPause();
+        }
+    }
+
 }
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java b/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java
index 7493366..7f62f66 100644
--- a/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java
+++ b/tests/OneMedia/src/com/android/onemedia/playback/LocalRenderer.java
@@ -499,11 +499,12 @@
     @Override
     public boolean onPause() {
         MediaPlayer player = mPlayer;
+        // If the user paused us make sure we won't start playing again until
+        // asked to
+        mPlayOnReady = false;
         if (player != null && (mState & CAN_PAUSE) != 0) {
             player.pause();
             setState(STATE_PAUSED);
-        } else if ((mState & CAN_READY_PLAY) != 0) {
-            mPlayOnReady = false;
         } else if (!isPaused()) {
             return false;
         }
diff --git a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
index a39aba8..09531fd 100644
--- a/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
+++ b/tests/RenderThreadTest/src/com/example/renderthread/MainActivity.java
@@ -7,7 +7,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.SystemClock;
-import android.view.DisplayList;
+import android.view.RenderNode;
 import android.view.HardwareRenderer;
 import android.view.ThreadedRenderer;
 import android.view.View;
@@ -70,7 +70,7 @@
         private static final TimeInterpolator sDefaultInterpolator =
                 new AccelerateDecelerateInterpolator();
 
-        DisplayList mDisplayList;
+        RenderNode mDisplayList;
         float mFromValue;
         float mDelta;
         long mDuration = DURATION * 2;
diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
index 6666385..b235408 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java
@@ -142,6 +142,13 @@
     }
 
     @LayoutlibDelegate
+    /*package*/ static boolean native_isConvex(long nPath) {
+        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
+                "Path.isConvex is not supported.", null, null);
+        return true;
+    }
+
+    @LayoutlibDelegate
     /*package*/ static int native_getFillType(long nPath) {
         Path_Delegate pathDelegate = sManager.getDelegate(nPath);
         if (pathDelegate == null) {
diff --git a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
index d40352f..b16b4aa 100644
--- a/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
+++ b/tools/layoutlib/bridge/src/libcore/icu/ICU_Delegate.java
@@ -18,6 +18,7 @@
 
 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
 import com.ibm.icu.text.DateTimePatternGenerator;
+import com.ibm.icu.util.Currency;
 import com.ibm.icu.util.ULocale;
 
 import java.util.Locale;
@@ -117,6 +118,11 @@
     }
 
     @LayoutlibDelegate
+    /*package*/ static int getCurrencyNumericCode(String currencyCode) {
+        return Currency.getInstance(currencyCode).getNumericCode();
+    }
+
+    @LayoutlibDelegate
     /*package*/ static String getCurrencySymbol(String locale, String currencyCode) {
         return "";
     }
@@ -231,7 +237,7 @@
         result.percent = '%';
         result.perMill = '\u2030';
         result.monetarySeparator = ' ';
-        result.minusSign = '-';
+        result.minusSign = "-";
         result.exponentSeparator = "e";
         result.infinity = "\u221E";
         result.NaN = "NaN";